@cluesmith/codev 3.1.6 → 3.1.8

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 (123) hide show
  1. package/dashboard-dist/assets/{index-5eO1yGoy.js → index-DM7OU-EI.js} +43 -41
  2. package/dashboard-dist/assets/index-DM7OU-EI.js.map +1 -0
  3. package/dashboard-dist/index.html +1 -1
  4. package/dist/agent-farm/commands/spawn-worktree.d.ts +8 -2
  5. package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
  6. package/dist/agent-farm/commands/spawn-worktree.js +53 -9
  7. package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
  8. package/dist/agent-farm/commands/tower.d.ts +12 -0
  9. package/dist/agent-farm/commands/tower.d.ts.map +1 -1
  10. package/dist/agent-farm/commands/tower.js +11 -3
  11. package/dist/agent-farm/commands/tower.js.map +1 -1
  12. package/dist/agent-farm/lib/tunnel-client.d.ts +4 -0
  13. package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
  14. package/dist/agent-farm/lib/tunnel-client.js +12 -5
  15. package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
  16. package/dist/agent-farm/servers/overview.d.ts +26 -145
  17. package/dist/agent-farm/servers/overview.d.ts.map +1 -1
  18. package/dist/agent-farm/servers/overview.js +76 -9
  19. package/dist/agent-farm/servers/overview.js.map +1 -1
  20. package/dist/agent-farm/servers/resolved-enrichment-cache.d.ts +55 -0
  21. package/dist/agent-farm/servers/resolved-enrichment-cache.d.ts.map +1 -0
  22. package/dist/agent-farm/servers/resolved-enrichment-cache.js +55 -0
  23. package/dist/agent-farm/servers/resolved-enrichment-cache.js.map +1 -0
  24. package/dist/agent-farm/servers/tower-routes.d.ts +4 -0
  25. package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
  26. package/dist/agent-farm/servers/tower-routes.js +99 -2
  27. package/dist/agent-farm/servers/tower-routes.js.map +1 -1
  28. package/dist/agent-farm/servers/tower-server.js +6 -0
  29. package/dist/agent-farm/servers/tower-server.js.map +1 -1
  30. package/dist/agent-farm/servers/tower-terminals.d.ts +14 -0
  31. package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
  32. package/dist/agent-farm/servers/tower-terminals.js +95 -9
  33. package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
  34. package/dist/agent-farm/servers/tower-websocket.d.ts.map +1 -1
  35. package/dist/agent-farm/servers/tower-websocket.js +42 -5
  36. package/dist/agent-farm/servers/tower-websocket.js.map +1 -1
  37. package/dist/agent-farm/types.d.ts +13 -3
  38. package/dist/agent-farm/types.d.ts.map +1 -1
  39. package/dist/commands/consult/index.d.ts +51 -1
  40. package/dist/commands/consult/index.d.ts.map +1 -1
  41. package/dist/commands/consult/index.js +310 -51
  42. package/dist/commands/consult/index.js.map +1 -1
  43. package/dist/commands/consult/usage-extractor.d.ts +12 -10
  44. package/dist/commands/consult/usage-extractor.d.ts.map +1 -1
  45. package/dist/commands/consult/usage-extractor.js +16 -88
  46. package/dist/commands/consult/usage-extractor.js.map +1 -1
  47. package/dist/commands/doctor.d.ts.map +1 -1
  48. package/dist/commands/doctor.js +101 -25
  49. package/dist/commands/doctor.js.map +1 -1
  50. package/dist/lib/forge-contracts.d.ts +7 -0
  51. package/dist/lib/forge-contracts.d.ts.map +1 -1
  52. package/dist/lib/forge-contracts.js.map +1 -1
  53. package/dist/lib/forge.js +1 -1
  54. package/dist/lib/forge.js.map +1 -1
  55. package/dist/lib/github.d.ts +13 -0
  56. package/dist/lib/github.d.ts.map +1 -1
  57. package/dist/lib/github.js +21 -0
  58. package/dist/lib/github.js.map +1 -1
  59. package/dist/terminal/pty-manager.d.ts +8 -0
  60. package/dist/terminal/pty-manager.d.ts.map +1 -1
  61. package/dist/terminal/pty-manager.js +8 -1
  62. package/dist/terminal/pty-manager.js.map +1 -1
  63. package/package.json +24 -23
  64. package/scripts/forge/gitea/auth-status.sh +0 -0
  65. package/scripts/forge/gitea/issue-comment.sh +0 -0
  66. package/scripts/forge/gitea/issue-list.sh +0 -0
  67. package/scripts/forge/gitea/issue-search.sh +28 -0
  68. package/scripts/forge/gitea/issue-view.sh +0 -0
  69. package/scripts/forge/gitea/pr-exists.sh +0 -0
  70. package/scripts/forge/gitea/pr-list.sh +0 -0
  71. package/scripts/forge/gitea/pr-merge.sh +0 -0
  72. package/scripts/forge/gitea/pr-view.sh +0 -0
  73. package/scripts/forge/gitea/recently-closed.sh +0 -0
  74. package/scripts/forge/gitea/recently-merged.sh +0 -0
  75. package/scripts/forge/gitea/repo-archive.sh +0 -0
  76. package/scripts/forge/gitea/user-identity.sh +0 -0
  77. package/scripts/forge/github/auth-status.sh +0 -0
  78. package/scripts/forge/github/issue-comment.sh +0 -0
  79. package/scripts/forge/github/issue-list.sh +0 -0
  80. package/scripts/forge/github/issue-search.sh +13 -0
  81. package/scripts/forge/github/issue-view.sh +0 -0
  82. package/scripts/forge/github/on-it-timestamps.sh +0 -0
  83. package/scripts/forge/github/pr-diff.sh +0 -0
  84. package/scripts/forge/github/pr-exists.sh +0 -0
  85. package/scripts/forge/github/pr-list.sh +0 -0
  86. package/scripts/forge/github/pr-merge.sh +0 -0
  87. package/scripts/forge/github/pr-search.sh +0 -0
  88. package/scripts/forge/github/pr-view.sh +0 -0
  89. package/scripts/forge/github/recently-closed.sh +0 -0
  90. package/scripts/forge/github/recently-merged.sh +0 -0
  91. package/scripts/forge/github/repo-archive.sh +0 -0
  92. package/scripts/forge/github/team-activity.sh +0 -0
  93. package/scripts/forge/github/user-identity.sh +0 -0
  94. package/scripts/forge/gitlab/auth-status.sh +0 -0
  95. package/scripts/forge/gitlab/issue-comment.sh +0 -0
  96. package/scripts/forge/gitlab/issue-list.sh +0 -0
  97. package/scripts/forge/gitlab/issue-search.sh +19 -0
  98. package/scripts/forge/gitlab/issue-view.sh +0 -0
  99. package/scripts/forge/gitlab/pr-diff.sh +0 -0
  100. package/scripts/forge/gitlab/pr-exists.sh +0 -0
  101. package/scripts/forge/gitlab/pr-list.sh +0 -0
  102. package/scripts/forge/gitlab/pr-merge.sh +0 -0
  103. package/scripts/forge/gitlab/pr-search.sh +0 -0
  104. package/scripts/forge/gitlab/pr-view.sh +0 -0
  105. package/scripts/forge/gitlab/recently-closed.sh +0 -0
  106. package/scripts/forge/gitlab/recently-merged.sh +0 -0
  107. package/scripts/forge/gitlab/repo-archive.sh +0 -0
  108. package/scripts/forge/gitlab/user-identity.sh +0 -0
  109. package/scripts/forge/linear/auth-status.sh +0 -0
  110. package/scripts/forge/linear/issue-comment.sh +0 -0
  111. package/scripts/forge/linear/issue-list.sh +0 -0
  112. package/scripts/forge/linear/issue-search.sh +49 -0
  113. package/scripts/forge/linear/issue-view.sh +0 -0
  114. package/scripts/forge/linear/recently-closed.sh +0 -0
  115. package/scripts/forge/linear/user-identity.sh +0 -0
  116. package/skeleton/.claude/skills/consult/SKILL.md +1 -1
  117. package/skeleton/DEPENDENCIES.md +17 -6
  118. package/skeleton/protocols/aspir/protocol.json +5 -5
  119. package/skeleton/protocols/spir/protocol.json +5 -5
  120. package/skeleton/resources/commands/codev.md +1 -1
  121. package/skeleton/resources/commands/consult.md +21 -6
  122. package/LICENSE +0 -201
  123. package/dashboard-dist/assets/index-5eO1yGoy.js.map +0 -1
@@ -16,6 +16,7 @@ interface ModelConfig {
16
16
  envVar: string | null;
17
17
  }
18
18
  declare const MODEL_CONFIGS: Record<string, ModelConfig>;
19
+ declare const MODEL_ALIASES: Record<string, string>;
19
20
  export interface ConsultOptions {
20
21
  model: string;
21
22
  prompt?: string;
@@ -63,6 +64,55 @@ declare function computePersistentOutputPath(state: BuilderProjectState, model:
63
64
  * Mirrors runClaudeConsultation() — streams events, captures usage, records metrics.
64
65
  */
65
66
  export declare function runCodexConsultation(queryText: string, role: string, workspaceRoot: string, outputPath?: string, metricsCtx?: MetricsContext): Promise<void>;
67
+ /**
68
+ * Build the env passed to the Claude Agent SDK subprocess for a consultation.
69
+ *
70
+ * Copies the given environment, but when a Claude subscription/OAuth token
71
+ * (`CLAUDE_CODE_OAUTH_TOKEN`) is present, strips `ANTHROPIC_API_KEY` and
72
+ * `ANTHROPIC_AUTH_TOKEN` from the *copy* (never the global `process.env`).
73
+ * The Agent SDK prioritizes the API key over the OAuth token, so leaving the
74
+ * key in would silently route CMAP/review traffic to the metered Opus API
75
+ * instead of the Claude subscription (issue #985).
76
+ *
77
+ * When no OAuth token is set, the API key is preserved so CI / key-only
78
+ * environments continue to authenticate.
79
+ *
80
+ * The deletion is scoped to this subprocess env only — other callers that need
81
+ * the API key (persona, dev:local) are unaffected.
82
+ */
83
+ export declare function buildClaudeConsultEnv(processEnv: NodeJS.ProcessEnv): Record<string, string>;
84
+ export declare const AGY_OAUTH_MARKERS: string[];
85
+ /**
86
+ * Verify a path is the real headless `agy` CLI, not the Antigravity IDE
87
+ * launcher. The IDE ships `~/.antigravity/.../bin/agy` as a symlink to the
88
+ * Electron app binary (`Antigravity.app/.../antigravity`); resolving it and
89
+ * launching it would open the IDE, never produce a `--print` review. We reject
90
+ * by realpath WITHOUT executing anything (no risk of launching the GUI).
91
+ */
92
+ export declare function isRealAgyCli(p: string): boolean;
93
+ /**
94
+ * Resolve the real `agy` CLI binary deterministically — never trust a bare
95
+ * PATH lookup (a stale shell or the IDE symlink shadows the CLI). Prefers the
96
+ * official installer path, then a PATH `agy` verified not to be the IDE.
97
+ * Returns null if no valid headless CLI is found.
98
+ */
99
+ /**
100
+ * Positively verify a candidate behaves like the real headless agy CLI by
101
+ * running `--version` (read-only, fast). `isRealAgyCli` rejects the IDE launcher
102
+ * by realpath; this adds behavioral verification for an *untrusted* PATH
103
+ * candidate so we only run a binary proven to be the CLI.
104
+ */
105
+ export declare function agyRespondsToVersion(bin: string): boolean;
106
+ export declare function resolveAgyBin(): string | null;
107
+ /** Non-blocking skip artifact: porch's verdict parser treats COMMENT as non-blocking. */
108
+ declare function agySkipContent(reason: string): string;
109
+ /**
110
+ * Run the `gemini` consult lane via the Antigravity CLI (`agy --print`).
111
+ * Preserves agentic file-reading (--sandbox --add-dir), folds the role into the
112
+ * prompt, and NEVER blocks the run: a missing/unauthed/invalid CLI or a
113
+ * timeout/error produces a non-blocking COMMENT skip instead of throwing.
114
+ */
115
+ declare function runAgyConsultation(queryText: string, role: string, workspaceRoot: string, outputPath?: string, metricsCtx?: MetricsContext): Promise<void>;
66
116
  /**
67
117
  * Get a compact diff stat summary and list of changed files.
68
118
  *
@@ -115,5 +165,5 @@ declare function buildPlanQuery(plan: ContentRef, spec: ContentRef | null): stri
115
165
  * Main consult entry point
116
166
  */
117
167
  export declare function consult(options: ConsultOptions): Promise<void>;
118
- export { getDiffStat as _getDiffStat, buildSpecQuery as _buildSpecQuery, buildPlanQuery as _buildPlanQuery, buildPRQuery as _buildPRQuery, composePRQueryText as _composePRQueryText, computePersistentOutputPath as _computePersistentOutputPath, MODEL_CONFIGS as _MODEL_CONFIGS, };
168
+ export { getDiffStat as _getDiffStat, buildSpecQuery as _buildSpecQuery, buildPlanQuery as _buildPlanQuery, buildPRQuery as _buildPRQuery, composePRQueryText as _composePRQueryText, computePersistentOutputPath as _computePersistentOutputPath, MODEL_CONFIGS as _MODEL_CONFIGS, MODEL_ALIASES as _MODEL_ALIASES, runAgyConsultation as _runAgyConsultation, agySkipContent as _agySkipContent, };
119
169
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/consult/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/consult/index.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@
9
9
  import * as fs from 'node:fs';
10
10
  import * as path from 'node:path';
11
11
  import { spawn, execSync, execFileSync } from 'node:child_process';
12
- import { tmpdir } from 'node:os';
12
+ import { tmpdir, homedir } from 'node:os';
13
13
  import chalk from 'chalk';
14
14
  import { query as claudeQuery } from '@anthropic-ai/claude-agent-sdk';
15
15
  import { Codex } from '@openai/codex-sdk';
@@ -20,7 +20,10 @@ import { MetricsDB } from './metrics.js';
20
20
  import { extractUsage, extractReviewText } from './usage-extractor.js';
21
21
  import { executeForgeCommandSync } from '../../lib/forge.js';
22
22
  const MODEL_CONFIGS = {
23
- gemini: { cli: 'gemini', args: ['--model', 'gemini-3.1-pro-preview'], envVar: 'GEMINI_SYSTEM_MD' },
23
+ // gemini dispatches to the Antigravity CLI (`agy`) via runAgyConsultation —
24
+ // this entry exists only for model validation and the `pro` alias; its
25
+ // cli/args are NOT used for dispatch (agy's binary path is resolved at runtime).
26
+ gemini: { cli: 'agy', args: [], envVar: null },
24
27
  hermes: { cli: 'hermes', args: ['chat', '-q'], envVar: null },
25
28
  };
26
29
  // Models that use an Agent SDK instead of CLI subprocess
@@ -381,6 +384,35 @@ export async function runCodexConsultation(queryText, role, workspaceRoot, outpu
381
384
  }
382
385
  }
383
386
  }
387
+ /**
388
+ * Build the env passed to the Claude Agent SDK subprocess for a consultation.
389
+ *
390
+ * Copies the given environment, but when a Claude subscription/OAuth token
391
+ * (`CLAUDE_CODE_OAUTH_TOKEN`) is present, strips `ANTHROPIC_API_KEY` and
392
+ * `ANTHROPIC_AUTH_TOKEN` from the *copy* (never the global `process.env`).
393
+ * The Agent SDK prioritizes the API key over the OAuth token, so leaving the
394
+ * key in would silently route CMAP/review traffic to the metered Opus API
395
+ * instead of the Claude subscription (issue #985).
396
+ *
397
+ * When no OAuth token is set, the API key is preserved so CI / key-only
398
+ * environments continue to authenticate.
399
+ *
400
+ * The deletion is scoped to this subprocess env only — other callers that need
401
+ * the API key (persona, dev:local) are unaffected.
402
+ */
403
+ export function buildClaudeConsultEnv(processEnv) {
404
+ const env = {};
405
+ for (const [key, value] of Object.entries(processEnv)) {
406
+ if (value !== undefined) {
407
+ env[key] = value;
408
+ }
409
+ }
410
+ if (env.CLAUDE_CODE_OAUTH_TOKEN) {
411
+ delete env.ANTHROPIC_API_KEY;
412
+ delete env.ANTHROPIC_AUTH_TOKEN;
413
+ }
414
+ return env;
415
+ }
384
416
  /**
385
417
  * Run Claude consultation via Agent SDK.
386
418
  * Uses the SDK's query() function instead of CLI subprocess.
@@ -397,12 +429,7 @@ async function runClaudeConsultation(queryText, role, workspaceRoot, outputPath,
397
429
  // the nesting guard. Restore it after the SDK call.
398
430
  const savedClaudeCode = process.env.CLAUDECODE;
399
431
  delete process.env.CLAUDECODE;
400
- const env = {};
401
- for (const [key, value] of Object.entries(process.env)) {
402
- if (value !== undefined) {
403
- env[key] = value;
404
- }
405
- }
432
+ const env = buildClaudeConsultEnv(process.env);
406
433
  try {
407
434
  const session = claudeQuery({
408
435
  prompt: queryText,
@@ -474,6 +501,265 @@ async function runClaudeConsultation(queryText, role, workspaceRoot, outputPath,
474
501
  }
475
502
  }
476
503
  }
504
+ // ── Antigravity CLI (`agy`) backend for the `gemini` lane ──────────────────
505
+ // Replaces the retiring Gemini CLI. agy is an agent (reads files from disk via
506
+ // --add-dir under --sandbox), OAuth-only, default model = Flash, plain-text
507
+ // output (no usage JSON). See spec/plan 778.
508
+ // Markers that indicate agy is NOT authenticated (it prints an OAuth URL and
509
+ // waits ~30s for an interactive login that can't complete headlessly). When
510
+ // seen, we terminate early and emit a non-blocking COMMENT skip.
511
+ export const AGY_OAUTH_MARKERS = [
512
+ 'accounts.google.com/o/oauth2',
513
+ 'Authentication required',
514
+ 'paste the authorization code',
515
+ 'Waiting for authentication',
516
+ ];
517
+ const AGY_PRINT_TIMEOUT = '5m'; // passed to `agy --print-timeout`
518
+ const AGY_TIMEOUT_MS = 6 * 60 * 1000; // Codev-owned hard cap (> agy's own timeout)
519
+ // OAuth banner appears before any review text; only scan the early stream.
520
+ const AGY_MARKER_SCAN_LIMIT = 8192;
521
+ // agy's own print-timeout message: on an agentic task that outruns --print-timeout,
522
+ // it returns this (often with a "monitoring the task" note) instead of a review.
523
+ // Treat it as a non-response → non-blocking skip rather than a garbage "review".
524
+ const AGY_NONRESPONSE_MARKER = 'timed out waiting for response';
525
+ /**
526
+ * Verify a path is the real headless `agy` CLI, not the Antigravity IDE
527
+ * launcher. The IDE ships `~/.antigravity/.../bin/agy` as a symlink to the
528
+ * Electron app binary (`Antigravity.app/.../antigravity`); resolving it and
529
+ * launching it would open the IDE, never produce a `--print` review. We reject
530
+ * by realpath WITHOUT executing anything (no risk of launching the GUI).
531
+ */
532
+ export function isRealAgyCli(p) {
533
+ try {
534
+ if (!fs.existsSync(p))
535
+ return false;
536
+ const real = fs.realpathSync(p);
537
+ if (real.includes('Antigravity.app'))
538
+ return false; // IDE app bundle
539
+ if (/[/\\]antigravity(\.exe)?$/.test(real))
540
+ return false; // IDE launcher binary
541
+ return true;
542
+ }
543
+ catch {
544
+ return false;
545
+ }
546
+ }
547
+ /**
548
+ * Resolve the real `agy` CLI binary deterministically — never trust a bare
549
+ * PATH lookup (a stale shell or the IDE symlink shadows the CLI). Prefers the
550
+ * official installer path, then a PATH `agy` verified not to be the IDE.
551
+ * Returns null if no valid headless CLI is found.
552
+ */
553
+ /**
554
+ * Positively verify a candidate behaves like the real headless agy CLI by
555
+ * running `--version` (read-only, fast). `isRealAgyCli` rejects the IDE launcher
556
+ * by realpath; this adds behavioral verification for an *untrusted* PATH
557
+ * candidate so we only run a binary proven to be the CLI.
558
+ */
559
+ export function agyRespondsToVersion(bin) {
560
+ try {
561
+ const out = execSync(`"${bin}" --version 2>/dev/null`, { encoding: 'utf-8', timeout: 5000 }).trim();
562
+ return out.length > 0;
563
+ }
564
+ catch {
565
+ return false;
566
+ }
567
+ }
568
+ export function resolveAgyBin() {
569
+ // Explicit override (advanced users / tests): use it if valid, never silently
570
+ // fall back to a different binary the user didn't ask for.
571
+ const override = process.env.CODEV_AGY_BIN;
572
+ if (override)
573
+ return isRealAgyCli(override) ? override : null;
574
+ // Canonical install path — trusted location; realpath-reject the IDE only.
575
+ const preferred = path.join(homedir(), '.local', 'bin', 'agy');
576
+ if (isRealAgyCli(preferred))
577
+ return preferred;
578
+ // A bare PATH `agy` is untrusted: require it to NOT be the IDE (realpath) AND
579
+ // to behave like the headless CLI (`--version`) before we'll run it.
580
+ try {
581
+ const found = execSync('command -v agy 2>/dev/null', { encoding: 'utf-8' }).trim();
582
+ if (found && isRealAgyCli(found) && agyRespondsToVersion(found))
583
+ return found;
584
+ }
585
+ catch {
586
+ // not on PATH
587
+ }
588
+ return null;
589
+ }
590
+ /** Non-blocking skip artifact: porch's verdict parser treats COMMENT as non-blocking. */
591
+ function agySkipContent(reason) {
592
+ return [
593
+ '---',
594
+ 'VERDICT: COMMENT',
595
+ `SUMMARY: Gemini lane skipped — ${reason}`,
596
+ 'CONFIDENCE: LOW',
597
+ '---',
598
+ '',
599
+ `The Gemini (Antigravity \`agy\`) reviewer was skipped: ${reason}.`,
600
+ 'This is a non-blocking skip; the remaining reviewers still apply. To enable the',
601
+ 'Gemini lane, install the CLI (https://antigravity.google/cli/install.sh) and run',
602
+ '`agy` once to sign in.',
603
+ ].join('\n');
604
+ }
605
+ /**
606
+ * Per-process sandbox temp dir for consult artifacts (the PR diff written by
607
+ * buildPRQuery, and the large-prompt file written by runAgyConsultation).
608
+ *
609
+ * Created once per CLI invocation (each `consult` run is its own process), so the
610
+ * sandboxed `agy` reviewer can be granted exactly this directory via `--add-dir`
611
+ * instead of the entire OS temp dir — keeping the grant scoped to the artifacts
612
+ * this flow creates. `mkdtempSync` yields a private, user-owned dir; callers still
613
+ * write with mode 0o600 / flag 'wx' to defeat symlink/clobber races.
614
+ */
615
+ let _consultSandboxDir = null;
616
+ function consultSandboxDir() {
617
+ if (!_consultSandboxDir) {
618
+ _consultSandboxDir = fs.mkdtempSync(path.join(tmpdir(), 'codev-consult-'));
619
+ }
620
+ return _consultSandboxDir;
621
+ }
622
+ function writeConsultOutput(outputPath, content) {
623
+ if (!outputPath || content.length === 0)
624
+ return;
625
+ const outputDir = path.dirname(outputPath);
626
+ if (!fs.existsSync(outputDir))
627
+ fs.mkdirSync(outputDir, { recursive: true });
628
+ fs.writeFileSync(outputPath, content);
629
+ console.error(`\nOutput written to: ${outputPath}`);
630
+ }
631
+ function recordAgyMetrics(metricsCtx, startTime, exitCode, errorMessage) {
632
+ if (!metricsCtx)
633
+ return;
634
+ recordMetrics(metricsCtx, {
635
+ durationSeconds: (Date.now() - startTime) / 1000,
636
+ // agy --print emits plain text, no token usage → cost rows degrade gracefully (null).
637
+ inputTokens: null,
638
+ cachedInputTokens: null,
639
+ outputTokens: null,
640
+ costUsd: null,
641
+ exitCode,
642
+ errorMessage,
643
+ });
644
+ }
645
+ /**
646
+ * Run the `gemini` consult lane via the Antigravity CLI (`agy --print`).
647
+ * Preserves agentic file-reading (--sandbox --add-dir), folds the role into the
648
+ * prompt, and NEVER blocks the run: a missing/unauthed/invalid CLI or a
649
+ * timeout/error produces a non-blocking COMMENT skip instead of throwing.
650
+ */
651
+ async function runAgyConsultation(queryText, role, workspaceRoot, outputPath, metricsCtx) {
652
+ const startTime = Date.now();
653
+ const bin = resolveAgyBin();
654
+ if (!bin) {
655
+ const reason = 'agy CLI not found (install: https://antigravity.google/cli/install.sh)';
656
+ const content = agySkipContent(reason);
657
+ process.stdout.write(content);
658
+ writeConsultOutput(outputPath, content);
659
+ recordAgyMetrics(metricsCtx, startTime, 0, reason);
660
+ console.error(`\n[gemini (agy) skipped: ${reason}]`);
661
+ return;
662
+ }
663
+ // agy has no system-prompt flag — fold the role into the prompt (hermes precedent).
664
+ const prompt = `${role}\n\n---\n\n${queryText}`;
665
+ // Grant the sandboxed agent read access to the workspace AND the dedicated consult
666
+ // sandbox dir (where buildPRQuery writes the diff and, below, a large-prompt file
667
+ // lands) — NOT the entire OS temp dir, which would over-expose unrelated /tmp files.
668
+ const addDirs = [workspaceRoot, consultSandboxDir()];
669
+ let tempFile = null;
670
+ let promptArg = prompt;
671
+ // Large prompts can exceed ARG_MAX (E2BIG) — write to a temp file and point agy at it.
672
+ if (prompt.length > CLI_PROMPT_INLINE_MAX_CHARS) {
673
+ tempFile = path.join(consultSandboxDir(), `codev-consult-prompt-${Date.now()}.md`);
674
+ fs.writeFileSync(tempFile, prompt);
675
+ promptArg = [
676
+ `Read the full consultation prompt from this file: ${tempFile}`,
677
+ 'You have file access. Read files directly from disk to review code.',
678
+ ].join('\n\n');
679
+ }
680
+ const args = ['--print', '--sandbox', '--print-timeout', AGY_PRINT_TIMEOUT];
681
+ for (const d of addDirs)
682
+ args.push('--add-dir', d);
683
+ args.push(promptArg);
684
+ const cleanup = () => {
685
+ if (tempFile && fs.existsSync(tempFile)) {
686
+ try {
687
+ fs.unlinkSync(tempFile);
688
+ }
689
+ catch { /* best-effort */ }
690
+ }
691
+ };
692
+ return new Promise((resolve) => {
693
+ const proc = spawn(bin, args, {
694
+ cwd: workspaceRoot,
695
+ stdio: ['ignore', 'pipe', 'pipe'],
696
+ });
697
+ const outChunks = [];
698
+ let scanBuf = '';
699
+ let settled = false;
700
+ const settleSkip = (reason, exitCode = 0) => {
701
+ if (settled)
702
+ return;
703
+ settled = true;
704
+ clearTimeout(timer);
705
+ try {
706
+ proc.kill('SIGTERM');
707
+ }
708
+ catch { /* already gone */ }
709
+ cleanup();
710
+ const content = agySkipContent(reason);
711
+ process.stdout.write(content);
712
+ writeConsultOutput(outputPath, content);
713
+ recordAgyMetrics(metricsCtx, startTime, exitCode, reason);
714
+ console.error(`\n[gemini (agy) skipped: ${reason}]`);
715
+ resolve();
716
+ };
717
+ const timer = setTimeout(() => settleSkip('agy timed out (no response)', 1), AGY_TIMEOUT_MS);
718
+ const watch = (buf, isStdout) => {
719
+ if (isStdout)
720
+ outChunks.push(buf);
721
+ if (scanBuf.length < AGY_MARKER_SCAN_LIMIT) {
722
+ scanBuf += buf.toString('utf-8');
723
+ if (AGY_OAUTH_MARKERS.some((m) => scanBuf.includes(m))) {
724
+ settleSkip('agy not authenticated — run `agy` once to sign in (OAuth)', 1);
725
+ }
726
+ }
727
+ };
728
+ proc.stdout?.on('data', (b) => watch(b, true));
729
+ proc.stderr?.on('data', (b) => watch(b, false));
730
+ proc.on('error', (err) => {
731
+ settleSkip(`agy failed to start: ${err.message}`, 1);
732
+ });
733
+ proc.on('close', (code) => {
734
+ if (settled)
735
+ return;
736
+ settled = true;
737
+ clearTimeout(timer);
738
+ cleanup();
739
+ const raw = Buffer.concat(outChunks).toString('utf-8').trim();
740
+ if (code !== 0 || raw.length === 0 || raw.includes(AGY_NONRESPONSE_MARKER)) {
741
+ const reason = code !== 0
742
+ ? `agy exited with code ${code}`
743
+ : raw.includes(AGY_NONRESPONSE_MARKER)
744
+ ? 'agy timed out producing the review'
745
+ : 'agy produced no review output';
746
+ const content = agySkipContent(reason);
747
+ process.stdout.write(content);
748
+ writeConsultOutput(outputPath, content);
749
+ recordAgyMetrics(metricsCtx, startTime, code ?? 1, reason);
750
+ console.error(`\n[gemini (agy) skipped: ${reason}]`);
751
+ resolve();
752
+ return;
753
+ }
754
+ // Plain-text stdout IS the review.
755
+ process.stdout.write(raw);
756
+ writeConsultOutput(outputPath, raw);
757
+ recordAgyMetrics(metricsCtx, startTime, 0, null);
758
+ console.error(`\n[gemini (agy) completed in ${((Date.now() - startTime) / 1000).toFixed(1)}s]`);
759
+ resolve();
760
+ });
761
+ });
762
+ }
477
763
  /**
478
764
  * Run the consultation — dispatches to the correct model runner.
479
765
  */
@@ -495,6 +781,14 @@ async function runConsultation(model, query, workspaceRoot, role, outputPath, me
495
781
  console.error(`\n[${model} completed in ${duration.toFixed(1)}s]`);
496
782
  return;
497
783
  }
784
+ // gemini lane → Antigravity CLI (`agy`); handles its own logging, metrics,
785
+ // and non-blocking skip (see runAgyConsultation).
786
+ if (model === 'gemini') {
787
+ const startTime = Date.now();
788
+ await runAgyConsultation(query, role, workspaceRoot, outputPath, metricsCtx);
789
+ logQuery(workspaceRoot, model, query, (Date.now() - startTime) / 1000);
790
+ return;
791
+ }
498
792
  const config = MODEL_CONFIGS[model];
499
793
  if (!config) {
500
794
  throw new Error(`Unknown model: ${model}`);
@@ -504,31 +798,8 @@ async function runConsultation(model, query, workspaceRoot, role, outputPath, me
504
798
  throw new Error(`${config.cli} not found. Please install it first.`);
505
799
  }
506
800
  let tempFile = null;
507
- const env = {};
508
801
  let cmd;
509
- // When true, the query is written to the child's stdin instead of argv.
510
- // Used for gemini to avoid V8 heap exhaustion on large prompts (#680).
511
- let stdinPayload = null;
512
- if (model === 'gemini') {
513
- // Gemini uses GEMINI_SYSTEM_MD env var for role
514
- tempFile = path.join(tmpdir(), `codev-role-${Date.now()}.md`);
515
- fs.writeFileSync(tempFile, role);
516
- env['GEMINI_SYSTEM_MD'] = tempFile;
517
- // Bugfix #680: gemini-cli v0.37.x crashes on large PR diffs (>500KB) due to
518
- // V8 old-space exhaustion in the spawned subprocess. Mitigations:
519
- // 1. Bump heap via NODE_OPTIONS (survives gemini-cli's internal relaunch).
520
- // 2. Pipe the prompt via stdin instead of argv — avoids ARG_MAX and keeps
521
- // V8 from holding the full prompt buffer twice.
522
- env['NODE_OPTIONS'] = [process.env.NODE_OPTIONS ?? '', '--max-old-space-size=8192']
523
- .join(' ')
524
- .trim();
525
- stdinPayload = query;
526
- // Use --output-format json to capture token usage/cost in structured output.
527
- // Never use --yolo — it allows Gemini to write files (#370).
528
- // No positional query arg: prompt arrives on stdin (triggers non-interactive mode).
529
- cmd = [config.cli, '--output-format', 'json', ...config.args];
530
- }
531
- else if (model === 'hermes') {
802
+ if (model === 'hermes') {
532
803
  // Hermes does not have a dedicated system prompt flag for single-shot mode.
533
804
  // Include role context at the top of the prompt.
534
805
  const hermesPrompt = `${role}\n\n---\n\n${query}`;
@@ -551,27 +822,14 @@ async function runConsultation(model, query, workspaceRoot, role, outputPath, me
551
822
  else {
552
823
  throw new Error(`Unknown model: ${model}`);
553
824
  }
554
- // Execute with passthrough stdio.
555
- // Use 'ignore' for stdin when no payload — prevents blocking when spawned as subprocess.
556
- // Use 'pipe' when we need to stream the prompt in (e.g. gemini, see #680).
557
- const fullEnv = { ...process.env, ...env };
825
+ // Execute with passthrough stdio. stdin is 'ignore' (hermes passes its prompt
826
+ // via argv) — prevents blocking when spawned as a subprocess.
558
827
  const startTime = Date.now();
559
- const stdinMode = stdinPayload !== null ? 'pipe' : 'ignore';
560
828
  return new Promise((resolve, reject) => {
561
829
  const proc = spawn(cmd[0], cmd.slice(1), {
562
830
  cwd: workspaceRoot,
563
- env: fullEnv,
564
- stdio: [stdinMode, 'pipe', 'inherit'],
831
+ stdio: ['ignore', 'pipe', 'inherit'],
565
832
  });
566
- if (stdinPayload !== null && proc.stdin) {
567
- proc.stdin.on('error', (err) => {
568
- // EPIPE can happen if the child exits before reading all input — not fatal.
569
- if (err.code !== 'EPIPE') {
570
- reject(err);
571
- }
572
- });
573
- proc.stdin.end(stdinPayload, 'utf-8');
574
- }
575
833
  const chunks = [];
576
834
  if (proc.stdout) {
577
835
  proc.stdout.on('data', (chunk) => {
@@ -774,9 +1032,10 @@ function buildPRQuery(prId) {
774
1032
  const prData = fetchPRData(prId);
775
1033
  const diff = fetchPRDiff(prId);
776
1034
  // Private-per-user dir to avoid world-readable /tmp diffs + symlink/clobber
777
- // races: mkdtempSync creates a fresh dir owned by us; writeFileSync with
1035
+ // races: consultSandboxDir() is a fresh mkdtempSync dir owned by us (and the
1036
+ // only temp dir granted to the sandboxed agy reviewer); writeFileSync with
778
1037
  // flag 'wx' refuses to follow a symlink or overwrite an existing file.
779
- const diffDir = fs.mkdtempSync(path.join(tmpdir(), 'codev-pr-'));
1038
+ const diffDir = consultSandboxDir();
780
1039
  const diffPath = path.join(diffDir, `pr-${prId}.diff`);
781
1040
  fs.writeFileSync(diffPath, diff, { encoding: 'utf-8', mode: 0o600, flag: 'wx' });
782
1041
  const diffBytes = Buffer.byteLength(diff, 'utf-8');
@@ -1400,5 +1659,5 @@ export async function consult(options) {
1400
1659
  await runConsultation(model, query, workspaceRoot, role, outputPath, metricsCtx, isGeneralMode);
1401
1660
  }
1402
1661
  // Exported for testing
1403
- export { getDiffStat as _getDiffStat, buildSpecQuery as _buildSpecQuery, buildPlanQuery as _buildPlanQuery, buildPRQuery as _buildPRQuery, composePRQueryText as _composePRQueryText, computePersistentOutputPath as _computePersistentOutputPath, MODEL_CONFIGS as _MODEL_CONFIGS, };
1662
+ export { getDiffStat as _getDiffStat, buildSpecQuery as _buildSpecQuery, buildPlanQuery as _buildPlanQuery, buildPRQuery as _buildPRQuery, composePRQueryText as _composePRQueryText, computePersistentOutputPath as _computePersistentOutputPath, MODEL_CONFIGS as _MODEL_CONFIGS, MODEL_ALIASES as _MODEL_ALIASES, runAgyConsultation as _runAgyConsultation, agySkipContent as _agySkipContent, };
1404
1663
  //# sourceMappingURL=index.js.map