@agentex/agent 0.0.38 → 0.0.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +45 -13
- package/dist/providers/antigravity/codec.d.ts +4 -0
- package/dist/providers/antigravity/codec.d.ts.map +1 -0
- package/dist/providers/antigravity/codec.js +27 -0
- package/dist/providers/antigravity/codec.js.map +1 -0
- package/dist/providers/antigravity/connection.d.ts +100 -0
- package/dist/providers/antigravity/connection.d.ts.map +1 -0
- package/dist/providers/antigravity/connection.js +267 -0
- package/dist/providers/antigravity/connection.js.map +1 -0
- package/dist/providers/antigravity/discovery.d.ts +11 -0
- package/dist/providers/antigravity/discovery.d.ts.map +1 -0
- package/dist/providers/antigravity/discovery.js +92 -0
- package/dist/providers/antigravity/discovery.js.map +1 -0
- package/dist/providers/antigravity/execute.d.ts +9 -0
- package/dist/providers/antigravity/execute.d.ts.map +1 -0
- package/dist/providers/antigravity/execute.js +206 -0
- package/dist/providers/antigravity/execute.js.map +1 -0
- package/dist/providers/antigravity/index.d.ts +12 -0
- package/dist/providers/antigravity/index.d.ts.map +1 -0
- package/dist/providers/antigravity/index.js +46 -0
- package/dist/providers/antigravity/index.js.map +1 -0
- package/dist/providers/antigravity/parse.d.ts +114 -0
- package/dist/providers/antigravity/parse.d.ts.map +1 -0
- package/dist/providers/antigravity/parse.js +369 -0
- package/dist/providers/antigravity/parse.js.map +1 -0
- package/dist/providers/antigravity/probe.d.ts +3 -0
- package/dist/providers/antigravity/probe.d.ts.map +1 -0
- package/dist/providers/antigravity/probe.js +84 -0
- package/dist/providers/antigravity/probe.js.map +1 -0
- package/dist/providers/antigravity/runtime.d.ts +30 -0
- package/dist/providers/antigravity/runtime.d.ts.map +1 -0
- package/dist/providers/antigravity/runtime.js +69 -0
- package/dist/providers/antigravity/runtime.js.map +1 -0
- package/dist/providers/antigravity/session.d.ts +7 -0
- package/dist/providers/antigravity/session.d.ts.map +1 -0
- package/dist/providers/antigravity/session.js +317 -0
- package/dist/providers/antigravity/session.js.map +1 -0
- package/dist/providers/gemini/index.d.ts.map +1 -1
- package/dist/providers/gemini/index.js +6 -0
- package/dist/providers/gemini/index.js.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +2 -0
- package/dist/registry.js.map +1 -1
- package/dist/types.d.ts +6 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/auth.d.ts +1 -1
- package/dist/utils/auth.d.ts.map +1 -1
- package/dist/utils/auth.js +79 -1
- package/dist/utils/auth.js.map +1 -1
- package/dist/utils/binary.d.ts.map +1 -1
- package/dist/utils/binary.js +10 -0
- package/dist/utils/binary.js.map +1 -1
- package/dist/utils/instructions.d.ts.map +1 -1
- package/dist/utils/instructions.js +12 -9
- package/dist/utils/instructions.js.map +1 -1
- package/dist/utils/runtime-homes.d.ts.map +1 -1
- package/dist/utils/runtime-homes.js +4 -0
- package/dist/utils/runtime-homes.js.map +1 -1
- package/dist/utils/skills.d.ts +3 -3
- package/dist/utils/skills.d.ts.map +1 -1
- package/dist/utils/skills.js +16 -2
- package/dist/utils/skills.js.map +1 -1
- package/package.json +3 -2
- package/src/providers/antigravity/codec.ts +29 -0
- package/src/providers/antigravity/connection.ts +304 -0
- package/src/providers/antigravity/discovery.ts +90 -0
- package/src/providers/antigravity/execute.ts +214 -0
- package/src/providers/antigravity/index.ts +48 -0
- package/src/providers/antigravity/parse.ts +439 -0
- package/src/providers/antigravity/probe.ts +89 -0
- package/src/providers/antigravity/runtime.ts +64 -0
- package/src/providers/antigravity/session.ts +359 -0
- package/src/providers/gemini/index.ts +6 -0
- package/src/registry.ts +2 -0
- package/src/types.ts +6 -5
- package/src/utils/auth.ts +82 -1
- package/src/utils/binary.ts +10 -0
- package/src/utils/instructions.ts +10 -9
- package/src/utils/runtime-homes.ts +4 -0
- package/src/utils/skills.ts +17 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.0.39 — Antigravity provider (Google's successor to Gemini CLI)
|
|
4
|
+
|
|
5
|
+
Gemini CLI stopped serving free, Google AI Pro, and Google AI Ultra sign-ins on 2026-06-18 ("This client is no longer supported for Gemini Code Assist for individuals"). Google moved those accounts to the Antigravity CLI, `agy`. This release adds it as a first-class provider. Wire behavior follows the documented headless protocol and was checked against `agy` 1.2.14.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`antigravity` provider** (`getProvider("antigravity")`). Drives `agy --input-format stream-json --output-format stream-json`.
|
|
10
|
+
- **Sessions.** One `agy` process per session. Each `send()` writes one NDJSON user message and resolves on that turn's `result`. Sessions resume with `--conversation`. `sessionParams` are `{ sessionId, cwd }`, because Antigravity scopes conversations to a directory. Params saved for another directory start a new conversation instead of resuming the wrong one.
|
|
11
|
+
- **One-shot `execute()`.** Writes the prompt over stdin and closes it, so prompts are never argv-limited or visible in `ps`. It waits for the process to exit.
|
|
12
|
+
- **Interrupts.** The CLI has no control protocol, so `interrupt()`, timeouts, and abort signals SIGINT the process group (Ctrl+C). If `agy` exits instead of reporting `INTERRUPTED`, the next `send()` resumes the conversation in a new process. A message sent to a process that exits without acknowledging it is re-run once on a fresh one.
|
|
13
|
+
- **Events.** `system/init`, `assistant` (with `assistant_delta` under `includePartialMessages`), `thinking`, correlated `tool_call`/`tool_result` (`toolCallId` = `<conversationId>:<stepIndex>`, subagent steps included), `result`, `turn_start`/`turn_end`, `auth_required`, and `unknown` for future step types.
|
|
14
|
+
- **Usage.** agy reports cumulative usage per process. agentex reports each turn's share, with `cachedInputTokens` from `cache_read_tokens`.
|
|
15
|
+
- **Config mapping.** `model` → `--model`. `effort` → `--effort` (`low|medium|high|max`). `modeId`/`mode` → `--mode` (`default`, `accept-edits`, `plan`). `planMode` → `--mode plan`, which wins over `skipPermissions` → `--dangerously-skip-permissions`. `sandbox` → `--sandbox`. `instructionsFile` is prepended to a new conversation's first message. `skillDirs` are linked into `~/.gemini/antigravity-cli/skills`.
|
|
16
|
+
- **Permissions.** Headless agy cannot ask. Tools needing approval are soft-denied by policy and surface on `ExecutionResult.permissionDenials`. `capabilities.permissionRequests` is `false`.
|
|
17
|
+
- **Errors.** `AGY_ERROR` stderr reports map to `rate_limited`, `invalid_model`, `waiting_for_input` (status `blocked`), or `agent_error`.
|
|
18
|
+
- **Discovery.** `listModels()` reads `agy models`. `listModes()` is static and spawns nothing. `probeCapabilities()` checks `--help` for the stream-json flags (profile `agy-stream-json-v1`) and reports "not signed in" as `missing` rather than `upgrade_required`.
|
|
19
|
+
- **Fast sign-in failure.** An unsigned headless `agy` prints a login URL and blocks for 60 seconds waiting for a pasted code. agentex stops it as soon as the prompt appears, emits `auth_required` with `loginCommand: "agy"`, and fails with `errorCode: "auth_required"`. Against the real CLI this takes about 0.5s instead of 60.
|
|
20
|
+
- **Auth.** `resolveAuthForProvider("antigravity")` reports the sign-in from `agy models` (there is no status subcommand). `GEMINI_API_KEY` counts only when `~/.gemini/antigravity-cli/settings.json` sets `"modelProvider": "gemini"`, because the CLI ignores the variable otherwise. `detectAuth` and `loginCommandFor` (`"agy"`) follow the same rules.
|
|
21
|
+
- **`SkillRuntime` gains `"antigravity"`.** Workspace skills use the standard `.agents/skills` channel. Global skills go to `~/.gemini/antigravity-cli/skills`. Instructions use `AGENTS.md`, and the global native file is the `~/.gemini/GEMINI.md` it shares with Gemini CLI.
|
|
22
|
+
- `findBinary("agy")` also checks `~/.local/bin/agy`, where the official installer puts it and which GUI apps usually lack on `PATH`. It also checks `/usr/local/bin`, `/opt/homebrew/bin`, and on Windows `%LOCALAPPDATA%\agy\bin`.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- `installSkills`/`removeSkills`/`listInstalledSkills` with `includeNativeDirs` skip a runtime folder that is already a standard channel, so nothing is installed or reported twice.
|
|
27
|
+
- Global `resolveInstructionTargets`/`installInstructions` merge runtimes that share a file. Gemini CLI and Antigravity both read `~/.gemini/GEMINI.md`, so it becomes one target serving both.
|
|
28
|
+
- The `gemini` provider documents the personal-account retirement and points to `antigravity`. It still works with paid API keys and Gemini Code Assist Standard/Enterprise.
|
|
29
|
+
- The barrel-import module budget in `tests/packaging/lazy-graph.test.ts` is re-pinned from 51 to 53. The new provider adds the same light `index` + `codec` pair every provider ships, and no heavy modules.
|
|
30
|
+
|
|
3
31
|
## 0.0.38 — AGENTS.md is the workspace instruction file for every runtime
|
|
4
32
|
|
|
5
33
|
Claude Code reads `AGENTS.md` since 2.1.277, loaded exactly where `CLAUDE.md` would be, but only in a folder with no `CLAUDE.md`. A `CLAUDE.md`, a `CLAUDE.local.md`, or one in a parent folder hides `AGENTS.md` completely (verified against 2.1.281). Not yet on Bedrock, Vertex or Foundry.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @agentex/agent
|
|
2
2
|
|
|
3
|
-
Programmatic execution of AI coding agents. Spawn and manage Claude Code, Codex, Gemini, Cursor, OpenCode, Pi, OpenClaw, or any CLI-based agent as a child process with streaming output, multi-turn sessions, auth detection, isolated workspaces, skill installation, and a unified interface.
|
|
3
|
+
Programmatic execution of AI coding agents. Spawn and manage Claude Code, Codex, Antigravity, Gemini, Cursor, OpenCode, Pi, OpenClaw, or any CLI-based agent as a child process with streaming output, multi-turn sessions, auth detection, isolated workspaces, skill installation, and a unified interface.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -48,7 +48,7 @@ Providers fall into three tiers:
|
|
|
48
48
|
|
|
49
49
|
- **Tier 1 — deep native:** `claude`, `codex`. Hand-built adapters over each CLI's richest protocol (Claude's stream-json, Codex's `app-server` JSON-RPC). Subscription-native, fullest feature set.
|
|
50
50
|
- **Tier 2 — ACP:** `gemini`, `copilot`, plus any agent registered via [`acpProvider`](#custom--byok-providers) or `extends: "acp"` config. One shared, tested base over the open [Agent Client Protocol](https://agentclientprotocol.com) (JSON-RPC over stdio).
|
|
51
|
-
- **Tier 3 — bespoke escape hatches:** `opencode` (authenticated HTTP/SSE daemon), `pi` (persistent RPC), `cursor` (exec-backed resume), `openclaw` (HTTP gateway), `process` (any executable).
|
|
51
|
+
- **Tier 3 — bespoke escape hatches:** `opencode` (authenticated HTTP/SSE daemon), `pi` (persistent RPC), `antigravity` (persistent stream-json), `cursor` (exec-backed resume), `openclaw` (HTTP gateway), `process` (any executable).
|
|
52
52
|
|
|
53
53
|
| Provider | Transport | Tier | Sessions | Modes | Permissions |
|
|
54
54
|
| ---------- | -------------------------------------- | ---- | --------- | ----- | ----------- |
|
|
@@ -58,12 +58,41 @@ Providers fall into three tiers:
|
|
|
58
58
|
| `copilot` | `copilot --acp` (ACP) | 2 | ✅ | ✅ | ✅ |
|
|
59
59
|
| `opencode` | authenticated `opencode serve` HTTP + SSE | 3 | ✅ resume | ✅ | ✅ |
|
|
60
60
|
| `pi` | persistent `pi --mode rpc` | 3 | ✅ resume | — | — |
|
|
61
|
+
| `antigravity` | persistent `agy` stream-json (stdin + stdout) | 3 | ✅ resume | ✅ | policy |
|
|
61
62
|
| `cursor` | `cursor-agent` stream-json per turn | 3 | ✅ resume | probed | — |
|
|
62
63
|
| `openclaw` | HTTP gateway | 3 | — | — | — |
|
|
63
64
|
| `process` | any executable | 3 | — | — | — |
|
|
64
65
|
|
|
65
66
|
Cursor sessions are exec-backed. Each `send()` starts one CLI process and promotes the returned Cursor session ID into `--resume` for the next turn. `probeCapabilities()` verifies the selected binary's model catalog and advertised modes. Each execution independently validates the supported stream-json acceptance marker before releasing output. Older Cursor CLIs report `upgrade_required` instead of silently advertising discovery features they do not expose.
|
|
66
67
|
|
|
68
|
+
### Antigravity (Google)
|
|
69
|
+
|
|
70
|
+
Google moved personal accounts (Free, Google AI Pro, Google AI Ultra) from Gemini CLI to the [Antigravity CLI](https://antigravity.google/docs/cli/overview) on 2026-06-18. Signing in to Gemini CLI with one of those accounts now fails with "This client is no longer supported for Gemini Code Assist for individuals". Use the `antigravity` provider for them. The `gemini` provider still works with a paid API key or Gemini Code Assist Standard/Enterprise.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
curl -fsSL https://antigravity.google/cli/install.sh | bash # installs ~/.local/bin/agy
|
|
74
|
+
agy # once, to sign in through the browser
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const agy = getProvider("antigravity");
|
|
79
|
+
const session = await agy.createSession!({
|
|
80
|
+
cwd,
|
|
81
|
+
config: { model: "gemini-3.1-pro-high", effort: "high", modeId: "accept-edits" },
|
|
82
|
+
onEvent: (e) => { if (e.type === "assistant") console.log(e.text); },
|
|
83
|
+
});
|
|
84
|
+
await (await session.send("Summarize this repo")).result;
|
|
85
|
+
await (await session.send("Now list its entry points")).result; // same agy process, same conversation
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- **Transport.** A session is one `agy --input-format stream-json --output-format stream-json` process. Each `send()` writes one NDJSON user message and resolves on that turn's `result` event. `execute()` writes one message and closes stdin, so prompts never travel through argv. Saved `sessionParams` are `{ sessionId, cwd }` and resume with `--conversation`. Antigravity scopes conversations to a directory, so params saved for another `cwd` start a new conversation instead of resuming.
|
|
89
|
+
- **Interrupts.** The CLI has no control protocol, so `interrupt()`, timeouts, and abort signals send SIGINT to the process group, like Ctrl+C. If agy exits instead of reporting the turn as `INTERRUPTED`, the next `send()` starts a new process on the same conversation.
|
|
90
|
+
- **Permissions.** Headless agy cannot ask. `skipPermissions` maps to `--dangerously-skip-permissions`. Without it, actions that would need approval (shell commands by default) are soft-denied and listed in `ExecutionResult.permissionDenials`, and the run still succeeds. Grant specific actions with `permissions.allow` rules in `~/.gemini/antigravity-cli/settings.json`. `permissionRequests` is therefore `false`.
|
|
91
|
+
- **Modes, effort, models.** `listModes()` returns `default`, `accept-edits`, and `plan` (`--mode`). `planMode` maps to `--mode plan`. `config.effort` maps to `--effort` (`low`, `medium`, `high`, `max`). `listModels()` reads `agy models`, which needs a signed-in account.
|
|
92
|
+
- **Sign-in.** An unsigned headless agy prints a login URL and waits a minute for a code. agentex stops it as soon as the prompt appears, emits `auth_required` with `loginCommand: "agy"`, and fails the turn with `errorCode: "auth_required"`.
|
|
93
|
+
- **Usage.** agy reports cumulative usage per process. agentex reports each turn's share, keyed by the pinned model (or `"default"`). `cachedInputTokens` comes from `cache_read_tokens`.
|
|
94
|
+
- **Not yet wired.** `config.mcpServers` (agy reads `~/.gemini/config/mcp_config.json` and `.agents/mcp_config.json` itself), and history import.
|
|
95
|
+
|
|
67
96
|
OpenCode sessions use a password-authenticated loopback server, SSE events, permission and question reconciliation, durable service-backed history, saved-session discovery and import, runtime model and agent discovery, and upstream provider authentication. `config.mcpServers` remains unsupported for OpenCode because strict isolation from ambient OpenCode MCP configuration is not yet proven.
|
|
68
97
|
|
|
69
98
|
### OpenCode and Cursor discovery
|
|
@@ -256,7 +285,7 @@ interface ProviderConfig {
|
|
|
256
285
|
command?: string; // Override CLI binary path
|
|
257
286
|
model?: string;
|
|
258
287
|
modelVariant?: string; // OpenCode provider-native variant, separate from effort
|
|
259
|
-
effort?: string;
|
|
288
|
+
effort?: string; // claude/antigravity: --effort; codex: turn effort override
|
|
260
289
|
unattendedPermissionPolicy?: "allow" | "deny";
|
|
261
290
|
inputRequestTimeoutSec?: number; // OpenCode permission/question response deadline, default 300
|
|
262
291
|
maxTurns?: number;
|
|
@@ -269,14 +298,14 @@ interface ProviderConfig {
|
|
|
269
298
|
strictMcpConfig?: boolean; // claude: --strict-mcp-config — MCP surface is exactly what you attach
|
|
270
299
|
allowedTools?: string[]; // claude: --allowed-tools (patterns verbatim; codex ignores)
|
|
271
300
|
disallowedTools?: string[]; // claude: --disallowed-tools (deny wins; codex ignores)
|
|
272
|
-
includePartialMessages?: boolean; // claude: emit assistant_delta/thinking_delta typewriter events
|
|
301
|
+
includePartialMessages?: boolean; // claude, antigravity: emit assistant_delta/thinking_delta typewriter events
|
|
273
302
|
extraArgs?: string[]; // always appended LAST — hosts can override any generated flag
|
|
274
303
|
search?: boolean;
|
|
275
|
-
sandbox?: boolean;
|
|
304
|
+
sandbox?: boolean; // antigravity: --sandbox (terminal sandbox)
|
|
276
305
|
thinking?: string;
|
|
277
|
-
mode?: string; // cursor: --mode <mode>; not for plan mode
|
|
278
|
-
modeId?: string; // select an operating mode from listModes() (codex/ACP)
|
|
279
|
-
planMode?: boolean; // read-only "plan" mode (claude/codex)
|
|
306
|
+
mode?: string; // cursor, antigravity: --mode <mode>; not for plan mode
|
|
307
|
+
modeId?: string; // select an operating mode from listModes() (codex/ACP/antigravity)
|
|
308
|
+
planMode?: boolean; // read-only "plan" mode (claude/codex/cursor/opencode/antigravity)
|
|
280
309
|
workspace?: { strategy: "worktree"; baseBranch?: string; branchName?: string };
|
|
281
310
|
}
|
|
282
311
|
```
|
|
@@ -434,7 +463,7 @@ When in doubt, `raw` is the verbatim provider event — parse it yourself for an
|
|
|
434
463
|
|
|
435
464
|
### Other providers
|
|
436
465
|
|
|
437
|
-
`gemini` and `copilot` (ACP) and the session-backed `opencode` and `pi` emit real, correlated `StreamEvent`s — assistant text, thinking, and tool_call/tool_result with proper tool-call ids (ACP and Codex have no per-event/message ids, so those stay `null`). `cursor` and `openclaw` still emit the same `StreamEvent` shape with most ids stubbed to `null`; their `raw` field is populated. `cursor` will gain full fidelity when it moves to the ACP tier.
|
|
466
|
+
`gemini` and `copilot` (ACP), `antigravity`, and the session-backed `opencode` and `pi` emit real, correlated `StreamEvent`s — assistant text, thinking, and tool_call/tool_result with proper tool-call ids (ACP and Codex have no per-event/message ids, so those stay `null`). `cursor` and `openclaw` still emit the same `StreamEvent` shape with most ids stubbed to `null`; their `raw` field is populated. `cursor` will gain full fidelity when it moves to the ACP tier. `antigravity` has no per-call tool ids, so `toolCallId` is `<conversationId>:<stepIndex>`, and `messageId` uses the same key for a response step's `assistant` and `assistant_delta` events.
|
|
438
467
|
|
|
439
468
|
## Sessions (multi-turn)
|
|
440
469
|
|
|
@@ -797,6 +826,7 @@ const executeRun = await claude.execute({
|
|
|
797
826
|
| -------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
798
827
|
| `claude` | `--permission-mode plan` (CLI-native plan UX) | Agent calls the `ExitPlanMode` tool with the plan as a permission request. Host extracts via `parseExitPlanMode(req)` from `onUserInputRequest`. The plan is **not** in the persisted transcript — capture it live. |
|
|
799
828
|
| `codex` | `--sandbox read-only` **plus** an injected planning system preamble | Plain text in the agent's final assistant message (i.e. `result.summary`). |
|
|
829
|
+
| `antigravity` | `--mode plan` (CLI-native: read-only tools, then a plan) | Plain text in the turn's response (`result.summary`). Headless runs proceed through plan review automatically. |
|
|
800
830
|
|
|
801
831
|
The mechanism difference matters:
|
|
802
832
|
|
|
@@ -905,6 +935,7 @@ await claude.execute({ prompt: "Respond with 'hello'.", config: { timeoutSec: 15
|
|
|
905
935
|
| `codex` | `codex login status` · fallback: `$CODEX_HOME/auth.json` | `OPENAI_API_KEY` | — |
|
|
906
936
|
| `gemini` | `$GEMINI_CONFIG_DIR/oauth_creds.json` | `GEMINI_API_KEY`, `GOOGLE_API_KEY` | — |
|
|
907
937
|
| `cursor` | selected CLI's `status` command | `CURSOR_API_KEY` | `OPENAI_API_KEY` is intentionally ignored |
|
|
938
|
+
| `antigravity` | `agy models` exit status (keyring sign-in) | `GEMINI_API_KEY`, only with `"modelProvider": "gemini"` in `~/.gemini/antigravity-cli/settings.json` | The CLI ignores `GEMINI_API_KEY` otherwise |
|
|
908
939
|
| `opencode`| — | `OPENAI_API_KEY`, `ANTHROPIC_API_KEY` | — |
|
|
909
940
|
| `pi` | — | `OPENAI_API_KEY`, `ANTHROPIC_API_KEY` | — |
|
|
910
941
|
|
|
@@ -917,6 +948,7 @@ The library reflects real CLI behavior rather than imposing its own:
|
|
|
917
948
|
| Claude | API key wins (documented). Set `hasApiKey` + show a billing warning. |
|
|
918
949
|
| Codex | Subscription wins (current CLI; see openai/codex#2733, #3286). |
|
|
919
950
|
| Gemini | API key wins in non-interactive mode. |
|
|
951
|
+
| Antigravity | `settings.json` decides: `modelProvider: "gemini"` uses the API key, otherwise the signed-in account. |
|
|
920
952
|
|
|
921
953
|
### Caching
|
|
922
954
|
|
|
@@ -1024,7 +1056,7 @@ const skillDirs = ["/path/to/code-review", "/path/to/testing"];
|
|
|
1024
1056
|
await installSkills(skillDirs, {
|
|
1025
1057
|
location: "workspace", // or "global"
|
|
1026
1058
|
cwd: process.cwd(), // required for workspace installs
|
|
1027
|
-
includeNativeDirs: false, // true also installs into ~/.gemini/skills/, etc.
|
|
1059
|
+
includeNativeDirs: false, // true also installs into ~/.gemini/skills/, ~/.gemini/antigravity-cli/skills/, etc.
|
|
1028
1060
|
});
|
|
1029
1061
|
|
|
1030
1062
|
const installed = await listInstalledSkills({ location: "workspace", cwd: process.cwd() });
|
|
@@ -1247,7 +1279,7 @@ registerProvider(myProvider);
|
|
|
1247
1279
|
- `ensureCommandResolvable(command)` — like `findBinary` but accepts an absolute path too.
|
|
1248
1280
|
- `clearBinaryCache()` — invalidate the binary-resolution cache.
|
|
1249
1281
|
- `provider.checkQuota?(ctx)` — rate-limit / quota status (when `capabilities.quotaProbing`).
|
|
1250
|
-
- `provider.listModels?(opts?)` — enumerate models the binary can drive
|
|
1282
|
+
- `provider.listModels?(opts?)` — enumerate models the binary can drive, where the CLI exposes a catalog (for example `cursor`, `opencode`, and `antigravity` via `agy models`). Otherwise pass the model you want directly via `ExecutionContext.model` or `ProviderConfig.model`.
|
|
1251
1283
|
|
|
1252
1284
|
### Workspace
|
|
1253
1285
|
- `prepareWorkspace({ strategy, baseBranch?, branchName?, targetDir? })` → `PreparedWorkspace` with `cwd`, `diff()`, `cleanup()`.
|
|
@@ -1283,8 +1315,8 @@ registerProvider(myProvider);
|
|
|
1283
1315
|
## Requirements
|
|
1284
1316
|
|
|
1285
1317
|
- Node.js >= 18
|
|
1286
|
-
- Each provider's CLI installed and resolvable on `$PATH` (`claude`, `codex`, `gemini`, `agent` for Cursor, `opencode`, `pi`, or a reachable OpenClaw gateway)
|
|
1287
|
-
- For subscription auth, the relevant CLI must already be logged in (`codex login`, `claude login`, `
|
|
1318
|
+
- Each provider's CLI installed and resolvable on `$PATH` (`claude`, `codex`, `agy` for Antigravity, `gemini`, `agent` for Cursor, `opencode`, `pi`, or a reachable OpenClaw gateway). `agy` is also found at `~/.local/bin/agy` when that folder is not on `$PATH`.
|
|
1319
|
+
- For subscription auth, the relevant CLI must already be logged in (`codex login`, `claude login`, `agy` once for Antigravity, etc.)
|
|
1288
1320
|
|
|
1289
1321
|
## License
|
|
1290
1322
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../../src/providers/antigravity/codec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAqBnD,0FAA0F;AAC1F,eAAO,MAAM,uBAAuB,EAAE,YAMrC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function readNonEmptyString(value) {
|
|
2
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
3
|
+
}
|
|
4
|
+
function readSessionId(obj) {
|
|
5
|
+
return readNonEmptyString(obj["sessionId"])
|
|
6
|
+
?? readNonEmptyString(obj["session_id"])
|
|
7
|
+
?? readNonEmptyString(obj["conversationId"]);
|
|
8
|
+
}
|
|
9
|
+
function normalize(raw) {
|
|
10
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
11
|
+
return null;
|
|
12
|
+
const obj = raw;
|
|
13
|
+
const sessionId = readSessionId(obj);
|
|
14
|
+
if (!sessionId)
|
|
15
|
+
return null;
|
|
16
|
+
const cwd = readNonEmptyString(obj["cwd"]);
|
|
17
|
+
return { sessionId, ...(cwd ? { cwd } : {}) };
|
|
18
|
+
}
|
|
19
|
+
/** Antigravity session params: the conversation id plus the directory it is scoped to. */
|
|
20
|
+
export const antigravitySessionCodec = {
|
|
21
|
+
deserialize: normalize,
|
|
22
|
+
serialize: (params) => normalize(params),
|
|
23
|
+
getDisplayId(params) {
|
|
24
|
+
return params ? readSessionId(params) : null;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../../src/providers/antigravity/codec.ts"],"names":[],"mappings":"AAEA,SAAS,kBAAkB,CAAC,KAAc;IACxC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpF,CAAC;AAED,SAAS,aAAa,CAAC,GAA4B;IACjD,OAAO,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;WACtC,kBAAkB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;WACrC,kBAAkB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,SAAS,CAAC,GAAY;IAC7B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/E,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,GAAG,GAAG,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAChD,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,MAAM,uBAAuB,GAAiB;IACnD,WAAW,EAAE,SAAS;IACtB,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC;IACxC,YAAY,CAAC,MAAM;QACjB,OAAO,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { StreamEvent } from "../../types.js";
|
|
2
|
+
import { type AgyErrorReport, type AgyResult, type AgyStreamParser } from "./parse.js";
|
|
3
|
+
export interface AgyConnectionOptions {
|
|
4
|
+
command: string;
|
|
5
|
+
args: string[];
|
|
6
|
+
cwd: string;
|
|
7
|
+
env: Record<string, string>;
|
|
8
|
+
parser: AgyStreamParser;
|
|
9
|
+
onEvent?: (event: StreamEvent) => void | Promise<void>;
|
|
10
|
+
onOutput?: (stream: "stdout" | "stderr", chunk: string) => void | Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
/** How a turn (or the whole process) ended, as seen by the host. */
|
|
13
|
+
export interface AgyTurnOutcome {
|
|
14
|
+
/** The turn's `result` event, or null when the process exited first. */
|
|
15
|
+
result: AgyResult | null;
|
|
16
|
+
/** The process has exited. */
|
|
17
|
+
exited: boolean;
|
|
18
|
+
exitCode: number | null;
|
|
19
|
+
signal: string | null;
|
|
20
|
+
/** The CLI asked for a sign-in, which a headless run can never complete. */
|
|
21
|
+
authRequired: boolean;
|
|
22
|
+
agyError: AgyErrorReport | null;
|
|
23
|
+
/** Last ~16KB of stderr, for error messages. */
|
|
24
|
+
stderr: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* One headless `agy` process speaking `stream-json` in both directions.
|
|
28
|
+
*
|
|
29
|
+
* Every stdout line is parsed and dispatched through a single promise chain,
|
|
30
|
+
* so `onEvent` handlers run strictly in wire order and a turn's waiter
|
|
31
|
+
* resolves only after the handler for its `result` event has settled.
|
|
32
|
+
*/
|
|
33
|
+
export declare class AgyConnection {
|
|
34
|
+
private readonly options;
|
|
35
|
+
readonly pid: number | null;
|
|
36
|
+
authRequired: boolean;
|
|
37
|
+
agyError: AgyErrorReport | null;
|
|
38
|
+
private readonly child;
|
|
39
|
+
private chain;
|
|
40
|
+
private stdoutBuffer;
|
|
41
|
+
private stderrLineBuffer;
|
|
42
|
+
private stderrTail;
|
|
43
|
+
private exitInfo;
|
|
44
|
+
private finalized;
|
|
45
|
+
private readonly waiters;
|
|
46
|
+
private readonly exitWaiters;
|
|
47
|
+
constructor(options: AgyConnectionOptions);
|
|
48
|
+
get alive(): boolean;
|
|
49
|
+
/** Exit status, or null while the process runs. */
|
|
50
|
+
get exit(): {
|
|
51
|
+
code: number | null;
|
|
52
|
+
signal: string | null;
|
|
53
|
+
} | null;
|
|
54
|
+
/** Last ~16KB of stderr. */
|
|
55
|
+
get stderr(): string;
|
|
56
|
+
/** Resolves once the process has exited and every queued event was dispatched. */
|
|
57
|
+
exited(): Promise<void>;
|
|
58
|
+
/** Send one user message. Resolve it with `nextTurn()`. */
|
|
59
|
+
write(text: string): void;
|
|
60
|
+
/** Close stdin. `agy` finishes the current turn and exits. */
|
|
61
|
+
endInput(): void;
|
|
62
|
+
/** Resolves with the next `result` event, or with the exit when no result comes. */
|
|
63
|
+
nextTurn(): Promise<AgyTurnOutcome>;
|
|
64
|
+
/** Signal the whole process group. */
|
|
65
|
+
signal(signal: NodeJS.Signals): void;
|
|
66
|
+
/** True when the process exited within `ms`. */
|
|
67
|
+
waitForExit(ms: number): Promise<boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* Stop the process: close stdin and give it a moment to exit on its own
|
|
70
|
+
* (an idle `agy` flushes its conversation history and exits), then
|
|
71
|
+
* SIGTERM, then SIGKILL after `graceSec`.
|
|
72
|
+
*/
|
|
73
|
+
terminate(graceSec?: number, idleWaitMs?: number): Promise<void>;
|
|
74
|
+
private onStdout;
|
|
75
|
+
private enqueueLine;
|
|
76
|
+
private onStderr;
|
|
77
|
+
private inspectStderrLine;
|
|
78
|
+
/**
|
|
79
|
+
* A headless run without a cached sign-in prints a login URL and waits a
|
|
80
|
+
* full minute for a code nobody can paste. Fail fast instead: report it
|
|
81
|
+
* and stop the process.
|
|
82
|
+
*/
|
|
83
|
+
private onAuthRequired;
|
|
84
|
+
private appendStderrTail;
|
|
85
|
+
private finalize;
|
|
86
|
+
private outcome;
|
|
87
|
+
private emitEvent;
|
|
88
|
+
private emitOutput;
|
|
89
|
+
}
|
|
90
|
+
/** First meaningful stderr line, skipping the sign-in URL noise. */
|
|
91
|
+
export declare function firstAgyErrorLine(stderr: string): string | null;
|
|
92
|
+
/** Waits for `promise` up to `ms`; resolves null on timeout. */
|
|
93
|
+
export declare function within<T>(promise: Promise<T>, ms: number): Promise<T | null>;
|
|
94
|
+
/**
|
|
95
|
+
* Interrupt the running turn like Ctrl+C would: SIGINT the process group,
|
|
96
|
+
* give agy a moment to report the turn as INTERRUPTED, and stop the process
|
|
97
|
+
* if it does not. Resolves with whatever outcome arrived.
|
|
98
|
+
*/
|
|
99
|
+
export declare function interruptAgyTurn(connection: AgyConnection, pending: Promise<AgyTurnOutcome>, graceSec?: number): Promise<AgyTurnOutcome | null>;
|
|
100
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/providers/antigravity/connection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAKpB,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjF;AAED,oEAAoE;AACpE,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,8BAA8B;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,4EAA4E;IAC5E,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;IAeZ,OAAO,CAAC,QAAQ,CAAC,OAAO;IAdpC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,UAAS;IACrB,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAQ;IAEvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,QAAQ,CAA+D;IAC/E,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgD;IACxE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyB;gBAExB,OAAO,EAAE,oBAAoB;IAuB1D,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,mDAAmD;IACnD,IAAI,IAAI,IAAI;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAEhE;IAED,4BAA4B;IAC5B,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,kFAAkF;IAClF,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAKvB,2DAA2D;IAC3D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKzB,8DAA8D;IAC9D,QAAQ,IAAI,IAAI;IAQhB,oFAAoF;IACpF,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC;IAKnC,sCAAsC;IACtC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI;IAIpC,gDAAgD;IAC1C,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI/C;;;;OAIG;IACG,SAAS,CAAC,QAAQ,SAAI,EAAE,UAAU,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/D,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,iBAAiB;IAMzB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAqBtB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,OAAO;YAYD,SAAS;YAST,UAAU;CAQzB;AAED,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO/D;AAED,gEAAgE;AAChE,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAc5E;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,aAAa,EACzB,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,EAChC,QAAQ,SAAI,GACX,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAMhC"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { killProcessTree } from "../../utils/process.js";
|
|
3
|
+
import { ANTIGRAVITY_PROVIDER_TYPE, isAgyAuthRequired, parseAgyErrorLine, } from "./parse.js";
|
|
4
|
+
import { AGY_LOGIN_COMMAND } from "./runtime.js";
|
|
5
|
+
const STDERR_TAIL_BYTES = 16 * 1024;
|
|
6
|
+
/**
|
|
7
|
+
* One headless `agy` process speaking `stream-json` in both directions.
|
|
8
|
+
*
|
|
9
|
+
* Every stdout line is parsed and dispatched through a single promise chain,
|
|
10
|
+
* so `onEvent` handlers run strictly in wire order and a turn's waiter
|
|
11
|
+
* resolves only after the handler for its `result` event has settled.
|
|
12
|
+
*/
|
|
13
|
+
export class AgyConnection {
|
|
14
|
+
options;
|
|
15
|
+
pid;
|
|
16
|
+
authRequired = false;
|
|
17
|
+
agyError = null;
|
|
18
|
+
child;
|
|
19
|
+
chain = Promise.resolve();
|
|
20
|
+
stdoutBuffer = "";
|
|
21
|
+
stderrLineBuffer = "";
|
|
22
|
+
stderrTail = "";
|
|
23
|
+
exitInfo = null;
|
|
24
|
+
finalized = false;
|
|
25
|
+
waiters = [];
|
|
26
|
+
exitWaiters = [];
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.options = options;
|
|
29
|
+
this.child = spawn(options.command, options.args, {
|
|
30
|
+
cwd: options.cwd,
|
|
31
|
+
env: options.env,
|
|
32
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
33
|
+
shell: false,
|
|
34
|
+
// A process group lets interrupt/terminate reach the commands agy runs.
|
|
35
|
+
detached: process.platform !== "win32",
|
|
36
|
+
});
|
|
37
|
+
this.pid = this.child.pid ?? null;
|
|
38
|
+
this.child.stdin?.on("error", () => { });
|
|
39
|
+
this.child.stdout?.setEncoding("utf-8");
|
|
40
|
+
this.child.stderr?.setEncoding("utf-8");
|
|
41
|
+
this.child.stdout?.on("data", (chunk) => this.onStdout(chunk));
|
|
42
|
+
this.child.stderr?.on("data", (chunk) => this.onStderr(chunk));
|
|
43
|
+
this.child.on("error", (err) => {
|
|
44
|
+
this.appendStderrTail(`${err.message}\n`);
|
|
45
|
+
this.finalize(null, null);
|
|
46
|
+
});
|
|
47
|
+
this.child.on("close", (code, signal) => this.finalize(code, signal ?? null));
|
|
48
|
+
}
|
|
49
|
+
get alive() {
|
|
50
|
+
return this.exitInfo === null;
|
|
51
|
+
}
|
|
52
|
+
/** Exit status, or null while the process runs. */
|
|
53
|
+
get exit() {
|
|
54
|
+
return this.exitInfo;
|
|
55
|
+
}
|
|
56
|
+
/** Last ~16KB of stderr. */
|
|
57
|
+
get stderr() {
|
|
58
|
+
return this.stderrTail;
|
|
59
|
+
}
|
|
60
|
+
/** Resolves once the process has exited and every queued event was dispatched. */
|
|
61
|
+
exited() {
|
|
62
|
+
if (this.finalized)
|
|
63
|
+
return this.chain;
|
|
64
|
+
return new Promise((resolve) => this.exitWaiters.push(resolve));
|
|
65
|
+
}
|
|
66
|
+
/** Send one user message. Resolve it with `nextTurn()`. */
|
|
67
|
+
write(text) {
|
|
68
|
+
if (!this.alive || !this.child.stdin || this.child.stdin.destroyed)
|
|
69
|
+
return;
|
|
70
|
+
this.child.stdin.write(`${JSON.stringify({ event: "user", message: { content: text } })}\n`);
|
|
71
|
+
}
|
|
72
|
+
/** Close stdin. `agy` finishes the current turn and exits. */
|
|
73
|
+
endInput() {
|
|
74
|
+
try {
|
|
75
|
+
this.child.stdin?.end();
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
/* already closed */
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** Resolves with the next `result` event, or with the exit when no result comes. */
|
|
82
|
+
nextTurn() {
|
|
83
|
+
if (this.finalized)
|
|
84
|
+
return Promise.resolve(this.outcome(null));
|
|
85
|
+
return new Promise((resolve) => this.waiters.push(resolve));
|
|
86
|
+
}
|
|
87
|
+
/** Signal the whole process group. */
|
|
88
|
+
signal(signal) {
|
|
89
|
+
if (this.pid != null && this.alive)
|
|
90
|
+
killProcessTree(this.pid, signal);
|
|
91
|
+
}
|
|
92
|
+
/** True when the process exited within `ms`. */
|
|
93
|
+
async waitForExit(ms) {
|
|
94
|
+
return (await within(this.exited().then(() => true), ms)) === true;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Stop the process: close stdin and give it a moment to exit on its own
|
|
98
|
+
* (an idle `agy` flushes its conversation history and exits), then
|
|
99
|
+
* SIGTERM, then SIGKILL after `graceSec`.
|
|
100
|
+
*/
|
|
101
|
+
async terminate(graceSec = 5, idleWaitMs = 1000) {
|
|
102
|
+
if (this.finalized)
|
|
103
|
+
return;
|
|
104
|
+
this.endInput();
|
|
105
|
+
if (idleWaitMs > 0 && await this.waitForExit(idleWaitMs))
|
|
106
|
+
return;
|
|
107
|
+
this.signal("SIGTERM");
|
|
108
|
+
if (await this.waitForExit(graceSec * 1000))
|
|
109
|
+
return;
|
|
110
|
+
this.signal("SIGKILL");
|
|
111
|
+
await this.waitForExit(1000);
|
|
112
|
+
}
|
|
113
|
+
onStdout(chunk) {
|
|
114
|
+
this.stdoutBuffer += chunk;
|
|
115
|
+
const lines = this.stdoutBuffer.split("\n");
|
|
116
|
+
this.stdoutBuffer = lines.pop() ?? "";
|
|
117
|
+
for (const line of lines)
|
|
118
|
+
this.enqueueLine(line);
|
|
119
|
+
}
|
|
120
|
+
enqueueLine(rawLine) {
|
|
121
|
+
const line = rawLine.replace(/\r$/, "");
|
|
122
|
+
if (!line.trim())
|
|
123
|
+
return;
|
|
124
|
+
this.chain = this.chain.then(async () => {
|
|
125
|
+
await this.emitOutput("stdout", `${line}\n`);
|
|
126
|
+
const parsed = this.options.parser.parseLine(line);
|
|
127
|
+
for (const event of parsed.events)
|
|
128
|
+
await this.emitEvent(event);
|
|
129
|
+
if (parsed.result)
|
|
130
|
+
this.waiters.shift()?.(this.outcome(parsed.result));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
onStderr(chunk) {
|
|
134
|
+
this.appendStderrTail(chunk);
|
|
135
|
+
this.chain = this.chain.then(() => this.emitOutput("stderr", chunk));
|
|
136
|
+
this.stderrLineBuffer += chunk;
|
|
137
|
+
const lines = this.stderrLineBuffer.split("\n");
|
|
138
|
+
this.stderrLineBuffer = lines.pop() ?? "";
|
|
139
|
+
for (const line of lines)
|
|
140
|
+
this.inspectStderrLine(line);
|
|
141
|
+
// The sign-in prompt can sit on an unterminated line while agy waits.
|
|
142
|
+
if (!this.authRequired && isAgyAuthRequired(this.stderrLineBuffer))
|
|
143
|
+
this.onAuthRequired(this.stderrLineBuffer);
|
|
144
|
+
}
|
|
145
|
+
inspectStderrLine(line) {
|
|
146
|
+
const report = parseAgyErrorLine(line);
|
|
147
|
+
if (report)
|
|
148
|
+
this.agyError = report;
|
|
149
|
+
if (!this.authRequired && isAgyAuthRequired(line))
|
|
150
|
+
this.onAuthRequired(line);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* A headless run without a cached sign-in prints a login URL and waits a
|
|
154
|
+
* full minute for a code nobody can paste. Fail fast instead: report it
|
|
155
|
+
* and stop the process.
|
|
156
|
+
*/
|
|
157
|
+
onAuthRequired(message) {
|
|
158
|
+
this.authRequired = true;
|
|
159
|
+
const event = {
|
|
160
|
+
type: "auth_required",
|
|
161
|
+
httpStatus: null,
|
|
162
|
+
reason: "missing",
|
|
163
|
+
loginCommand: AGY_LOGIN_COMMAND,
|
|
164
|
+
message: message.trim() || "Antigravity CLI requires sign-in.",
|
|
165
|
+
timestamp: new Date().toISOString(),
|
|
166
|
+
providerType: ANTIGRAVITY_PROVIDER_TYPE,
|
|
167
|
+
sessionId: this.options.parser.conversationId,
|
|
168
|
+
messageId: null,
|
|
169
|
+
eventId: null,
|
|
170
|
+
turnId: null,
|
|
171
|
+
parentToolCallId: null,
|
|
172
|
+
raw: { stderr: message },
|
|
173
|
+
};
|
|
174
|
+
this.chain = this.chain.then(() => this.emitEvent(event));
|
|
175
|
+
this.signal("SIGTERM");
|
|
176
|
+
}
|
|
177
|
+
appendStderrTail(chunk) {
|
|
178
|
+
this.stderrTail = (this.stderrTail + chunk).slice(-STDERR_TAIL_BYTES);
|
|
179
|
+
}
|
|
180
|
+
finalize(code, signal) {
|
|
181
|
+
if (this.exitInfo === null)
|
|
182
|
+
this.exitInfo = { code, signal };
|
|
183
|
+
if (this.finalized)
|
|
184
|
+
return;
|
|
185
|
+
this.finalized = true;
|
|
186
|
+
if (this.stdoutBuffer.trim())
|
|
187
|
+
this.enqueueLine(this.stdoutBuffer);
|
|
188
|
+
this.stdoutBuffer = "";
|
|
189
|
+
if (this.stderrLineBuffer.trim())
|
|
190
|
+
this.inspectStderrLine(this.stderrLineBuffer);
|
|
191
|
+
this.stderrLineBuffer = "";
|
|
192
|
+
this.chain = this.chain.then(() => {
|
|
193
|
+
for (const waiter of this.waiters.splice(0))
|
|
194
|
+
waiter(this.outcome(null));
|
|
195
|
+
for (const waiter of this.exitWaiters.splice(0))
|
|
196
|
+
waiter();
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
outcome(result) {
|
|
200
|
+
return {
|
|
201
|
+
result,
|
|
202
|
+
exited: this.exitInfo !== null,
|
|
203
|
+
exitCode: this.exitInfo?.code ?? null,
|
|
204
|
+
signal: this.exitInfo?.signal ?? null,
|
|
205
|
+
authRequired: this.authRequired,
|
|
206
|
+
agyError: this.agyError,
|
|
207
|
+
stderr: this.stderrTail,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
async emitEvent(event) {
|
|
211
|
+
if (!this.options.onEvent)
|
|
212
|
+
return;
|
|
213
|
+
try {
|
|
214
|
+
await this.options.onEvent(event);
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
/* a throwing handler must not break the stream */
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async emitOutput(stream, chunk) {
|
|
221
|
+
if (!this.options.onOutput)
|
|
222
|
+
return;
|
|
223
|
+
try {
|
|
224
|
+
await this.options.onOutput(stream, chunk);
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
/* swallow */
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/** First meaningful stderr line, skipping the sign-in URL noise. */
|
|
232
|
+
export function firstAgyErrorLine(stderr) {
|
|
233
|
+
for (const raw of stderr.split(/\r?\n/)) {
|
|
234
|
+
const line = raw.trim();
|
|
235
|
+
if (!line || /^https?:\/\//.test(line) || line.startsWith("AGY_ERROR:"))
|
|
236
|
+
continue;
|
|
237
|
+
return line.replace(/^error:\s*/i, "");
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
/** Waits for `promise` up to `ms`; resolves null on timeout. */
|
|
242
|
+
export function within(promise, ms) {
|
|
243
|
+
return new Promise((resolve) => {
|
|
244
|
+
const timer = setTimeout(() => resolve(null), ms);
|
|
245
|
+
promise.then((value) => {
|
|
246
|
+
clearTimeout(timer);
|
|
247
|
+
resolve(value);
|
|
248
|
+
}, () => {
|
|
249
|
+
clearTimeout(timer);
|
|
250
|
+
resolve(null);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Interrupt the running turn like Ctrl+C would: SIGINT the process group,
|
|
256
|
+
* give agy a moment to report the turn as INTERRUPTED, and stop the process
|
|
257
|
+
* if it does not. Resolves with whatever outcome arrived.
|
|
258
|
+
*/
|
|
259
|
+
export async function interruptAgyTurn(connection, pending, graceSec = 5) {
|
|
260
|
+
connection.signal("SIGINT");
|
|
261
|
+
const settled = await within(pending, 3000);
|
|
262
|
+
if (settled)
|
|
263
|
+
return settled;
|
|
264
|
+
await connection.terminate(graceSec, 0);
|
|
265
|
+
return within(pending, 2000);
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../../src/providers/antigravity/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AgentMode, ListModelsOptions, ListModesOptions, ProviderModel } from "../../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse `agy models`. The JSON form is preferred when a build supports it;
|
|
4
|
+
* the text form is one model per line: a slug, two or more spaces, then the
|
|
5
|
+
* display name, for example `gemini-3.1-pro-high Gemini 3.1 Pro (High)`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseAntigravityModels(output: string): ProviderModel[];
|
|
8
|
+
export declare function listAntigravityModels(options?: ListModelsOptions): Promise<ProviderModel[]>;
|
|
9
|
+
/** Antigravity's modes are a fixed set (`--mode`); listing them spawns nothing. */
|
|
10
|
+
export declare function listAntigravityModes(_options?: ListModesOptions): Promise<AgentMode[]>;
|
|
11
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/providers/antigravity/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AA6BpG;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,EAAE,CAmBtE;AAED,wBAAsB,qBAAqB,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAErG;AA6BD,mFAAmF;AACnF,wBAAsB,oBAAoB,CAAC,QAAQ,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAEhG"}
|