Skip to content

VS Code / GitHub Copilot hooks

Gensee integrates with VS Code agent mode through its command-hook interface. The hook records prompts and tool intent in the shared Gensee timeline and evaluates PreToolUse events against the active safety policy before a tool runs.

Setup

Install Gensee, then configure the user-level VS Code hooks file:

bash
gensee setup vscode --gensee-home "$GENSEE_HOME"

When running from a source checkout:

bash
cargo build -p gensee-crate-cli
GENSEE_HOME="$PWD/.gensee-dev" ./target/debug/gensee setup vscode

The setup command writes ~/.copilot/hooks/gensee.json, preserves non-Gensee hook entries in the same events, and replaces stale or duplicate Gensee entries. Changed files are backed up and written atomically; unchanged setup runs do not rewrite them. VS Code reloads hook files automatically when saved.

The one-line installer also supports an explicit VS Code toggle:

bash
curl -fsSL https://raw.githubusercontent.com/GenseeAI/gensee-crate/main/scripts/install_oss.sh | GENSEE_CONFIGURE_VSCODE=1 bash

VS Code also loads Claude-compatible hooks from ~/.claude/settings.json. If Claude Code hooks are already installed, VS Code may invoke those commands too. Gensee recognizes VS Code compatibility payloads using multiple runtime markers. The Claude compatibility invocation exits successfully without evaluating or recording only after the matching native VS Code invocation has been observed recently for the same session, event, and tool or timestamp. Hook configuration on disk is not treated as proof that a native hook is live. If the compatibility invocation wins a startup race, required identifiers are absent, or evidence cannot be read, it is processed through the VS Code parser. This can produce a duplicate event but preserves enforcement and the correct response format.

A suppressed invocation records the local telemetry event hook_compatibility_duplicate_suppressed. Gensee also writes a warning to the host hook log on the first suppression and periodically thereafter; the notice is rate-limited per native provider and does not depend on telemetry collection being enabled.

Custom hook locations

Pass --hooks for another user-level path or for a workspace hook checked into source control:

bash
gensee setup vscode \
  --gensee-home "$GENSEE_HOME" \
  --hooks .github/hooks/gensee.json

Use --bin when the generated hook should call a different Gensee binary:

bash
gensee setup vscode \
  --gensee-home "$GENSEE_HOME" \
  --bin /absolute/path/to/gensee

Enforcement behavior

Gensee installs hooks for UserPromptSubmit, PreToolUse, PostToolUse, and Stop. PreToolUse returns VS Code's allow, ask, or deny decision before the tool runs. Known native file tools are converted into read, write, edit, or delete policy subjects:

VS Code toolPolicy operation
runTerminalCommand, runInTerminalShell command and parsed file intents
editFiles, edit_filesEdit each path in tool_input.files
createFile, create_fileWrite
replaceStringInFile, replace_string_in_fileWrite
insertEditIntoFile, insert_edit_into_fileWrite
readFile, read_fileRead
deleteFile, delete_fileDelete

If a known file tool cannot be parsed, or an unknown tool carries file-shaped inputs, Gensee asks for approval instead of silently bypassing path policy. It also records a schema-drift event so runtime payload changes are visible.

Verify the installation

Run one terminal command and one file creation through VS Code agent mode, then inspect the VS Code Agent Log to confirm the actual tool_name and tool_input payloads. Hook schemas are evolving, so the runtime log is the source of truth for the installed VS Code build.

Inspect the resulting Gensee activity with:

bash
gensee timeline --latest

For generated hook JSON examples and implementation details, see the integration README.

Released under the Apache 2.0 License.