173 lines
6.2 KiB
Markdown
173 lines
6.2 KiB
Markdown
# MemPalace — Antigravity hook scripts
|
|
|
|
Lifecycle hooks for the [Antigravity IDE](https://antigravity.google/).
|
|
|
|
This is the third sibling of the Claude Code and Codex integrations
|
|
(see `hooks/mempal_save_hook.sh` and `.codex-plugin/hooks/`). The
|
|
overall shape is the same — a Stop event triggers a background save,
|
|
a startup-time event injects memory into the agent — but the wire
|
|
format and STDOUT contract are Antigravity-specific (see
|
|
[STDIN_SHAPE.md](STDIN_SHAPE.md)).
|
|
|
|
## Quick start
|
|
|
|
From the repo root:
|
|
|
|
```bash
|
|
bash hooks/antigravity/install.sh
|
|
```
|
|
|
|
This installs the plugin to `~/.gemini/config/plugins/mempalace/`.
|
|
Restart Antigravity and the MCP server, skill, and hooks all register
|
|
automatically.
|
|
|
|
To dry-run first:
|
|
|
|
```bash
|
|
bash hooks/antigravity/install.sh --dry-run
|
|
```
|
|
|
|
To uninstall:
|
|
|
|
```bash
|
|
bash hooks/antigravity/install.sh --uninstall
|
|
```
|
|
|
|
## What gets installed
|
|
|
|
```
|
|
~/.gemini/config/plugins/mempalace/
|
|
├── plugin.json # marker manifest
|
|
├── mcp_config.json # registers mempalace-mcp
|
|
├── hooks.json # rendered from hooks.json.tmpl
|
|
├── README.md
|
|
├── skills/
|
|
│ └── mempalace/
|
|
│ └── SKILL.md
|
|
└── hooks/
|
|
├── lib/
|
|
│ └── common.sh
|
|
├── mempal_save_hook_antigravity.sh # Stop event handler
|
|
└── mempal_wake_hook_antigravity.sh # PreInvocation handler
|
|
```
|
|
|
|
`hooks.json` carries absolute paths to the two hook scripts (resolved
|
|
from `__PLUGIN_DIR__` at install time).
|
|
|
|
## What the hooks do
|
|
|
|
### `mempal_save_hook_antigravity.sh` (Stop event)
|
|
|
|
Fires every time the agent's execution loop terminates. Increments a
|
|
per-conversation counter; every `MEMPAL_SAVE_INTERVAL` fires (default
|
|
15), spawns `mempalace mine <transcript-dir> --mode convos --wing
|
|
<inferred>` in the background. The hook itself returns `{}` to stdout
|
|
in under a few milliseconds — the actual mining runs detached and
|
|
does not block the user.
|
|
|
|
Defers when:
|
|
|
|
- `fullyIdle == false` (background tasks still running)
|
|
- `terminationReason == "error"` (transcript may be corrupt)
|
|
- A previous save for this conversation is still running
|
|
- Any kill switch is set
|
|
|
|
### `mempal_wake_hook_antigravity.sh` (PreInvocation event, gated)
|
|
|
|
Fires before every model invocation. Gated to `invocationNum == 1`
|
|
(first invocation of the conversation only) — beyond that we'd be
|
|
re-injecting on every turn. Calls `mempalace wake-up --wing <inferred>`
|
|
with a 500ms hard timeout and emits the verbatim output as an
|
|
`ephemeralMessage` so the agent sees relevant memory on its first
|
|
response without polluting the persistent transcript.
|
|
|
|
Skips when:
|
|
|
|
- `invocationNum != 1`
|
|
- Already woke this conversation (atomic `mkdir` loop guard)
|
|
- `mempalace wake-up` exits non-zero, times out, or produces empty output
|
|
- Any kill switch is set
|
|
|
|
## Kill switches
|
|
|
|
Any one of these disables both hooks (silent passthrough, exit 0):
|
|
|
|
| Knob | Value |
|
|
|------------------------------------------|--------------------------------|
|
|
| `MEMPAL_DISABLE_HOOK` | `1`, `true`, `yes` |
|
|
| `MEMPALACE_HOOKS_AUTO_SAVE` | `false`, `0`, `no` |
|
|
| `~/.mempalace/config.json` | `{"hooks": {"auto_save": false}}` |
|
|
| Removing `~/.mempalace/` entirely | (palace nuke) |
|
|
|
|
## Workspace-scoped install (advanced)
|
|
|
|
If you want MemPalace to load only inside a specific workspace,
|
|
manually copy the rendered plugin into your workspace's `.agents/plugins/`:
|
|
|
|
```bash
|
|
bash hooks/antigravity/install.sh --install-dir /tmp/render-stage
|
|
mkdir -p <workspace>/.agents/plugins/
|
|
cp -r /tmp/render-stage <workspace>/.agents/plugins/mempalace
|
|
rm -rf /tmp/render-stage
|
|
```
|
|
|
|
The global install at `~/.gemini/config/plugins/mempalace/` is the
|
|
canonical UX and what we recommend.
|
|
|
|
## Troubleshooting
|
|
|
|
### Hooks aren't firing
|
|
|
|
1. Confirm Antigravity sees the plugin: open the IDE, navigate to the
|
|
Customizations page; `mempalace` should appear in the global plugins
|
|
list.
|
|
2. Check `~/.mempalace/hook_state/antigravity_hook.log` — every fire
|
|
logs a line. No log lines = the hook is not being invoked.
|
|
3. Verify `mempalace-mcp` is on `$PATH`: `mempalace-mcp --version`.
|
|
4. Inspect the rendered `hooks.json` paths point at executable files:
|
|
`bash -n ~/.gemini/config/plugins/mempalace/hooks/*.sh`.
|
|
|
|
### Save fires but no mining happens
|
|
|
|
1. Look for the most recent `[event=stop]` lines in
|
|
`antigravity_hook.log` — `count` and `interval` should both be
|
|
visible. Mining only triggers when `count % interval == 0`.
|
|
2. Ensure a Python that can import `mempalace` is reachable. The hook
|
|
runs `"$MEMPAL_PYTHON_BIN" -m mempalace`, where `MEMPAL_PYTHON_BIN`
|
|
is resolved (in order) from `$MEMPAL_PYTHON`, the
|
|
`mempalace-mcp` / `mempalace` console-script shebang on `$PATH`,
|
|
then `python3`. A failed probe logs:
|
|
|
|
```
|
|
ERROR: mempalace is not runnable via <python> -m mempalace; install mempalace or set MEMPAL_PYTHON
|
|
```
|
|
|
|
On a GUI-launched Antigravity the harness `PATH` may differ from
|
|
your shell `PATH`; if the shebang heuristic can't find the right
|
|
interpreter, export `MEMPAL_PYTHON=/abs/path/python` (e.g.
|
|
`"$(uv tool dir)/mempalace/bin/python"`) and restart.
|
|
|
|
### Wake injection isn't appearing
|
|
|
|
1. The wake hook only injects on `invocationNum == 1`. Subsequent
|
|
invocations are gated.
|
|
2. The atomic `mkdir` marker
|
|
`~/.mempalace/hook_state/antigravity_woke_<conversationId>` exists
|
|
after a successful injection. Remove it to re-inject (rare).
|
|
3. `mempalace wake-up --wing <inferred>` may be returning empty output
|
|
if the wing doesn't exist yet. Run `mempalace status` to verify
|
|
wing presence.
|
|
|
|
## See also
|
|
|
|
- [INVESTIGATION.md](INVESTIGATION.md) — every Antigravity surface we
|
|
investigated, with verbatim quotes and source URLs.
|
|
- [STDIN_SHAPE.md](STDIN_SHAPE.md) — the exact wire format
|
|
Antigravity uses, with worked examples.
|
|
- [../mempal_save_hook.sh](../mempal_save_hook.sh) — Claude Code
|
|
equivalent.
|
|
- [../../.codex-plugin/hooks/](../../.codex-plugin/hooks/) — Codex
|
|
equivalent.
|
|
- [../../website/guide/antigravity.md](../../website/guide/antigravity.md)
|
|
— full user-facing guide.
|