From 3efe5e9858009026e279826e41d90189cc85f826 Mon Sep 17 00:00:00 2001 From: Thierry Kwiatkowski Date: Mon, 5 Oct 2026 23:43:18 +0200 Subject: [PATCH 1/4] feat(aidd-context): refresh AGENTS.md for antigravity and map its .agents/ surfaces update_memory.js accepts antigravity, and the onboarding, memory and generator references gain its paths, frontmatter and detection signals. The rule writer gains an antigravity target: a flat .agents/rules/.md with Antigravity's trigger frontmatter, refused over its 24,000-byte limit. Refs #511 Co-Authored-By: Claude Opus 5.5 --- README.md | 15 ++++++++++++++- plugins/aidd-context/hooks/update_memory.js | 1 + .../00-onboard/references/state/detection.md | 1 + .../skills/02-project-memory/references/tools.md | 1 + .../04-skill-generate/references/tool-detect.md | 3 ++- .../04-skill-generate/references/tool-write.md | 2 ++ .../05-rule-generate/references/tool-paths.md | 11 ++++++----- .../05-rule-generate/scripts/write-rule.cjs | 11 ++++++++--- .../06-agent-generate/references/tool-paths.md | 9 +++++++-- .../08-hook-generate/references/tool-paths.md | 8 +++++++- .../skills/10-learn/references/sync-arguments.md | 1 + .../skills/11-explore/references/ai-mapping.md | 5 ++++- scripts/__tests__/rule-generation.test.js | 10 +++++++++- scripts/__tests__/update-memory.test.js | 11 +++++++++++ 14 files changed, 74 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 362d9c5e1..8b78b5bef 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Why not just write your own commands? β†’ [FAQ](docs/FAQ.md#-why-aidd-instead-of ## βœ… Prerequisites -- **An AI coding tool** β€” Claude Code (native), or Cursor / Copilot / Codex / OpenCode / Kilo Code (see [Compatibility](#-compatibility)). +- **An AI coding tool** β€” Claude Code (native), or Cursor / Copilot / Codex / OpenCode / Kilo Code / Antigravity CLI (see [Compatibility](#-compatibility)). - **[Node](https://nodejs.org) 22 or later** on your `PATH`, only for the plugin that ships hooks ([what they do](docs/ARCHITECTURE.md#-bundled-hooks)); the workflows themselves are markdown and need nothing. ## πŸ”Œ Compatibility @@ -50,6 +50,7 @@ Why not just write your own commands? β†’ [FAQ](docs/FAQ.md#-why-aidd-instead-of | **Codex** | βœ… Supported | Marketplace Β· Flat | | **OpenCode** | βœ… Supported | Flat | | **Kilo Code** | βœ… Supported | Flat | +| **Antigravity CLI** | βœ… Supported | Flat | | **Gemini Β· Mistral** | 🚧 In progress | β€” | **Marketplace** = installed and updated through your tool's plugin manager. **Flat** = files copied directly into your project, no plugin manager involved. Install steps per tool β†’ [Other tools](#other-tools). @@ -185,6 +186,18 @@ codex plugin add aidd-context@aidd-framework # per plugin +
+Antigravity CLI β€” Flat only + +1. Unzip the `antigravity-flat` archive into your project root β†’ `.agents/`: skills, agents, and the memory hook in `.agents/hooks.json`. +2. Start `agy` in the project. A hook already in `.agents/hooks.json` under another name is kept. + +Codex flat also writes `.agents/skills/`: removing one of the two from a project that has both deletes skills the other still uses. + +[Docs](https://antigravity.google/docs/cli/overview) + +
+ ## πŸš€ Quick start Three ways in β€” pick one: diff --git a/plugins/aidd-context/hooks/update_memory.js b/plugins/aidd-context/hooks/update_memory.js index 2cfb4ba01..2f7677272 100644 --- a/plugins/aidd-context/hooks/update_memory.js +++ b/plugins/aidd-context/hooks/update_memory.js @@ -42,6 +42,7 @@ const TOOL_FILES = { codex: "AGENTS.md", cursor: "AGENTS.md", opencode: "AGENTS.md", + antigravity: "AGENTS.md", copilot: ".github/copilot-instructions.md", }; diff --git a/plugins/aidd-context/skills/00-onboard/references/state/detection.md b/plugins/aidd-context/skills/00-onboard/references/state/detection.md index f66011153..a8c0d4275 100644 --- a/plugins/aidd-context/skills/00-onboard/references/state/detection.md +++ b/plugins/aidd-context/skills/00-onboard/references/state/detection.md @@ -10,6 +10,7 @@ A tool is used when its own dir exists, or when a file only that tool reads exis | codex | `.codex/` | `AGENTS.md` | | cursor | `.cursor/` or `.cursorrules` | `AGENTS.md` | | opencode | `.opencode/` | `AGENTS.md` | +| antigravity | `.agents/agents/`, `.agents/rules/` or `.agents/hooks.json` | `AGENTS.md` | | copilot | `.github/copilot-instructions.md` or `.github/{instructions,agents,skills,prompts}/` | `.github/copilot-instructions.md` | - Detected tools only. An unused optional tool is omitted, never crossed. diff --git a/plugins/aidd-context/skills/02-project-memory/references/tools.md b/plugins/aidd-context/skills/02-project-memory/references/tools.md index 4b90d76d1..f25dc0bbe 100644 --- a/plugins/aidd-context/skills/02-project-memory/references/tools.md +++ b/plugins/aidd-context/skills/02-project-memory/references/tools.md @@ -8,6 +8,7 @@ The AI tools a project can use. | codex | `.codex/` | `AGENTS.md` | | cursor | `.cursor/` or `.cursorrules` | `AGENTS.md` | | opencode | `.opencode/` | `AGENTS.md` | +| antigravity | `.agents/agents/`, `.agents/rules/` or `.agents/hooks.json` | `AGENTS.md` | | copilot | `.github/copilot-instructions.md` or `.github/{instructions,agents,skills,prompts}/` | `.github/copilot-instructions.md` | - A shared `AGENTS.md` is a wiring target, never a detection signal. diff --git a/plugins/aidd-context/skills/04-skill-generate/references/tool-detect.md b/plugins/aidd-context/skills/04-skill-generate/references/tool-detect.md index 286dbc7a3..94fbe2467 100644 --- a/plugins/aidd-context/skills/04-skill-generate/references/tool-detect.md +++ b/plugins/aidd-context/skills/04-skill-generate/references/tool-detect.md @@ -9,5 +9,6 @@ Which AI tools a project has installed. | OpenCode | `.opencode/` | | GitHub Copilot | `.github/copilot-instructions.md` | | Codex CLI | `.codex/` | +| Antigravity CLI | `.agents/agents/`, `.agents/rules/` or `.agents/hooks.json` | -A bare `AGENTS.md` means Cursor, OpenCode, or Codex. Several signals can coexist. +A bare `AGENTS.md` means Cursor, OpenCode, Codex, or Antigravity CLI. `.agents/skills/` alone is no signal: Codex and Antigravity CLI both read it. Several signals can coexist. diff --git a/plugins/aidd-context/skills/04-skill-generate/references/tool-write.md b/plugins/aidd-context/skills/04-skill-generate/references/tool-write.md index 2863f4ccd..852aa9f06 100644 --- a/plugins/aidd-context/skills/04-skill-generate/references/tool-write.md +++ b/plugins/aidd-context/skills/04-skill-generate/references/tool-write.md @@ -11,6 +11,7 @@ Where a skill tree is written, per tool. | OpenCode | `.opencode/skills//` | | GitHub Copilot | `.github/skills//` | | Codex CLI | `.agents/skills//` | +| Antigravity CLI | `.agents/skills//` | | Plugin source | `plugins//skills//` | ## Frontmatter @@ -23,3 +24,4 @@ Emit `description` always, `name` only where listed, drop the rest. | Cursor, GitHub Copilot | `name`, `description`, opt `allowed-tools` | | OpenCode | `description`, opt `permission` map | | Codex CLI | `name`, `description` (strips the rest) | +| Antigravity CLI | `name`, `description` | diff --git a/plugins/aidd-context/skills/05-rule-generate/references/tool-paths.md b/plugins/aidd-context/skills/05-rule-generate/references/tool-paths.md index b8e6338b2..7c30334b5 100644 --- a/plugins/aidd-context/skills/05-rule-generate/references/tool-paths.md +++ b/plugins/aidd-context/skills/05-rule-generate/references/tool-paths.md @@ -11,12 +11,13 @@ This reference covers project rule generation only. Confirm hosts explicitly; a | GitHub Copilot | `copilot` | `.github/instructions/-.instructions.md` | comma-joined `applyTo`; `**` for all files | | Codex | `codex` | root `AGENTS.md`, shared signed `aidd_rules` contribution | scopes are instructions to the model | | OpenCode | `opencode` | the same contribution in root `AGENTS.md` | scopes are instructions to the model | +| Antigravity CLI | `antigravity` | `.agents/rules/.md` | with paths: `trigger: glob`, `description`, comma-joined `globs`; without: `trigger: always_on`, `description`, no `globs` | -Use taxonomy and `#-slug` naming in [rule-authoring.md](rule-authoring.md). Copilot drops the slug's single-digit prefix and adds the category's two-digit prefix, e.g. `01-standards/1-naming` becomes `01-naming.instructions.md`. +Use taxonomy and `#-slug` naming in [rule-authoring.md](rule-authoring.md). Copilot drops the slug's single-digit prefix and adds the category's two-digit prefix, e.g. `01-standards/1-naming` becomes `01-naming.instructions.md`. Antigravity reads only the direct `.md` children of `.agents/rules/`, so it drops the category folder and keeps the slug, e.g. `1-naming.md`; the slug's category digit keeps that flat name unique. Measured, `agy` truncates a rule file near 23 to 25 KB, so a rendered Antigravity rule over 24,000 bytes refuses the request before writes. Whether `agy` activates a `glob` rule only on matching files is unmeasured. Codex Markdown guidance is not a `.codex/rules` execution policy. OpenCode: write the root `AGENTS.md` only, never `.opencode/rules`. Native syntax tests prove rendering, not runtime consumption by every host. Codex/OpenCode selected together appear once in the shared file; other hosts may also discover AGENTS.md, so physical deduplication does not guarantee model-context deduplication across surfaces. -Official contracts: [Claude Code rules](https://code.claude.com/docs/en/memory#organize-rules-with-clauderules), [Cursor rules](https://cursor.com/docs/rules) and [CLI loading](https://cursor.com/docs/cli/using#rules), [Copilot CLI instructions](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-custom-instructions), [Codex AGENTS.md](https://learn.chatgpt.com/docs/agent-configuration/agents-md), [OpenCode rules](https://opencode.ai/docs/rules/) and [instructions](https://opencode.ai/v2/docs/instructions/). +Official contracts: [Claude Code rules](https://code.claude.com/docs/en/memory#organize-rules-with-clauderules), [Cursor rules](https://cursor.com/docs/rules) and [CLI loading](https://cursor.com/docs/cli/using#rules), [Copilot CLI instructions](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-custom-instructions), [Codex AGENTS.md](https://learn.chatgpt.com/docs/agent-configuration/agents-md), [OpenCode rules](https://opencode.ai/docs/rules/) and [instructions](https://opencode.ai/v2/docs/instructions/), [Antigravity rules](https://antigravity.google/docs/rules). Publication does not force a running host to reload. Verify changed rules in a fresh session: Codex builds its instruction chain at startup; Copilot applies edits to a new or resumed session. OpenCode V2 refreshes ambient AGENTS.md before the next request, but already loaded nested guidance needs a new session. Claude project rules require the `project` settings source; Cursor rules concern Agent rather than Tab or Inline Edit. The writer preserves patterns without implementing each host's glob parser; a syntactically invalid or unmatched pattern can activate no files. Confirm representative matching and nonmatching files in the selected host. @@ -41,9 +42,9 @@ Prepare a JSON request outside the project rule destinations: Use an absolute real project directory and confirmed comma-separated script IDs: ```sh -node "$installed_rule_script" --project "$project_root" --tools claude,cursor,copilot,codex,opencode --input "$request_json" -node "$installed_rule_script" --project "$project_root" --tools claude,cursor,copilot,codex,opencode --publish -node "$installed_rule_script" --project "$project_root" --tools claude,cursor,copilot,codex,opencode --delete 01-standards/1-naming +node "$installed_rule_script" --project "$project_root" --tools claude,cursor,copilot,codex,opencode,antigravity --input "$request_json" +node "$installed_rule_script" --project "$project_root" --tools claude,cursor,copilot,codex,opencode,antigravity --publish +node "$installed_rule_script" --project "$project_root" --tools claude,cursor,copilot,codex,opencode,antigravity --delete 01-standards/1-naming ``` Create/update records confirmed targets in `aidd_docs/rules//.md`. Publish synchronizes the named native hosts and the complete shared contribution from canonical targets; delete also cleans the deleted rule's previous targets. Updating targets cleans removed targets. JSON accepts exactly category, slug, description, optional paths and body. Empty/omitted paths mean all files. Reject comma-containing globs (including brace alternations) rather than serialize ambiguous native lists; supply separate globs. Description is one line. Body is preserved completely and must not begin with YAML frontmatter. Scope belongs in JSON, never an arbitrary YAML parser. diff --git a/plugins/aidd-context/skills/05-rule-generate/scripts/write-rule.cjs b/plugins/aidd-context/skills/05-rule-generate/scripts/write-rule.cjs index e7f1d0c9c..dcbf9c019 100644 --- a/plugins/aidd-context/skills/05-rule-generate/scripts/write-rule.cjs +++ b/plugins/aidd-context/skills/05-rule-generate/scripts/write-rule.cjs @@ -6,7 +6,7 @@ const fs = require("node:fs"); const path = require("node:path"); const { createHash, randomUUID } = require("node:crypto"); -const TOOLS = ["claude", "cursor", "copilot", "codex", "opencode"]; +const TOOLS = ["claude", "cursor", "copilot", "codex", "opencode", "antigravity"]; const CATEGORIES = ["architecture", "standards", "programming-languages", "frameworks-and-libraries", "tooling", "testing", "design-patterns", "quality", "domain", "other"]; const SHARED = ["codex", "opencode"]; const SOURCE = "aidd_docs/rules"; @@ -36,7 +36,7 @@ function options(args) { function tools(value) { const selected = typeof value === "string" ? value.split(",") : value; - if (!Array.isArray(selected) || !selected.length || new Set(selected).size !== selected.length || selected.some((tool) => !TOOLS.includes(tool))) fail("Targets must be distinct confirmed tools: claude,cursor,copilot,codex,opencode."); + if (!Array.isArray(selected) || !selected.length || new Set(selected).size !== selected.length || selected.some((tool) => !TOOLS.includes(tool))) fail("Targets must be distinct confirmed tools: claude,cursor,copilot,codex,opencode,antigravity."); return [...selected].sort(); } @@ -107,6 +107,8 @@ function nativePath(rule, tool) { const id = identity(rule.category, rule.slug); if (tool === "claude") return `.claude/rules/${id}.md`; if (tool === "cursor") return `.cursor/rules/${id}.mdc`; + // Antigravity loads only direct children; the slug's category digit keeps the flat name unique. + if (tool === "antigravity") return `.agents/rules/${rule.slug}.md`; return `.github/instructions/${rule.category.slice(0, 2)}-${rule.slug.slice(2)}.instructions.md`; } @@ -116,9 +118,12 @@ function renderNative(rule, tool, signed = true) { if (tool === "claude") fields = rule.paths.length ? `paths:\n${rule.paths.map((glob) => ` - ${quote(glob)}\n`).join("")}` : ""; if (tool === "cursor") fields = `description: ${quote(rule.description)}\n${rule.paths.length ? `globs: ${quote(rule.paths.join(","))}\n` : ""}alwaysApply: ${!rule.paths.length}\n`; if (tool === "copilot") fields = `applyTo: ${quote(rule.paths.length ? rule.paths.join(",") : "**")}\n`; + if (tool === "antigravity") fields = `trigger: ${rule.paths.length ? "glob" : "always_on"}\ndescription: ${quote(rule.description)}\n${rule.paths.length ? `globs: ${quote(rule.paths.join(","))}\n` : ""}`; const text = (fields ? `---\n${fields}---\n` : "") + rule.body; safeText(text); - return signed ? `${text}\n\n` : text; + const output = signed ? `${text}\n\n` : text; + if (tool === "antigravity" && Buffer.byteLength(output) > 24000) fail("Antigravity rule exceeds its 24,000-byte per-file limit."); + return output; } function ownedNative(existing, prior, tool, relative) { diff --git a/plugins/aidd-context/skills/06-agent-generate/references/tool-paths.md b/plugins/aidd-context/skills/06-agent-generate/references/tool-paths.md index 90a1badde..a01c4f9d9 100644 --- a/plugins/aidd-context/skills/06-agent-generate/references/tool-paths.md +++ b/plugins/aidd-context/skills/06-agent-generate/references/tool-paths.md @@ -11,8 +11,9 @@ The per-tool agent path and the gate every run executes before writing. Agent sl | OpenCode | `.opencode/agents/.md` | markdown + frontmatter | | GitHub Copilot | `.github/agents/.agent.md` | markdown + frontmatter | | Codex CLI | `.codex/agents/.toml` | TOML (converted) | +| Antigravity CLI | `.agents/agents//agent.md` | markdown + frontmatter | -Agents are supported on all five tools. +Agents are supported on all six tools. ## Frontmatter per tool @@ -25,6 +26,9 @@ The canonical agent carries `name` and `description`. Emit those a row accepts, | OpenCode | `name`, `description`, optional `model`, `temperature`, `permission` | | GitHub Copilot | `name`, `description`, optional `model`, `tools` | | Codex CLI | `name`, `description` (drops `model`) | +| Antigravity CLI | `name`, `description`, `model: inherit`, optional `tools` as a YAML list | + +`agy` drops in silence an agent whose `model` is not `inherit`, `flash` or `pro`, or whose `tools` is a comma-separated string. ## Codex TOML conversion @@ -43,7 +47,8 @@ Codex agents are TOML, not markdown. Convert: | `.opencode/` | OpenCode | | `.codex/` | Codex CLI | | `.github/copilot-instructions.md` | GitHub Copilot | -| `AGENTS.md` | Cursor, OpenCode, or Codex (list all) | +| `.agents/agents/`, `.agents/rules/` or `.agents/hooks.json` | Antigravity CLI | +| `AGENTS.md` | Cursor, OpenCode, Codex, or Antigravity CLI (list all) | ## Write targets diff --git a/plugins/aidd-context/skills/08-hook-generate/references/tool-paths.md b/plugins/aidd-context/skills/08-hook-generate/references/tool-paths.md index 48b1d19ef..0757af487 100644 --- a/plugins/aidd-context/skills/08-hook-generate/references/tool-paths.md +++ b/plugins/aidd-context/skills/08-hook-generate/references/tool-paths.md @@ -11,6 +11,7 @@ Per-tool hook support, event names, file formats, and scopes. Hook slice only: n | Cursor | yes | JSON config + script. | | GitHub Copilot | yes | JSON config + script. Also reads Claude's `.claude/` config. | | OpenCode | no | Hooks are JS/TS plugin modules, not config. Skip with the reason below. | +| Antigravity CLI | yes | JSON config + script. Project scope only here, see below. | **OpenCode skip reason.** OpenCode hooks are code, not a config entry plus a script. Point the user to write a plugin under `.opencode/plugins/` (project) or `~/.config/opencode/plugins/` (user), per `https://opencode.ai/docs/plugins`. This skill does not generate it. @@ -29,6 +30,8 @@ Each tool names the same moment differently and supports a different subset. Cor | turn stop | `Stop` | `Stop` | `stop` | `Stop` | | session end | `SessionEnd` | `SessionEnd` | `sessionEnd` | `SessionEnd` | +Antigravity CLI documents `PreToolUse`, `PostToolUse`, `PreInvocation`, `PostInvocation` and `Stop`; `SessionStart` works on `agy` 1.2.17 but is undocumented. Its tool names differ from Claude's, so a `matcher` never carries over. + Each tool exposes more moments than these. For the full list, read the tool's docs: Claude `https://code.claude.com/docs/en/hooks`, Codex `https://developers.openai.com/codex/hooks`, Cursor `https://cursor.com/docs/hooks`, Copilot `https://docs.github.com/en/copilot/reference/hooks-configuration`. Confirm a moment exists before wiring it. Copilot also accepts the camelCase names (`sessionStart`, `preToolUse`). ## File and format per tool @@ -39,9 +42,12 @@ Each tool exposes more moments than these. For the full list, read the tool's do | Codex CLI | `~/.codex/hooks.json` or `[hooks]` in `config.toml` | same entry shape as Claude. | | Cursor | `.cursor/hooks.json` | `{ "version": 1, "hooks": { "": [ { "command": "..." } ] } }` | | GitHub Copilot | `.github/hooks/*.json` or a `hooks` block in `.github/copilot/settings.json` | `{ "version": 1, "hooks": { "": [ { "type": "command", "command": "..." } ] } }` | +| Antigravity CLI | `.agents/hooks.json` | `{ "": { "": [ { "type": "command", "command": "..." } ] } }`, no `hooks` wrapper; a `matcher` entry only for `PreToolUse` and `PostToolUse` | A Claude `settings.json` and a plugin or standalone `hooks/hooks.json` both wrap the event map under a top-level `hooks` key, so the file is `{ "hooks": { "": [ ... ] } }`. A Codex `config.toml` uses a `[hooks]` table instead. +An Antigravity CLI handler runs from `/.agents`, through a shell: prefix a root-relative command with `cd .. && `. `agy` rejects a Claude-style nested `[ { "hooks": [ ... ] } ]` with `command hook must specify 'command'`. + ## Scopes per tool Ask the user which scope, then write the matching file. A `-` means the tool has no such scope. @@ -81,4 +87,4 @@ Written as `${VAR}` inside a command: `CLAUDE_PROJECT_DIR` (project root), `CLAU - **Asset-access precheck.** Before writing, confirm this reference is readable. If not, stop: the plugin is not installed in this host. - **Merge check.** Before writing, read the target file and confirm the new entry is appended to the moment's list, never overwriting a sibling. -- **Write-target validation.** After writing, confirm the file is valid and every handler path is an approved `${VAR}` or an absolute path under the workspace (a hook command runs from an arbitrary cwd, so an absolute path or `${VAR}` is expected, not a relative one). Otherwise stop and report. +- **Write-target validation.** After writing, confirm the file is valid and every handler path is an approved `${VAR}` or an absolute path under the workspace (a hook command runs from an arbitrary cwd, so an absolute path or `${VAR}` is expected, not a relative one; Antigravity CLI's `cd .. && ` prefix is the one relative form, since its cwd is fixed). Otherwise stop and report. diff --git a/plugins/aidd-context/skills/10-learn/references/sync-arguments.md b/plugins/aidd-context/skills/10-learn/references/sync-arguments.md index 5c3bc2e9a..f2f9f08b5 100644 --- a/plugins/aidd-context/skills/10-learn/references/sync-arguments.md +++ b/plugins/aidd-context/skills/10-learn/references/sync-arguments.md @@ -8,6 +8,7 @@ Arguments accepted by `hooks/update_memory.js`. The hook maps tool names to cont | `codex` | `AGENTS.md` | | `cursor` | `AGENTS.md` | | `opencode` | `AGENTS.md` | +| `antigravity` | `AGENTS.md` | | `copilot` | `.github/copilot-instructions.md` | Rules: diff --git a/plugins/aidd-context/skills/11-explore/references/ai-mapping.md b/plugins/aidd-context/skills/11-explore/references/ai-mapping.md index 5e0a7065d..028236d27 100644 --- a/plugins/aidd-context/skills/11-explore/references/ai-mapping.md +++ b/plugins/aidd-context/skills/11-explore/references/ai-mapping.md @@ -4,7 +4,7 @@ Where to look for each artifact type per AI tool. Scan-only: the paths and forma ## Presence signal -A tool is present only when one of its own mapped surfaces below holds a file. A shared parent directory is never a signal by itself. +A tool is present only when one of its own mapped surfaces below holds a file. A shared parent directory is never a signal by itself. `.agents/skills/` is mapped for both Codex CLI and Antigravity CLI, so alone it is no signal for either. ## AI quick map - content artifacts @@ -15,6 +15,7 @@ A tool is present only when one of its own mapped surfaces below holds a file. A | OpenCode | `.opencode/agents/` | `.opencode/commands/` | `aidd_docs/rules/` (canonical sources); shared `aidd_rules` contribution in root `AGENTS.md` | `.opencode/skills/` | `AGENTS.md` | | GitHub Copilot | `.github/agents/*.agent.md` | `.github/prompts/*.prompt.md` | `.github/instructions/*.instructions.md` | `.github/skills/` | `.github/copilot-instructions.md` | | Codex CLI | `.codex/agents/{name}.toml` | **Not supported** | `aidd_docs/rules/` (canonical sources); shared `aidd_rules` contribution in root `AGENTS.md`, not execution policies | `.agents/skills/aidd-{name}/SKILL.md` | `AGENTS.md` | +| Antigravity CLI | `.agents/agents/{name}/agent.md` | Not mapped | `.agents/rules/.md`, flat | `.agents/skills/aidd-{name}/SKILL.md` | `AGENTS.md` | ## AI quick map - hooks, plugins @@ -25,6 +26,7 @@ A tool is present only when one of its own mapped surfaces below holds a file. A | OpenCode | JS/TS module under `.opencode/plugins/` (parse as JS, not JSON) | Not supported | | GitHub Copilot | `.github/hooks/*.json` (workspace), `~/.copilot/hooks` (user), `/hooks.json` or `/hooks/hooks.json` (plugin) | `plugin.json` at plugin root | | Codex CLI | `.codex/hooks.json` (project / user) OR `[hooks]` table in `.codex/config.toml` | `.codex-plugin/plugin.json` | +| Antigravity CLI | `.agents/hooks.json` (project), keyed by hook name | `plugin.json` at plugin root | ## MCP config per tool @@ -57,3 +59,4 @@ Where to scan when enumerating installed plugins (not the plugin manifest path i | OpenCode | `~/.config/opencode/plugins/` (global JS/TS modules); `~/.cache/opencode/node_modules/` (npm-installed); project `.opencode/plugins/` | | GitHub Copilot | macOS: `~/Library/Application Support/Code/agentPlugins/` ; Linux: `~/.config/Code/agentPlugins/` ; Windows: `%APPDATA%\Code\agentPlugins\` ; CLI-installed: `~/.copilot/installed-plugins/` | | Codex CLI | `~/.codex/plugins/cache/$MARKETPLACE/$PLUGIN/$VERSION/` | +| Antigravity CLI | Unmeasured: `~/.gemini/config/plugins//` (`agy plugin install`) and project `.agents/plugins/` are assumed, not observed | diff --git a/scripts/__tests__/rule-generation.test.js b/scripts/__tests__/rule-generation.test.js index a387f554f..5b8621ec2 100644 --- a/scripts/__tests__/rule-generation.test.js +++ b/scripts/__tests__/rule-generation.test.js @@ -65,11 +65,12 @@ for (const paths of [[], ["src/domain/**/*.ts", 'tests/quoted"name/**/*.ts']]) t const f = fixture(t); const description = 'Review "domain": naΓ―ve \\ conventions #1'; const body = "# Review\r\n\r\n- Preserve exact text: cafΓ© βš™.\r\n"; - assert.equal(f.run({ ...rule, description, paths, body }, "claude,cursor,copilot").status, 0); + assert.equal(f.run({ ...rule, description, paths, body }, "claude,cursor,copilot,antigravity").status, 0); const documents = [ [".claude/rules/01-standards/1-naming.md", paths.length ? { paths } : null], [".cursor/rules/01-standards/1-naming.mdc", { description, ...(paths.length ? { globs: paths.join(",") } : {}), alwaysApply: !paths.length }], [".github/instructions/01-naming.instructions.md", { applyTo: paths.length ? paths.join(",") : "**" }], + [".agents/rules/1-naming.md", paths.length ? { trigger: "glob", description, globs: paths.join(",") } : { trigger: "always_on", description }], ]; for (const [name, expected] of documents) { const text = f.read(name); @@ -309,6 +310,13 @@ for (const target of ["aidd_docs/rules", ".claude/rules", "AGENTS.md"]) test(`sy assert.deepEqual(f.snapshot(), before); }); +test("Antigravity's 24,000-byte rule file limit refuses prospective writes", (t) => { + const f = fixture(t); + const before = f.snapshot(); + assert.notEqual(f.run({ ...rule, body: "x".repeat(24000) }, "antigravity").status, 0); + assert.deepEqual(f.snapshot(), before); +}); + test("Codex override and local 32 KiB limit refuse prospective writes", (t) => { const f = fixture(t); f.put("AGENTS.override.md", "override"); diff --git a/scripts/__tests__/update-memory.test.js b/scripts/__tests__/update-memory.test.js index fc9440cf4..2f38a170f 100644 --- a/scripts/__tests__/update-memory.test.js +++ b/scripts/__tests__/update-memory.test.js @@ -167,6 +167,17 @@ test("an unknown tool name is rejected", () => { assert.match(result.stderr, /unknown tool emacs/u); }); +test("antigravity refreshes AGENTS.md, the context file agy reads", () => { + const result = run({ + context: `${OPEN}\n${CLOSE}\n`, + contextAt: "AGENTS.md", + args: ["antigravity"], + }); + + assert.equal(result.status, 0); + assert.match(result.content, /^\[aidd_docs\/memory\/architecture\.md\]\(aidd_docs\/memory\/architecture\.md\)$/mu); +}); + test("a new-marker pair quoted in prose above the block does not hijack the splice", () => { const quote = `Upgrade note: the block now uses \`${OPEN}\` and \`${CLOSE}\`.`; const result = run({ context: `${quote}\n\n${OPEN}\n${CLOSE}\n` }); From 9fb7b64e0be19ef15590f5e3234383f3416ff722 Mon Sep 17 00:00:00 2001 From: Thierry Kwiatkowski Date: Mon, 5 Oct 2026 23:43:22 +0200 Subject: [PATCH 2/4] test(cli): add a local runtime smoke for antigravity pnpm smoke:antigravity installs AIDD into a throwaway project, then checks a logged-in agy expands a skill, loads and fires the memory hook, and lists an AIDD agent. Local only: a turn needs a Google login. Refs #511 Co-Authored-By: Claude Opus 5.5 --- cli/package.json | 1 + cli/scripts/smoke-antigravity.sh | 130 +++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100755 cli/scripts/smoke-antigravity.sh diff --git a/cli/package.json b/cli/package.json index fff9fdb34..a716ec8fd 100644 --- a/cli/package.json +++ b/cli/package.json @@ -54,6 +54,7 @@ "smoke:full": "pnpm build && SMOKE_REMOTE=1 bash scripts/smoke-tools.sh", "smoke:real": "pnpm build && bash scripts/smoke-real.sh", "smoke:collision": "pnpm build && bash scripts/smoke-collision.sh", + "smoke:antigravity": "pnpm build && bash scripts/smoke-antigravity.sh", "typecheck": "tsc --noEmit", "lint": "biome check .", "format": "biome format --write .", diff --git a/cli/scripts/smoke-antigravity.sh b/cli/scripts/smoke-antigravity.sh new file mode 100755 index 000000000..34c4bec63 --- /dev/null +++ b/cli/scripts/smoke-antigravity.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +# Runtime smoke against a real, logged-in `agy`: after `aidd setup --ai antigravity`, the host +# loads and fires the project memory hook, expands an AIDD skill, and lists an AIDD agent. +# Local only, never in CI or lefthook: a turn needs a Google login. `pnpm smoke:antigravity`. +# +# The hook sessions run interactive under a pty, killed after a bound: older `agy` fired no hook in +# print mode (`-p`), and a print turn waits on every user MCP server. Its log and the files it +# touched are the evidence. HOME stays real for the login; `AIDD_USER_CONFIG_DIR` is relocated so +# setup never touches the real aidd profile. +set -uo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +FRAMEWORK="$(cd "$ROOT/.." && pwd)" +CLI="$ROOT/dist/cli.js" +TURN_SECONDS="${SMOKE_AGY_TIMEOUT:-60}" + +SKILL="aidd-context-11-explore" +AGENT="aidd-dev-executor" +GHOST_AGENT="aidd-dev-ghost" + +command -v agy >/dev/null 2>&1 || { echo "FATAL: agy not on PATH β€” install Antigravity CLI and log in"; exit 1; } +[[ -f "$CLI" ]] || { echo "FATAL: $CLI missing β€” run 'pnpm build' first"; exit 1; } + +TMP="$(mktemp -d)" +WS="$TMP/project" +SESSION_PID="" +cleanup() { + if [[ -n "$SESSION_PID" ]]; then + pkill -P "$SESSION_PID" 2>/dev/null + kill "$SESSION_PID" 2>/dev/null + fi + rm -rf "$TMP" +} +trap cleanup EXIT + +export AIDD_USER_CONFIG_DIR="$TMP/aidd-config" +export AIDD_SKIP_UPDATE_CHECK=1 + +# Under a pseudo-terminal: util-linux script(1) takes the command as one -c string, BSD as arguments. +pty_run() { + if script --version >/dev/null 2>&1; then + script -qec "$(printf '%q ' "$@")" /dev/null + else + script -q /dev/null "$@" + fi +} + +# How many named hooks agy loads, from its log: user-global hooks included. +hook_count() { grep -Eo 'loaded [0-9]+ named hooks' "$1" 2>/dev/null | head -1 | grep -Eo '[0-9]+'; } + +FAIL=0 +pass() { echo " PASS $1"; echo " $2"; } +fail() { echo " FAIL $1"; FAIL=$((FAIL + 1)); } + +echo "agy $(agy --version 2>&1 | head -1), $(date '+%Y-%m-%d %H:%M %Z')" + +# A project with a memory bank and an empty memory block, so the hook has something to fill. +mkdir -p "$WS/aidd_docs/memory" +printf '# Architecture\n' >"$WS/aidd_docs/memory/architecture.md" +printf '# Project\n\n## Memory Management\n\n\n\n' >"$WS/AGENTS.md" +git -C "$WS" init -q +git -C "$WS" -c user.email=smoke@aidd -c user.name=smoke commit -q --allow-empty -m init + +if ! (cd "$WS" && node "$CLI" setup --source local --path "$FRAMEWORK" --ai antigravity --plugins recommended --yes) >"$TMP/setup.log" 2>&1; then + echo "FATAL: aidd setup failed"; tail -5 "$TMP/setup.log"; exit 1 +fi +for f in ".agents/skills/$SKILL/SKILL.md" ".agents/hooks.json" ".agents/agents/$AGENT/agent.md"; do + [[ -f "$WS/$f" ]] || { echo "FATAL: setup did not write $f"; exit 1; } +done + +# One interactive session logging to $1, killed once `$2…` succeeds or the bound runs out. +session() { + local log="$1"; shift + (cd "$WS" && pty_run agy -i "reply OK" --mode plan --add-dir "$WS" --log-file "$log") >"$log.out" 2>&1 & + SESSION_PID=$! + for ((i = 0; i < TURN_SECONDS; i++)); do + "$@" && break + sleep 1 + done + pkill -P "$SESSION_PID" 2>/dev/null + kill "$SESSION_PID" 2>/dev/null + wait "$SESSION_PID" 2>/dev/null + SESSION_PID="" +} + +LOG="$TMP/agy-session.log" +session "$LOG" grep -q 'aidd_docs/memory/architecture.md' "$WS/AGENTS.md" + +# Startup logs "not logged into Antigravity" before the stored login is read, so only a missing +# success line means no login. +if ! grep -q "OAuth: authenticated successfully" "$LOG" 2>/dev/null; then + echo "FATAL: agy is not logged in β€” run 'agy' once and sign in"; exit 1 +fi + +# The log never names a hook, and user-global hooks count too, so the project's own are proven by +# difference: the same session, in the same mode, without .agents/hooks.json must load fewer. +BASE_LOG="$TMP/agy-baseline.log" +[[ -f "$WS/.agents/hooks.json" ]] && mv "$WS/.agents/hooks.json" "$TMP/hooks.json" +session "$BASE_LOG" grep -qs 'named hooks' "$BASE_LOG" +[[ -f "$TMP/hooks.json" ]] && mv "$TMP/hooks.json" "$WS/.agents/hooks.json" +with="$(hook_count "$LOG")" +without="$(hook_count "$BASE_LOG")" +if [[ -n "$with" && -n "$without" && "$with" -gt "$without" ]]; then + pass "project hooks loaded" "$with named hooks with .agents/hooks.json, $without without" +else + fail "hooks: .agents/hooks.json adds no loaded hook (${with:-?} with, ${without:-?} without)" +fi + +line="$(grep -m1 'aidd_docs/memory/architecture.md' "$WS/AGENTS.md")" +[[ -n "$line" ]] && pass "memory refreshed at the repo root" "AGENTS.md: $line" || fail "memory: AGENTS.md block still empty, the SessionStart hook did not run at the repo root" + +# The expansion is logged before the model answers, so a short bound is enough. +SKILL_LOG="$TMP/agy-skill.log" +(cd "$WS" && agy --add-dir "$WS" --mode plan --print-timeout 20s --log-file "$SKILL_LOG" -p "/$SKILL") >/dev/null 2>&1 +line="$(grep -o "expanded slash command \"$SKILL\" (skill)" "$SKILL_LOG" 2>/dev/null | head -1)" +[[ -n "$line" ]] && pass "skill expanded" "$line" || fail "skill: no 'expanded slash command \"$SKILL\"' line in the agy log" + +# Print mode answers /agents without the model. +AGENTS_JSON="$TMP/agents.json" +(cd "$WS" && agy --add-dir "$WS" --output-format json --print-timeout "${TURN_SECONDS}s" -p "/agents") >"$AGENTS_JSON" 2>&1 +line="$(grep -o "\"$AGENT\"" "$AGENTS_JSON" | head -1)" +if [[ -n "$line" ]] && ! grep -q "\"$GHOST_AGENT\"" "$AGENTS_JSON"; then + pass "agent listed" "/agents: $line, $GHOST_AGENT absent" +else + fail "agents: /agents does not list \"$AGENT\" (or lists the invented $GHOST_AGENT)" +fi + +echo +[[ "$FAIL" -eq 0 ]] && { echo "smoke-antigravity: all passed"; exit 0; } +echo "smoke-antigravity: $FAIL failed"; exit 1 From f6e42bee1fe3a1a7fc17c1e55471e4165e4b9eea Mon Sep 17 00:00:00 2001 From: Thierry Kwiatkowski Date: Mon, 5 Oct 2026 23:43:28 +0200 Subject: [PATCH 3/4] docs: list antigravity cli as a supported flat host Refs #511 Co-Authored-By: Claude Opus 5.5 --- .../2026_10/2026_10_02_antigravity-flat-host/phase-5.md | 2 +- cli/README.md | 5 +++-- docs/FAQ.md | 2 +- docs/MAINTAINERS.md | 1 + 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/aidd_docs/tasks/2026_10/2026_10_02_antigravity-flat-host/phase-5.md b/aidd_docs/tasks/2026_10/2026_10_02_antigravity-flat-host/phase-5.md index c6448f792..50726156e 100644 --- a/aidd_docs/tasks/2026_10/2026_10_02_antigravity-flat-host/phase-5.md +++ b/aidd_docs/tasks/2026_10/2026_10_02_antigravity-flat-host/phase-5.md @@ -1,5 +1,5 @@ --- -status: pending +status: done --- diff --git a/cli/README.md b/cli/README.md index eca3691d9..be9c7ca68 100644 --- a/cli/README.md +++ b/cli/README.md @@ -3,7 +3,7 @@ `@ai-driven-dev/cli` installs AI tool runtime configs, IDE integrations, and plugins from an AIDD marketplace into a project. Every file it writes is hash-tracked in a manifest, so drift is detected and owned files can be restored. -Supported AI tools: Claude Code, Cursor, GitHub Copilot, Codex, OpenCode, Kilo Code. Supported IDE: VS Code. +Supported AI tools: Claude Code, Cursor, GitHub Copilot, Codex, OpenCode, Kilo Code, Antigravity CLI. Supported IDE: VS Code. Requires Node.js >= 22.12, and `git` to fetch marketplace plugins. ## Install @@ -153,8 +153,9 @@ Two output layouts, chosen by `--as`: | `codex` | yes | yes | `.codex/` | | `opencode` | no | yes | `.opencode/` | | `kilo` | no | yes | `.kilo/` | +| `antigravity` | no | yes | `.agents/` | -OpenCode and Kilo Code declare no marketplace contract, so they are flat only. Every other target accepts both layouts. +OpenCode, Kilo Code and Antigravity CLI declare no marketplace contract, so they are flat only. Every other target accepts both layouts. ## Environment variables diff --git a/docs/FAQ.md b/docs/FAQ.md index f7e4ae3e8..33bff5069 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -11,7 +11,7 @@ You can write your own Claude Code skills β€” nothing stops you. AIDD exists bec - **Install / first run** β†’ [Quick start](../README.md#-quick-start). - **Update plugins** β†’ `/plugin marketplace update aidd-framework`, or see [Versioning & updates](MARKETPLACE.md#-versioning--updates). - **Private repo?** Yes β€” `/plugin marketplace add` just needs GitHub read access (via `gh auth login` or a PAT). -- **Cursor / Copilot / Codex / OpenCode / Kilo Code?** Each other tool installs via its own native mechanism (project files, local plugins, or a plugin command) from the [release](https://github.com/ai-driven-dev/framework/releases/latest) archives. Steps per tool β†’ [Other tools](../README.md#other-tools). +- **Cursor / Copilot / Codex / OpenCode / Kilo Code / Antigravity CLI?** Each other tool installs via its own native mechanism (project files, local plugins, or a plugin command) from the [release](https://github.com/ai-driven-dev/framework/releases/latest) archives. Steps per tool β†’ [Other tools](../README.md#other-tools). ## πŸ’Έ Cost and quotas diff --git a/docs/MAINTAINERS.md b/docs/MAINTAINERS.md index 6ae24b5c2..d6881336b 100644 --- a/docs/MAINTAINERS.md +++ b/docs/MAINTAINERS.md @@ -148,6 +148,7 @@ Roles, promotion, and inactivity rules β†’ [`GOVERNANCE.md`](../GOVERNANCE.md#-r - The marketplace is Claude Code native. - Other tools are served by per-release archives the `aidd-cli` builds; this repo stays Claude-authored and tool-agnostic in its prose. - Keep tool-specific detail in plugin READMEs. +- Antigravity CLI has no runtime check in CI: a turn needs a Google login. Before a release that touches its profile, run `cd cli && pnpm smoke:antigravity` on a machine where `agy` is logged in. It installs AIDD into a throwaway project, then checks the `agy` log for a skill expansion and the loaded hooks, the project memory for the hook's refresh, and `/agents` for an AIDD agent. ## 🧱 Build your own plugin From bd0570069d7231ec42903bb4026b9c8f726461c7 Mon Sep 17 00:00:00 2001 From: Thierry Kwiatkowski Date: Mon, 5 Oct 2026 23:45:35 +0200 Subject: [PATCH 4/4] docs: mark the antigravity flat host plan implemented Refs #511 Co-Authored-By: Claude Opus 5.5 --- .../tasks/2026_10/2026_10_02_antigravity-flat-host/plan.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aidd_docs/tasks/2026_10/2026_10_02_antigravity-flat-host/plan.md b/aidd_docs/tasks/2026_10/2026_10_02_antigravity-flat-host/plan.md index f634dcd76..3a67151d4 100644 --- a/aidd_docs/tasks/2026_10/2026_10_02_antigravity-flat-host/plan.md +++ b/aidd_docs/tasks/2026_10/2026_10_02_antigravity-flat-host/plan.md @@ -1,6 +1,6 @@ --- objective: "`aidd setup --ai antigravity` and `aidd translate --to antigravity --as flat` write AIDD skills, the memory hook and agents under `.agents/`, which `agy` loads, without touching files AIDD did not write." -status: in-progress +status: implemented ---