Skip to content

VS Code support, and the Claude install that was already running there - #29

Merged
DurthVadr merged 2 commits into
mainfrom
prd-29/vscode-agent-plugin
Sep 20, 2026
Merged

DurthVadr merged 2 commits into
mainfrom
prd-29/vscode-agent-plugin

Conversation

@DurthVadr

Copy link
Copy Markdown
Member

The submission checks read plugin.json, .plugin/plugin.json or .github/plugin/plugin.json, and this repository carried only the Claude and Codex manifests. This adds the Agent Plugins v1 manifest at the plugin root — where github/awesome-copilot resolves it from the listing's source.path — with hooks in com.github.copilot/hooks/hooks.json.

What VS Code actually grants

Measured against VS Code 1.137.0 with Copilot Chat 0.65.0, not read out of its documentation:

Event Tried Result
UserPromptSubmit continue: false Stops it. "A hook prevented chat from continuing", with the reason, and no answer.
PreToolUse permissionDecision: "deny" Denies it. The command never ran and no PostToolUse followed.
PostToolUse decision: "block" Nothing. The model quoted the secret out of the blocked terminal output.
PostToolUse continue: false Nothing. The model answered from the result anyway.

Also: a read_file result reaches hooks as tool_response: "", so a file read is covered by its path before the read; a terminal result arrives in full.

So Adapter carries powerrewrite, refuse or report-only — and _decide caps the action at what the client grants. A mask becomes a refusal where only refusal exists; a refusal becomes a report where the model already holds the data. The session record says found rather than blocked, because reporting a block the model read through is worse than reporting the finding plainly.

The fault this uncovered

VS Code reads ~/.claude/settings.json by default, so shim install claude has been registering shim in two clients at once — and in VS Code it spoke Claude's protocol, whose decision: "block" VS Code ignores. Anyone running user-prompt = "enforce" who used VS Code had prompts sent that shim reported as blocked. They are now told apart by what each always sends (permission_mode against timestamp) and answered in their own protocol. The environment is no help here: the VS Code capture carried CLAUDE_CODE_* variables inherited from the terminal that started it.

A hook asked for a client this build does not know now inspects nothing and says so on stderr, instead of answering with another client's refusal — an older package meeting this newer plugin would otherwise have blocked every VS Code prompt with a message naming Codex.

Copilot CLI and the Copilot app read the same hook file, where shim install copilot is the route, so the command stands down on COPILOT_CLI.

Verified live

  • VS Code 1.137.0, shipped plugin through hooks/run-shim and the committed archive: prompt answered shim: found EMAIL (1) in your prompt. Not modified.; cat secrets.env answered shim: found DB_URI (1), EMAIL (1), SECRET (1) in run_in_terminal. Not modified. and the model described the file without quoting a value; Stop rendered the session summary, overhead 168 ms median.
  • Claude Code 2.1.273: a Read of a synthetic .env reached the model as <SECRET_1> and <EMAIL_1>, and it said a masking layer had replaced them.
  • Copilot CLI 1.0.85: plugin loaded, hook stood down, no shim line.
  • Claude Code and Codex 0.151.0: plugin detection unchanged by the new root manifest.

Codex had no live prompt on this build; the evidence record says so.

Captures are fixtures under tests/fixtures/probe/vscode/. 2,032 tests pass, gate green at 1.0.1.

🤖 Generated with Claude Code

DurthVadr and others added 2 commits September 20, 2026 12:31
The submission checks read plugin.json, .plugin/plugin.json or
.github/plugin/plugin.json, and this repository carried only the Claude and
Codex manifests. Add the Agent Plugins v1 manifest at the plugin root, where
github/awesome-copilot resolves it from the listing's source.path, with hooks
in com.github.copilot/hooks/hooks.json.

What VS Code grants was measured against 1.137.0 with Copilot Chat 0.65.0
rather than read out of its documentation, and it is narrower than the
documentation suggests. A prompt can be stopped before it is sent and a tool
call denied before it runs. After a tool, nothing can be withheld: a probe
answering decision: "block" on a terminal result was followed by the model
quoting the secret out of that result, and continue: false did not stop the
turn either. A read_file result never reaches the hook at all, arriving as an
empty tool_response, so a file read is covered by its path before the read.

So Adapter carries a third field, power, and every adapter states which of
rewrite, refuse or report-only its client grants at that event. _decide caps
the action at it: a mask becomes a refusal where only refusal exists, and a
refusal becomes a report where the model already holds the data. The session
record follows, saying found rather than blocked, because reporting a block
the model read through is worse than reporting the finding plainly.

The same run uncovered an older fault. VS Code reads ~/.claude/settings.json
by default, so shim install claude has been registering shim in two clients at
once, and in VS Code it spoke Claude's protocol: decision: "block" is a field
VS Code ignores. Anyone running user-prompt = "enforce" who used VS Code had
prompts sent that shim reported as blocked. The two are now told apart by what
each always sends, permission_mode against timestamp, and answered in their
own protocol. The environment cannot be used for this: the VS Code capture
carried CLAUDE_CODE_* variables, inherited from the terminal that started it.

A hook asked for a client this build does not know now inspects nothing and
says so on stderr, rather than answering with another client's refusal; an
older package meeting this newer plugin would otherwise have blocked every VS
Code prompt with a message naming Codex.

Copilot CLI and the Copilot app read the same hook file, where shim install
copilot is the supported route, so the command stands down on COPILOT_CLI.

Live: the shipped plugin in VS Code 1.137.0 (prompt, terminal result and
session summary), Claude Code 2.1.273 masking a .env through the committed
archive, Copilot CLI 1.0.85 standing down, and plugin detection unchanged on
Claude Code and Codex 0.151.0. Captures are fixtures under
tests/fixtures/probe/vscode/. 2,032 tests pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The README is the tour and commands.md is the reference; neither answers "my
team's hostnames are not secrets to the detector" or "one tool is noisy and I
do not want to disable a type everywhere". Eleven recipes, each one a problem
someone actually has, with the two lines that solve it.

Every command in it was run before it was written: the custom-pattern pair
against `shim redact`, the reveal format, `scan`'s grep-style exit codes, and
the settings path `shim config` prints. The client table says what each one can
do rather than what its documentation implies, including the VS Code limits
measured for 1.0.1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@DurthVadr
DurthVadr merged commit 4b68ff1 into main Sep 20, 2026
9 checks passed
@DurthVadr
DurthVadr deleted the prd-29/vscode-agent-plugin branch September 20, 2026 09:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant