Commit Graph

2 Commits

Author SHA1 Message Date
undeadindustries fc89a1b67e feat(antigravity): add recall skill, optional rule, shared protocol
Adds the recall layer to the Antigravity plugin, mirroring the three-
layer wiring from feat/cursor-hooks-support, adapted for Antigravity's
native plugin and hook surfaces.

The wake hook (PreInvocation, invocationNum==1) was already the eager
layer — it injects verbatim palace content via injectSteps[].
ephemeralMessage before the first model call, which is strictly better
than Cursor's static directive. This commit adds the on-demand layers:

- integrations/shared/recall-protocol.md: single canonical source of
  truth for "search before answering", shared across Cursor, Antigravity,
  Claude Code, Codex, OpenClaw. Ported from feat/cursor-hooks-support
  with the wake-up step de-coupled from any IDE-specific hook name.

- .antigravity-plugin/skills/mempalace-recall/SKILL.md: recall-only
  skill with Protocol, Tool selection, Unhappy paths, and Anti-patterns
  sections. Tailored to Antigravity: references injectSteps injection,
  not Cursor's additional_context; links to shared protocol via GitHub
  URL (relative file paths break in the installed copy at
  ~/.gemini/config/plugins/mempalace/).

- .antigravity-plugin/rules/mempalace-recall.md: plain .md recall rule
  (no .mdc extension, no YAML frontmatter — per Antigravity's plugin
  docs which specify rules/<name>.md). Body mirrors Cursor's rule;
  references the shared protocol via absolute GitHub URL.

- hooks/antigravity/install.sh: creates skills/mempalace-recall/ and
  rules/ in the install dir, copies both new files (cmp-gated,
  idempotent). Verified: first run writes both, second run is silent.

- .antigravity-plugin/README.md: updated layout tree + "Three recall
  layers" section documenting wake hook (eager), recall skill
  (on-demand), and optional rule.

- 11 new tests in tests/test_antigravity_plugin_manifest.py covering:
  shared protocol presence, recall skill structure (frontmatter,
  required sections, GitHub URL reference), rule format (plain .md, no
  frontmatter), and installer (mkdir + copy_file lines present).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-11 13:09:40 +10:00
undeadindustries bf156fb010 feat: add Antigravity IDE support (plugin, MCP, skill, hooks, docs, tests)
Adds first-class integration with Google's Antigravity IDE
(https://antigravity.google/) as a third sibling to the existing
Claude Code and Codex hook integrations. Strictly additive — no
existing files in main are restructured.

What ships
----------

* `.antigravity-plugin/` — verified-minimal plugin package:
  * `plugin.json` with `{"name": "mempalace"}` (no fabricated fields)
  * `mcp_config.json` registering the `mempalace-mcp` stdio server
  * `hooks.json.tmpl` templated with `__PLUGIN_DIR__` substitution
  * `skills/mempalace/SKILL.md` (real file — no symlinks)
* `hooks/antigravity/`:
  * `lib/common.sh` — shared bash 3.2.57-compatible helpers with
    sentinel-guarded camelCase JSON parser, antigravity_*-namespaced
    state files, every existing kill switch, `MEMPAL_SAVE_INTERVAL >= 1`
    floor (no /0), and fail-open emitters
  * `mempal_save_hook_antigravity.sh` — Stop event handler:
    increments per-conversation counter, defers when fullyIdle=False
    or terminationReason=error, validates transcriptPath against
    `..` traversal, spawns `mempalace mine --mode convos` in a
    detached subprocess with a per-conversation pending marker,
    ALWAYS emits `{}` (never `{"decision":"continue"}` — that would
    force an infinite agent loop)
  * `mempal_wake_hook_antigravity.sh` — PreInvocation handler gated
    to invocationNum==1 with an atomic mkdir loop guard, runs
    `mempalace wake-up` with a 500ms hard timeout, emits verbatim
    output as `{"injectSteps":[{"ephemeralMessage":"..."}]}` or
    `{}` on any failure
  * `install.sh` — idempotent installer with cmp-gated copies,
    `__PLUGIN_DIR__` substitution, relative path absolutization,
    `--dry-run`, and basename-guarded `--uninstall` (refuses to
    wipe a directory whose basename isn't `mempalace`)
  * `INVESTIGATION.md` — verbatim quotes + URLs + dates from the
    five official Antigravity doc pages, recording every surface
    shipped and every surface deliberately omitted
    (PreCompact equivalent, slash-commands, rules/, plugin
    permissions field — the latter is third-party fabrication)
  * `STDIN_SHAPE.md` — exact stdin/stdout contract per event with
    worked examples
  * `README.md` — local hook docs + troubleshooting
* `examples/antigravity/{hooks.json,mcp_config.json,README.md}` —
  standalone configs for users who don't want the full installer
* `website/guide/antigravity.md` + sidebar entry — VitePress guide
* Updates to `README.md`, `CHANGELOG.md` (Unreleased), `hooks/README.md`

Tests (56 new, all passing)
---------------------------

* `tests/test_antigravity_plugin_manifest.py` (11 tests) — schema
  contract on the in-repo `.antigravity-plugin/` directory, including
  guards against re-introducing the fabricated `permissions` field
  and against any symlink leak.
* `tests/test_antigravity_hooks_shell.py` (31 tests) — invokes the
  bash hooks via subprocess with synthetic camelCase stdin, asserts
  `{}` on every failure path, kill-switch coverage (env vars +
  config.json + palace nuke), divide-by-zero floor, transcript
  traversal rejection, namespacing, wing inference, and the hard
  refusal to ever emit `decision=continue` from the Stop hook.
* `tests/test_antigravity_hooks_install.py` (14 tests) — `--dry-run`
  side-effect-free, real install layout, executable bits preserved,
  byte-identical idempotent re-runs (md5 + filecmp), basename-match
  uninstall safety, refusal when plugin.json is missing or names a
  different plugin, relative path absolutization. Skipped on Windows.

Verification
------------

* `uv run pytest tests/ --ignore=tests/benchmarks -v` → 2314 passed,
  3 skipped (Windows), 1 unrelated warning
* `uv run ruff check .` → all checks passed
* `uv run ruff format --check .` → 139 files already formatted
* `bash -n` clean on common.sh, both hook scripts, install.sh
* Local install at `~/.gemini/config/plugins/mempalace/` verified end-
  to-end: layout correct, paths absolutized in hooks.json, both hooks
  fire with realistic camelCase JSON in <1s, wing inference picks
  `wing_mempalace` from workspacePaths[0], state files all
  `antigravity_*`-namespaced, second `install.sh` run produces
  byte-identical output (md5 snapshots match), uninstall removes
  only the mempalace plugin and leaves all 6 sibling Google plugins
  untouched.

Constraints honoured
--------------------

bash 3.2.57 (no mapfile / readarray / declare -A / `${var^^}`),
verbatim guarantee on all wake injections, hooks <500ms / startup
injection <100ms target (kill-switch path returns in <1.5s in CI),
zero new runtime dependencies, no telemetry, no external API,
strictly additive (existing Claude/Codex hooks unchanged).

Refs: hooks/antigravity/INVESTIGATION.md for the full audit.
2026-05-27 19:19:17 +10:00