Skip to content

feat(cli): merge plugin hooks into antigravity's .agents/hooks.json - #958

Draft
tkman59 wants to merge 1 commit into
feat/511-antigravity-hostfrom
feat/511-antigravity-memory-hook
Draft

tkman59 wants to merge 1 commit into
feat/511-antigravity-hostfrom
feat/511-antigravity-memory-hook

Conversation

@tkman59

@tkman59 tkman59 commented Oct 5, 2026

Copy link
Copy Markdown

🎯 What & why

aidd setup --ai antigravity now installs the AIDD memory hook: agy refreshes the project memory at session start. Phase 3 of #511, stacked on #957.

🛠️ How it works

  • Route. The memory hook reaches a project through the aidd-context plugin, not through HooksCapability. Codex's HooksCapability is never fed: no codex-hooks config ref exists, so copying it would have written nothing. Antigravity uses the project-hooks route Cursor already had, with idempotent merge, per-entry provenance and safe clean.
  • Generalisation, Cursor unchanged. A tool now declares a ProjectHooksFormat beside hooksDestination: "project", which flat mode may now declare too. project-hooks-materializer.ts and remove-project-hooks.ts read only that format, with no Cursor import left. Cursor's suites pass with no assertion changed.
  • Antigravity format (antigravity-hooks.ts):
    • one key per plugin, handlers directly under SessionStart;
    • scripts copied to .agents/hooks/<plugin>/;
    • every command prefixed with cd .. && ;
    • other events skipped with a warning;
    • translate --to antigravity --as flat uses the same merge function; hooksMerge now receives the plugin name.
  • Measured on agy 1.2.17, with an interactive session under a pty (script -q /dev/null agy -i … --add-dir <ws>). In print mode the model is never called, so no hook fires.
    • Claude's nested [{ "hooks": [...] }] is rejected: invalid hook "aidd-probe": command hook must specify 'command'.
    • A workspace hook runs from <repo>/.agents, through a shell. A probe hook logged "cwd":".../agy-cwd-probe/.agents" with "workspacePaths":[".../agy-cwd-probe"]. With cd .. && , the marker read AIDD-MEMORY-MARKER cwd=<repo> docs=true.
  • Safety. An unparsable .agents/hooks.json now stops the install with the file named (.agents/hooks.json is not valid JSON (…); left untouched.), for Cursor too.

🧪 How to verify

  • cd cli && pnpm test: 6835 passed, 1 skipped. pnpm smoke: 144 passed, 0 failed.
  • Real run in a temp git repo (with aidd_docs/memory/ and AGENTS.md carrying the memory markers):
    1. aidd setup --source local --path <framework> --ai antigravity --plugins recommended --yes writes .agents/hooks.json with the aidd-context key and .agents/hooks/aidd-context/update_memory.js.
    2. Add a user key lint, then run setup again: .agents/hooks.json is byte-identical.
    3. script -q /dev/null agy -i "reply OK" --add-dir <repo> logs loaded 2 named hooks from 1 hooks.json file(s), and AGENTS.md at the repo root gains the memory list.
    4. aidd clean --force leaves .agents/hooks.json holding only lint, and removes .agents/hooks/.
  • Golden: only the antigravity:flat cell moved (.agents/hooks.json and the copied script).

⚠️ Heads-up

  • No CI runtime proof: a turn needs a Google login, and print mode fires no hook on 1.2.17.
  • The second setup in the real run was a no-op ("already installed"). Re-merge idempotence is proven by the unit test.
  • Diff is about 540 lines of code and tests, plus about 65 lines of plan. The generalisation was not split out, because alone it has a single user.
  • Out of scope, worth an issue: Codex's HooksCapability and mergeCodexHooksJson are dead code.

🔗 Linked issue

Refs #511

✅ I certify

  • I DO CERTIFY I READ EACH LINE OF THE PULL REQUEST BECAUSE I AM A SOFTWARE ENGINEER, NOT A AI PUPPY.

🤖 Generated with Claude Code

Antigravity now receives the aidd-context memory hook. Setup and plugin
install merge each plugin's hooks into .agents/hooks.json under one key
named after the plugin, copy its scripts under .agents/hooks/<plugin>/,
and clean removes that key alone, deleting the file only when empty.

The project-hooks route Cursor used is generalised: a tool declares a
ProjectHooksFormat beside hooksDestination "project", now allowed in flat
mode too, and the installer and uninstaller read only that. Cursor's
behaviour is unchanged. An unparsable project hooks file now stops the
install with the file named.

agy 1.2.17 rejects Claude's nested { hooks: [...] } groups and runs a
workspace hook from <repo>/.agents through a shell, so each command is
prefixed with "cd .. && "; events other than SessionStart are skipped
with a warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant