Antigravity (agy): plugin hooks.json fails to parse — the using-superpowers bootstrap never loads

Author: medvegyCreated Sep 2, 2026Updated Oct 1, 2026
Labelsbugantigravityhooksskill:using-superpowers

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 agy 1.1.24, macOS 15.6

Reproduce

bash
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.log
W 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:

json
{ "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:

json
{ "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

  1. SessionStart is not a configurable agy event. The accepted config keys are PreToolUse, PostToolUse, PreInvocation, PostInvocation, Stop. (SessionStartHookArgs/SessionStartHookResult exist in agy's protobuf layer but are not exposed in hooks.json.)
  2. ${CLAUDE_PLUGIN_ROOT} is never set by agy, and agy does not interpolate ${...} in command strings — the same class of failure as #2105.
  3. Wrong output field. hooks/session-start falls through to the generic additionalContext branch. agy's injection field is injectSteps, an array of HookInjectedStep objects (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:

  1. Bootstrap via the global rules file. Generating ~/.gemini/config/AGENTS.md from the installed using-superpowers body plus references/antigravity-tools.md, inlined — agy does not expand @path includes in that file, it passes the literal string through into <RULE[user_global]>. Confirmed loaded with a marker token round-trip.
  2. A PreInvocation hook, 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.