diff --git a/README.md b/README.md index be19a87c..be823064 100644 --- a/README.md +++ b/README.md @@ -825,9 +825,11 @@ Full documentation: [`docs/adapters/kimi-code.md`](docs/adapters/kimi-code.md)
-Antigravity — MCP-only, no hooks +Antigravity IDE — MCP-only, no hooks -**Prerequisites:** Node.js >= 22.5 (or Bun), Antigravity installed. +> This is the Antigravity **desktop IDE**. For the `agy` **command-line tool**, see **Antigravity CLI (`agy`)** below — it installs as a full plugin with hooks. + +**Prerequisites:** Node.js >= 22.5 (or Bun), the Antigravity IDE installed. **Install:** @@ -868,43 +870,28 @@ Full configs: [`configs/antigravity/mcp_config.json`](configs/antigravity/mcp_co
Antigravity CLI (agy) — plugin (MCP + skill + hooks) -**Prerequisites:** Node.js >= 22.5 (or Bun), Antigravity CLI (`agy`) installed. +> The `agy` **command-line tool**, not the Antigravity desktop IDE above. -`agy` has a native **plugin** system, so context-mode installs as a first-class agy plugin that bundles the MCP server, a routing rule, a routing skill, and bounded hooks in one step. +**Prerequisites:** Node.js >= 22.5 (or Bun), Antigravity CLI (`agy`) **≥ 1.0.7** (`agy update` to upgrade). Verified on agy 1.0.10. -**Install** (same one-command pattern as OpenClaw — the script resolves the bundle path for you): +**Install:** -1. Make the MCP server available globally (the plugin runs the `context-mode` binary): +```bash +npm install -g context-mode # the plugin's MCP server + hooks run the global binary +agy plugin install https://github.com/mksglu/context-mode/tree/main/configs/antigravity-cli # registers MCP + rule + skill + hooks +``` - ```bash - npm install -g context-mode - ``` +Restart `agy`. -2. Clone and install the plugin: - - ```bash - git clone https://github.com/mksglu/context-mode.git - cd context-mode - npm run install:agy - ``` - - `npm run install:agy` runs `agy plugin install` on the bundle at `configs/antigravity-cli/` — registering the MCP server from the bundle's native `mcp_config.json`, the routing rule, routing skill, bounded `PreToolUse`, `PostToolUse` capture, and best-effort `Stop` capture hooks — then clears agy's stale tool-schema cache so the `ctx_*` tools appear in the model's tool list (agy caches MCP schemas and doesn't refresh them; an old cache hides the tools). The installer is cross-platform Node (runs natively on Windows, macOS, and Linux — no bash required). Restart `agy`. - - agy's native validation path expects root `plugin.json` + `mcp_config.json`; the bundle intentionally uses that single manifest shape. - -> **Hook version note:** the agy hooks run the **global** `context-mode` binary (`context-mode hook antigravity-cli `), so they need a context-mode version with Antigravity CLI hook support. On an older global the **MCP server + routing rule + routing skill still work**, but hook enforcement/capture may be inert — the installer probes for this and prints a warning if your global is too old (upgrade with `npm install -g context-mode@latest`). To remove the plugin later: `agy plugin uninstall context-mode`. - -> **Already using context-mode in Claude Code?** `agy plugin import claude` can import that existing Claude setup, but the native context-mode agy bundle above is the supported path for agy hooks. - -**Verify:** `agy -p "Use the context-mode ctx_execute MCP tool to compute 7 + 5. Answer only the number." --dangerously-skip-permissions` should print `12`. - -**Install (alternative — MCP only):** add context-mode to `~/.gemini/config/mcp_config.json` (agy's **global** MCP profile — `config/`, distinct from the Antigravity IDE's `antigravity/` path): +**MCP-only (no plugin, no hooks):** if you only want the `ctx_*` tools, skip the plugin and add context-mode to agy's global MCP profile `~/.gemini/config/mcp_config.json` (distinct from the Antigravity IDE's `~/.gemini/antigravity/` path), then restart `agy`: ```json { "mcpServers": { "context-mode": { "command": "context-mode" } } } ``` -**Routing & capture:** The routing rule plus routing skill provide the durable instruction layer, and bounded `PreToolUse` enforcement blocks mapped high-flood tools before execution (`run_command`, `view_file`, `grep_search`, `web_fetch`, `read_url_content`). `PostToolUse` records executed tool calls into `~/.gemini/context-mode/sessions/` and normalizes agy basics (`run_command`, `view_file`, `grep_search`, `list_dir`, `read_url_content`, `search_web`) onto context-mode's canonical tool names; `list_dir` and `search_web` are capture-only because context-mode has no LS/WebSearch PreToolUse routing branch. `Stop` is registered as best-effort session-end capture, but agy `-p` probes have not emitted it. `PreInvocation` and `PostInvocation` are intentionally not registered until agy's payload/response contract is verified for context-mode's pipeline. Auto-detected via MCP `clientInfo.name` (`agy`) or, in a bare shell, the `~/.local/bin/agy` / `~/.gemini/config/mcp_config.json` markers — probed before the generic `~/.claude` fallback so a gemini-cli→agy migrant is not mis-detected as Claude Code ([#774](https://github.com/mksglu/context-mode/issues/774)). +**Verify:** type `ctx stats` in an agy session, or run any prompt from [Try It](#try-it) and check the savings. `context-mode doctor` confirms MCP + hook registration. Remove with `agy plugin uninstall context-mode`. + +**Routing:** the routing rule and skill provide the instruction layer; bounded `PreToolUse` blocks high-flood tools and `PostToolUse` captures sessions. The bundle pins `CONTEXT_MODE_PLATFORM=antigravity-cli` so agy is detected even when Claude Code is co-installed ([#774](https://github.com/mksglu/context-mode/issues/774)).
diff --git a/docs/platform-support.md b/docs/platform-support.md index ca6b0720..7ecf4a0a 100644 --- a/docs/platform-support.md +++ b/docs/platform-support.md @@ -383,9 +383,11 @@ Google Antigravity is an AI-powered IDE by Google/DeepMind. It shares the `~/.ge The standalone Antigravity CLI (`agy`) is the command-line companion to Google Antigravity. Unlike the Antigravity IDE, `agy` has a **native plugin system** (`agy plugin install|import`) and a hook surface (`~/.gemini/config/hooks.json`). context-mode ships as a first-class agy plugin (`configs/antigravity-cli/`) bundling the MCP server, a routing rule, a routing skill, and bounded `PreToolUse`/`PostToolUse`/`Stop` hooks. It shares the `~/.gemini/` session root with the rest of the Gemini family; `agy` reads its **global** MCP profile from `~/.gemini/config/mcp_config.json` (not the IDE's `~/.gemini/antigravity/mcp_config.json`). -**Install** (same one-command pattern as OpenClaw — `npm run install:`): -- `npm install -g context-mode` (the plugin's MCP server runs the `context-mode` binary), then `git clone https://github.com/mksglu/context-mode.git && cd context-mode && npm run install:agy`. The `install:agy` script (`scripts/install-antigravity-cli-plugin.mjs`, cross-platform Node — runs natively on Windows, macOS, and Linux; no bash required) auto-resolves and runs `agy plugin install configs/antigravity-cli`, registering the bundle native `plugin.json` + `mcp_config.json`, routing rule, routing skill, and hooks into agy's plugin profile under `~/.gemini/config/plugins/context-mode/`. It then clears agy's stale tool-schema cache (`~/.gemini/antigravity-cli/mcp/context-mode/`) so agy re-fetches the current Gemini-safe schemas. -- Already on Claude Code (no clone): `agy plugin import claude` can import that existing Claude setup, but the native context-mode agy bundle above is the supported path for agy hooks. +**Verified:** agy 1.0.10 (Linux). The GitHub-subpath install requires **agy ≥ 1.0.7** (subpath + branch resolution landed in 1.0.7 — run `agy update` to upgrade). No agy hook event was added, removed, or renamed through 1.0.10, and the shared `~/.gemini/config/hooks.json` location has been canonical since agy 1.0.8, so the bundle's `PreToolUse`/`PostToolUse`/`Stop` wiring is current. + +**Install:** +- `npm install -g context-mode` (the plugin's MCP server + hooks run the `context-mode` binary), then `agy plugin install https://github.com/mksglu/context-mode/tree/main/configs/antigravity-cli`. agy clones the repo, resolves the `configs/antigravity-cli` subpath (with branch resolution), and registers the bundle's native `plugin.json` + `mcp_config.json`, routing rule, routing skill, and hooks into its plugin profile under `~/.gemini/config/plugins/context-mode/`. If `ctx_*` tools don't appear after an upgrade, clear agy's stale tool-schema cache (`~/.gemini/antigravity-cli/mcp/context-mode/`) and restart agy (agy caches MCP schemas and doesn't refresh them). +- Already on Claude Code: `agy plugin import claude` can import that existing Claude setup, but the native context-mode agy bundle above is the supported path for agy hooks. - MCP only: add context-mode to `~/.gemini/config/mcp_config.json` under `mcpServers` (`{"command":"context-mode"}`). **Detection:** @@ -407,7 +409,7 @@ The standalone Antigravity CLI (`agy`) is the command-line companion to Google A - `PreInvocation` and `PostInvocation` are visible in agy's hook list but intentionally not registered; agy 1.0.6 `-p` probes did not emit them, and their payload/response semantics are not verified against context-mode's pipeline. - agy's `PostToolUse` payload carries no tool-output text, so byte-accounting for tool output is unavailable on this surface; the tool call + project + error state are still captured. - Shares `~/.gemini/` with Gemini CLI and Antigravity — session DB uses the project hash to prevent collisions. -- **Gemini function-calling tool exposure.** agy exposes MCP tools as Gemini function declarations, and Gemini's API rejects JSON Schema `const` / `additionalProperties` — a rejected schema makes agy **silently drop** that tool from the model's function list (the agent then hand-rolls the tool via shell scripts instead of calling it). context-mode emits Gemini-safe tool schemas (`const`→`enum`, `additionalProperties` stripped) so the `ctx_*` tools are exposed. agy also **caches** each server's tool schemas under `~/.gemini/antigravity-cli/mcp//` and does **not** refresh them on reconnect, so a cache captured by an older context-mode keeps the tools hidden — `npm run install:agy` clears that cache (delete `~/.gemini/antigravity-cli/mcp/context-mode/` by hand if you registered MCP without the installer). +- **Gemini function-calling tool exposure.** agy exposes MCP tools as Gemini function declarations, and Gemini's API rejects JSON Schema `const` / `additionalProperties` — a rejected schema makes agy **silently drop** that tool from the model's function list (the agent then hand-rolls the tool via shell scripts instead of calling it). context-mode emits Gemini-safe tool schemas (`const`→`enum`, `additionalProperties` stripped) so the `ctx_*` tools are exposed. agy also **caches** each server's tool schemas under `~/.gemini/antigravity-cli/mcp//` and does **not** refresh them on reconnect, so a cache captured by an older context-mode keeps the tools hidden — delete `~/.gemini/antigravity-cli/mcp/context-mode/` and restart agy to force a re-fetch. --- diff --git a/package.json b/package.json index 70f208f1..b3e6bb72 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,6 @@ "openclaw.plugin.json", "start.mjs", "scripts/postinstall.mjs", - "scripts/install-antigravity-cli-plugin.mjs", "scripts/heal-better-sqlite3.mjs", "scripts/heal-installed-plugins.mjs", "scripts/plugin-cache-integrity.mjs", @@ -99,7 +98,6 @@ "test:compare": "npx tsx tests/context-comparison.ts", "test:ecosystem": "npx tsx tests/ecosystem-benchmark.ts", "install:openclaw": "node -e \"if(process.platform==='win32'){console.error('OpenClaw install requires bash (Git Bash or WSL)');process.exit(1)}else{require('child_process').execSync('bash scripts/install-openclaw-plugin.sh',{stdio:'inherit'})}\"", - "install:agy": "node scripts/install-antigravity-cli-plugin.mjs", "postinstall": "node scripts/postinstall.mjs" }, "dependencies": { diff --git a/scripts/install-antigravity-cli-plugin.mjs b/scripts/install-antigravity-cli-plugin.mjs deleted file mode 100644 index eaadbb9e..00000000 --- a/scripts/install-antigravity-cli-plugin.mjs +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env node -/** - * Cross-platform installer: register the context-mode plugin into Antigravity CLI (agy). - * - * Replaces the former bash-only scripts/install-antigravity-cli-plugin.sh so - * `npm run install:agy` runs natively on Windows (PowerShell/cmd) as well as - * macOS/Linux. agy itself runs on Windows, so its installer must too — unlike - * the openclaw installer, which is genuinely POSIX-only (signals, pgrep, /tmp). - * - * The bundle (configs/antigravity-cli/) registers the context-mode MCP server, - * routing rule, routing skill, and bounded PreToolUse/PostToolUse/Stop hooks in - * one step. - * - * Usage: npm run install:agy (or: node scripts/install-antigravity-cli-plugin.mjs) - */ -import { spawnSync } from "node:child_process"; -import { existsSync, rmSync } from "node:fs"; -import { homedir } from "node:os"; -import { dirname, join, resolve } from "node:path"; -import { fileURLToPath } from "node:url"; - -const isWin = process.platform === "win32"; -const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), ".."); -const bundle = resolve(repoRoot, "configs", "antigravity-cli"); - -// Double-quote a path so a clone dir with spaces survives the shell on both -// cmd.exe and /bin/sh (paths never contain literal quotes). -const q = (s) => `"${s}"`; - -// Cross-platform "is on PATH?" — `where` on Windows, `command -v` on POSIX. -// shell:true is required: `command -v` is a shell builtin and `where`/`agy` may -// resolve to a .cmd shim on Windows that only the shell can launch. -function onPath(cmd) { - const probe = isWin ? `where ${cmd}` : `command -v ${cmd}`; - return spawnSync(probe, { stdio: "ignore", shell: true }).status === 0; -} - -// — preflight — -if (!onPath("agy")) { - console.error("✗ 'agy' (Antigravity CLI) not found in PATH. Install agy first, then re-run."); - process.exit(1); -} -if (!existsSync(bundle)) { - console.error(`✗ plugin bundle not found at ${bundle}`); - process.exit(1); -} - -console.log("→ context-mode agy plugin installer"); -console.log(` bundle : ${bundle}`); - -// The plugin's MCP server runs the global `context-mode` binary (it needs the -// native better-sqlite3 dependency, which a bare clone does not have). Warn — do -// not silently global-install on the user's behalf. -const hasContextMode = onPath("context-mode"); -if (!hasContextMode) { - console.error("⚠ 'context-mode' is not on PATH — the plugin's MCP server requires it."); - console.error(" Install it with: npm install -g context-mode"); -} - -// Run `agy plugin install `. String command + shell:true so cmd.exe can -// resolve agy's .cmd shim on Windows; the quoted bundle path handles spaces. -const install = spawnSync(`agy plugin install ${q(bundle)}`, { stdio: "inherit", shell: true }); -if (install.status !== 0) { - console.error(`✗ 'agy plugin install' failed (exit ${install.status ?? "unknown"}).`); - process.exit(install.status ?? 1); -} - -// MCP is registered by `agy plugin install` above, straight from the bundle's -// native `mcp_config.json` (env-pinned CONTEXT_MODE_PLATFORM=antigravity-cli). -// Verified on agy 1.0.6: it logs "mcpServers : 1 processed" and writes the -// server into agy's plugin profile -// (~/.gemini/config/plugins/context-mode/mcp_config.json, env preserved). -// agy native validation/install does not read `.mcp.json`; keep the bundle on -// the single native `mcp_config.json` path to avoid manifest drift. - -// agy CACHES each MCP server's tool schemas under -// ~/.gemini/antigravity-cli/mcp// and does NOT refresh them on reconnect -// (verified on agy 1.0.6). A cache captured by an older context-mode holds the -// Gemini-incompatible schemas (`const` / `additionalProperties`) that make -// Antigravity CLI silently DROP the ctx_* tools from the model's function list — -// so even after upgrading, agy keeps hiding the tools and the agent works around -// them via shell scripts. Clear the cache so agy re-fetches the current -// (Gemini-safe) tools/list on its next launch. -const agyToolCache = join(homedir(), ".gemini", "antigravity-cli", "mcp", "context-mode"); -let cacheCleared = false; -if (existsSync(agyToolCache)) { - try { - rmSync(agyToolCache, { recursive: true, force: true }); - cacheCleared = true; - } catch (err) { - console.error(`⚠ Could not clear agy's stale tool-schema cache at ${agyToolCache}: ${err.message}`); - console.error(" If ctx_* tools don't appear in agy, delete that folder manually and restart agy."); - } -} - -// Probe whether the global `context-mode` understands the antigravity-cli hooks. -// The shipped hook commands resolve the GLOBAL binary at runtime. A context-mode -// older than the release that added Antigravity CLI support may have no -// `antigravity-cli` HOOK_MAP entry, and the dispatcher suppresses stderr, so the -// hooks would be a SILENT no-op. Detect that here and tell the user instead. -let hooksOk = false; -if (hasContextMode) { - hooksOk = ["pretooluse", "posttooluse", "stop"].every((event) => { - const probe = spawnSync(`context-mode hook antigravity-cli ${event}`, { - input: "{}", - stdio: ["pipe", "ignore", "ignore"], - shell: true, - }); - return probe.status === 0; - }); -} - -console.log(""); -// Confirm `agy plugin install` actually registered the MCP from the bundle's -// MCP config (it writes it into agy's plugin profile). If a future agy build -// skips it, fall back to a one-line manual instruction rather than silently -// leaving MCP unconfigured — never re-introduce a blind global-profile write. -const pluginMcp = join(homedir(), ".gemini", "config", "plugins", "context-mode", "mcp_config.json"); -if (existsSync(pluginMcp)) { - console.log("✓ Installed the context-mode agy plugin: MCP server + routing rule + routing skill + hooks."); - console.log(` MCP registered from the bundle's mcp_config.json → ${pluginMcp}`); -} else { - console.log("✓ Installed the context-mode agy plugin: routing rule + routing skill + hooks."); - console.error("⚠ MCP server not found in agy's plugin profile. If ctx_* tools don't appear, add"); - console.error(' { "mcpServers": { "context-mode": { "command": "context-mode" } } }'); - console.error(" to ~/.gemini/config/mcp_config.json and restart agy."); -} -if (cacheCleared) { - console.log("✓ Cleared agy's stale tool-schema cache — agy re-fetches Gemini-safe schemas on next launch."); -} -if (hooksOk) { - console.log("✓ Antigravity CLI hooks are ACTIVE (this context-mode supports antigravity-cli)."); -} else { - console.error("⚠ Antigravity CLI hooks may be INACTIVE: your global 'context-mode' is missing or too old"); - console.error(" to handle 'context-mode hook antigravity-cli'. MCP tools + the routing rule + routing skill still work."); - console.error(" Enable hook enforcement/capture with: npm install -g context-mode@latest"); -} -console.log(""); -console.log(" Restart agy, then verify:"); -console.log(' agy -p "Use the context-mode ctx_execute MCP tool to compute 7 + 5. Answer only the number." --dangerously-skip-permissions'); -console.log(" Expected output: 12"); diff --git a/src/adapters/antigravity-cli/index.ts b/src/adapters/antigravity-cli/index.ts index edd87c01..267245aa 100644 --- a/src/adapters/antigravity-cli/index.ts +++ b/src/adapters/antigravity-cli/index.ts @@ -48,7 +48,7 @@ export function antigravityCliHooksPath(): string { /** * `agy plugin install ` registers MCP + hook + skill into agy's plugin - * profile under ~/.gemini/config/plugins// (verified on agy 1.0.6) — the + * profile under ~/.gemini/config/plugins// (verified on agy 1.0.6, re-verified 1.0.10) — the * canonical install. The global mcp_config.json / hooks.json paths above are the * manual (no-plugin) fallback. doctor must recognize BOTH. */ @@ -159,8 +159,9 @@ function readRegisteredHooks(paths: string[]): { /* unreadable/missing — try next */ } } - // Stop is registered when possible, but agy 1.0.6 `-p` probes did not emit it. - // Treat it as best-effort so doctor does not mark a working Pre/Post install + // Stop is registered when possible, but agy 1.0.6 `-p` probes did not emit it + // (no Stop-hook change in agy's changelog through 1.0.10). Treat it as + // best-effort so doctor does not mark a working Pre/Post install // as degraded solely because Stop is absent. return { ...found, ok: found.preOk && found.postOk }; } @@ -298,7 +299,7 @@ export class AntigravityCliAdapter extends AntigravityAdapter { check: "MCP registration", status: "fail", message: "context-mode not found in Antigravity CLI mcpServers", - fix: "npm run install:agy", + fix: "agy plugin install https://github.com/mksglu/context-mode/tree/main/configs/antigravity-cli", }; } @@ -387,8 +388,8 @@ export class AntigravityCliAdapter extends AntigravityAdapter { status: ok ? "pass" : "warn", message: ok ? `PreToolUse guard and PostToolUse capture configured in ${where}${stopOk ? "; best-effort Stop hook also configured" : ""}` - : `Antigravity CLI hooks incomplete (${missing || "none found"} missing) — MCP tools still work, but bounded routing enforcement and session capture are degraded. Run \`npm run install:agy\` (agy plugin) or \`context-mode upgrade\` to repair hooks.`, - ...(ok ? {} : { fix: "npm run install:agy" }), + : `Antigravity CLI hooks incomplete (${missing || "none found"} missing) — MCP tools still work, but bounded routing enforcement and session capture are degraded. Run \`agy plugin install https://github.com/mksglu/context-mode/tree/main/configs/antigravity-cli\` or \`context-mode upgrade\` to repair hooks.`, + ...(ok ? {} : { fix: "agy plugin install https://github.com/mksglu/context-mode/tree/main/configs/antigravity-cli" }), }, ]; } diff --git a/tests/adapters/antigravity.test.ts b/tests/adapters/antigravity.test.ts index 4c9b8d2d..76fa3848 100644 --- a/tests/adapters/antigravity.test.ts +++ b/tests/adapters/antigravity.test.ts @@ -228,14 +228,14 @@ describe("AntigravityCliAdapter", () => { ); }); - it("checkPluginRegistration fails with the install:agy remediation when nothing is registered", () => { + it("checkPluginRegistration fails with the agy plugin install remediation when nothing is registered", () => { rmSync(adapter.getSettingsPath(), { force: true }); rmSync(join(antigravityCliPluginDir(), "mcp_config.json"), { force: true }); expect(adapter.checkPluginRegistration()).toMatchObject({ check: "MCP registration", status: "fail", - fix: "npm run install:agy", + fix: "agy plugin install https://github.com/mksglu/context-mode/tree/main/configs/antigravity-cli", }); }); @@ -341,20 +341,21 @@ describe("AntigravityCliAdapter", () => { /** * Guards the shipped agy plugin bundle (configs/antigravity-cli/), which users - * install with `npm run install:agy` (→ `agy plugin install configs/antigravity-cli`). + * install in one command — `agy plugin install ` — with agy + * cloning the repo and resolving the configs/antigravity-cli subpath itself + * (no local clone needed). * * agy's native plugin system reads the root `plugin.json` + `mcp_config.json` - * shape. Verified on agy 1.0.6: `agy plugin install` logs "mcpServers : 1 + * shape. Verified on agy 1.0.6, re-verified on 1.0.10: `agy plugin install` logs "mcpServers : 1 * processed" and registers the server — env preserved — into * ~/.gemini/config/plugins//mcp_config.json. `.mcp.json` and * `.claude-plugin/plugin.json` are intentionally not shipped here because agy * native validate/install does not read them. * - * Like the Copilot bundle, the MCP config is committed in the plugin bundle - * rather than generated during install. + * The MCP config is committed in the plugin bundle rather than generated during + * install. */ const AGY_PLUGIN = resolve(__dirname, "..", "..", "configs", "antigravity-cli"); -const AGY_REPO_ROOT = resolve(__dirname, "..", ".."); describe("configs/antigravity-cli — agy plugin bundle", () => { it("ships native agy plugin.json + mcp_config.json pinned to antigravity-cli", () => { @@ -439,23 +440,4 @@ describe("configs/antigravity-cli — agy plugin bundle", () => { expect(existsSync(resolve(__dirname, "..", "..", "hooks", "antigravity-cli", "stop.mjs"))).toBe(true); expect(existsSync(resolve(__dirname, "..", "..", "hooks", "antigravity-cli", "payload.mjs"))).toBe(true); }); - - it("ships the npm run install:agy one-command installer (cross-platform Node)", () => { - const pkg = JSON.parse(readFileSync(resolve(AGY_REPO_ROOT, "package.json"), "utf-8")); - // A Node installer (not bash) so `npm run install:agy` runs natively on - // Windows too — agy runs on Windows, so its installer must. - expect(pkg.scripts["install:agy"]).toContain("scripts/install-antigravity-cli-plugin.mjs"); - expect(pkg.files).toContain("scripts/install-antigravity-cli-plugin.mjs"); - - const installer = resolve(AGY_REPO_ROOT, "scripts", "install-antigravity-cli-plugin.mjs"); - expect(existsSync(installer)).toBe(true); - const body = readFileSync(installer, "utf-8"); - expect(body).toContain("agy plugin install"); - expect(body).toContain("antigravity-cli"); - // agy caches tool schemas and never refreshes them; the installer must clear - // that cache (~/.gemini/antigravity-cli/mcp/context-mode) or the Gemini-safe - // schema fix never reaches the model. - expect(body).toContain("rmSync"); - expect(body).toContain('"mcp", "context-mode"'); - }); });