{"id":"antigravity-cli","repo":"lefos13/paseo-plugin-antigravity-cli","url":"https://github.com/lefos13/paseo-plugin-antigravity-cli","package":"paseo-plugin-antigravity-cli","npm":{"package":"paseo-plugin-antigravity-cli","version":"0.3.0","integrity":"sha512-ONpQPCUhB/ApvBMe4yfvdHG+N3xyvEiSlJvIkLvK9kiFocurQYv71NbpxHc81yskkkjCaAkeqPkjVnfFIbzIkQ==","publishedAt":"2026-09-24T08:33:24.244Z","downloadsLast30Days":0},"name":"antigravity-cli","description":"Antigravity CLI (agy) as a Paseo provider: streaming turns, tool rows with diffs, images, structured output, skills and slash commands, conversation import, and opt-in MCP sharing.","categories":["provider"],"platforms":[],"caveats":["Requires Google's Antigravity CLI (agy) installed and signed in on the daemon host; built against agy 1.2.10.","No steering, tool-approval prompts, or revert: agy's stream-json mode does not expose them.","Sharing Paseo's MCP tools is opt-in and writes a credential-bearing .agents/mcp_config.json (locally git-excluded).","Plan mode is enforced by the plugin (instruction plus approval prompt); agy's headless --mode plan does not block edits.","Verified end to end on macOS only."],"images":[],"themes":[],"health":{"manifestValid":true,"hasReadme":true,"hasLicense":true,"hasTests":true,"hasTypecheckScript":true,"updatedRecently":true},"scannedAt":"2026-09-24T19:54:43.946Z","addedAt":"2026-09-24T20:52:43+01:00","npmSecurity":{"status":"passed","blockingFindings":0,"advisoryFindings":0,"scannedAt":"2026-09-24T19:54:35.179Z","version":"0.3.0","integrity":"sha512-ONpQPCUhB/ApvBMe4yfvdHG+N3xyvEiSlJvIkLvK9kiFocurQYv71NbpxHc81yskkkjCaAkeqPkjVnfFIbzIkQ=="},"version":"0.3.0","security":{"status":"passed","blockingFindings":0,"advisoryFindings":0,"scannedAt":"2026-09-24T19:54:35.179Z","commit":"23678d03f35dd7d0925257388da3b0254253ee81"},"author":"lefos13","license":"MIT","paseoVersionRequirement":">=0.9.1","descriptionNodes":[{"type":"text","text":"Antigravity CLI (agy) as a Paseo provider: streaming turns, tool rows with diffs, images, structured output, skills and slash commands, conversation import, and opt-in MCP sharing."}],"caveatNodes":[[{"type":"text","text":"Requires Google's Antigravity CLI (agy) installed and signed in on the daemon host; built against agy 1.2.10."}],[{"type":"text","text":"No steering, tool-approval prompts, or revert: agy's stream-json mode does not expose them."}],[{"type":"text","text":"Sharing Paseo's MCP tools is opt-in and writes a credential-bearing .agents/mcp_config.json (locally git-excluded)."}],[{"type":"text","text":"Plan mode is enforced by the plugin (instruction plus approval prompt); agy's headless --mode plan does not block edits."}],[{"type":"text","text":"Verified end to end on macOS only."}]],"manifest":{"id":"antigravity-cli","requirements":{"paseo":">=0.9.1"}},"repoMeta":{"stars":0,"defaultBranch":"main","pushedAt":"2026-09-24T08:28:46Z"},"owner":{"login":"lefos13","avatarUrl":"https://avatars.githubusercontent.com/u/71150524?v=4"},"installNotesHtml":"<p>From npm (Paseo 0.9):</p>\n<pre><code>paseo plugin install npm:paseo-plugin-antigravity-cli\n</code></pre>\n<p>Or from GitHub:</p>\n<pre><code>paseo plugin install github:lefos13/paseo-plugin-antigravity-cli\n</code></pre>\n<p>You can also paste either source into <strong>Settings → Plugins → Plugin source</strong>. Check it with\n<code>paseo plugin ls</code>; <code>antigravity-cli</code> should be <code>running</code>.</p>\n<p>Antigravity must already work on its own: <code>agy --version</code> should print, and <code>agy</code> should be signed\nin. Then pick <strong>Antigravity</strong> as the provider when you start a new agent.</p>\n<h3>How this differs from <code>agy-provider</code></h3>\n<p><a href=\"https://paseo.cafe/plugins/agy-provider\"><code>agy-provider</code></a> adapts Google's Antigravity ACP server\nthrough Paseo's ACP shim. This plugin drives the <code>agy</code> CLI directly over its documented\n<code>--input-format stream-json</code> / <code>--output-format stream-json</code> mode, so it needs no extra server\ninstall. On top of plain turns it adds edit diffs rebuilt from file snapshots, structured output\nthrough <code>--json-schema</code>, image input, import of existing agy conversations, slash commands and\nskills, and opt-in sharing of Paseo's MCP tools.</p>\n<h3>Which <code>agy</code> gets launched</h3>\n<p>The first one that resolves, in this order:</p>\n<ol>\n<li><code>providerOptions.agyPath</code> — a per-session absolute path to the binary.</li>\n<li><code>PASEO_ANTIGRAVITY_BIN</code> — an environment variable for the daemon's environment.</li>\n<li><code>~/.local/bin/agy</code> — checked explicitly because a daemon started by a GUI app often does not\ninherit that directory on <code>PATH</code>.</li>\n<li><code>agy</code> — resolved from <code>PATH</code>.</li>\n</ol>","readmeText":"# Antigravity CLI provider for Paseo\n\nRuns Google's official Antigravity CLI (`agy`) as a Paseo provider: Paseo owns the session, the\nCLI does the work, and every turn, tool call, and message is rendered from the CLI's `stream-json`\nprotocol. Nothing about Antigravity is reimplemented — this plugin spawns the `agy` binary that is\nalready installed and signed in on your machine.\n\n- Provider id: `antigravity-cli`\n- Requires: Paseo ≥ 0.9.1 (provider protocol version 1), Node 24 for the plugin process, and\n  Antigravity CLI 1.2.9 for the behaviour described below.\n\n## Install\n\nFrom npm (Paseo 0.9):\n\n```\npaseo plugin install npm:paseo-plugin-antigravity-cli\n```\n\nOr from GitHub:\n\n```\npaseo plugin install github:lefos13/paseo-plugin-antigravity-cli\n```\n\nYou can also paste either source into **Settings → Plugins → Plugin source**. Check it with\n`paseo plugin ls`; `antigravity-cli` should be `running`.\n\nAntigravity must already work on its own: `agy --version` should print, and `agy` should be signed\nin. Then pick **Antigravity** as the provider when you start a new agent.\n\n### How this differs from `agy-provider`\n\n[`agy-provider`](https://paseo.cafe/plugins/agy-provider) adapts Google's Antigravity ACP server\nthrough Paseo's ACP shim. This plugin drives the `agy` CLI directly over its documented\n`--input-format stream-json` / `--output-format stream-json` mode, so it needs no extra server\ninstall. On top of plain turns it adds edit diffs rebuilt from file snapshots, structured output\nthrough `--json-schema`, image input, import of existing agy conversations, slash commands and\nskills, and opt-in sharing of Paseo's MCP tools.\n\n### Which `agy` gets launched\n\nThe first one that resolves, in this order:\n\n1. `providerOptions.agyPath` — a per-session absolute path to the binary.\n2. `PASEO_ANTIGRAVITY_BIN` — an environment variable for the daemon's environment.\n3. `~/.local/bin/agy` — checked explicitly because a daemon started by a GUI app often does not\n   inherit that directory on `PATH`.\n4. `agy` — resolved from `PATH`.\n\n## What the plugin supports\n\n| Capability | Behaviour |\n|---|---|\n| `prompt.message` | One `agy` process per session; each prompt is one NDJSON turn on its stdin and exactly one `result` back. A prompt sent while a turn runs is queued by the CLI and becomes the next turn. |\n| `prompt.command` | Slash commands, through the composer's command picker. A command turn runs on a CLI launched *without* `--disable-slash-commands` and sends `/<name> <arguments>` as the first token of the turn, which is what makes the CLI expand it; the next plain turn relaunches with the flag again (see below). |\n| `prompt.image` | Images cannot go over `stream-json` (`stream input content block type \"image\" is not supported (only \"text\")`), so each image part is written to the plugin's attachments folder and the prompt names its absolute path with `view it with view_file`. The folder is passed as an extra `--add-dir` and deleted on `session.close`. Nothing is written into your workspace. |\n| `prompt.output_schema` | A prompt with an `outputSchema` is served by a CLI launched with `--json-schema <file> --conversation <id>`; the turn's last assistant message is `JSON.stringify(result.structured_output)`. The flag is launch-time only, so the CLI is relaunched without it before the next plain turn, and a schema prompt is refused with `code: \"busy\"` while another turn is pending. |\n| `session.configure` | Model, reasoning tier, mode, and settings. All of them are launch flags, so a change restarts the CLI on the next turn, resuming the same conversation with `--conversation <id>`. |\n| `session.list` | Imports existing Antigravity conversations by reading `~/.gemini/antigravity-cli/conversation_summaries.db` read-only. Filter by workspace, text, and limit; subagent runs are excluded. |\n| `session.persistence` | The conversation id agy reports is persisted, so reopening an agent resumes the same Antigravity conversation. |\n| `session.subsession` | Each subagent an `invoke_subagent` call starts is shown as a child session of the agent that spawned it, linked to its row, and follows the child's own transcript live (see [Subagents](#subagents)). |\n| `permission` | Used only for plan approval: a plan-mode turn ends with an *Implement this plan?* prompt (see [Plan mode](#plan-mode)). agy's own tool approvals cannot be surfaced. |\n| `permission.tool_policy` | Accepted (Paseo rejects a session carrying a tool policy otherwise), but preapproved MCP tools cannot be forwarded: agy reads its own rules from `settings.json`. |\n\nModels come from `agy models` (cached for 10 minutes against the resolved binary's path and\nmtime; `force` rediscovers). Reasoning tiers are encoded in the model id itself\n(`gemini-3.8-flash-high`), so the composer shows one model per family with High/Medium/Low and maps\nthe choice back onto the slug — `--effort` is never passed, because the CLI rejects the pair.\n\nModes: *Default* (review file writes before they run), *Accept edits*, *Plan*.\n\nTool rows are mapped from the CLI's own step parameters: shell commands, file reads and writes,\nedits (with a unified diff), `grep_search`/`find_by_name`/`list_dir`, `search_web`,\n`read_url_content`, `define_subagent`, and `call_mcp_tool` (shown as `server/tool`). Subagents\nget their own rows, below.\n\n### Plan mode\n\n`agy --mode plan` does not stop a headless run from editing: agy 1.1.28+ approves its own plan\nreview when nobody can answer it, and on CLI 1.2.10 a `--mode plan` run edited files straight away,\nwith and without `--dangerously-skip-permissions` (probed 2026-09-24). The plugin therefore enforces\nplan mode itself:\n\n- every plan-mode turn is prefixed with a `<plan_mode>` block telling the model to investigate\n  read-only and end with an implementation plan instead of implementing it;\n- when the turn completes, its last answer is offered as a plan (`kind: \"plan\"` permission) with\n  **Implement** and **Keep planning**. *Implement* switches the session to *Accept edits* and sends\n  `The plan is approved. Implement it now.`; *Keep planning*, or simply sending another message,\n  withdraws the prompt and stays in plan mode.\n\nThis is an instruction, not a sandbox: agy has no headless flag that denies edits, so a model that\nignores the instruction can still write files.\n\n### Background commands\n\nWhen the model starts a long-running command in the background (a dev server, a watcher), agy\nkeeps that tool `ACTIVE` on the stream until the command exits and holds back every later step and\nthe turn's `result` behind it — the conversation itself carries on and finishes (CLI 1.2.10). A\ntool still running after 5 s therefore makes the plugin read the conversation's own transcript\n(`~/.gemini/antigravity-cli/brain/<conversation>/.system_generated/logs/transcript.jsonl`), publish\nthe steps the stream is holding, and complete the turn as soon as the transcript shows the final\nanswer. The CLI holding the command is left running, so the server stays up; a notice says so.\nIt cannot take another turn (a line written to it would queue behind the command), so your next\nmessage stops it — and the command with it — and resumes the conversation in a fresh CLI.\n\n## Subagents\n\nWhen the model delegates with `invoke_subagent`, agy starts each subagent as its own conversation\nin the background and keeps the parent turn open until their reports arrive. The plugin shows that\nin two layers:\n\n1. **A subagent row in the parent timeline**, built only from the parent's stream: one row per\n   subagent (one call may start several), with its type, role, and the prompt it was given. The\n   row stays *running* while the subagent works, and ends *completed* when the subagent finishes or\n   the turn succeeds, *canceled* when the turn is interrupted, and *failed* when the turn fails.\n2. **A child session per subagent.** agy names each subagent's transcript\n   (`~/.gemini/antigravity-cli/brain/<id>/.system_generated/logs/transcript.jsonl`, handed out as\n   the step's `log_uri`). The plugin follows that file while the subagent runs and shows it as a\n   Paseo child session linked to the row: the subagent's prompt, each tool call with its result,\n   and its final answer. The row's text becomes the report the subagent sent back to the parent,\n   and the row lists the subagent's tool calls. The child's rows are stored like the parent's, so\n   reopening the agent with history restores its children too.\n\nThe transcript file is agy-internal and undocumented, so the child session is best-effort: a\nmissing or unreadable transcript, or one in a shape the plugin does not recognise, leaves the row\nfrom step 1 in place (the parent turn is never affected), and lines of an unknown kind are skipped.\nA subagent counts as finished when its transcript ends on an answer with no further tool call; the\nparent's own \"report arrived\" step is not used, because it arrives well after the transcript's last\nline and does not say which subagent it belongs to. The plugin stops following a transcript when\nthe subagent finishes, when the session or the plugin closes, when the parent turn is interrupted or\nfails, when the file never shows up within a minute, or after ten minutes without a new line.\n\n## Slash commands\n\nThe composer's command picker lists the commands this plugin has verified the CLI expands in\n`stream-json` mode (each one probed against CLI 1.2.9 with `--log-file`, which is the only place\n`Print mode: expanded slash command \"<name>\"` is written — stderr never shows it):\n\n| Command | Source |\n|---|---|\n| `/plan`, `/goal`, `/grill-me`, `/teamwork-preview`, `/learn`, `/schedule`, `/boost`, `/browser` | The CLI's own workflows (`(system)` in the log). `/learn` writes the behaviour into the workspace's `GEMINI.md`; `/schedule` sets up a recurring run; `/boost` runs the task with deep thinking, multiple perspectives and rigorous verification (it answers `Routine: Solo` when it keeps the work to itself); `/browser` hands the task to the CLI's browser agent. |\n| `/<name>` | A skill in this workspace's customization roots: `.agents/skills/<name>/SKILL.md`, and the same under `.agent/`, `_agents/`, `_agent/` (`(skill)` in the log). The name is the skill's own frontmatter `name`, not its directory. |\n| `/<name>` | A skill installed for every workspace, in the CLI's own precedence order: `~/.gemini/antigravity-cli/skills/<name>/SKILL.md`, `~/.gemini/config/skills/<name>/SKILL.md`, then `~/.gemini/skills/<name>/SKILL.md`. All three expand (`(skill)` in the log), and each one outranks the CLI's built-in skills. |\n| `<plugin>:<name>` | A skill of a plugin installed for the CLI, under `~/.gemini/config/plugins/<plugin>/skills/`. A plugin that keeps its one skill directly in `skills/` is addressed with a `..` placeholder — `/android-cli-plugin:..:android-cli` — because that is the name the CLI expands. |\n| `<name>` | A skill the CLI ships itself, under `~/.gemini/antigravity-cli/builtin/skills/`. |\n| `/<name>` | A skill in the shared installer's directory, `~/.agents/skills/<name>/SKILL.md`. The CLI never reads that directory, so the **plugin expands this one itself**: agy is sent the skill's own instructions as a plain message (never a slash name) and is given the skill's directory as an extra `--add-dir`, so the turn can read the scripts and templates the skill refers to. A name the CLI expands on its own, or a workspace skill, always wins over the copy here. |\n\nAntigravity decides some built-ins per account, not per binary: `/boost` and `/teamwork-preview`\nanswer to the `boost_command_disabled` and `teamwork_preview_command_disabled` admin controls, and\n`/compact`, `/review` and `/owl` exist in the binary but stayed inert for the account these probes\nran on (`enable-compact-slash-command`, `enable-review`, `enable-owl-slash-command`). A built-in\nthat is disabled for your account simply **does not expand**: agy treats the text as an ordinary\nmessage and the model answers it, so choosing one of the commands above costs a normal turn rather\nthan failing it. `/boost` and `/browser` expanded on every probe on the same account as the six\nbefore them, so they are listed; `/compact`, `/review` and `/owl` never expanded there, and a\nplugin cannot tell whether any other account has them, so they stay out rather than send a name\nthat would silently be answered as text.\n\nCommands the CLI answers itself (`/skills`, `/usage`, `/quota`, `/credits`, `/model`, `/effort`,\n`/help`, `/config`, `/permissions`, `/hooks`, `/agents`, `/changelog`, …) are deliberately absent:\nin a `stream-json` turn each one ends the turn with `ERROR` and exit 2 — `/skills` says so itself\n(`/skills is answered by the CLI itself and is unavailable with --input-format stream-json; run it\nas its own --print /skills invocation`), and `/btw` and `/tasks` report \"not available in print\nmode\" — so offering one would kill the turn instead of running it. They remain available inside the\nCLI's own TUI, or through a separate `--print <command>` invocation.\n\nA command is a *turn*, so it obeys the relaunch rules: `--disable-slash-commands` is left off for\nthat turn's process and put back for the next plain turn, on the same conversation. That flag is\nalso what keeps a plain message starting with `/` from being expanded, so while a command turn is\nrunning both a further command and a plain prompt are refused with `code: \"busy\"` rather than\nqueued into a process that would serve them wrongly.\n\nA plugin-expanded skill (`~/.agents/skills`, above) is the mirror image: `--disable-slash-commands`\nstays on, because the turn is an ordinary message, but the skill's directory joins the launch flags\nfor that turn alone, so it is its own launch too — the next plain turn relaunches without it. While\nsuch a turn runs, a second command and a plain prompt are refused with `code: \"busy\"` for the same\nreason: the CLI cannot be replaced until the turn it owes has finished.\n\n## What it cannot do, and why\n\n- **Steering** (`prompt.steer`): a line written to agy's stdin while a turn is running is *queued\n  into a following turn*, not applied to the running one. There is no way to steer, so Paseo\n  replaces the active turn instead of offering it.\n- **Tool permission prompts**: agy resolves tool approval internally through its own\n  `toolPermission` setting and cannot surface a request over `stream-json`. Choose the approval\n  behaviour in the session settings instead. (`permission` is negotiated only for plan approval.)\n- **Rewind** (`session.revert.*`): Antigravity's `/rewind` is interactive-only; nothing in\n  `stream-json` exposes it.\n- **Shared-installer skills are expanded by the plugin, not the CLI.** `~/.agents/skills/<name>/SKILL.md`\n  — the directory other agent CLIs install skills into — is never read by `agy` (probed on CLI 1.2.9:\n  a probe skill there was absent from `agy --print /skills`, and a skill that does exist there,\n  `/paseo-help`, reached the model as plain text). Paseo therefore offers those names and this plugin\n  expands them itself: the turn is sent the `SKILL.md` body, frontmatter stripped, capped at 64 KiB\n  (a larger file fails that prompt with `code: \"skill_too_large\"`, and one that is gone by the time\n  the command runs fails with `code: \"skill_unavailable\"`), followed by the skill's directory and your\n  request. Because it is one message and not a CLI command, nothing in it is expanded as a slash name.\n  A skill you want the CLI itself to expand belongs under one of the CLI's own roots above.\n\n## Session settings\n\n- **Tool approval** … default *Use Antigravity setting*, no flag; *Skip all permissions* passes\n  `--dangerously-skip-permissions`.\n- **Sandbox** — an Off/On select. *On* passes `--sandbox`.\n- **Share Paseo tools with Antigravity** — an Off/On select, *Off* by default (below).\n\nThe booleans are selects rather than toggles because Paseo draws a plugin toggle as an icon-only\nbutton with no on/off state, so its value is invisible; a select shows the current value as a pill.\nSettin"}