aicodeman 1.19.7 → 1.20.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 (142) hide show
  1. package/dist/git-clone.d.ts +7 -0
  2. package/dist/git-clone.d.ts.map +1 -1
  3. package/dist/git-clone.js +10 -2
  4. package/dist/git-clone.js.map +1 -1
  5. package/dist/ralph-loop.d.ts.map +1 -1
  6. package/dist/ralph-loop.js +8 -1
  7. package/dist/ralph-loop.js.map +1 -1
  8. package/dist/session.d.ts +34 -0
  9. package/dist/session.d.ts.map +1 -1
  10. package/dist/session.js +61 -1
  11. package/dist/session.js.map +1 -1
  12. package/dist/tmux-manager.d.ts.map +1 -1
  13. package/dist/tmux-manager.js +11 -8
  14. package/dist/tmux-manager.js.map +1 -1
  15. package/dist/types/session.d.ts +8 -0
  16. package/dist/types/session.d.ts.map +1 -1
  17. package/dist/types/session.js.map +1 -1
  18. package/dist/types/update.d.ts +45 -0
  19. package/dist/types/update.d.ts.map +1 -1
  20. package/dist/utils/antigravity-cli-resolver.d.ts +4 -0
  21. package/dist/utils/antigravity-cli-resolver.d.ts.map +1 -1
  22. package/dist/utils/antigravity-cli-resolver.js +17 -29
  23. package/dist/utils/antigravity-cli-resolver.js.map +1 -1
  24. package/dist/utils/claude-cli-resolver.d.ts +1 -0
  25. package/dist/utils/claude-cli-resolver.d.ts.map +1 -1
  26. package/dist/utils/claude-cli-resolver.js +15 -28
  27. package/dist/utils/claude-cli-resolver.js.map +1 -1
  28. package/dist/utils/cli-executable-resolver.d.ts +98 -0
  29. package/dist/utils/cli-executable-resolver.d.ts.map +1 -0
  30. package/dist/utils/cli-executable-resolver.js +229 -0
  31. package/dist/utils/cli-executable-resolver.js.map +1 -0
  32. package/dist/utils/codex-cli-resolver.d.ts +1 -0
  33. package/dist/utils/codex-cli-resolver.d.ts.map +1 -1
  34. package/dist/utils/codex-cli-resolver.js +8 -30
  35. package/dist/utils/codex-cli-resolver.js.map +1 -1
  36. package/dist/utils/gemini-cli-resolver.d.ts +1 -0
  37. package/dist/utils/gemini-cli-resolver.d.ts.map +1 -1
  38. package/dist/utils/gemini-cli-resolver.js +8 -29
  39. package/dist/utils/gemini-cli-resolver.js.map +1 -1
  40. package/dist/utils/index.d.ts +6 -6
  41. package/dist/utils/index.d.ts.map +1 -1
  42. package/dist/utils/index.js +6 -6
  43. package/dist/utils/index.js.map +1 -1
  44. package/dist/utils/opencode-cli-resolver.d.ts +1 -0
  45. package/dist/utils/opencode-cli-resolver.d.ts.map +1 -1
  46. package/dist/utils/opencode-cli-resolver.js +8 -31
  47. package/dist/utils/opencode-cli-resolver.js.map +1 -1
  48. package/dist/utils/pi-cli-resolver.d.ts +12 -3
  49. package/dist/utils/pi-cli-resolver.d.ts.map +1 -1
  50. package/dist/utils/pi-cli-resolver.js +40 -55
  51. package/dist/utils/pi-cli-resolver.js.map +1 -1
  52. package/dist/web/approval-inbox.d.ts +45 -8
  53. package/dist/web/approval-inbox.d.ts.map +1 -1
  54. package/dist/web/approval-inbox.js +116 -28
  55. package/dist/web/approval-inbox.js.map +1 -1
  56. package/dist/web/public/admin-ui.js.gz +0 -0
  57. package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
  58. package/dist/web/public/app.56c520ff.js.gz +0 -0
  59. package/dist/web/public/approvals-ui.js.gz +0 -0
  60. package/dist/web/public/{constants.dc5d04bb.js → constants.5abbd823.js} +53 -0
  61. package/dist/web/public/constants.5abbd823.js.br +0 -0
  62. package/dist/web/public/constants.5abbd823.js.gz +0 -0
  63. package/dist/web/public/cron-ui.js.gz +0 -0
  64. package/dist/web/public/entrance-animations.js.gz +0 -0
  65. package/dist/web/public/home-sessions.js.gz +0 -0
  66. package/dist/web/public/i18n.196a992e.js +1 -0
  67. package/dist/web/public/i18n.196a992e.js.br +0 -0
  68. package/dist/web/public/i18n.196a992e.js.gz +0 -0
  69. package/dist/web/public/image-input.ee16ad88.js.gz +0 -0
  70. package/dist/web/public/index.html +18 -5
  71. package/dist/web/public/index.html.br +0 -0
  72. package/dist/web/public/index.html.gz +0 -0
  73. package/dist/web/public/input-cjk.63794d0b.js.gz +0 -0
  74. package/dist/web/public/keyboard-accessory.0454a3e9.js.gz +0 -0
  75. package/dist/web/public/mobile-handlers.0f83a608.js.gz +0 -0
  76. package/dist/web/public/mobile-overview.js.gz +0 -0
  77. package/dist/web/public/mobile.49aeb17e.css.gz +0 -0
  78. package/dist/web/public/notification-manager.5d229063.js.gz +0 -0
  79. package/dist/web/public/orchestrator-panel.js.gz +0 -0
  80. package/dist/web/public/panels-ui.5e97a36e.js.gz +0 -0
  81. package/dist/web/public/ralph-panel.6de2d0f8.js.gz +0 -0
  82. package/dist/web/public/ralph-wizard.13a1831e.js.gz +0 -0
  83. package/dist/web/public/readmymind-ui.js.gz +0 -0
  84. package/dist/web/public/respawn-ui.ff0dae4c.js.gz +0 -0
  85. package/dist/web/public/sanitize-html.bc7078d6.js.gz +0 -0
  86. package/dist/web/public/session-lineage.js.gz +0 -0
  87. package/dist/web/public/session-ui.71a0ce9a.js.gz +0 -0
  88. package/dist/web/public/settings-ui.1a62e935.js +67 -0
  89. package/dist/web/public/settings-ui.1a62e935.js.br +0 -0
  90. package/dist/web/public/settings-ui.1a62e935.js.gz +0 -0
  91. package/dist/web/public/styles.68f9e118.css.gz +0 -0
  92. package/dist/web/public/subagent-windows.e6ca799f.js.gz +0 -0
  93. package/dist/web/public/sw.js.gz +0 -0
  94. package/dist/web/public/terminal-ui.5f4158b7.js +2 -0
  95. package/dist/web/public/terminal-ui.5f4158b7.js.br +0 -0
  96. package/dist/web/public/terminal-ui.5f4158b7.js.gz +0 -0
  97. package/dist/web/public/ultracode-panel.js.gz +0 -0
  98. package/dist/web/public/ultracode-windows.js.gz +0 -0
  99. package/dist/web/public/upload.html.gz +0 -0
  100. package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
  101. package/dist/web/public/vendor/marked.min.js.gz +0 -0
  102. package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
  103. package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
  104. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
  105. package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
  106. package/dist/web/public/vendor/xterm-predictive-echo.bd6882b8.js.gz +0 -0
  107. package/dist/web/public/vendor/xterm-zerolag-input.6fee72f2.js.gz +0 -0
  108. package/dist/web/public/vendor/xterm.css.gz +0 -0
  109. package/dist/web/public/vendor/xterm.min.js.gz +0 -0
  110. package/dist/web/public/voice-input.4ec670b0.js.gz +0 -0
  111. package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
  112. package/dist/web/public/webview-tabs.js.gz +0 -0
  113. package/dist/web/repo-status.d.ts +124 -0
  114. package/dist/web/repo-status.d.ts.map +1 -0
  115. package/dist/web/repo-status.js +353 -0
  116. package/dist/web/repo-status.js.map +1 -0
  117. package/dist/web/response-viewer-transcript.d.ts +12 -0
  118. package/dist/web/response-viewer-transcript.d.ts.map +1 -0
  119. package/dist/web/response-viewer-transcript.js +345 -0
  120. package/dist/web/response-viewer-transcript.js.map +1 -0
  121. package/dist/web/routes/session-routes.d.ts.map +1 -1
  122. package/dist/web/routes/session-routes.js +41 -22
  123. package/dist/web/routes/session-routes.js.map +1 -1
  124. package/dist/web/routes/system-routes.d.ts.map +1 -1
  125. package/dist/web/routes/system-routes.js +5 -0
  126. package/dist/web/routes/system-routes.js.map +1 -1
  127. package/dist/web/session-listener-wiring.d.ts +1 -0
  128. package/dist/web/session-listener-wiring.d.ts.map +1 -1
  129. package/dist/web/session-listener-wiring.js +26 -3
  130. package/dist/web/session-listener-wiring.js.map +1 -1
  131. package/package.json +1 -1
  132. package/dist/web/public/constants.dc5d04bb.js.br +0 -0
  133. package/dist/web/public/constants.dc5d04bb.js.gz +0 -0
  134. package/dist/web/public/i18n.6a46f014.js +0 -1
  135. package/dist/web/public/i18n.6a46f014.js.br +0 -0
  136. package/dist/web/public/i18n.6a46f014.js.gz +0 -0
  137. package/dist/web/public/settings-ui.b62c70a3.js +0 -67
  138. package/dist/web/public/settings-ui.b62c70a3.js.br +0 -0
  139. package/dist/web/public/settings-ui.b62c70a3.js.gz +0 -0
  140. package/dist/web/public/terminal-ui.4723f5d4.js +0 -4
  141. package/dist/web/public/terminal-ui.4723f5d4.js.br +0 -0
  142. package/dist/web/public/terminal-ui.4723f5d4.js.gz +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"gemini-cli-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/gemini-cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAqBH;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAyBhD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C"}
1
+ {"version":3,"file":"gemini-cli-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/gemini-cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmBH;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEhD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD"}
@@ -6,11 +6,9 @@
6
6
  *
7
7
  * @module utils/gemini-cli-resolver
8
8
  */
9
- import { execSync } from 'node:child_process';
10
- import { existsSync } from 'node:fs';
11
- import { dirname, join } from 'node:path';
9
+ import { join } from 'node:path';
12
10
  import { homedir } from 'node:os';
13
- import { EXEC_TIMEOUT_MS } from '../config/exec-timeout.js';
11
+ import { createCliExecutableResolver, formatCliNotFoundMessage } from './cli-executable-resolver.js';
14
12
  /** Common directories where the Gemini CLI binary may be installed */
15
13
  const GEMINI_SEARCH_DIRS = [
16
14
  join(homedir(), '.gemini', 'bin'),
@@ -20,8 +18,8 @@ const GEMINI_SEARCH_DIRS = [
20
18
  join(homedir(), '.npm-global', 'bin'),
21
19
  join(homedir(), 'bin'),
22
20
  ];
23
- /** Cached directory containing the gemini binary (empty string = searched but not found) */
24
- let _geminiDir = null;
21
+ const geminiResolver = createCliExecutableResolver({ binary: 'gemini', searchDirs: GEMINI_SEARCH_DIRS });
22
+ const GEMINI_NOT_FOUND = 'Gemini CLI not found. Install with: npm install -g @google/gemini-cli';
25
23
  /**
26
24
  * Finds the directory containing the `gemini` binary.
27
25
  * Checks `which gemini` first, then falls back to common install locations.
@@ -29,29 +27,7 @@ let _geminiDir = null;
29
27
  * @returns Directory path, or null if not found
30
28
  */
31
29
  export function resolveGeminiDir() {
32
- if (_geminiDir !== null)
33
- return _geminiDir || null;
34
- try {
35
- const result = execSync('which gemini', {
36
- encoding: 'utf-8',
37
- timeout: EXEC_TIMEOUT_MS,
38
- }).trim();
39
- if (result && existsSync(result)) {
40
- _geminiDir = dirname(result);
41
- return _geminiDir;
42
- }
43
- }
44
- catch {
45
- // Gemini not in PATH, will check common locations
46
- }
47
- for (const dir of GEMINI_SEARCH_DIRS) {
48
- if (existsSync(join(dir, 'gemini'))) {
49
- _geminiDir = dir;
50
- return _geminiDir;
51
- }
52
- }
53
- _geminiDir = '';
54
- return null;
30
+ return geminiResolver.resolve()?.directory ?? null;
55
31
  }
56
32
  /**
57
33
  * Check if Gemini CLI is available on the system.
@@ -59,4 +35,7 @@ export function resolveGeminiDir() {
59
35
  export function isGeminiAvailable() {
60
36
  return resolveGeminiDir() !== null;
61
37
  }
38
+ export function getGeminiNotFoundMessage() {
39
+ return formatCliNotFoundMessage(GEMINI_NOT_FOUND, geminiResolver.diagnostics());
40
+ }
62
41
  //# sourceMappingURL=gemini-cli-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gemini-cli-resolver.js","sourceRoot":"","sources":["../../src/utils/gemini-cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,sEAAsE;AACtE,MAAM,kBAAkB,GAAG;IACzB,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC;IACjC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC;IAChC,gBAAgB;IAChB,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,KAAK,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC;CACvB,CAAC;AAEF,4FAA4F;AAC5F,IAAI,UAAU,GAAkB,IAAI,CAAC;AAErC;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,UAAU,IAAI,IAAI,CAAC;IAEnD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,EAAE;YACtC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,eAAe;SACzB,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;YAC7B,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kDAAkD;IACpD,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACrC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;YACpC,UAAU,GAAG,GAAG,CAAC;YACjB,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IAED,UAAU,GAAG,EAAE,CAAC;IAChB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,gBAAgB,EAAE,KAAK,IAAI,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"gemini-cli-resolver.js","sourceRoot":"","sources":["../../src/utils/gemini-cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAErG,sEAAsE;AACtE,MAAM,kBAAkB,GAAG;IACzB,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC;IACjC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC;IAChC,gBAAgB;IAChB,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,KAAK,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC;CACvB,CAAC;AAEF,MAAM,cAAc,GAAG,2BAA2B,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC,CAAC;AACzG,MAAM,gBAAgB,GAAG,uEAAuE,CAAC;AAEjG;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,cAAc,CAAC,OAAO,EAAE,EAAE,SAAS,IAAI,IAAI,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,gBAAgB,EAAE,KAAK,IAAI,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,OAAO,wBAAwB,CAAC,gBAAgB,EAAE,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;AAClF,CAAC"}
@@ -18,13 +18,13 @@ export { stringSimilarity, fuzzyPhraseMatch, todoContentHash } from './string-si
18
18
  export { assertNever } from './type-safety.js';
19
19
  export { wrapWithNice } from './nice-wrapper.js';
20
20
  export { resolveLocalShell, loginShellArgs } from './shell-resolver.js';
21
- export { findClaudeDir, getAugmentedPath, getClaudeCliVersion, getClaudeBinaryPath } from './claude-cli-resolver.js';
21
+ export { findClaudeDir, getAugmentedPath, getClaudeCliVersion, getClaudeBinaryPath, getClaudeNotFoundMessage, } from './claude-cli-resolver.js';
22
22
  export { spawnPtyWithHelperRepair } from './node-pty-repair.js';
23
- export { resolveOpenCodeDir } from './opencode-cli-resolver.js';
24
- export { resolveCodexDir, isCodexAvailable } from './codex-cli-resolver.js';
25
- export { resolveGeminiDir, isGeminiAvailable } from './gemini-cli-resolver.js';
26
- export { resolveAntigravityDir, isAntigravityAvailable } from './antigravity-cli-resolver.js';
27
- export { resolvePiDir, isPiAvailable, getPiCliVersion } from './pi-cli-resolver.js';
23
+ export { resolveOpenCodeDir, getOpenCodeNotFoundMessage } from './opencode-cli-resolver.js';
24
+ export { resolveCodexDir, isCodexAvailable, getCodexNotFoundMessage } from './codex-cli-resolver.js';
25
+ export { resolveGeminiDir, isGeminiAvailable, getGeminiNotFoundMessage } from './gemini-cli-resolver.js';
26
+ export { resolveAntigravityDir, isAntigravityAvailable, getAntigravityNotFoundMessage, } from './antigravity-cli-resolver.js';
27
+ export { resolvePiDir, isPiAvailable, getPiCliVersion, getPiNotFoundMessage } from './pi-cli-resolver.js';
28
28
  export { compileFileQuery, matchFileQuery } from './file-query.js';
29
29
  export type { FileQueryMatcher } from './file-query.js';
30
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC9F,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -17,12 +17,12 @@ export { stringSimilarity, fuzzyPhraseMatch, todoContentHash } from './string-si
17
17
  export { assertNever } from './type-safety.js';
18
18
  export { wrapWithNice } from './nice-wrapper.js';
19
19
  export { resolveLocalShell, loginShellArgs } from './shell-resolver.js';
20
- export { findClaudeDir, getAugmentedPath, getClaudeCliVersion, getClaudeBinaryPath } from './claude-cli-resolver.js';
20
+ export { findClaudeDir, getAugmentedPath, getClaudeCliVersion, getClaudeBinaryPath, getClaudeNotFoundMessage, } from './claude-cli-resolver.js';
21
21
  export { spawnPtyWithHelperRepair } from './node-pty-repair.js';
22
- export { resolveOpenCodeDir } from './opencode-cli-resolver.js';
23
- export { resolveCodexDir, isCodexAvailable } from './codex-cli-resolver.js';
24
- export { resolveGeminiDir, isGeminiAvailable } from './gemini-cli-resolver.js';
25
- export { resolveAntigravityDir, isAntigravityAvailable } from './antigravity-cli-resolver.js';
26
- export { resolvePiDir, isPiAvailable, getPiCliVersion } from './pi-cli-resolver.js';
22
+ export { resolveOpenCodeDir, getOpenCodeNotFoundMessage } from './opencode-cli-resolver.js';
23
+ export { resolveCodexDir, isCodexAvailable, getCodexNotFoundMessage } from './codex-cli-resolver.js';
24
+ export { resolveGeminiDir, isGeminiAvailable, getGeminiNotFoundMessage } from './gemini-cli-resolver.js';
25
+ export { resolveAntigravityDir, isAntigravityAvailable, getAntigravityNotFoundMessage, } from './antigravity-cli-resolver.js';
26
+ export { resolvePiDir, isPiAvailable, getPiCliVersion, getPiNotFoundMessage } from './pi-cli-resolver.js';
27
27
  export { compileFileQuery, matchFileQuery } from './file-query.js';
28
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC9F,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
@@ -18,4 +18,5 @@ export declare function resolveOpenCodeDir(): string | null;
18
18
  * Check if OpenCode CLI is available on the system.
19
19
  */
20
20
  export declare function isOpenCodeAvailable(): boolean;
21
+ export declare function getOpenCodeNotFoundMessage(): string;
21
22
  //# sourceMappingURL=opencode-cli-resolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-cli-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/opencode-cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAsBH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CA2BlD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C"}
1
+ {"version":3,"file":"opencode-cli-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/opencode-cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAoBH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAElD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD"}
@@ -6,11 +6,9 @@
6
6
  *
7
7
  * @module utils/opencode-cli-resolver
8
8
  */
9
- import { execSync } from 'node:child_process';
10
- import { existsSync } from 'node:fs';
11
- import { dirname, join } from 'node:path';
9
+ import { join } from 'node:path';
12
10
  import { homedir } from 'node:os';
13
- import { EXEC_TIMEOUT_MS } from '../config/exec-timeout.js';
11
+ import { createCliExecutableResolver, formatCliNotFoundMessage } from './cli-executable-resolver.js';
14
12
  /** Common directories where the OpenCode CLI binary may be installed */
15
13
  const OPENCODE_SEARCH_DIRS = [
16
14
  join(homedir(), '.opencode', 'bin'), // Default install location
@@ -21,8 +19,8 @@ const OPENCODE_SEARCH_DIRS = [
21
19
  join(homedir(), '.npm-global', 'bin'), // npm global
22
20
  join(homedir(), 'bin'), // User bin
23
21
  ];
24
- /** Cached directory containing the opencode binary (empty string = searched but not found) */
25
- let _openCodeDir = null;
22
+ const openCodeResolver = createCliExecutableResolver({ binary: 'opencode', searchDirs: OPENCODE_SEARCH_DIRS });
23
+ const OPENCODE_NOT_FOUND = 'OpenCode CLI not found. Install with: curl -fsSL https://opencode.ai/install | bash';
26
24
  /**
27
25
  * Finds the directory containing the `opencode` binary.
28
26
  * Checks `which opencode` first, then falls back to common install locations.
@@ -31,31 +29,7 @@ let _openCodeDir = null;
31
29
  * @returns Directory path, or null if not found
32
30
  */
33
31
  export function resolveOpenCodeDir() {
34
- if (_openCodeDir !== null)
35
- return _openCodeDir || null;
36
- // Try `which` first (respects current PATH)
37
- try {
38
- const result = execSync('which opencode', {
39
- encoding: 'utf-8',
40
- timeout: EXEC_TIMEOUT_MS,
41
- }).trim();
42
- if (result && existsSync(result)) {
43
- _openCodeDir = dirname(result);
44
- return _openCodeDir;
45
- }
46
- }
47
- catch {
48
- // OpenCode not in PATH, will check common locations
49
- }
50
- // Fallback: check common installation directories
51
- for (const dir of OPENCODE_SEARCH_DIRS) {
52
- if (existsSync(join(dir, 'opencode'))) {
53
- _openCodeDir = dir;
54
- return _openCodeDir;
55
- }
56
- }
57
- _openCodeDir = ''; // mark as searched, not found
58
- return null;
32
+ return openCodeResolver.resolve()?.directory ?? null;
59
33
  }
60
34
  /**
61
35
  * Check if OpenCode CLI is available on the system.
@@ -63,4 +37,7 @@ export function resolveOpenCodeDir() {
63
37
  export function isOpenCodeAvailable() {
64
38
  return resolveOpenCodeDir() !== null;
65
39
  }
40
+ export function getOpenCodeNotFoundMessage() {
41
+ return formatCliNotFoundMessage(OPENCODE_NOT_FOUND, openCodeResolver.diagnostics());
42
+ }
66
43
  //# sourceMappingURL=opencode-cli-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-cli-resolver.js","sourceRoot":"","sources":["../../src/utils/opencode-cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,wEAAwE;AACxE,MAAM,oBAAoB,GAAG;IAC3B,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,2BAA2B;IAChE,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,+BAA+B;IACjE,gBAAgB,EAAE,oBAAoB;IACtC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,aAAa;IAC3C,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa;IAC7C,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,aAAa;IACpD,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,WAAW;CACpC,CAAC;AAEF,8FAA8F;AAC9F,IAAI,YAAY,GAAkB,IAAI,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB;IAChC,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO,YAAY,IAAI,IAAI,CAAC;IAEvD,4CAA4C;IAC5C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,gBAAgB,EAAE;YACxC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,eAAe;SACzB,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;YAC/B,OAAO,YAAY,CAAC;QACtB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,oDAAoD;IACtD,CAAC;IAED,kDAAkD;IAClD,KAAK,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;QACvC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;YACtC,YAAY,GAAG,GAAG,CAAC;YACnB,OAAO,YAAY,CAAC;QACtB,CAAC;IACH,CAAC;IAED,YAAY,GAAG,EAAE,CAAC,CAAC,8BAA8B;IACjD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,kBAAkB,EAAE,KAAK,IAAI,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"opencode-cli-resolver.js","sourceRoot":"","sources":["../../src/utils/opencode-cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAErG,wEAAwE;AACxE,MAAM,oBAAoB,GAAG;IAC3B,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,2BAA2B;IAChE,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,+BAA+B;IACjE,gBAAgB,EAAE,oBAAoB;IACtC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,aAAa;IAC3C,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa;IAC7C,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,aAAa;IACpD,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,WAAW;CACpC,CAAC;AAEF,MAAM,gBAAgB,GAAG,2BAA2B,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAC,CAAC;AAC/G,MAAM,kBAAkB,GAAG,qFAAqF,CAAC;AAEjH;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,gBAAgB,CAAC,OAAO,EAAE,EAAE,SAAS,IAAI,IAAI,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,kBAAkB,EAAE,KAAK,IAAI,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,0BAA0B;IACxC,OAAO,wBAAwB,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAC;AACtF,CAAC"}
@@ -14,6 +14,7 @@
14
14
  *
15
15
  * @module utils/pi-cli-resolver
16
16
  */
17
+ import { type CliResolverHost } from './cli-executable-resolver.js';
17
18
  /**
18
19
  * A real `pi --version` prints a semver-shaped string (e.g. `0.84.1`).
19
20
  *
@@ -28,6 +29,13 @@
28
29
  * No `g` flag, so there is no shared `lastIndex` to reset.
29
30
  */
30
31
  export declare const PI_VERSION_REGEX: RegExp;
32
+ type PiVersionProbe = (binPath: string) => string | null;
33
+ /**
34
+ * Creates an isolated Pi wrapper around an injected host, version probe and
35
+ * clock. Omitting `versionProbe` keeps the ambient (VITEST-gated) probe, which
36
+ * is exactly what the hermeticity test exercises.
37
+ */
38
+ export declare function createPiResolverForTest(host: CliResolverHost, versionProbe?: PiVersionProbe, now?: () => number): import("./cli-executable-resolver.js").CliExecutableResolver<string>;
31
39
  /**
32
40
  * Finds the directory containing a verified `pi` binary.
33
41
  * Checks `which pi` first, then falls back to common install locations. Every
@@ -41,10 +49,11 @@ export declare function resolvePiDir(): string | null;
41
49
  * Check if the Pi CLI is available on the system.
42
50
  */
43
51
  export declare function isPiAvailable(): boolean;
52
+ export declare function getPiNotFoundMessage(): string;
44
53
  /**
45
- * Version reported by the resolved `pi` binary, or null when pi is unavailable
46
- * (or when the probe was skipped, i.e. under vitest). Surfaced through
47
- * `GET /api/pi/status` so a misresolution is diagnosable from the UI.
54
+ * Version reported by the resolved `pi` binary, or null when pi is unavailable.
55
+ * Surfaced through `GET /api/pi/status` so a misresolution is diagnosable from the UI.
48
56
  */
49
57
  export declare function getPiCliVersion(): string | null;
58
+ export {};
50
59
  //# sourceMappingURL=pi-cli-resolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pi-cli-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/pi-cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAiBH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,QAA4B,CAAC;AAkC1D;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAyC5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAG/C"}
1
+ {"version":3,"file":"pi-cli-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/pi-cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,8BAA8B,CAAC;AAWtC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,QAA4B,CAAC;AAuC1D,KAAK,cAAc,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAiBzD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,MAAM,MAAM,wEAE/G;AAID;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAE5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C"}
@@ -14,11 +14,11 @@
14
14
  *
15
15
  * @module utils/pi-cli-resolver
16
16
  */
17
- import { execFileSync, execSync } from 'node:child_process';
18
- import { existsSync } from 'node:fs';
19
- import { dirname, join } from 'node:path';
17
+ import { execFileSync } from 'node:child_process';
18
+ import { join } from 'node:path';
20
19
  import { homedir } from 'node:os';
21
20
  import { EXEC_TIMEOUT_MS } from '../config/exec-timeout.js';
21
+ import { createCliExecutableResolver, formatCliNotFoundMessage, } from './cli-executable-resolver.js';
22
22
  /** Common directories where the Pi CLI binary may be installed */
23
23
  const PI_SEARCH_DIRS = [
24
24
  join(homedir(), '.local', 'bin'),
@@ -41,10 +41,7 @@ const PI_SEARCH_DIRS = [
41
41
  * No `g` flag, so there is no shared `lastIndex` to reset.
42
42
  */
43
43
  export const PI_VERSION_REGEX = /(?:^|\s)(\d+\.\d+\.\d+)/;
44
- /** Cached directory containing the pi binary (empty string = searched but not found) */
45
- let _piDir = null;
46
- /** Cached version string reported by the resolved binary (empty string = probed, unusable) */
47
- let _piVersion = null;
44
+ const PI_NOT_FOUND = 'Pi CLI not found. Install with: npm install -g --ignore-scripts @earendil-works/pi-coding-agent';
48
45
  /**
49
46
  * Run `pi --version` on a candidate path and return the trimmed version when it
50
47
  * looks like the coding agent. Returns null for anything else — a missing
@@ -52,7 +49,12 @@ let _piVersion = null;
52
49
  * (which is how an unrelated `pi` on PATH gets rejected).
53
50
  *
54
51
  * Never runs under vitest: the suites must stay hermetic and must not depend on
55
- * whether the dev box happens to have pi installed.
52
+ * whether the dev box happens to have pi installed — and since `pi` is a short
53
+ * GENERIC name, this probe would EXECUTE whatever binary of that name the
54
+ * machine carries. The shared resolver host is already inert under vitest, so
55
+ * this gate is defense in depth for any opted-in host that still carries the
56
+ * default probe; tests drive resolution via `createPiResolverForTest`, whose
57
+ * injected probe bypasses it. Pinned by test/pi-cli-resolver.test.ts.
56
58
  */
57
59
  function probePiVersion(binPath) {
58
60
  if (process.env.VITEST)
@@ -62,6 +64,9 @@ function probePiVersion(binPath) {
62
64
  encoding: 'utf-8',
63
65
  timeout: EXEC_TIMEOUT_MS,
64
66
  stdio: ['ignore', 'pipe', 'ignore'],
67
+ // A stuck or hostile `pi` that ignores SIGTERM would survive the timeout
68
+ // and block the server (execFileSync keeps waiting after the signal).
69
+ killSignal: 'SIGKILL',
65
70
  }).trim();
66
71
  // Upstream prints a bare version today; tolerate a `pi 0.84.1` style prefix too.
67
72
  const candidate = PI_VERSION_REGEX.exec(out)?.[1];
@@ -74,6 +79,26 @@ function probePiVersion(binPath) {
74
79
  }
75
80
  return null;
76
81
  }
82
+ function createPiResolver(host, versionProbe = probePiVersion, now) {
83
+ return createCliExecutableResolver({
84
+ binary: 'pi',
85
+ searchDirs: PI_SEARCH_DIRS,
86
+ validateCandidate: (binPath) => {
87
+ const version = versionProbe(binPath);
88
+ return version ? { accepted: true, metadata: version } : { accepted: false };
89
+ },
90
+ now,
91
+ }, host);
92
+ }
93
+ /**
94
+ * Creates an isolated Pi wrapper around an injected host, version probe and
95
+ * clock. Omitting `versionProbe` keeps the ambient (VITEST-gated) probe, which
96
+ * is exactly what the hermeticity test exercises.
97
+ */
98
+ export function createPiResolverForTest(host, versionProbe, now) {
99
+ return createPiResolver(host, versionProbe ?? probePiVersion, now);
100
+ }
101
+ const piResolver = createPiResolver();
77
102
  /**
78
103
  * Finds the directory containing a verified `pi` binary.
79
104
  * Checks `which pi` first, then falls back to common install locations. Every
@@ -83,48 +108,7 @@ function probePiVersion(binPath) {
83
108
  * @returns Directory path, or null if not found
84
109
  */
85
110
  export function resolvePiDir() {
86
- if (_piDir !== null)
87
- return _piDir || null;
88
- const accept = (binPath) => {
89
- // Under vitest the probe never runs, so existence alone decides (keeps the
90
- // suites hermetic and matches how the sibling resolvers behave there).
91
- if (process.env.VITEST) {
92
- _piDir = dirname(binPath);
93
- _piVersion = '';
94
- return _piDir;
95
- }
96
- const version = probePiVersion(binPath);
97
- if (!version)
98
- return null;
99
- _piDir = dirname(binPath);
100
- _piVersion = version;
101
- return _piDir;
102
- };
103
- try {
104
- const result = execSync('which pi', {
105
- encoding: 'utf-8',
106
- timeout: EXEC_TIMEOUT_MS,
107
- }).trim();
108
- if (result && existsSync(result)) {
109
- const dir = accept(result);
110
- if (dir)
111
- return dir;
112
- }
113
- }
114
- catch {
115
- // pi not in PATH, will check common locations
116
- }
117
- for (const dir of PI_SEARCH_DIRS) {
118
- const binPath = join(dir, 'pi');
119
- if (!existsSync(binPath))
120
- continue;
121
- const accepted = accept(binPath);
122
- if (accepted)
123
- return accepted;
124
- }
125
- _piDir = '';
126
- _piVersion = '';
127
- return null;
111
+ return piResolver.resolve()?.directory ?? null;
128
112
  }
129
113
  /**
130
114
  * Check if the Pi CLI is available on the system.
@@ -132,13 +116,14 @@ export function resolvePiDir() {
132
116
  export function isPiAvailable() {
133
117
  return resolvePiDir() !== null;
134
118
  }
119
+ export function getPiNotFoundMessage() {
120
+ return formatCliNotFoundMessage(PI_NOT_FOUND, piResolver.diagnostics());
121
+ }
135
122
  /**
136
- * Version reported by the resolved `pi` binary, or null when pi is unavailable
137
- * (or when the probe was skipped, i.e. under vitest). Surfaced through
138
- * `GET /api/pi/status` so a misresolution is diagnosable from the UI.
123
+ * Version reported by the resolved `pi` binary, or null when pi is unavailable.
124
+ * Surfaced through `GET /api/pi/status` so a misresolution is diagnosable from the UI.
139
125
  */
140
126
  export function getPiCliVersion() {
141
- resolvePiDir();
142
- return _piVersion || null;
127
+ return piResolver.resolve()?.metadata ?? null;
143
128
  }
144
129
  //# sourceMappingURL=pi-cli-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pi-cli-resolver.js","sourceRoot":"","sources":["../../src/utils/pi-cli-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pi-cli-resolver.js","sourceRoot":"","sources":["../../src/utils/pi-cli-resolver.ts"],"names":[],"mappings":"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"}
@@ -22,7 +22,7 @@
22
22
  * - Acknowledgement (`acknowledge()`, idle items only) is NOT resolution: the
23
23
  * item stays pending, it just stops arming the tab alert on every client.
24
24
  *
25
- * @dependencies utils (stripAnsi)
25
+ * @dependencies utils (stripAnsi, CLAUDE_WORKING_LINE_PATTERN)
26
26
  * @consumedby web/routes/hook-event-routes (notePrompt/resolve), web/routes/approval-routes,
27
27
  * web/session-listener-wiring (working/exit resolution), web/server (emit callbacks + stop)
28
28
  *
@@ -109,7 +109,8 @@ export declare function parseDialogOptions(context: string | undefined): Approva
109
109
  export declare class ApprovalInbox {
110
110
  /** Keyed by sessionId; the one-active-item-per-session invariant lives here. */
111
111
  private items;
112
- private recaptureTimers;
112
+ /** Post-capture timers per item id (re-capture + the delayed staleness check). */
113
+ private itemTimers;
113
114
  /** Capture callbacks kept for answer-time re-verification; dropped on remove. */
114
115
  private captures;
115
116
  private seq;
@@ -126,14 +127,45 @@ export declare class ApprovalInbox {
126
127
  notePrompt(args: NotePromptArgs): ApprovalItem;
127
128
  /**
128
129
  * Answer-time guard: re-capture the pane and check the dialog is still on
129
- * screen before keystrokes are sent at it. Only conclusive when the ORIGINAL
130
- * frame parsed options: if a fresh capture then parses none, the dialog is
131
- * gone (answered in the terminal moments ago), so the item resolves and the
132
- * answer must be refused, because the digit would land in whatever now has
133
- * focus. Unparseable-from-the-start items stay answerable (approve/deny
134
- * only), same risk the terminal user already carries.
130
+ * screen before keystrokes are sent at it. If the dialog is gone (answered in
131
+ * the terminal moments ago) the item resolves and the answer is refused,
132
+ * because the digit would land in whatever now has focus.
133
+ *
134
+ * A fresh frame that parses NO options is conclusive in two cases, and only
135
+ * those; anything else stays answerable, so an unreadable capture keeps the
136
+ * alert rather than losing a live dialog:
137
+ *
138
+ * 1. The item HAD parsed options. They cannot vanish while the dialog is up.
139
+ * 2. The frame shows Claude actively running a turn. A modal dialog BLOCKS
140
+ * the turn, so a working line and a dialog cannot coexist — measured on
141
+ * v2.1.237: a live-dialog frame carries neither the `… (13s` timer nor
142
+ * even the `esc to interrupt` footer, which the dialog replaces with
143
+ * `Enter to select · ↑/↓ to navigate · Esc to cancel`.
144
+ *
145
+ * Case 2 is what closes the late-hook hole. Claude Code fires the
146
+ * Notification behind the dialog, so a prompt answered before the hook lands
147
+ * produces an item whose FIRST capture already has no dialog in it — never
148
+ * parsed, so case 1 can never fire, and the red alert then outlived even
149
+ * `stop` (which had already fired) and survived reloads until the 12h TTL.
135
150
  */
136
151
  verifyStillAnswerable(id: string): boolean;
152
+ /**
153
+ * "This session's pane started moving again": re-verify its pending DIALOG
154
+ * item against the screen and resolve it if the dialog is gone.
155
+ *
156
+ * The staleness check itself lived only in `GET /api/approvals`, which
157
+ * nothing calls while a page is open (`seedApprovals()` runs on init and
158
+ * reconnect), so a dialog answered in the terminal kept its red tab alert for
159
+ * the whole rest of the turn. The `working` signal is exactly the moment an
160
+ * answer lands, and routing it through `verifyStillAnswerable` is what makes
161
+ * it safe to act on for a permission/question item: `working` is heuristic
162
+ * and can flap, but it only decides WHEN to look — the pane decides the
163
+ * outcome, and an unreadable capture keeps the alert.
164
+ *
165
+ * Cheap by construction: a Map miss unless a dialog item is actually pending,
166
+ * and the item is gone after the first successful resolve.
167
+ */
168
+ resolveIfDialogGone(sessionId: string): void;
137
169
  /** Pending item for a session, TTL-checked. */
138
170
  getForSession(sessionId: string): ApprovalItem | undefined;
139
171
  /** Pending item by id, TTL-checked. */
@@ -171,6 +203,11 @@ export declare class ApprovalInbox {
171
203
  resolveForSession(sessionId: string, resolution: ApprovalResolution, kinds?: ApprovalKind[]): void;
172
204
  /** Clear all timers (shutdown/tests). Items become inert; no events fire after this. */
173
205
  stop(): void;
206
+ /**
207
+ * Run `fn` after `delayMs` if the item is still the live one for its session,
208
+ * tracking the timer so `remove()`/`stop()` can cancel it.
209
+ */
210
+ private scheduleForItem;
174
211
  private applyCapture;
175
212
  private remove;
176
213
  private isExpired;
@@ -1 +1 @@
1
- {"version":3,"file":"approval-inbox.d.ts","sourceRoot":"","sources":["../../src/web/approval-inbox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"approval-inbox.d.ts","sourceRoot":"","sources":["../../src/web/approval-inbox.ts"],"names":[],"mappings":"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"}