Antigravity (agy): plugin hooks.json fails to parse — the using-superpowers bootstrap never loads
Summary
On Antigravity CLI (agy 1.1.24) the plugin's hooks/hooks.json is not merely unfired for want of a SessionStart event — it fails to parse. agy plugin install reports ✔ hooks : 1 processed, but agy rejects the file at load time. Antigravity users therefore get the 14 skills on disk with no bootstrap, which by this project's own porting guide means "the skill files are inert — present on disk, never invoked."
Versions
- superpowers 6.3.0, installed with
agy plugin install https://github.com/obra/superpowers - Antigravity CLI
agy1.1.24, macOS 15.6
Reproduce
agy plugin install https://github.com/obra/superpowers
# [ok] superpowers
# ✔ skills : 14 processed
# ✔ hooks : 1 processed <-- counted, but not loadable
agy --log-file /tmp/agy.log --print "hi"
grep -i hook /tmp/agy.logW hooks.go:73] Failed to parse hooks for plugin superpowers:
invalid hook "hooks": command hook must specify 'command'Root cause
hooks/hooks.json wraps its events in a top-level hooks key:
{ "hooks": { "SessionStart": [ ... ] } }agy treats each top-level key as a hook name, so it reads a hook literally named hooks, finds no command on it, and discards the file. The shape agy accepts is a named hook mapping event names to entries that carry command directly:
{ "superpowers-gate": {
"enabled": true,
"PreInvocation": [ { "type": "command", "command": "/abs/path/hook.sh", "timeout": 10 } ] } }Worth noting this is also not the shape in Google's published hooks docs, which show matcher plus a nested hooks[] array — that form is rejected with the same error.
Three further blockers, even if it parsed
SessionStartis not a configurable agy event. The accepted config keys arePreToolUse,PostToolUse,PreInvocation,PostInvocation,Stop. (SessionStartHookArgs/SessionStartHookResultexist in agy's protobuf layer but are not exposed inhooks.json.)${CLAUDE_PLUGIN_ROOT}is never set by agy, and agy does not interpolate${...}in command strings — the same class of failure as #2105.- Wrong output field.
hooks/session-startfalls through to the genericadditionalContextbranch. agy's injection field isinjectSteps, an array ofHookInjectedStepobjects (userMessage/ephemeralMessage/systemMessage/toolCall), so a parsed and fired hook would still emit a field agy ignores.
Docs mismatch
docs/porting-to-a-new-harness.md prescribes, for Antigravity, a .antigravity-plugin/install.sh shipping a generated context file declared by a manifest contextFileName, and states that agy plugin install reports ✔ context : ANTIGRAVITY.md.
There is no .antigravity-plugin/ on main, and agy's Plugin message has no context component — its fields are skills, agents, mcp_servers, rules, hooks_json. I also tested shipping a plugin containing rules/: the files are copied into the plugin dir, but agy plugin list reports "components": null, so rules are not a plugin-installable component either.
What does work
Two mechanisms, both verified on this machine:
- Bootstrap via the global rules file. Generating
~/.gemini/config/AGENTS.mdfrom the installedusing-superpowersbody plusreferences/antigravity-tools.md, inlined — agy does not expand@pathincludes in that file, it passes the literal string through into<RULE[user_global]>. Confirmed loaded with a marker token round-trip. - A
PreInvocationhook, using the flat schema above and emitting{"injectSteps":[{"ephemeralMessage":"..."}]}. Confirmed firing and confirmed reaching the model.
Related: #1636, #1657, #2105.
Happy to open a PR if you'd like a particular direction — the minimal fix is the hooks.json shape plus an Antigravity-aware branch in hooks/session-start, though that only helps once agy exposes a session-start event; the global-rules-file route works today.
Source: obra/superpowers