Repository navigation
feat(cli): give Copilot searches graph context through a PostToolUse hook - #2801
Merged
Merged
Conversation
…hook Copilot CLI's preToolUse output can only decide permissions, and its command hooks fail closed on errors, so the graph context that Claude Code and Codex searches get could not ride a pre-tool hook there. postToolUse additionalContext is appended to the tool result the model sees on the same turn (github/docs content/copilot/reference/hooks-reference.md). VS Code's agent mode shares the Copilot harness and reads the same ~/.copilot/hooks manifest. - Manifest: $COPILOT_HOME/hooks/codebase-memory-mcp.json adds a PascalCase PostToolUse entry, matcher "Bash|Grep|Glob|bash|powershell|grep|rg|glob", running hook-augment --event PostToolUse --dialect copilot. The previous lifecycle-only manifest, as installs up to v0.12 wrote it, stays recognized as owned: install upgrades it in place and uninstall removes either generation. A foreign manifest still fails closed. - hook-augment: the Copilot dialect reads either payload form (tool_name/tool_input or toolName/toolArgs), maps runtime tool names to the Claude names (bash/powershell to Bash, grep/rg to Grep, glob to Glob), parses arguments passed as a JSON string, and answers with top-level additionalContext. - Fast path: Copilot's forced PostToolUse goes through the no-op gate before executable-identity hashing. The gate also skips tools the augmenter does not read, because VS Code's local hook parser ignores matchers, so a non-search shell call or an edit exits in about 20 ms instead of paying the full round-trip of about 130 ms. - The context header no longer says the search results are "below": after a post-tool hook they are above it. - Tests: the three Copilot foreign-manifest tests now create .copilot/mcp-config.json. Without it Copilot CLI was never detected, so install and uninstall never reached the manifest, and the tests also passed with the ownership checks removed. Refs #509 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
…h hooks The Codex CLI row still listed only SessionStart and SubagentStart after the PreToolUse Bash hook landed (#2719), and the hook section described only Claude Code's search context. The row now names the Codex search hook, and the section says how Codex, Copilot CLI and VS Code's Copilot runtime get search context. Refs #509 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The PostToolUse change rendered the manifest twice per install and uninstall (current and previous generation) and freed both with free(), which grew the raw allocator count in src/cli/cli.c past its baseline (lint-memory-core). The manifest is now written with cbm_json_writer_allocator() and released with cbm_free(CBM_MEM_CLASS_OTHER, ...), including the frees that predate the change, so cli.c drops from 170 to 166 raw sites and its baseline is lowered to match. The rendered bytes are unchanged, so byte-exact ownership of manifests written by earlier installs still holds. Refs #509 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Claude Code's and Codex's searches get graph context from a PreToolUse hook. GitHub Copilot CLI only had the SessionStart and SubagentStart context. Its hook contract rules out the pre-tool route (github/docs
content/copilot/reference/hooks-reference.md):preToolUseoutput can only decide permissions (permissionDecision,permissionDecisionReason,modifiedArgs), and commandpreToolUsehooks fail closed on errors.postToolUsecan return a top-leveladditionalContext, which is "appended totextResultForLlmso the model sees it after the tool output on the same turn".VS Code's agent mode shares the Copilot harness and reads the same
~/.copilot/hooksmanifest (code.visualstudio.com/docs/copilot/customization/hooks), so the same entry serves it.What changes
$COPILOT_HOME/hooks/codebase-memory-mcp.jsonadds a PascalCasePostToolUseentry, matcherBash|Grep|Glob|bash|powershell|grep|rg|glob, runninghook-augment --event PostToolUse --dialect copilot. The matcher names both the Claude names and the runtime names, because the documented PostToolUse matcher is a regex against the runtime tool name. The previous lifecycle-only manifest, as installs up to v0.12 wrote it, stays recognized as owned: install upgrades it in place, and uninstall removes either generation. A foreign same-named manifest still fails closed.tool_name/tool_inputortoolName/toolArgs), maps the runtime tool names to the Claude names (bash/powershellto Bash,grep/rgto Grep,globto Glob), parses arguments passed as a JSON string, and answers with top-leveladditionalContext.PostToolUsenow goes through the hook client's no-op gate before executable-identity hashing. For Copilot the gate also skips tools the augmenter does not read, because VS Code's local hook parser ignores matchers and the entry can fire after every tool. Other dialects keep their gate unchanged.cbm_json_writer_allocator()and released withcbm_free(CBM_MEM_CLASS_OTHER, ...), the frees that predate this change included.src/cli/cli.cdrops from 170 to 166 raw allocator sites, and itsscripts/memory-core-baseline.txtline is lowered to match. The rendered bytes are unchanged.PreToolUseBashhook, and the hook section says how Codex and Copilot get search context.Proof on real output
Built binaries, isolated
HOME/cache/runtime, live daemon:sessionStart+subagentStartPostToolUseadded with the matcher above,hooks: SessionStart + SubagentStart + PostToolUse searchestool_namerg, run through the manifest's ownbashcommandadditionalContextwith the graph symbol and the follow-up line, about 137 mstoolNamebash,toolArgsas a JSON stringbash ls -la, and aneditcallTests
cli_copilot_manifest_adds_posttooluse_search_hookpins the entry's shape beside the lifecycle pair, and that the previous rendering has no PostToolUse.cli_copilot_install_upgrades_previous_manifestcovers upgrade in place, idempotence, and uninstall of the previous manifest.cli_hook_augment_copilot_posttooluse_searchcovers therg, Claude-name and camelCase string-argument forms, theviewtool staying silent, and invocation support.cli_hook_augment_copilot_posttooluse_noop_gatecovers non-search shell calls and unread tools as no-ops, searches paying full fare, and the Claude and Gemini gates unchanged..copilot/mcp-config.json. Without it Copilot CLI was never detected, so install and uninstall never reached the manifest, and the tests also passed with the ownership checks removed.cli370 passed / 0 failed (1 Windows-only skip from fix(cli): resolve Windows CLI detection for long PATH and npm/mise/scoop shims (#221) #2381),agent_clients39 / 0,daemon_application87 / 0,daemon_bootstrap28 / 0.Refs #509