aicodeman 1.19.6 → 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 (180) 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/file-query.d.ts +39 -0
  37. package/dist/utils/file-query.d.ts.map +1 -0
  38. package/dist/utils/file-query.js +90 -0
  39. package/dist/utils/file-query.js.map +1 -0
  40. package/dist/utils/gemini-cli-resolver.d.ts +1 -0
  41. package/dist/utils/gemini-cli-resolver.d.ts.map +1 -1
  42. package/dist/utils/gemini-cli-resolver.js +8 -29
  43. package/dist/utils/gemini-cli-resolver.js.map +1 -1
  44. package/dist/utils/index.d.ts +8 -6
  45. package/dist/utils/index.d.ts.map +1 -1
  46. package/dist/utils/index.js +7 -6
  47. package/dist/utils/index.js.map +1 -1
  48. package/dist/utils/opencode-cli-resolver.d.ts +1 -0
  49. package/dist/utils/opencode-cli-resolver.d.ts.map +1 -1
  50. package/dist/utils/opencode-cli-resolver.js +8 -31
  51. package/dist/utils/opencode-cli-resolver.js.map +1 -1
  52. package/dist/utils/pi-cli-resolver.d.ts +12 -3
  53. package/dist/utils/pi-cli-resolver.d.ts.map +1 -1
  54. package/dist/utils/pi-cli-resolver.js +40 -55
  55. package/dist/utils/pi-cli-resolver.js.map +1 -1
  56. package/dist/web/approval-inbox.d.ts +45 -8
  57. package/dist/web/approval-inbox.d.ts.map +1 -1
  58. package/dist/web/approval-inbox.js +116 -28
  59. package/dist/web/approval-inbox.js.map +1 -1
  60. package/dist/web/public/admin-ui.js.gz +0 -0
  61. package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
  62. package/dist/web/public/{app.e538c4dd.js → app.56c520ff.js} +1 -1
  63. package/dist/web/public/app.56c520ff.js.br +0 -0
  64. package/dist/web/public/app.56c520ff.js.gz +0 -0
  65. package/dist/web/public/approvals-ui.js.gz +0 -0
  66. package/dist/web/public/{constants.1dc77e55.js → constants.5abbd823.js} +197 -0
  67. package/dist/web/public/constants.5abbd823.js.br +0 -0
  68. package/dist/web/public/constants.5abbd823.js.gz +0 -0
  69. package/dist/web/public/cron-ui.js.gz +0 -0
  70. package/dist/web/public/entrance-animations.js.gz +0 -0
  71. package/dist/web/public/fonts/LICENSE-nerd-fonts.txt +21 -0
  72. package/dist/web/public/fonts/symbols-nerd-font-mono.woff2 +0 -0
  73. package/dist/web/public/home-sessions.js.gz +0 -0
  74. package/dist/web/public/i18n.196a992e.js +1 -0
  75. package/dist/web/public/i18n.196a992e.js.br +0 -0
  76. package/dist/web/public/i18n.196a992e.js.gz +0 -0
  77. package/dist/web/public/image-input.ee16ad88.js.gz +0 -0
  78. package/dist/web/public/index.html +41 -12
  79. package/dist/web/public/index.html.br +0 -0
  80. package/dist/web/public/index.html.gz +0 -0
  81. package/dist/web/public/input-cjk.63794d0b.js.gz +0 -0
  82. package/dist/web/public/keyboard-accessory.0454a3e9.js.gz +0 -0
  83. package/dist/web/public/{mobile-handlers.05b89237.js → mobile-handlers.0f83a608.js} +38 -1
  84. package/dist/web/public/mobile-handlers.0f83a608.js.br +0 -0
  85. package/dist/web/public/mobile-handlers.0f83a608.js.gz +0 -0
  86. package/dist/web/public/mobile-overview.js.gz +0 -0
  87. package/dist/web/public/mobile.49aeb17e.css.gz +0 -0
  88. package/dist/web/public/notification-manager.5d229063.js.gz +0 -0
  89. package/dist/web/public/orchestrator-panel.js.gz +0 -0
  90. package/dist/web/public/{panels-ui.c5a82b6e.js → panels-ui.5e97a36e.js} +1 -1
  91. package/dist/web/public/panels-ui.5e97a36e.js.br +0 -0
  92. package/dist/web/public/panels-ui.5e97a36e.js.gz +0 -0
  93. package/dist/web/public/ralph-panel.6de2d0f8.js.gz +0 -0
  94. package/dist/web/public/ralph-wizard.13a1831e.js.gz +0 -0
  95. package/dist/web/public/readmymind-ui.js.gz +0 -0
  96. package/dist/web/public/respawn-ui.ff0dae4c.js.gz +0 -0
  97. package/dist/web/public/sanitize-html.bc7078d6.js.gz +0 -0
  98. package/dist/web/public/session-lineage.js.gz +0 -0
  99. package/dist/web/public/session-ui.71a0ce9a.js.gz +0 -0
  100. package/dist/web/public/settings-ui.1a62e935.js +67 -0
  101. package/dist/web/public/settings-ui.1a62e935.js.br +0 -0
  102. package/dist/web/public/settings-ui.1a62e935.js.gz +0 -0
  103. package/dist/web/public/styles.68f9e118.css +1 -0
  104. package/dist/web/public/styles.68f9e118.css.br +0 -0
  105. package/dist/web/public/styles.68f9e118.css.gz +0 -0
  106. package/dist/web/public/subagent-windows.e6ca799f.js.gz +0 -0
  107. package/dist/web/public/sw.js.gz +0 -0
  108. package/dist/web/public/terminal-ui.5f4158b7.js +2 -0
  109. package/dist/web/public/terminal-ui.5f4158b7.js.br +0 -0
  110. package/dist/web/public/terminal-ui.5f4158b7.js.gz +0 -0
  111. package/dist/web/public/ultracode-panel.js.gz +0 -0
  112. package/dist/web/public/ultracode-windows.js.gz +0 -0
  113. package/dist/web/public/upload.html.gz +0 -0
  114. package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
  115. package/dist/web/public/vendor/marked.min.js.gz +0 -0
  116. package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
  117. package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
  118. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
  119. package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
  120. package/dist/web/public/vendor/{xterm-predictive-echo.6cec0fba.js → xterm-predictive-echo.bd6882b8.js} +1 -1
  121. package/dist/web/public/vendor/xterm-predictive-echo.bd6882b8.js.br +0 -0
  122. package/dist/web/public/vendor/xterm-predictive-echo.bd6882b8.js.gz +0 -0
  123. package/dist/web/public/vendor/xterm-zerolag-input.6fee72f2.js +4 -0
  124. package/dist/web/public/vendor/xterm-zerolag-input.6fee72f2.js.br +0 -0
  125. package/dist/web/public/vendor/xterm-zerolag-input.6fee72f2.js.gz +0 -0
  126. package/dist/web/public/vendor/xterm.css.gz +0 -0
  127. package/dist/web/public/vendor/xterm.min.js.gz +0 -0
  128. package/dist/web/public/voice-input.4ec670b0.js.gz +0 -0
  129. package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
  130. package/dist/web/public/webview-tabs.js.gz +0 -0
  131. package/dist/web/repo-status.d.ts +124 -0
  132. package/dist/web/repo-status.d.ts.map +1 -0
  133. package/dist/web/repo-status.js +353 -0
  134. package/dist/web/repo-status.js.map +1 -0
  135. package/dist/web/response-viewer-transcript.d.ts +12 -0
  136. package/dist/web/response-viewer-transcript.d.ts.map +1 -0
  137. package/dist/web/response-viewer-transcript.js +345 -0
  138. package/dist/web/response-viewer-transcript.js.map +1 -0
  139. package/dist/web/routes/file-routes.d.ts.map +1 -1
  140. package/dist/web/routes/file-routes.js +90 -1
  141. package/dist/web/routes/file-routes.js.map +1 -1
  142. package/dist/web/routes/session-routes.d.ts.map +1 -1
  143. package/dist/web/routes/session-routes.js +41 -22
  144. package/dist/web/routes/session-routes.js.map +1 -1
  145. package/dist/web/routes/system-routes.d.ts.map +1 -1
  146. package/dist/web/routes/system-routes.js +5 -0
  147. package/dist/web/routes/system-routes.js.map +1 -1
  148. package/dist/web/server.d.ts.map +1 -1
  149. package/dist/web/server.js +17 -4
  150. package/dist/web/server.js.map +1 -1
  151. package/dist/web/session-listener-wiring.d.ts +1 -0
  152. package/dist/web/session-listener-wiring.d.ts.map +1 -1
  153. package/dist/web/session-listener-wiring.js +26 -3
  154. package/dist/web/session-listener-wiring.js.map +1 -1
  155. package/package.json +2 -2
  156. package/dist/web/public/app.e538c4dd.js.br +0 -0
  157. package/dist/web/public/app.e538c4dd.js.gz +0 -0
  158. package/dist/web/public/constants.1dc77e55.js.br +0 -0
  159. package/dist/web/public/constants.1dc77e55.js.gz +0 -0
  160. package/dist/web/public/i18n.4bff95df.js +0 -1
  161. package/dist/web/public/i18n.4bff95df.js.br +0 -0
  162. package/dist/web/public/i18n.4bff95df.js.gz +0 -0
  163. package/dist/web/public/mobile-handlers.05b89237.js.br +0 -0
  164. package/dist/web/public/mobile-handlers.05b89237.js.gz +0 -0
  165. package/dist/web/public/panels-ui.c5a82b6e.js.br +0 -0
  166. package/dist/web/public/panels-ui.c5a82b6e.js.gz +0 -0
  167. package/dist/web/public/settings-ui.6cb12d4b.js +0 -67
  168. package/dist/web/public/settings-ui.6cb12d4b.js.br +0 -0
  169. package/dist/web/public/settings-ui.6cb12d4b.js.gz +0 -0
  170. package/dist/web/public/styles.1d72c88f.css +0 -1
  171. package/dist/web/public/styles.1d72c88f.css.br +0 -0
  172. package/dist/web/public/styles.1d72c88f.css.gz +0 -0
  173. package/dist/web/public/terminal-ui.02b89e2c.js +0 -4
  174. package/dist/web/public/terminal-ui.02b89e2c.js.br +0 -0
  175. package/dist/web/public/terminal-ui.02b89e2c.js.gz +0 -0
  176. package/dist/web/public/vendor/xterm-predictive-echo.6cec0fba.js.br +0 -0
  177. package/dist/web/public/vendor/xterm-predictive-echo.6cec0fba.js.gz +0 -0
  178. package/dist/web/public/vendor/xterm-zerolag-input.137ad9f0.js +0 -4
  179. package/dist/web/public/vendor/xterm-zerolag-input.137ad9f0.js.br +0 -0
  180. package/dist/web/public/vendor/xterm-zerolag-input.137ad9f0.js.gz +0 -0
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @fileoverview Pure file-name/path query matcher for the Files panel search
3
+ * (COD-236). Compiles a user query string into a reusable predicate so the
4
+ * server-side file walk can prune to matching entries instead of streaming the
5
+ * whole tree.
6
+ *
7
+ * Semantics:
8
+ * - Empty / whitespace-only query → `compileFileQuery` returns `null` (the
9
+ * caller treats this as "no search", falling back to the full tree). A query
10
+ * longer than `MAX_QUERY_LENGTH` compiles to `null` too: no honest filename
11
+ * search is that long, and the glob walk below is O(text · pattern).
12
+ * - A query containing a glob metachar (`*` or `?`) matches anchored and
13
+ * case-insensitively, `*` spanning any run (slashes included) and `?` exactly
14
+ * one character; every other character matches literally.
15
+ * - Otherwise the query is a plain case-insensitive substring.
16
+ * - When the query contains a `/` it matches against the relative path; else it
17
+ * matches against the bare entry name.
18
+ *
19
+ * ⚠️ Globs are matched by `globMatch` below, never by compiling the query into
20
+ * a RegExp: `*a*a*a…` translated to `^.*a.*a.*a…$` is a classic backtracking
21
+ * blowup, evaluated synchronously against every walked path — a pathological
22
+ * query could freeze the event loop for the whole server (the same reason
23
+ * `search-service.ts` is regex-free). The two-pointer wildcard walk is
24
+ * O(text · pattern) worst case, with both operands short by construction.
25
+ *
26
+ * No fs / IO — safe to unit-test directly.
27
+ */
28
+ export type FileQueryMatcher = (name: string, relativePath: string) => boolean;
29
+ /**
30
+ * Compile a query string into a matcher predicate, or `null` when the query is
31
+ * empty/whitespace or overlong (caller treats null as "no search").
32
+ */
33
+ export declare function compileFileQuery(query: string): FileQueryMatcher | null;
34
+ /**
35
+ * Convenience: compile the query and apply it in one call. Returns false when
36
+ * the query compiles to null (empty).
37
+ */
38
+ export declare function matchFileQuery(query: string, name: string, relativePath: string): boolean;
39
+ //# sourceMappingURL=file-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-query.d.ts","sourceRoot":"","sources":["../../src/utils/file-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;AAqC/E;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAcvE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAGzF"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @fileoverview Pure file-name/path query matcher for the Files panel search
3
+ * (COD-236). Compiles a user query string into a reusable predicate so the
4
+ * server-side file walk can prune to matching entries instead of streaming the
5
+ * whole tree.
6
+ *
7
+ * Semantics:
8
+ * - Empty / whitespace-only query → `compileFileQuery` returns `null` (the
9
+ * caller treats this as "no search", falling back to the full tree). A query
10
+ * longer than `MAX_QUERY_LENGTH` compiles to `null` too: no honest filename
11
+ * search is that long, and the glob walk below is O(text · pattern).
12
+ * - A query containing a glob metachar (`*` or `?`) matches anchored and
13
+ * case-insensitively, `*` spanning any run (slashes included) and `?` exactly
14
+ * one character; every other character matches literally.
15
+ * - Otherwise the query is a plain case-insensitive substring.
16
+ * - When the query contains a `/` it matches against the relative path; else it
17
+ * matches against the bare entry name.
18
+ *
19
+ * ⚠️ Globs are matched by `globMatch` below, never by compiling the query into
20
+ * a RegExp: `*a*a*a…` translated to `^.*a.*a.*a…$` is a classic backtracking
21
+ * blowup, evaluated synchronously against every walked path — a pathological
22
+ * query could freeze the event loop for the whole server (the same reason
23
+ * `search-service.ts` is regex-free). The two-pointer wildcard walk is
24
+ * O(text · pattern) worst case, with both operands short by construction.
25
+ *
26
+ * No fs / IO — safe to unit-test directly.
27
+ */
28
+ // Longer than any honest file search; bounds the O(text · pattern) glob walk.
29
+ const MAX_QUERY_LENGTH = 256;
30
+ /**
31
+ * Anchored glob match, linear-space two-pointer walk (no RegExp — see the
32
+ * fileoverview). `pattern` must already be lowercased; `text` is lowercased
33
+ * here so one compiled matcher serves many entries.
34
+ */
35
+ function globMatch(pattern, rawText) {
36
+ const text = rawText.toLowerCase();
37
+ let p = 0;
38
+ let t = 0;
39
+ let starP = -1;
40
+ let starT = -1;
41
+ while (t < text.length) {
42
+ const pc = p < pattern.length ? pattern[p] : '';
43
+ if (pc === '?' || pc === text[t]) {
44
+ p++;
45
+ t++;
46
+ }
47
+ else if (pc === '*') {
48
+ // Remember the star; try matching zero characters first, and on a later
49
+ // mismatch re-expand it one character at a time from here.
50
+ starP = p++;
51
+ starT = t;
52
+ }
53
+ else if (starP !== -1) {
54
+ p = starP + 1;
55
+ t = ++starT;
56
+ }
57
+ else {
58
+ return false;
59
+ }
60
+ }
61
+ while (p < pattern.length && pattern[p] === '*')
62
+ p++;
63
+ return p === pattern.length;
64
+ }
65
+ /**
66
+ * Compile a query string into a matcher predicate, or `null` when the query is
67
+ * empty/whitespace or overlong (caller treats null as "no search").
68
+ */
69
+ export function compileFileQuery(query) {
70
+ const trimmed = query.trim();
71
+ if (trimmed === '' || trimmed.length > MAX_QUERY_LENGTH)
72
+ return null;
73
+ const matchesPath = trimmed.includes('/');
74
+ const isGlob = trimmed.includes('*') || trimmed.includes('?');
75
+ if (isGlob) {
76
+ const pattern = trimmed.toLowerCase();
77
+ return (name, relativePath) => globMatch(pattern, matchesPath ? relativePath : name);
78
+ }
79
+ const needle = trimmed.toLowerCase();
80
+ return (name, relativePath) => (matchesPath ? relativePath : name).toLowerCase().includes(needle);
81
+ }
82
+ /**
83
+ * Convenience: compile the query and apply it in one call. Returns false when
84
+ * the query compiles to null (empty).
85
+ */
86
+ export function matchFileQuery(query, name, relativePath) {
87
+ const matcher = compileFileQuery(query);
88
+ return matcher ? matcher(name, relativePath) : false;
89
+ }
90
+ //# sourceMappingURL=file-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-query.js","sourceRoot":"","sources":["../../src/utils/file-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,8EAA8E;AAC9E,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B;;;;GAIG;AACH,SAAS,SAAS,CAAC,OAAe,EAAE,OAAe;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACnC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;IACf,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;IACf,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACjC,CAAC,EAAE,CAAC;YACJ,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACtB,wEAAwE;YACxE,2DAA2D;YAC3D,KAAK,GAAG,CAAC,EAAE,CAAC;YACZ,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;aAAM,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACxB,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;YACd,CAAC,GAAG,EAAE,KAAK,CAAC;QACd,CAAC;aAAM,CAAC;YACN,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,CAAC,EAAE,CAAC;IACrD,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,MAAM,GAAG,gBAAgB;QAAE,OAAO,IAAI,CAAC;IAErE,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAE9D,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QACtC,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACpG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,IAAY,EAAE,YAAoB;IAC9E,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACvD,CAAC"}
@@ -17,4 +17,5 @@ export declare function resolveGeminiDir(): string | null;
17
17
  * Check if Gemini CLI is available on the system.
18
18
  */
19
19
  export declare function isGeminiAvailable(): boolean;
20
+ export declare function getGeminiNotFoundMessage(): string;
20
21
  //# sourceMappingURL=gemini-cli-resolver.d.ts.map
@@ -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,11 +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
+ export { compileFileQuery, matchFileQuery } from './file-query.js';
29
+ export type { FileQueryMatcher } from './file-query.js';
28
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"}
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,11 +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
+ export { compileFileQuery, matchFileQuery } from './file-query.js';
27
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"}
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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"}