Repository navigation
feat(hook): add native Google Antigravity plugin lifecycle and hook support - #3711
Conversation
ef02ead to
3e03020
Compare
8b88dc0 to
17bfef3
Compare
Update: Rebased & Refactored to Canonical Antigravity Plugin IntegrationI have rebased this PR onto latest
Ready for review! |
17bfef3 to
406b928
Compare
406b928 to
064cb2f
Compare
Update: Rebased on
|
…t like the sibling agents On develop the rules file handed the agent the full awareness text; the plugin bundle carried none, so a session got the rewrite and nothing that says output is condensed or how to recover with rtk proxy. The plugin now holds rules/AGENTS.md with the file awareness.level selects, plain markdown with no frontmatter, which Antigravity applies whenever the plugin is enabled. A re-run rewrites it, so changing the level takes effect. The plugin files go through the shared atomic_write, and plugin.json, the file that makes Antigravity discover the directory, is written last: a write that fails halfway leaves no plugin rather than one missing its rules. The install output tells the user to restart Antigravity, which only discovers a plugin directory on startup. Uninstall reports like Factory Droid: a "not installed (nothing to remove)" line when there is no plugin, otherwise a header and the removed items, and the dry-run footer; the helper that removes the directory prints nothing. README's agent table and the configuration guide no longer describe the rules file, and the "<1.5ms" figure goes: the hook measures about 7 ms end to end. Process-level tests pin the printed lines and that both dry runs change nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Round 1 of 3 — APPROVED, follow-ups filed
Claim: rtk hook antigravity is a native PreToolUse hook that rewrites run_command calls through overwrite.CommandLine, and rtk init [-g] --agent antigravity [--uninstall | --dry-run] installs and removes an Antigravity plugin bundle at .agents/plugins/rtk/ or ~/.gemini/config/plugins/rtk/, replacing the rules-file mode.
Scope: accept if narrowed to "the native hook and the plugin lifecycle for a fresh install"; migrating a project set up by an earlier release (its .agents/rules/antigravity-rtk-rules.md) is cut and tracked as #4317. #3959 proposes the same hook with a root hooks.json merge and no uninstall; it is a duplicate of this one, and the comment there recommends closing it. #4269 (maintainer branch, every init write through one guarded path) touches the same directory and lands after this PR; routing the two new writes is done there.
Ran: agy 1.2.12 embedded hook and plugin docs (Docker) × the contract this PR implements; rtk hook antigravity × 16 payload shapes (rewrite, already-prefixed, pipe, && chain, cd &&, subshell, redirect, unknown binary, other tool, empty command, invalid JSON, empty stdin, closed stdin, BOM, command key, cwd = plugin dir) × merge-base vs head; init/uninstall × local, global, dry-run, re-run, nothing installed, foreign files in the plugin dir, symlinked plugin dir, root hooks.json present, ~/.claude/settings.json present; upgrade from the merge-base's rules-file install. Invariants: every decision arm driven (Deny is unreachable for Host::Antigravity, as for Host::Vibe); under the hook (rtk rewrite, rtk hook check --agent antigravity); split streams (stdout is the JSON only). Mutation: 5 mutants (BOM strip, command key fallback, uninstall no-op, AgentPath back to rules-only, global root = local root), each killed by a named test. Windows cfg paths type-checked. Savings: n/a (hook, no filtered output).
Matrix: executed this round @064cb2f7 and on the fixup head @0671ac5b.
CI @0671ac5b: all green (11/11, including test on ubuntu, macos and windows); the author's head 064cb2f had never been built by CI.
Blocks merge (1, frozen at round 1; closed by the fixup)
src/hooks/init/antigravity.rs:71— awareness text dropped (1 site). Ondevelop,rtk init --agent antigravitygives the agent the full awareness text through.agents/rules/antigravity-rtk-rules.md; the plugin this PR installs holdsplugin.jsonandhooks.jsononly, so an Antigravity session gets the rewrite and nothing that says output is condensed, thatrtk proxy <cmd>is the recovery path, or thatrtk gainexists. Evidence:find .agents -type fafter init on the merge-base lists the rules file; on the head it lists the two JSON files and no rules. Antigravity's plugin docs (agy 1.2.12) give the slot:rules/AGENTS.md, plain markdown, no frontmatter, always on while the plugin is enabled. The fixup writes it withawareness_content(ctx.awareness), soawareness.levelapplies as it does for Gemini and Vibe. Test:test_antigravity_mode_writes_awareness_rules_at_each_level.
Filed as follow-ups
- #4317
rtk init --agent antigravityleaves the rules file written by earlier releases in place — cut by the narrowed claim; filed. - #913 "No hook installed" warning for non-Claude agents — pre-existing (
hook_check::status()reads Claude's settings only; reproduced:rtk gainwarns after an Antigravity-only install whenever~/.claudeexists); absorbed, comment added for the Antigravity arm. - #3404 and #3406 stay open: this PR fixes their Antigravity arm only (the global uninstall no longer runs the Claude uninstaller, and the rules-file substring check is gone for this agent); Kilo Code, Windsurf, Cline and Kimi are unchanged.
Checked and correct — no need to re-verify
- Contract matches the CLI's own docs: hook-name namespace with
enabled,PreToolUsegrouped undermatcher/hooks,run_command,timeoutin seconds,overwriteshallow-merged at top level, the agent notified of rewritten keys. Plugin discovery from.agents/plugins/<name>/and~/.gemini/config/plugins/<name>/withplugin.jsonas the marker, hooks loaded from the plugin. - Fail-open on every malformed input (invalid JSON, empty, closed stdin, BOM); other tools and an empty
CommandLineanswer{"decision":"allow"}with nooverwrite; already-prefixed commands are not rewritten; chains and pipes are rewritten per segment like every other host. - The hook runs with its cwd set to the plugin directory (Antigravity's rule): the decision does not depend on cwd for this host, output identical from the project root and from
.agents/plugins/rtk/. rtk init -g --agent antigravity --uninstallno longer reaches the Claude uninstaller: on the merge-base it emptied~/.claude/settings.json'sPreToolUse; on the head that file is untouched.- A root
.agents/hooks.jsonwith foreign content is never read or written; a foreign file inside.agents/plugins/rtk/survives install and is removed with the directory on uninstall (the directory is RTK's, same as the Hermes plugin dir). - A symlinked
.agents/plugins/rtkis written through and only the link is removed on uninstall — the same behaviour every init writer has today, which #4269 changes for all of them. - Gate on the head: fmt, clippy,
cargo test --all4052 passed; Windowscfgpaths compile. Fixup head: 4057 passed, Windows paths compile, matrix rerun with only the intended output lines changed.
Your questions
- None posted on this PR. One from me, not holding merge: in your live runs with no
permissions.allowrule forgit status, does the hook'sallowstill prompt interactively before the rewritten command runs? The CLI's docs sayallow"automatically allows"; the binary's grant reasons have nohook_allowentry (onlyhook_deny,hook_force_ask,hook_deny_unless_prior_grant, prior-grant, workspace and autoexec grants), and #3959's author measured a headless run still denied by the host's own rules under a hookallow. If a prompt-less run is what you see, say so and the mapping becomesaskon Defer with a config toggle; otherwise the current mapping stands as documented.
Next
fixup 0671ac5 pushed, code-reviewed: the plugin gains rules/AGENTS.md at the configured awareness.level, rewritten on every run so a new level takes effect (the blocker above); the three plugin files go through the shared atomic_write (crash-safe, symlink preserved, mode 600 like every other file rtk init writes), with plugin.json written last so a failed first install leaves no half-plugin; install says to restart Antigravity; uninstall reports like Factory Droid (nothing-to-remove line, header and items, dry-run footer); README's agent table and the configuration guide stop describing the rules file; the "<1.5ms" figure is dropped; process-level tests pin every printed line and that both dry runs change nothing. The PR body's "Resolves #1975, #2803, #3404, and #3406" is narrowed to "Resolves #1975" plus a plain mention of the Antigravity arm of #2803, #3404 and #3406, so merging does not close the four-agent issues. Approving.
Rounds: 1/3. Threads: 0 open, 0 resolved this round.
|
@KuSh Thanks for the review and the polish in the fixup! Regarding your question about
So in the version I tested (live session), the hook's Based on that, keeping |
Summary
PreToolUselifecycle hook (rtk hook antigravity).--agent antigravitytarget, providing automatic command rewriting across all Antigravity surfaces: Antigravity CLI (agy), Antigravity IDE, and Antigravity 2.0..agents/plugins/rtk/for workspace,~/.gemini/config/plugins/rtk/for machine-global).rtk init --agent antigravityrtk init -g --agent antigravityrtk init --agent antigravity --dry-runrtk init --agent antigravity --uninstallrules/AGENTS.mdcarries the awareness text at the configuredawareness.level. Migrating a project set up by an earlier release (its.agents/rules/antigravity-rtk-rules.md) is tracked inrtk init --agent antigravityleaves the rules file written by earlier releases in place, on install and on uninstall #4317.rtkitself),rtk init --uninstall -g --agent kilocode(and windsurf/cline/antigravity/kimi) runs the Claude uninstaller instead — removing Claude's config and nothing of the named agent #3404 (--uninstall -g --agent antigravityno longer runs the Claude uninstaller) and Cline/Windsurf/Kilo/Antigravity install skips silently if the project's rules file contains the substring "rtk" — e.g. "RTK Query" in a Redux project #3406 (no rules-file substring check for this agent); those three stay open for Kilo Code, Windsurf, Cline and Kimi.Architectural Rationale: Modular Plugin vs. Direct File Mutation
Antigravity officially specifies plugins as the recommended way to distribute modular capabilities (
docs/plugins.md). Rather than parsing and re-serializing the user's root.agents/hooks.json(which risks dropping formatting or corrupting foreign hook configurations):plugins/rtk/), leaving root user configurations untouched.rtk init --uninstallcleanly removes the directory without leaving orphaned keys or modifying other tools.Note on Antigravity Permission Evaluation
Antigravity evaluates its tool
permissions.allowrules after thePreToolUsehook rewrites the command. If a user enforces command allowlists, permitted commands should account forrtk(e.g.command(rtk git status)orcommand(rtk *)). This is documented inhooks/antigravity/README.mdand the CLI init output.Test Plan
cargo fmt --all --checkcargo clippy --bin rtk -- -D warningscargo test --bin rtk test_antigravity— all 12 unit & lifecycle tests pass.