Repository navigation
Make the plugin the only Claude Code wiring and add a Codex plugin - #258
Merged
Merged
Conversation
The plugin now starts zerograph's MCP server itself and ships seven slash commands that call its tools: ask, impact, trace, changes, explain, status and refresh. Each pre-approves only the mcp__plugin_zerograph_zerograph__* tools it calls and tells the model how to read the answer: open the top path:line, and pair a "nothing uses this" with a text search. A use-the-graph skill tells the model when to reach for those tools instead of grep. The server is declared in plugin.json and started by scripts/mcp.mjs, which finds the binary the way the status mod does: the binary option when it is absolute, else zerograph on PATH outside the checkout. plugin.json can substitute the option but not branch on it. The MCP server gains cache_status, the report `cache status` prints, and reindex now starts a first build where no store stands rather than an update, each taking the writer lock in its own process. install-agent --claude's local-scope server would run beside the plugin's, so the docs say to remove it when the plugin is installed.
- Refuse to start npm's zerograph.cmd shim through cmd when its path or the checkout's holds & | < > ^ " % !, which cmd would act on, and say so on stderr. - Hand the server a PATH cut to the entries outside the checkout. - Compare PATH entries with the checkout both as spelled and with links followed, so a symlinked alias does not let a checkout binary through. - Require the exec bit on a PATH candidate on POSIX. - Outside git, take the nearest ancestor holding .zerograph/ as the repository, as the CLI does, before falling back to the project dir. - cache_status no longer creates the cache directory: a cache not made yet reports as empty. - Document the bare node the plugin config starts, the .cmd refusal and the cut PATH.
Main's Status now carries the models and the unreadable bytes, so the report of a cache not made yet is compared whole instead of through a Vec method it no longer is.
The Claude Code plugin now carries the session hook (moved from agent/hook.mjs to agent/claude-code/scripts/hook.mjs) beside its MCP server, and both find and start the binary through one shared launcher.mjs, so they cannot disagree about which zerograph is safe to run. The hook takes the plugin's binary option, and a checkout that never asked for an index hears nothing from it. agent/codex/ is a new Codex plugin listed by .agents/plugins/marketplace.json: the MCP server through a bootstrap that finds the installed plugin under CODEX_HOME (Codex substitutes nothing in MCP args), the hook on SessionStart, SubagentStart and after an apply_patch, and the commands as explicit-only skills. Its scripts are copies of the Claude Code plugin's, held identical by plugin.test.mjs, which CI now runs. install-agent --claude and --codex install the plugin through the claude or codex CLI, print the commands when the CLI is missing, and only once it is in take out what earlier releases wrote: the local-scope MCP servers for the checkout and its worktrees, the hook entries and script, the skills and subagent while still generated, and the instructions stanza (kept in AGENTS.md while opencode reads it). BREAKING CHANGE: install-agent --claude/--codex no longer register an MCP server, write hooks, skills or a stanza; they install the plugin and remove those files from an earlier install. --command no longer reaches Claude Code or Codex.
- Hook entries are retired per command, so a command sharing a matcher group with ours stays. - A symlinked settings file, rule, subagent or hook script is left and named instead of unlinked. - $CODEX_HOME/hooks.json is rewritten where its link points. - The MCP launcher takes ZEROGRAPH_BIN before the binary option, as the hook does, and treats the unsubstituted option as unset. - On Windows the claude and codex CLIs are found as npm .cmd shims too. - The docs no longer promise a refresh after every edit.
…he CLI does - When the checkout is the home directory, an ancestor of it or a filesystem root (a ~/.zerograph or a dotfiles ~/.git), the PATH cut is skipped in both the MCP launcher and the session hook, since it took nvm, cargo and ~/.local/bin with it. - PATH is matched case-insensitively only on Windows. - A quoted Windows PATH entry is judged without its quotes and kept as written. - The checkout is looked up from the real path of the session directory, as the CLI canonicalizes its working directory.
Carries #257's launcher fixes into the shared launcher.mjs: no PATH cut when the checkout is the home directory, above it or a filesystem root; PATH matched case-insensitively only on Windows; a quoted Windows entry judged without its quotes and kept; the checkout found from the session directory's real path. The hook now finds its checkout through the launcher, and a PATH entry that does not exist yet is compared with its existing part's links followed, so it still names a checkout reached through /var or another link.
The checkout lookup follows links with realpathSync.native, which on Windows also expands 8.3 short names such as RUNNER~1, so the tests now build their expected paths the same way. The POSIX PATH-key case uses POSIX literals, since a drive letter's colon split a Windows host's real paths.
The checkout lookup follows links with realpathSync.native, which on Windows also expands 8.3 short names such as RUNNER~1, so the tests now build their expected paths the same way. The POSIX PATH-key case uses POSIX literals, since a drive letter's colon split a Windows host's real paths.
…agent-plugins # Conflicts: # agent/claude-code/scripts/mcp.test.mjs
# Conflicts: # .github/workflows/ci.yml # README.md # agent/claude-code/scripts/hook.mjs # agent/claude-code/scripts/mcp.mjs # agent/claude-code/scripts/mcp.test.mjs # docs/install.md # docs/mcp.md
- The risk line reads Codex's apply_patch: every file a patch adds, updates or moves to is scored, not only Claude Code's file_path. - install-agent takes a hook script out only after the entries that run it are gone, in .claude/settings.json and in $CODEX_HOME/hooks.json, and only while it is the text 0.6.0-0.6.4 wrote (kept in agent/legacy/zerograph-hook.mjs). - Files git tracks are left for the team and listed in one line; --retire-repo takes them out once every teammate has the plugin. - A re-run after a binary upgrade moves the plugin with it: Claude Code refreshes the marketplace and runs plugin update, and Codex removes and re-adds a marketplace pinned to an older tag. - The Codex MCP bootstrap finds the newest installed version instead of naming one, says so when none is installed, and passes the ZEROGRAPH_*, model cache, proxy, certificate and locale variables through. - Codex hooks carry a commandWindows form that reads PLUGIN_ROOT in node. - mcp.mjs drops its own copy of the unset-option placeholder. - scripts/sync-plugin-scripts.sh copies the launcher scripts into the Codex plugin. - Docs and release notes name the commands the code runs.
On Windows the report holds backslash paths, so a string suffix with forward slashes never matched.
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.
Summary
Stacked on #257. Makes the plugin the only way zerograph wires into Claude Code, and adds the same plugin for Codex.
Claude Code plugin carries the session hook.
agent/hook.mjsmoves toagent/claude-code/scripts/hook.mjs, wired throughhooks/hooks.jsonon SessionStart, SubagentStart, PreToolUse and PostToolUse. The hook andmcp.mjsnow sharescripts/launcher.mjs, so binary lookup, the.cmdguard and the PATH cut have one source. The hook reads the plugin'sbinaryoption. A checkout that never asked for an index (nozerograph.toml, no legacy hook, no built main worktree) hears nothing. Therepo-scoutsubagent ships in the plugin.Codex plugin,
agent/codex/, listed by.agents/plugins/marketplace.json. Codex substitutes nothing in MCP args, so.mcp.jsonruns anode -ebootstrap that importsscripts/mcp.mjsfrom$CODEX_HOME/plugins/cache/zerograph/zerograph/<version>/. The hooks run on SessionStart, SubagentStart and PostToolUse (apply_patch|Edit|Write); like before there is no PreToolUse interceptor. The seven commands ship as$zerograph:<name>skills withallow_implicit_invocation: false, plususe-the-graph. The scripts are copies of the Claude Code ones, andagent/codex/plugin.test.mjsfails when they differ. It also fails when the bootstrap's version, the two plugin versions or the crate's disagree.install-agent --claude/--codexrunclaude plugin marketplace add+plugin install(orcodex plugin marketplace add --ref v<version>+plugin add). Where the CLI is missing they print the commands and change nothing. Only once the plugin is in do they remove the earlier install:~/.claude.jsonfor the checkout, its worktrees and removed checkouts;.claude/settings.jsonand$CODEX_HOME/hooks.json;zerograph/repo-queryskills andrepo-scout, while still generated;AGENTS.mdwhile opencode reads it.Edited files are left and named. The git-block retirement is unchanged. Legacy templates move to
agent/legacy/for the comparisons.Docs: the README install line and plugin section,
docs/install.md(Upgrading, Claude Code plugin, a new Codex plugin section),docs/mcp.md,docs/keeping-fresh.md,agent/codex.md, and a Breaking line indocs/releases/0.7.0.md. The release-note lines for the superseded registration and printed-hook fixes are removed.CI runs the moved hook test and the new Codex plugin test.
Open points:
--ref v0.7.0resolves only once the tag exists.${PLUGIN_ROOT}undercmd) are untested.--commandno longer affects the Claude Code or Codex integration.Test plan
cargo test: all suites green, including 26 install_agent tests covering the plugin steps per harness, a missing CLI, a failed step, a re-run over an older install, edited files kept, the opencode stanza, a linked CLAUDE.md, the Codex hooks file and pruning a live replaced checkout.cargo clippy --all-targets -- -D warningsnode --test agent/claude-code/scripts/hook.test.mjs agent/claude-code/scripts/mcp.test.mjs agent/codex/plugin.test.mjs npm/zerograph/test/launcher.test.js: 71 pass.claude plugin validate --strict agent/claude-codeand on the repo marketplace;claude plugin test agent/claude-code(26 pass).claude -p --plugin-dir agent/claude-code "/zerograph:impact priceOf"on a scratch repo: the SessionStart brief was injected,plugin:zerograph:zerographwas connected, the command calledmcp__plugin_zerograph_zerograph__impact, and the PreToolUse interceptor answered the follow-up grep from the graph.CODEX_HOME:codex plugin marketplace add <worktree>+plugin addinstalled 0.7.0, the app server listed the skills,codex execran the SessionStart hook, and the MCP bootstrap started the binary as--repo <project> mcp.install-agent --claude --codexagainst fakeclaude/codexCLIs over a hand-made 0.6.x install. Both plugins were installed. The hook, the settings entries, the stanza and the~/.claude.jsonserver were removed; an edited skill and an edited rule were kept with a note.