Repository navigation
feat: report Antigravity CLI sessions to lich - #21
Merged
Merged
Conversation
The registration was written against Claude Code's assumptions, so none of it
ran. Five things were wrong, each silent:
- `${CLAUDE_PLUGIN_ROOT}` — Antigravity sets no plugin-root variable. It runs a
hook through `sh -c` with the working directory set to the folder holding
hooks.json, so the paths are relative to that. Under the old registration
every hook ran `/hooks/<script>` and exited 127, on every event.
- No manifest — an Antigravity plugin is `plugins/<name>/plugin.json` with its
`hooks.json` and `skills/` beside it. Neither name is configurable, so
`hooks/antigravity-hooks.json` was discovered by nothing. Both files move to
the repository root, which is the plugin directory once the clone is linked
in; `agy plugin validate .` went from "missing plugin.json" to loading one
skill and one hook.
- No verdict on stdout — Antigravity reads a JSON object back and acts on it,
and `decision` is required before a tool call. The registration now appends
the answer each event asks for, so the shared scripts stay silent for Codex,
where stdout answers a permission request.
- Tool names that do not exist — `write_to_file`, `replace_file_content` and
`find_by_name` are Windsurf's. Antigravity's come from its step-type enum:
`propose_code`, `file_change`, `edit_notebook`, `run_command`. The touched
matcher had been naming tools it could never match. Same for three of
detail.jq's argument fields.
- An edited fixture — the fixtures are lich's, and lich has not registered the
provider, so `/session-start` answers 400. Reverted; `PENDING_UPSTREAM` in
tests/contract.mjs names the gap, and fails once a refreshed fixture closes
it. The shape assertions never needed the edit.
The suite could not catch the first of these because it exported
$CLAUDE_PLUGIN_ROOT for every harness. Registrations now run the way their own
harness runs them, and two guards cover the Antigravity-specific rules.
The previous commit replaced `write_to_file|replace_file_content|run_command` with names read out of the binary's step-type enum. The enum is the implementation's vocabulary, not the payload's: a turn measured on agy 1.1.19 sends `write_to_file`, `replace_file_content`, `view_file`, `list_dir`, `run_command` and `call_mcp_tool`, and only the last of those resembles its enum entry (`MCP_TOOL`). So the corrected matcher matched `run_command` alone, and a write with no shell behind it stopped refreshing the card's git status — the same silent failure as before, with the sign flipped. Measured names restored, here and in the docs. Same for detail.jq: `TargetFile`, `AbsolutePath` and `DirectoryPath` are what arrive; the four enum-derived spellings beside them are dropped rather than left as rungs nothing ever lands on. While there: every MCP server's tools reach a hook as the single tool `call_mcp_tool`, so the card was showing that name for all of them. The server and the tool it called come as arguments, and detail.jq now reads them — lich's own tools are what a session is most likely to be running. The rule in CLAUDE.md said to take names from the harness itself and gave the binary as one of the places to look. It is not: a name is measured off a real payload or it is a guess.
lich registered the provider (lichdotdev/lich#370), so `refresh-fixtures.sh` brings down a `session-start` case for it and `PENDING_UPSTREAM` empties — the guard that fails once a refreshed fixture registers a pending provider did exactly that, which is what emptied it. The enumerations come from the fixtures alone again, and the antigravity payload is now held to an accepted case by value rather than by shape.
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
Adds support for Google Antigravity CLI as a sixth supported harness.
Key Changes:
hooks/antigravity-hooks.json): Configured lifecycle hooks for Antigravity CLI:PreInvocation: Reports session start (report-session-start.sh antigravity) and busy state (report-state.sh busy).PreToolUse: Reports currently executing tool with details (report-tool.sh).PostToolUse: Refreshes git status on write tools (write_to_file|replace_file_content|run_command).Stop: Reportsdonestate and extracts the session title (report-title.sh).report-session-start.sh: Added.conversationIdpayload support.report-tool.sh: Added.toolCall.namepayload support.detail.jq: Supports Antigravity workspace roots (.workspacePaths[0]) and PascalCase tool argument fields (CommandLine,TargetFile,AbsolutePath,SearchPath,Query,Url, etc.).report-title.sh: Reads firstUSER_INPUTline fromtranscriptPathand trims<USER_REQUEST>block tags.tests/hooks.test.mjsand fixtures (all 182 tests passing).docs/providers.md,docs/session-*.md, andCHANGELOG.md.