comfyui-mcp 0.43.0 → 0.44.0

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.
Files changed (57) hide show
  1. package/README.md +8 -0
  2. package/dist/config.js +42 -0
  3. package/dist/config.js.map +1 -1
  4. package/dist/orchestrator/agent-backend.js +24 -10
  5. package/dist/orchestrator/agent-backend.js.map +1 -1
  6. package/dist/orchestrator/antigravity-backend.js +575 -0
  7. package/dist/orchestrator/antigravity-backend.js.map +1 -0
  8. package/dist/orchestrator/backend-readiness.js +23 -14
  9. package/dist/orchestrator/backend-readiness.js.map +1 -1
  10. package/dist/orchestrator/copilot-backend.js +3 -2
  11. package/dist/orchestrator/copilot-backend.js.map +1 -1
  12. package/dist/orchestrator/index.js +267 -147
  13. package/dist/orchestrator/index.js.map +1 -1
  14. package/dist/orchestrator/panel-agent.js +138 -18
  15. package/dist/orchestrator/panel-agent.js.map +1 -1
  16. package/dist/orchestrator/panel-console-http.js +4 -3
  17. package/dist/orchestrator/panel-console-http.js.map +1 -1
  18. package/dist/orchestrator/start-failure-notice.js +63 -0
  19. package/dist/orchestrator/start-failure-notice.js.map +1 -0
  20. package/dist/services/code-provider-auth.js +49 -14
  21. package/dist/services/code-provider-auth.js.map +1 -1
  22. package/dist/services/job-history.js +50 -0
  23. package/dist/services/job-history.js.map +1 -1
  24. package/dist/services/job-watcher.js +2 -0
  25. package/dist/services/job-watcher.js.map +1 -1
  26. package/dist/services/openai-provider-registry.js +87 -0
  27. package/dist/services/openai-provider-registry.js.map +1 -0
  28. package/dist/services/panel-secrets.js +167 -59
  29. package/dist/services/panel-secrets.js.map +1 -1
  30. package/dist/services/queue-manager.js +2 -1
  31. package/dist/services/queue-manager.js.map +1 -1
  32. package/dist/services/queue-monitor.js +241 -7
  33. package/dist/services/queue-monitor.js.map +1 -1
  34. package/dist/services/queue-monitor.poll.test.js +267 -0
  35. package/dist/services/queue-monitor.poll.test.js.map +1 -0
  36. package/dist/services/queue-status-broadcast.js +26 -9
  37. package/dist/services/queue-status-broadcast.js.map +1 -1
  38. package/dist/services/queue-status-broadcast.test.js +49 -0
  39. package/dist/services/queue-status-broadcast.test.js.map +1 -1
  40. package/dist/services/runpod-client.js +190 -0
  41. package/dist/services/runpod-client.js.map +1 -0
  42. package/dist/services/runpod-watch.js +174 -0
  43. package/dist/services/runpod-watch.js.map +1 -0
  44. package/dist/tools/diagnostics.js +54 -27
  45. package/dist/tools/diagnostics.js.map +1 -1
  46. package/dist/tools/index.js +2 -0
  47. package/dist/tools/index.js.map +1 -1
  48. package/dist/tools/queue-management.js +1 -1
  49. package/dist/tools/queue-management.js.map +1 -1
  50. package/dist/tools/runpod.js +285 -0
  51. package/dist/tools/runpod.js.map +1 -0
  52. package/package.json +1 -1
  53. package/plugin/skills/ltx-director/SKILL.md +174 -0
  54. package/dist/orchestrator/glm-backend.js +0 -20
  55. package/dist/orchestrator/glm-backend.js.map +0 -1
  56. package/dist/orchestrator/moonshot-backend.js +0 -22
  57. package/dist/orchestrator/moonshot-backend.js.map +0 -1
@@ -0,0 +1,575 @@
1
+ // Google Antigravity CLI backend (issue #262) — the provider adapter behind the
2
+ // AgentBackend port for `agy`, the official Antigravity CLI that replaced the
3
+ // individual-tier Gemini CLI subscription path on 2026-06-18 (Google AI Pro /
4
+ // Ultra / free tiers moved to Antigravity; Gemini CLI remains for enterprise +
5
+ // API-key users, and keeps its own separate `gemini` backend here).
6
+ //
7
+ // Unlike the ACP/app-server adapters (gemini/codex), `agy` exposes NO documented
8
+ // machine-readable streaming protocol — only a plain-text non-interactive print
9
+ // mode. So this adapter is a SPAWN-PER-TURN driver over the supported public
10
+ // surface, exactly as requested in #262 ("start with final-text responses"):
11
+ //
12
+ // turn N=1 agy -p "<prompt>" [--model m] --dangerously-skip-permissions
13
+ // turn N>1 agy -c -p "<prompt>" ... (--continue = latest conversation)
14
+ // resume same as N>1 (`-c`); `agy` owns conversation storage
15
+ // interrupt() kill the in-flight child process tree (Windows taskkill /T /F)
16
+ // listModels() parse `agy models` (live account catalog — no static list)
17
+ //
18
+ // stdout is streamed to the panel as assistant deltas as it arrives (agy prints
19
+ // the final answer progressively in -p mode; if a build buffers, the deltas just
20
+ // land at once — still correct). There is no per-turn rewind anchor and no
21
+ // in-process MCP: forkAtAnchor=false, inProcessMcp=false.
22
+ //
23
+ // AUTH: the CLI owns authentication (system keyring + Google Sign-In). Per #262
24
+ // we deliberately do NOT read tokens from the keyring or Antigravity state files
25
+ // — readiness is "the executable exists", and the real auth signal is whether
26
+ // `agy models` answers (the connect ack's model probe). An unauthenticated CLI
27
+ // gets an actionable "run `agy` once and sign in" message.
28
+ //
29
+ // MCP / ComfyUI tools: `agy` reads MCP servers from a per-workspace
30
+ // `.agents/mcp_config.json` (and a global ~/.gemini/config/mcp_config.json we
31
+ // NEVER touch). Before the first turn we MERGE our two servers — the headless
32
+ // `comfyui` stdio MCP and the per-tab `panel` HTTP MCP — into the workspace file
33
+ // under our own names, preserving every other entry byte-for-byte. Scoped,
34
+ // merge-safe, reversible (delete the two keys) — per #262's requirements.
35
+ //
36
+ // LIMITS (flagged honestly, mirrors the issue's "reduced capabilities" ask):
37
+ // - `-p` prints plain text: no structured tool-call events, so the panel shows
38
+ // no per-tool progress for agy turns (onActivity still fires on every stdout
39
+ // chunk, keeping the idle watchdog armed).
40
+ // - `--continue` binds to the account's LATEST conversation; a user running
41
+ // `agy` interactively in parallel can steal continuity. The supported
42
+ // surface offers no way to read the new conversation's id from -p output.
43
+ // - No documented image-input path for -p → vision=false (image refs are
44
+ // already named in the turn text as a fallback).
45
+ import { spawn, spawnSync } from "node:child_process";
46
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
47
+ import { homedir } from "node:os";
48
+ import { join } from "node:path";
49
+ import { logger } from "../utils/logger.js";
50
+ import { ANTIGRAVITY_CAPABILITIES, } from "./agent-backend.js";
51
+ function msgOf(err) {
52
+ return err instanceof Error ? err.message : String(err);
53
+ }
54
+ /** Kill an entire process tree (identical posture to gemini/codex-backend):
55
+ * Windows taskkill /T /F; POSIX negative-pid process-group signal with a
56
+ * single-pid fallback. Best-effort — teardown must never throw. */
57
+ function killProcessTree(pid) {
58
+ if (!Number.isFinite(pid))
59
+ return;
60
+ const p = pid;
61
+ if (process.platform === "win32") {
62
+ try {
63
+ spawnSync("taskkill", ["/PID", String(p), "/T", "/F"], { windowsHide: true });
64
+ }
65
+ catch {
66
+ try {
67
+ process.kill(p);
68
+ }
69
+ catch {
70
+ // already gone
71
+ }
72
+ }
73
+ return;
74
+ }
75
+ try {
76
+ process.kill(-p, "SIGTERM");
77
+ }
78
+ catch {
79
+ try {
80
+ process.kill(p, "SIGTERM");
81
+ }
82
+ catch {
83
+ // already gone
84
+ }
85
+ }
86
+ }
87
+ /**
88
+ * Resolve the `agy` executable. Order: COMFYUI_MCP_ANTIGRAVITY_PATH (explicit
89
+ * escape hatch) → PATH (agy / agy.exe) → the official installers' well-known
90
+ * locations (%LOCALAPPDATA%\agy\bin on Windows, ~/.local/bin elsewhere).
91
+ * Returns an absolute path when found on disk, the bare name as a last resort,
92
+ * or null when clearly absent. We never spawn through a shell — the prompt is
93
+ * user data, and the official installers ship a real executable (a `.cmd` npm
94
+ * shim is NOT supported; Node refuses shell-less .cmd spawns post-CVE-2024-27980,
95
+ * and shell quoting of arbitrary prompt text would be an injection risk).
96
+ */
97
+ export function resolveAgyBin(home = homedir()) {
98
+ const override = process.env.COMFYUI_MCP_ANTIGRAVITY_PATH?.trim();
99
+ if (override)
100
+ return override;
101
+ const names = process.platform === "win32" ? ["agy.exe", "agy"] : ["agy"];
102
+ const sep = process.platform === "win32" ? ";" : ":";
103
+ for (const dir of (process.env.PATH || "").split(sep).filter(Boolean)) {
104
+ for (const name of names) {
105
+ try {
106
+ const full = join(dir, name);
107
+ if (existsSync(full))
108
+ return full;
109
+ }
110
+ catch {
111
+ // unreadable PATH entry — skip
112
+ }
113
+ }
114
+ }
115
+ const wellKnown = process.platform === "win32"
116
+ ? [join(process.env.LOCALAPPDATA || join(home, "AppData", "Local"), "agy", "bin", "agy.exe")]
117
+ : [join(home, ".local", "bin", "agy"), "/usr/local/bin/agy", "/opt/homebrew/bin/agy"];
118
+ for (const p of wellKnown) {
119
+ try {
120
+ if (existsSync(p))
121
+ return p;
122
+ }
123
+ catch {
124
+ // skip
125
+ }
126
+ }
127
+ return null;
128
+ }
129
+ /** Strip ANSI escape sequences (agy's TUI heritage may color even -p output). */
130
+ function stripAnsi(s) {
131
+ // eslint-disable-next-line no-control-regex
132
+ return s.replace(/\[[0-9;?]*[ -/]*[@-~]/g, "");
133
+ }
134
+ /**
135
+ * Parse `agy models` output into ModelChoices. The format is not a documented
136
+ * contract, so this is deliberately TOLERANT: strip ANSI, take each non-empty
137
+ * line, drop obvious headers/rules/prose, strip list markers and a
138
+ * "(default)"/"(current)" tag, and keep the first token when it looks like a
139
+ * model id. A `*`-marked or "(default)" row is surfaced first. Returns [] when
140
+ * nothing parses (the panel degrades gracefully on an empty list).
141
+ */
142
+ export function parseAgyModels(output) {
143
+ const out = [];
144
+ let defaultId = null;
145
+ for (const raw of stripAnsi(output).split(/\r?\n/)) {
146
+ const line = raw.trim();
147
+ if (!line)
148
+ continue;
149
+ // Header / separator / prose rows.
150
+ if (/^[-=─│+|]+$/.test(line))
151
+ continue;
152
+ if (/^(available|models?|name|id|description|usage|use )\b/i.test(line) && !/^[a-z0-9][\w.:/-]*$/i.test(line))
153
+ continue;
154
+ const marked = /^[*✓✔>]/.test(line);
155
+ const cleaned = line.replace(/^[*✓✔>•\-\s]+/, "");
156
+ const isDefault = marked || /\((default|current|active)\)/i.test(cleaned);
157
+ const token = cleaned.split(/\s+/)[0]?.replace(/[,;]$/, "") ?? "";
158
+ // A plausible model id: starts alphanumeric, id-ish charset, has a digit or
159
+ // dash (filters prose words like "Run"), not an obvious column header.
160
+ if (!/^[a-z0-9][\w.:/-]*$/i.test(token))
161
+ continue;
162
+ if (!/[\d-]/.test(token))
163
+ continue;
164
+ if (/^(name|model|models|id)$/i.test(token))
165
+ continue;
166
+ if (out.some((m) => m.id === token))
167
+ continue;
168
+ out.push({ id: token });
169
+ if (isDefault && !defaultId)
170
+ defaultId = token;
171
+ }
172
+ if (defaultId) {
173
+ out.sort((a, b) => (a.id === defaultId ? -1 : b.id === defaultId ? 1 : 0));
174
+ }
175
+ return out;
176
+ }
177
+ /**
178
+ * Merge our MCP servers into a workspace `.agents/mcp_config.json`, preserving
179
+ * every entry we don't own. Antigravity's schema (per the official docs): local
180
+ * servers are { command, args, env: {K:V} }, remote ones { serverUrl }. Handles
181
+ * both the bare { name: {...} } layout and a { mcpServers: { name: {...} } }
182
+ * wrapper, preferring whichever the existing file already uses (wrapper when
183
+ * creating fresh). Returns the merged JSON text it wrote (for tests).
184
+ */
185
+ export function mergeAgyMcpConfig(existingText, servers) {
186
+ let root = {};
187
+ try {
188
+ if (existingText?.trim())
189
+ root = JSON.parse(existingText);
190
+ }
191
+ catch {
192
+ // Unparseable user file: do NOT clobber it — merge into a fresh wrapper and
193
+ // let the caller decide; we keep the unparseable original under a backup key
194
+ // is worse than refusing. Treat as empty but log at the call site.
195
+ root = {};
196
+ }
197
+ const hasWrapper = typeof root.mcpServers === "object" && root.mcpServers !== null && !Array.isArray(root.mcpServers);
198
+ // If the file is bare-layout (top-level server entries, no mcpServers key and
199
+ // at least one object value), keep that layout; otherwise use the wrapper.
200
+ const bareLayout = !hasWrapper && Object.values(root).some((v) => typeof v === "object" && v !== null);
201
+ const target = bareLayout
202
+ ? root
203
+ : (root.mcpServers ?? {});
204
+ for (const [name, spec] of Object.entries(servers)) {
205
+ target[name] =
206
+ spec.transport === "stdio"
207
+ ? { command: spec.command, args: spec.args ?? [], env: spec.env ?? {} }
208
+ : { serverUrl: spec.url };
209
+ }
210
+ const merged = bareLayout ? target : { ...root, mcpServers: target };
211
+ return `${JSON.stringify(merged, null, 2)}\n`;
212
+ }
213
+ /** Sentinel session id: agy owns conversation storage and -p output carries no
214
+ * conversation id, so "resume" means `--continue` (the account's latest). */
215
+ const AGY_SESSION_SENTINEL = "antigravity-latest";
216
+ /**
217
+ * The Antigravity CLI adapter. One instance per PanelAgent; spawn-per-turn, so
218
+ * there is no persistent child between turns — only the in-flight one.
219
+ */
220
+ export class AntigravityBackend {
221
+ id = "antigravity";
222
+ capabilities = ANTIGRAVITY_CAPABILITIES;
223
+ deps;
224
+ model;
225
+ bin; // undefined = not yet resolved
226
+ /** The in-flight per-turn child (interrupt/close kill its tree). */
227
+ child = null;
228
+ interrupted = false;
229
+ disposed = false;
230
+ /** False until the first turn of a FRESH conversation completes; resumed
231
+ * sessions start true so every turn continues the latest conversation. */
232
+ continueNext = false;
233
+ needsSystemPreamble = false;
234
+ mcpConfigWritten = false;
235
+ constructor(deps = {}) {
236
+ this.deps = deps;
237
+ this.model = deps.model;
238
+ }
239
+ resolveBin() {
240
+ if (this.bin === undefined)
241
+ this.bin = resolveAgyBin();
242
+ if (!this.bin) {
243
+ throw new Error("Antigravity CLI (`agy`) not found. Install it from https://antigravity.google " +
244
+ "(Windows: `irm https://antigravity.google/cli/install.ps1 | iex`; macOS/Linux: " +
245
+ "`curl -fsSL https://antigravity.google/cli/install.sh | bash`), run `agy` once to " +
246
+ "sign in with your Google account, then reconnect. You can also point " +
247
+ "COMFYUI_MCP_ANTIGRAVITY_PATH at the executable.");
248
+ }
249
+ return this.bin;
250
+ }
251
+ /** One-time preflight: resolve the executable so a missing install fails fast
252
+ * with the actionable message above (mirrors the other CLI backends). */
253
+ async prepare() {
254
+ if (this.disposed)
255
+ throw new Error("antigravity backend is closed.");
256
+ this.resolveBin();
257
+ }
258
+ /** Merge our MCP servers into the workspace .agents/mcp_config.json (once per
259
+ * backend instance). Never touches the global ~/.gemini/config/mcp_config.json.
260
+ * Failure is non-fatal: the agent still answers, just without ComfyUI tools —
261
+ * logged so the gap is visible. */
262
+ ensureMcpConfig(cwd) {
263
+ if (this.mcpConfigWritten || !this.deps.mcpServers || !Object.keys(this.deps.mcpServers).length)
264
+ return;
265
+ const dir = join(cwd, ".agents");
266
+ const file = join(dir, "mcp_config.json");
267
+ try {
268
+ let existing = null;
269
+ try {
270
+ existing = readFileSync(file, "utf8");
271
+ }
272
+ catch {
273
+ existing = null;
274
+ }
275
+ if (existing) {
276
+ try {
277
+ JSON.parse(existing);
278
+ }
279
+ catch {
280
+ logger.warn(`[antigravity-backend] ${file} exists but is not valid JSON — leaving it untouched (ComfyUI MCP tools will be unavailable to agy until it parses)`);
281
+ return;
282
+ }
283
+ }
284
+ mkdirSync(dir, { recursive: true });
285
+ writeFileSync(file, mergeAgyMcpConfig(existing, this.deps.mcpServers), "utf8");
286
+ this.mcpConfigWritten = true;
287
+ logger.info(`[antigravity-backend] merged comfyui/panel MCP servers into ${file}`);
288
+ }
289
+ catch (err) {
290
+ logger.warn(`[antigravity-backend] could not write ${file}: ${msgOf(err)}`);
291
+ }
292
+ }
293
+ /**
294
+ * Drive the session: one `agy -p` child per neutral turn, continuity via
295
+ * `--continue`. The channel async-iteration IS the turn gate (PanelAgent
296
+ * releases one batch per turn).
297
+ */
298
+ async *run(opts) {
299
+ // Panel may pass the Claude panel model unconditionally — only honor a model
300
+ // that plausibly belongs to this provider (anything not Claude-shaped; the
301
+ // real catalog is the account's own `agy models`).
302
+ if (opts.model && !/^claude/i.test(opts.model))
303
+ this.model = opts.model;
304
+ await this.prepare();
305
+ const cwd = opts.cwd ?? this.deps.cwd ?? process.cwd();
306
+ this.ensureMcpConfig(cwd);
307
+ const resuming = !!(opts.resume ?? opts.sessionId);
308
+ this.continueNext = resuming;
309
+ this.needsSystemPreamble = !resuming && !!this.deps.systemAppend;
310
+ yield {
311
+ type: "session",
312
+ sessionId: AGY_SESSION_SENTINEL,
313
+ ...(this.model ? { model: this.model } : {}),
314
+ };
315
+ for await (const turn of opts.channel) {
316
+ yield* this.runTurn(turn, cwd, opts.onActivity);
317
+ }
318
+ }
319
+ /** Run ONE turn = one `agy -p` child. stdout streams as assistant deltas;
320
+ * exit 0 commits the accumulated text and a successful result; a non-zero
321
+ * exit (or spawn failure) surfaces an error + failed result. Exactly one
322
+ * terminal result per turn (PanelAgent's gate depends on it). */
323
+ async *runTurn(turn, cwd, onActivity) {
324
+ let text = turn.text;
325
+ if (this.needsSystemPreamble && this.deps.systemAppend) {
326
+ text =
327
+ `<system>\n${this.deps.systemAppend}\n</system>\n\n` +
328
+ `The user's first message follows.\n\n${turn.text}`;
329
+ this.needsSystemPreamble = false;
330
+ }
331
+ // Image refs: no documented -p image input — the refs are already named in
332
+ // the turn text (vision=false tells the panel up front).
333
+ const bin = this.resolveBin();
334
+ const timeout = process.env.COMFYUI_MCP_ANTIGRAVITY_PRINT_TIMEOUT?.trim() || "45m";
335
+ const args = [
336
+ ...(this.continueNext ? ["-c"] : []),
337
+ "-p",
338
+ text,
339
+ "--print-timeout",
340
+ timeout,
341
+ // The panel agent is an isolated background agent (same posture as
342
+ // Claude bypassPermissions / the ACP auto-approve): tool calls must not
343
+ // block on an interactive prompt that nothing will ever answer.
344
+ "--dangerously-skip-permissions",
345
+ ...(this.model ? ["--model", this.model] : []),
346
+ ];
347
+ // NOTE: `interrupted` is deliberately NOT cleared here. A Stop can land
348
+ // while this turn is still starting up (run() awaits prepare() and the
349
+ // channel before reaching runTurn), and clearing at turn START silently
350
+ // discarded it — the turn then ran with nothing able to stop it. The flag is
351
+ // cleared when a turn SETTLES instead, so it survives setup and the child
352
+ // assignment below acts on it.
353
+ const queue = [];
354
+ let wake = null;
355
+ let done = false;
356
+ const push = (ev) => {
357
+ queue.push(ev);
358
+ wake?.();
359
+ wake = null;
360
+ };
361
+ const finish = () => {
362
+ done = true;
363
+ wake?.();
364
+ wake = null;
365
+ };
366
+ let out = "";
367
+ let errOut = "";
368
+ let streamOpen = false;
369
+ let child;
370
+ try {
371
+ child = spawn(bin, args, {
372
+ cwd,
373
+ env: process.env,
374
+ stdio: ["ignore", "pipe", "pipe"],
375
+ windowsHide: true,
376
+ detached: process.platform !== "win32",
377
+ });
378
+ }
379
+ catch (err) {
380
+ yield { type: "error", message: `Could not start agy: ${msgOf(err)}` };
381
+ yield { type: "result", ok: false, subtype: "error" };
382
+ return;
383
+ }
384
+ this.child = child;
385
+ // LIVENESS heartbeat: agy -p may print NOTHING for minutes while it works
386
+ // (tool calls, long generations) — there is no event stream to observe. The
387
+ // child process being alive is the only honest liveness signal, so bump the
388
+ // idle watchdog on an interval while it runs. A truly hung child is bounded
389
+ // by agy's own --print-timeout, which ends the turn with a non-zero exit.
390
+ const heartbeat = setInterval(() => {
391
+ try {
392
+ onActivity?.();
393
+ }
394
+ catch {
395
+ // watchdog bump must never throw
396
+ }
397
+ }, 15_000);
398
+ heartbeat.unref?.();
399
+ child.stdout.setEncoding("utf8");
400
+ child.stderr.setEncoding("utf8");
401
+ child.stdout.on("data", (chunk) => {
402
+ try {
403
+ onActivity?.();
404
+ }
405
+ catch {
406
+ // watchdog bump must never break the reader
407
+ }
408
+ const clean = stripAnsi(chunk);
409
+ if (!clean)
410
+ return;
411
+ out += clean;
412
+ if (!streamOpen) {
413
+ streamOpen = true;
414
+ push({ type: "stream_start", id: null });
415
+ }
416
+ push({ type: "assistant_delta", text: clean });
417
+ });
418
+ child.stderr.on("data", (chunk) => {
419
+ try {
420
+ onActivity?.();
421
+ }
422
+ catch {
423
+ // ignore
424
+ }
425
+ errOut += chunk;
426
+ });
427
+ let settled = false;
428
+ const settle = (code, spawnErr) => {
429
+ if (settled)
430
+ return;
431
+ settled = true;
432
+ clearInterval(heartbeat);
433
+ if (this.child === child)
434
+ this.child = null;
435
+ if (streamOpen)
436
+ push({ type: "stream_end" });
437
+ const finalText = out.trim();
438
+ if (this.interrupted) {
439
+ if (finalText)
440
+ push({ type: "assistant", text: finalText });
441
+ push({ type: "result", ok: false, subtype: "cancelled" });
442
+ }
443
+ else if (spawnErr || code !== 0) {
444
+ const stderrTail = stripAnsi(errOut).trim().split(/\r?\n/).slice(-3).join(" ").trim();
445
+ const authish = /sign.?in|log.?in|auth|credential|unauthoriz/i.test(stderrTail + finalText);
446
+ const message = spawnErr
447
+ ? /ENOENT/i.test(spawnErr.message)
448
+ ? "Antigravity CLI (`agy`) could not be launched — it may have been uninstalled. Reinstall from https://antigravity.google and reconnect."
449
+ : `agy failed to start: ${spawnErr.message}`
450
+ : authish
451
+ ? `Antigravity CLI is not signed in. Run \`agy\` once in a terminal, complete the Google Sign-In, then send your message again.${stderrTail ? ` (agy: ${stderrTail})` : ""}`
452
+ : `agy exited with code ${code}.${stderrTail ? ` ${stderrTail}` : ""}`;
453
+ push({ type: "error", message });
454
+ push({ type: "result", ok: false, subtype: "error" });
455
+ }
456
+ else {
457
+ if (finalText)
458
+ push({ type: "assistant", text: finalText });
459
+ // From here on, continue the conversation agy just recorded.
460
+ this.continueNext = true;
461
+ push({ type: "result", ok: true, subtype: "end_turn" });
462
+ }
463
+ // Clear the interrupt HERE (turn end), not at turn start — see the note
464
+ // where the queue is set up. The flag has now been consumed to pick this
465
+ // turn's result, so the next turn starts clean.
466
+ this.interrupted = false;
467
+ finish();
468
+ };
469
+ child.on("error", (err) => settle(null, err));
470
+ child.on("exit", (code) => settle(code));
471
+ // An interrupt can arrive while spawn() is in flight — `this.child` was
472
+ // still null then, so interrupt() could only raise the flag. Honor it now.
473
+ // This MUST come after the exit/error listeners above: killing earlier can
474
+ // deliver the child's death before anything is listening, and then the turn
475
+ // never settles (exactly what hung the interrupt test).
476
+ if (this.interrupted)
477
+ killProcessTree(child.pid);
478
+ // Drain the bridged queue until the child settles.
479
+ while (true) {
480
+ while (queue.length)
481
+ yield queue.shift();
482
+ if (done)
483
+ break;
484
+ await new Promise((resolve) => {
485
+ wake = resolve;
486
+ });
487
+ }
488
+ while (queue.length)
489
+ yield queue.shift();
490
+ }
491
+ /** Stop the current turn: kill the in-flight child's process tree. The next
492
+ * turn continues the conversation (`-c`) with whatever agy recorded. */
493
+ async interrupt() {
494
+ // Set the flag FIRST and UNCONDITIONALLY. `this.child` is only assigned
495
+ // after spawn() returns, so an interrupt landing in that window used to hit
496
+ // the `if (!child) return` below, leave `interrupted` false, and never kill
497
+ // anything — the turn then ran to completion with nothing able to stop it.
498
+ // In the panel that is "hit Stop right after Send and the turn hangs
499
+ // forever"; in CI it was a 5s timeout in the interrupt test. run() re-checks
500
+ // this flag the moment it assigns the child, so a kill is never lost.
501
+ this.interrupted = true;
502
+ const child = this.child;
503
+ if (!child)
504
+ return; // spawn window — run() kills it as soon as it exists
505
+ killProcessTree(child.pid);
506
+ }
507
+ /** Switch the model for subsequent turns (--model is per-spawn, so this is
508
+ * free — no respawn dance). Ignores Claude-shaped ids the panel may pass. */
509
+ async setModel(model) {
510
+ if (/^claude/i.test(model))
511
+ return;
512
+ this.model = model;
513
+ }
514
+ /**
515
+ * Enumerate the account's models via `agy models` (per #262: parse the live
516
+ * catalog, never ship a static list). Also serves as the safe auth probe: an
517
+ * unauthenticated CLI fails here → the connect ack degrades with sign-in
518
+ * guidance instead of greeting ready.
519
+ */
520
+ async listModels() {
521
+ const bin = this.resolveBin();
522
+ return await new Promise((resolve, reject) => {
523
+ let out = "";
524
+ let err = "";
525
+ let child;
526
+ try {
527
+ child = spawn(bin, ["models"], {
528
+ cwd: this.deps.cwd ?? process.cwd(),
529
+ env: process.env,
530
+ stdio: ["ignore", "pipe", "pipe"],
531
+ windowsHide: true,
532
+ });
533
+ }
534
+ catch (e) {
535
+ reject(new Error(`Could not run \`agy models\`: ${msgOf(e)}`));
536
+ return;
537
+ }
538
+ const timer = setTimeout(() => {
539
+ killProcessTree(child.pid);
540
+ reject(new Error("`agy models` timed out after 30s."));
541
+ }, 30_000);
542
+ timer.unref?.();
543
+ child.stdout.setEncoding("utf8");
544
+ child.stderr.setEncoding("utf8");
545
+ child.stdout.on("data", (c) => (out += c));
546
+ child.stderr.on("data", (c) => (err += c));
547
+ child.on("error", (e) => {
548
+ clearTimeout(timer);
549
+ reject(new Error(`Could not run \`agy models\`: ${e.message}`));
550
+ });
551
+ child.on("exit", (code) => {
552
+ clearTimeout(timer);
553
+ if (code === 0) {
554
+ resolve(parseAgyModels(out));
555
+ }
556
+ else {
557
+ const tail = stripAnsi(err || out).trim().split(/\r?\n/).slice(-2).join(" ");
558
+ reject(new Error(`\`agy models\` exited with code ${code}${tail ? ` (${tail})` : ""}. ` +
559
+ "If you haven't signed in yet, run `agy` once and complete the Google Sign-In."));
560
+ }
561
+ });
562
+ });
563
+ }
564
+ /** Dispose: kill any in-flight child tree. Idempotent, safe when never started. */
565
+ async close() {
566
+ this.disposed = true;
567
+ const child = this.child;
568
+ this.child = null;
569
+ if (child) {
570
+ this.interrupted = true;
571
+ killProcessTree(child.pid);
572
+ }
573
+ }
574
+ }
575
+ //# sourceMappingURL=antigravity-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antigravity-backend.js","sourceRoot":"","sources":["../../src/orchestrator/antigravity-backend.ts"],"names":[],"mappings":"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"}