@caupulican/pi-adaptative 0.81.38 → 0.81.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (433) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/dist/bundled-resources/extensions/tmux-agent-manager/README.md +18 -1
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +131 -0
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -0
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +196 -0
  6. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -0
  7. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +308 -0
  8. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +22 -2
  9. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
  10. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +585 -24
  11. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
  12. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +749 -27
  13. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/__init__.py +43 -0
  14. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/fs.py +270 -0
  15. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/search.py +252 -0
  16. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/strings.py +399 -0
  17. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/text.py +575 -0
  18. package/dist/bundled-resources/runtimes/pi-shell-engine/context.py +52 -0
  19. package/dist/bundled-resources/runtimes/pi-shell-engine/errors.py +49 -0
  20. package/dist/bundled-resources/runtimes/pi-shell-engine/exec.py +734 -0
  21. package/dist/bundled-resources/runtimes/pi-shell-engine/expand.py +238 -0
  22. package/dist/bundled-resources/runtimes/pi-shell-engine/main.py +132 -0
  23. package/dist/bundled-resources/runtimes/pi-shell-engine/nodes.py +116 -0
  24. package/dist/bundled-resources/runtimes/pi-shell-engine/parser.py +287 -0
  25. package/dist/bundled-resources/runtimes/pi-shell-engine/proc.py +137 -0
  26. package/dist/bundled-resources/runtimes/pi-shell-engine/state.py +100 -0
  27. package/dist/bundled-resources/runtimes/pi-shell-engine/tokens.py +579 -0
  28. package/dist/bundled-resources/skills/tool-call-repair/SKILL.md +19 -9
  29. package/dist/bundled-resources/skills/tool-call-repair/references/failure-grammar.md +22 -5
  30. package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +5 -5
  31. package/dist/bundled-resources/skills/tool-call-repair/references/text-protocol-grammar.md +28 -7
  32. package/dist/cli/args.d.ts +3 -0
  33. package/dist/cli/args.d.ts.map +1 -1
  34. package/dist/cli/args.js +15 -0
  35. package/dist/cli/args.js.map +1 -1
  36. package/dist/core/agent-paths.d.ts +49 -0
  37. package/dist/core/agent-paths.d.ts.map +1 -0
  38. package/dist/core/agent-paths.js +107 -0
  39. package/dist/core/agent-paths.js.map +1 -0
  40. package/dist/core/agent-session-services.d.ts.map +1 -1
  41. package/dist/core/agent-session-services.js +3 -3
  42. package/dist/core/agent-session-services.js.map +1 -1
  43. package/dist/core/agent-session.d.ts +234 -17
  44. package/dist/core/agent-session.d.ts.map +1 -1
  45. package/dist/core/agent-session.js +484 -62
  46. package/dist/core/agent-session.js.map +1 -1
  47. package/dist/core/autonomy/contracts.d.ts +9 -0
  48. package/dist/core/autonomy/contracts.d.ts.map +1 -1
  49. package/dist/core/autonomy/contracts.js.map +1 -1
  50. package/dist/core/autonomy/lane-tracker.d.ts +10 -1
  51. package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
  52. package/dist/core/autonomy/lane-tracker.js +5 -1
  53. package/dist/core/autonomy/lane-tracker.js.map +1 -1
  54. package/dist/core/background-lane-controller.d.ts +122 -6
  55. package/dist/core/background-lane-controller.d.ts.map +1 -1
  56. package/dist/core/background-lane-controller.js +446 -89
  57. package/dist/core/background-lane-controller.js.map +1 -1
  58. package/dist/core/bash-execution-controller.d.ts +4 -0
  59. package/dist/core/bash-execution-controller.d.ts.map +1 -1
  60. package/dist/core/bash-execution-controller.js +7 -1
  61. package/dist/core/bash-execution-controller.js.map +1 -1
  62. package/dist/core/compaction-support.d.ts +13 -3
  63. package/dist/core/compaction-support.d.ts.map +1 -1
  64. package/dist/core/compaction-support.js +43 -7
  65. package/dist/core/compaction-support.js.map +1 -1
  66. package/dist/core/context/context-audit.d.ts +33 -1
  67. package/dist/core/context/context-audit.d.ts.map +1 -1
  68. package/dist/core/context/context-audit.js +31 -5
  69. package/dist/core/context/context-audit.js.map +1 -1
  70. package/dist/core/context-gc.d.ts.map +1 -1
  71. package/dist/core/context-gc.js +16 -1
  72. package/dist/core/context-gc.js.map +1 -1
  73. package/dist/core/context-pipeline.d.ts +26 -4
  74. package/dist/core/context-pipeline.d.ts.map +1 -1
  75. package/dist/core/context-pipeline.js +137 -14
  76. package/dist/core/context-pipeline.js.map +1 -1
  77. package/dist/core/cost-guard.d.ts +19 -3
  78. package/dist/core/cost-guard.d.ts.map +1 -1
  79. package/dist/core/cost-guard.js +18 -3
  80. package/dist/core/cost-guard.js.map +1 -1
  81. package/dist/core/delegation/session-worker-result.d.ts +34 -4
  82. package/dist/core/delegation/session-worker-result.d.ts.map +1 -1
  83. package/dist/core/delegation/session-worker-result.js +64 -4
  84. package/dist/core/delegation/session-worker-result.js.map +1 -1
  85. package/dist/core/delegation/worker-result.d.ts +42 -1
  86. package/dist/core/delegation/worker-result.d.ts.map +1 -1
  87. package/dist/core/delegation/worker-result.js +68 -0
  88. package/dist/core/delegation/worker-result.js.map +1 -1
  89. package/dist/core/extensions/loader.d.ts.map +1 -1
  90. package/dist/core/extensions/loader.js +20 -0
  91. package/dist/core/extensions/loader.js.map +1 -1
  92. package/dist/core/extensions/runner.d.ts.map +1 -1
  93. package/dist/core/extensions/runner.js +1 -0
  94. package/dist/core/extensions/runner.js.map +1 -1
  95. package/dist/core/extensions/types.d.ts +51 -0
  96. package/dist/core/extensions/types.d.ts.map +1 -1
  97. package/dist/core/extensions/types.js.map +1 -1
  98. package/dist/core/goal-loop-controller.d.ts +17 -1
  99. package/dist/core/goal-loop-controller.d.ts.map +1 -1
  100. package/dist/core/goal-loop-controller.js +79 -11
  101. package/dist/core/goal-loop-controller.js.map +1 -1
  102. package/dist/core/goals/goal-continuation-controller.d.ts +48 -2
  103. package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
  104. package/dist/core/goals/goal-continuation-controller.js +77 -0
  105. package/dist/core/goals/goal-continuation-controller.js.map +1 -1
  106. package/dist/core/goals/goal-continuation-defaults.d.ts +39 -0
  107. package/dist/core/goals/goal-continuation-defaults.d.ts.map +1 -1
  108. package/dist/core/goals/goal-continuation-defaults.js +42 -0
  109. package/dist/core/goals/goal-continuation-defaults.js.map +1 -1
  110. package/dist/core/goals/goal-continuation-prompt.d.ts +4 -0
  111. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  112. package/dist/core/goals/goal-continuation-prompt.js +51 -10
  113. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  114. package/dist/core/goals/goal-runtime-snapshot.d.ts +101 -2
  115. package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
  116. package/dist/core/goals/goal-runtime-snapshot.js +87 -4
  117. package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
  118. package/dist/core/goals/goal-state.d.ts +89 -1
  119. package/dist/core/goals/goal-state.d.ts.map +1 -1
  120. package/dist/core/goals/goal-state.js +71 -5
  121. package/dist/core/goals/goal-state.js.map +1 -1
  122. package/dist/core/goals/goal-tool-core.d.ts +56 -2
  123. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  124. package/dist/core/goals/goal-tool-core.js +111 -5
  125. package/dist/core/goals/goal-tool-core.js.map +1 -1
  126. package/dist/core/goals/session-goal-state.d.ts +11 -2
  127. package/dist/core/goals/session-goal-state.d.ts.map +1 -1
  128. package/dist/core/goals/session-goal-state.js +32 -17
  129. package/dist/core/goals/session-goal-state.js.map +1 -1
  130. package/dist/core/keybindings.d.ts +10 -0
  131. package/dist/core/keybindings.d.ts.map +1 -1
  132. package/dist/core/keybindings.js +10 -2
  133. package/dist/core/keybindings.js.map +1 -1
  134. package/dist/core/learning/observation-store.d.ts +12 -3
  135. package/dist/core/learning/observation-store.d.ts.map +1 -1
  136. package/dist/core/learning/observation-store.js +30 -15
  137. package/dist/core/learning/observation-store.js.map +1 -1
  138. package/dist/core/learning/skill-curator.d.ts +5 -1
  139. package/dist/core/learning/skill-curator.d.ts.map +1 -1
  140. package/dist/core/learning/skill-curator.js +21 -19
  141. package/dist/core/learning/skill-curator.js.map +1 -1
  142. package/dist/core/local-runtime-controller.d.ts +65 -3
  143. package/dist/core/local-runtime-controller.d.ts.map +1 -1
  144. package/dist/core/local-runtime-controller.js +186 -26
  145. package/dist/core/local-runtime-controller.js.map +1 -1
  146. package/dist/core/memory/providers/file-store.d.ts +1 -1
  147. package/dist/core/memory/providers/file-store.d.ts.map +1 -1
  148. package/dist/core/memory/providers/file-store.js +6 -6
  149. package/dist/core/memory/providers/file-store.js.map +1 -1
  150. package/dist/core/model-capability.d.ts +34 -0
  151. package/dist/core/model-capability.d.ts.map +1 -1
  152. package/dist/core/model-capability.js +42 -1
  153. package/dist/core/model-capability.js.map +1 -1
  154. package/dist/core/model-router/tool-escalation.d.ts +15 -0
  155. package/dist/core/model-router/tool-escalation.d.ts.map +1 -1
  156. package/dist/core/model-router/tool-escalation.js +23 -1
  157. package/dist/core/model-router/tool-escalation.js.map +1 -1
  158. package/dist/core/model-router-controller.d.ts +34 -7
  159. package/dist/core/model-router-controller.d.ts.map +1 -1
  160. package/dist/core/model-router-controller.js +95 -16
  161. package/dist/core/model-router-controller.js.map +1 -1
  162. package/dist/core/models/adaptation-store.d.ts +7 -0
  163. package/dist/core/models/adaptation-store.d.ts.map +1 -1
  164. package/dist/core/models/adaptation-store.js +47 -11
  165. package/dist/core/models/adaptation-store.js.map +1 -1
  166. package/dist/core/models/default-model-suggestions.d.ts.map +1 -1
  167. package/dist/core/models/default-model-suggestions.js +17 -0
  168. package/dist/core/models/default-model-suggestions.js.map +1 -1
  169. package/dist/core/models/fitness-store.d.ts +3 -0
  170. package/dist/core/models/fitness-store.d.ts.map +1 -1
  171. package/dist/core/models/fitness-store.js +11 -2
  172. package/dist/core/models/fitness-store.js.map +1 -1
  173. package/dist/core/models/llamacpp-runtime.d.ts +180 -0
  174. package/dist/core/models/llamacpp-runtime.d.ts.map +1 -0
  175. package/dist/core/models/llamacpp-runtime.js +475 -0
  176. package/dist/core/models/llamacpp-runtime.js.map +1 -0
  177. package/dist/core/models/local-registration.d.ts +40 -0
  178. package/dist/core/models/local-registration.d.ts.map +1 -1
  179. package/dist/core/models/local-registration.js +94 -5
  180. package/dist/core/models/local-registration.js.map +1 -1
  181. package/dist/core/models/local-runtime.d.ts.map +1 -1
  182. package/dist/core/models/local-runtime.js +6 -5
  183. package/dist/core/models/local-runtime.js.map +1 -1
  184. package/dist/core/models/model-ref.d.ts +7 -0
  185. package/dist/core/models/model-ref.d.ts.map +1 -1
  186. package/dist/core/models/model-ref.js +26 -0
  187. package/dist/core/models/model-ref.js.map +1 -1
  188. package/dist/core/models/needle-runtime.d.ts +257 -0
  189. package/dist/core/models/needle-runtime.d.ts.map +1 -0
  190. package/dist/core/models/needle-runtime.js +519 -0
  191. package/dist/core/models/needle-runtime.js.map +1 -0
  192. package/dist/core/models/prism-llamacpp-lifecycle.d.ts +89 -0
  193. package/dist/core/models/prism-llamacpp-lifecycle.d.ts.map +1 -0
  194. package/dist/core/models/prism-llamacpp-lifecycle.js +121 -0
  195. package/dist/core/models/prism-llamacpp-lifecycle.js.map +1 -0
  196. package/dist/core/package-manager.d.ts.map +1 -1
  197. package/dist/core/package-manager.js +11 -10
  198. package/dist/core/package-manager.js.map +1 -1
  199. package/dist/core/process-matrix/codes.d.ts +72 -0
  200. package/dist/core/process-matrix/codes.d.ts.map +1 -0
  201. package/dist/core/process-matrix/codes.js +15 -0
  202. package/dist/core/process-matrix/codes.js.map +1 -0
  203. package/dist/core/process-matrix/runtime.d.ts +63 -0
  204. package/dist/core/process-matrix/runtime.d.ts.map +1 -0
  205. package/dist/core/process-matrix/runtime.js +310 -0
  206. package/dist/core/process-matrix/runtime.js.map +1 -0
  207. package/dist/core/process-matrix/store.d.ts +22 -0
  208. package/dist/core/process-matrix/store.d.ts.map +1 -0
  209. package/dist/core/process-matrix/store.js +80 -0
  210. package/dist/core/process-matrix/store.js.map +1 -0
  211. package/dist/core/process-matrix/supervisor.d.ts +72 -0
  212. package/dist/core/process-matrix/supervisor.d.ts.map +1 -0
  213. package/dist/core/process-matrix/supervisor.js +130 -0
  214. package/dist/core/process-matrix/supervisor.js.map +1 -0
  215. package/dist/core/profile-registry.d.ts +7 -0
  216. package/dist/core/profile-registry.d.ts.map +1 -1
  217. package/dist/core/profile-registry.js +20 -0
  218. package/dist/core/profile-registry.js.map +1 -1
  219. package/dist/core/python-runtime.d.ts.map +1 -1
  220. package/dist/core/python-runtime.js +3 -3
  221. package/dist/core/python-runtime.js.map +1 -1
  222. package/dist/core/reflection-controller.d.ts +29 -5
  223. package/dist/core/reflection-controller.d.ts.map +1 -1
  224. package/dist/core/reflection-controller.js +215 -126
  225. package/dist/core/reflection-controller.js.map +1 -1
  226. package/dist/core/reload-blockers.d.ts +36 -0
  227. package/dist/core/reload-blockers.d.ts.map +1 -1
  228. package/dist/core/reload-blockers.js +44 -0
  229. package/dist/core/reload-blockers.js.map +1 -1
  230. package/dist/core/resource-loader.d.ts.map +1 -1
  231. package/dist/core/resource-loader.js +8 -7
  232. package/dist/core/resource-loader.js.map +1 -1
  233. package/dist/core/runtime-builder.d.ts +58 -5
  234. package/dist/core/runtime-builder.d.ts.map +1 -1
  235. package/dist/core/runtime-builder.js +209 -25
  236. package/dist/core/runtime-builder.js.map +1 -1
  237. package/dist/core/scout-controller.d.ts +6 -0
  238. package/dist/core/scout-controller.d.ts.map +1 -1
  239. package/dist/core/scout-controller.js +66 -52
  240. package/dist/core/scout-controller.js.map +1 -1
  241. package/dist/core/sdk.d.ts.map +1 -1
  242. package/dist/core/sdk.js +3 -3
  243. package/dist/core/sdk.js.map +1 -1
  244. package/dist/core/session-role.d.ts +31 -0
  245. package/dist/core/session-role.d.ts.map +1 -0
  246. package/dist/core/session-role.js +52 -0
  247. package/dist/core/session-role.js.map +1 -0
  248. package/dist/core/settings-manager.d.ts +42 -3
  249. package/dist/core/settings-manager.d.ts.map +1 -1
  250. package/dist/core/settings-manager.js +94 -60
  251. package/dist/core/settings-manager.js.map +1 -1
  252. package/dist/core/system-prompt-builder.d.ts +12 -0
  253. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  254. package/dist/core/system-prompt-builder.js +6 -0
  255. package/dist/core/system-prompt-builder.js.map +1 -1
  256. package/dist/core/system-prompt.d.ts +14 -1
  257. package/dist/core/system-prompt.d.ts.map +1 -1
  258. package/dist/core/system-prompt.js +20 -3
  259. package/dist/core/system-prompt.js.map +1 -1
  260. package/dist/core/tasks/session-task-state.d.ts +11 -2
  261. package/dist/core/tasks/session-task-state.d.ts.map +1 -1
  262. package/dist/core/tasks/session-task-state.js +27 -11
  263. package/dist/core/tasks/session-task-state.js.map +1 -1
  264. package/dist/core/tasks/task-contract-monitor.d.ts +45 -0
  265. package/dist/core/tasks/task-contract-monitor.d.ts.map +1 -0
  266. package/dist/core/tasks/task-contract-monitor.js +56 -0
  267. package/dist/core/tasks/task-contract-monitor.js.map +1 -0
  268. package/dist/core/tasks/task-state.d.ts +8 -0
  269. package/dist/core/tasks/task-state.d.ts.map +1 -1
  270. package/dist/core/tasks/task-state.js +28 -1
  271. package/dist/core/tasks/task-state.js.map +1 -1
  272. package/dist/core/tool-gate-controller.d.ts.map +1 -1
  273. package/dist/core/tool-gate-controller.js +5 -0
  274. package/dist/core/tool-gate-controller.js.map +1 -1
  275. package/dist/core/tool-recovery-log-records.d.ts +7 -0
  276. package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
  277. package/dist/core/tool-recovery-log-records.js +14 -6
  278. package/dist/core/tool-recovery-log-records.js.map +1 -1
  279. package/dist/core/tool-selection/promotion.d.ts +54 -0
  280. package/dist/core/tool-selection/promotion.d.ts.map +1 -0
  281. package/dist/core/tool-selection/promotion.js +81 -0
  282. package/dist/core/tool-selection/promotion.js.map +1 -0
  283. package/dist/core/tool-selection/tool-performance-store.d.ts +37 -0
  284. package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -1
  285. package/dist/core/tool-selection/tool-performance-store.js +87 -3
  286. package/dist/core/tool-selection/tool-performance-store.js.map +1 -1
  287. package/dist/core/tool-selection/tool-selection-controller.d.ts +45 -0
  288. package/dist/core/tool-selection/tool-selection-controller.d.ts.map +1 -1
  289. package/dist/core/tool-selection/tool-selection-controller.js +96 -0
  290. package/dist/core/tool-selection/tool-selection-controller.js.map +1 -1
  291. package/dist/core/tools/bash.d.ts +18 -0
  292. package/dist/core/tools/bash.d.ts.map +1 -1
  293. package/dist/core/tools/bash.js +95 -16
  294. package/dist/core/tools/bash.js.map +1 -1
  295. package/dist/core/tools/delegate-status.d.ts +14 -0
  296. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  297. package/dist/core/tools/delegate-status.js +82 -7
  298. package/dist/core/tools/delegate-status.js.map +1 -1
  299. package/dist/core/tools/delegate.d.ts.map +1 -1
  300. package/dist/core/tools/delegate.js +25 -8
  301. package/dist/core/tools/delegate.js.map +1 -1
  302. package/dist/core/tools/goal.d.ts +94 -3
  303. package/dist/core/tools/goal.d.ts.map +1 -1
  304. package/dist/core/tools/goal.js +165 -15
  305. package/dist/core/tools/goal.js.map +1 -1
  306. package/dist/core/tools/model-fitness.d.ts +7 -0
  307. package/dist/core/tools/model-fitness.d.ts.map +1 -1
  308. package/dist/core/tools/model-fitness.js +2 -2
  309. package/dist/core/tools/model-fitness.js.map +1 -1
  310. package/dist/core/tools/shell-contract-router.d.ts +6 -1
  311. package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
  312. package/dist/core/tools/shell-contract-router.js +23 -2
  313. package/dist/core/tools/shell-contract-router.js.map +1 -1
  314. package/dist/core/tools/shell-session.d.ts +89 -0
  315. package/dist/core/tools/shell-session.d.ts.map +1 -0
  316. package/dist/core/tools/shell-session.js +432 -0
  317. package/dist/core/tools/shell-session.js.map +1 -0
  318. package/dist/core/tools/task-steps.d.ts +4 -0
  319. package/dist/core/tools/task-steps.d.ts.map +1 -1
  320. package/dist/core/tools/task-steps.js +63 -8
  321. package/dist/core/tools/task-steps.js.map +1 -1
  322. package/dist/core/tools/tmux-dispatch.d.ts +86 -0
  323. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -0
  324. package/dist/core/tools/tmux-dispatch.js +91 -0
  325. package/dist/core/tools/tmux-dispatch.js.map +1 -0
  326. package/dist/core/tools/windows-shell-engine.d.ts +42 -0
  327. package/dist/core/tools/windows-shell-engine.d.ts.map +1 -0
  328. package/dist/core/tools/windows-shell-engine.js +153 -0
  329. package/dist/core/tools/windows-shell-engine.js.map +1 -0
  330. package/dist/core/tools/windows-shell-state.d.ts +40 -0
  331. package/dist/core/tools/windows-shell-state.d.ts.map +1 -0
  332. package/dist/core/tools/windows-shell-state.js +59 -0
  333. package/dist/core/tools/windows-shell-state.js.map +1 -0
  334. package/dist/core/tools/worktree-sync.d.ts +24 -0
  335. package/dist/core/tools/worktree-sync.d.ts.map +1 -0
  336. package/dist/core/tools/worktree-sync.js +338 -0
  337. package/dist/core/tools/worktree-sync.js.map +1 -0
  338. package/dist/core/trust-manager.d.ts +4 -1
  339. package/dist/core/trust-manager.d.ts.map +1 -1
  340. package/dist/core/trust-manager.js +20 -2
  341. package/dist/core/trust-manager.js.map +1 -1
  342. package/dist/core/util/atomic-file.d.ts +55 -0
  343. package/dist/core/util/atomic-file.d.ts.map +1 -0
  344. package/dist/core/util/atomic-file.js +255 -0
  345. package/dist/core/util/atomic-file.js.map +1 -0
  346. package/dist/core/util/minimatch-cache.d.ts +33 -0
  347. package/dist/core/util/minimatch-cache.d.ts.map +1 -0
  348. package/dist/core/util/minimatch-cache.js +0 -0
  349. package/dist/core/util/minimatch-cache.js.map +1 -0
  350. package/dist/core/worktree-sync/codes.d.ts +227 -0
  351. package/dist/core/worktree-sync/codes.d.ts.map +1 -0
  352. package/dist/core/worktree-sync/codes.js +14 -0
  353. package/dist/core/worktree-sync/codes.js.map +1 -0
  354. package/dist/core/worktree-sync/git-engine.d.ts +156 -0
  355. package/dist/core/worktree-sync/git-engine.d.ts.map +1 -0
  356. package/dist/core/worktree-sync/git-engine.js +1191 -0
  357. package/dist/core/worktree-sync/git-engine.js.map +1 -0
  358. package/dist/core/worktree-sync/lane-gate.d.ts +75 -0
  359. package/dist/core/worktree-sync/lane-gate.d.ts.map +1 -0
  360. package/dist/core/worktree-sync/lane-gate.js +360 -0
  361. package/dist/core/worktree-sync/lane-gate.js.map +1 -0
  362. package/dist/core/worktree-sync/runtime.d.ts +47 -0
  363. package/dist/core/worktree-sync/runtime.d.ts.map +1 -0
  364. package/dist/core/worktree-sync/runtime.js +96 -0
  365. package/dist/core/worktree-sync/runtime.js.map +1 -0
  366. package/dist/core/worktree-sync/store.d.ts +69 -0
  367. package/dist/core/worktree-sync/store.d.ts.map +1 -0
  368. package/dist/core/worktree-sync/store.js +247 -0
  369. package/dist/core/worktree-sync/store.js.map +1 -0
  370. package/dist/core/worktree-sync/watcher.d.ts +29 -0
  371. package/dist/core/worktree-sync/watcher.d.ts.map +1 -0
  372. package/dist/core/worktree-sync/watcher.js +93 -0
  373. package/dist/core/worktree-sync/watcher.js.map +1 -0
  374. package/dist/main.d.ts.map +1 -1
  375. package/dist/main.js +94 -0
  376. package/dist/main.js.map +1 -1
  377. package/dist/migrations.d.ts +9 -0
  378. package/dist/migrations.d.ts.map +1 -1
  379. package/dist/migrations.js +38 -0
  380. package/dist/migrations.js.map +1 -1
  381. package/dist/modes/interactive/auto-learn-controller.d.ts +16 -1
  382. package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -1
  383. package/dist/modes/interactive/auto-learn-controller.js +50 -8
  384. package/dist/modes/interactive/auto-learn-controller.js.map +1 -1
  385. package/dist/modes/interactive/components/profile-resource-editor.d.ts.map +1 -1
  386. package/dist/modes/interactive/components/profile-resource-editor.js +23 -1
  387. package/dist/modes/interactive/components/profile-resource-editor.js.map +1 -1
  388. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  389. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  390. package/dist/modes/interactive/interactive-mode.js +4 -0
  391. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  392. package/dist/modes/interactive/local-model-commands.d.ts +43 -0
  393. package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
  394. package/dist/modes/interactive/local-model-commands.js +290 -3
  395. package/dist/modes/interactive/local-model-commands.js.map +1 -1
  396. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
  397. package/dist/modes/interactive/session-flow-commands.js +24 -4
  398. package/dist/modes/interactive/session-flow-commands.js.map +1 -1
  399. package/dist/utils/fs-watch.d.ts +11 -0
  400. package/dist/utils/fs-watch.d.ts.map +1 -1
  401. package/dist/utils/fs-watch.js +20 -2
  402. package/dist/utils/fs-watch.js.map +1 -1
  403. package/dist/utils/highlight-js-languages.d.ts +4 -0
  404. package/dist/utils/highlight-js-languages.d.ts.map +1 -0
  405. package/dist/utils/highlight-js-languages.js +573 -0
  406. package/dist/utils/highlight-js-languages.js.map +1 -0
  407. package/dist/utils/shell.d.ts +7 -1
  408. package/dist/utils/shell.d.ts.map +1 -1
  409. package/dist/utils/shell.js +21 -6
  410. package/dist/utils/shell.js.map +1 -1
  411. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  412. package/dist/utils/syntax-highlight.js +53 -5
  413. package/dist/utils/syntax-highlight.js.map +1 -1
  414. package/dist/utils/tools-manager.d.ts.map +1 -1
  415. package/dist/utils/tools-manager.js +112 -1
  416. package/dist/utils/tools-manager.js.map +1 -1
  417. package/docs/process-matrix.md +120 -0
  418. package/docs/settings.md +3 -0
  419. package/docs/tmux-agent-manager.md +85 -2
  420. package/docs/windows.md +52 -3
  421. package/docs/work-directory.md +29 -0
  422. package/docs/worktree-sync.md +250 -0
  423. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  424. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  425. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  426. package/examples/extensions/sandbox/package-lock.json +2 -2
  427. package/examples/extensions/sandbox/package.json +1 -1
  428. package/examples/extensions/with-deps/package-lock.json +2 -2
  429. package/examples/extensions/with-deps/package.json +1 -1
  430. package/npm-shrinkwrap.json +12 -12
  431. package/package.json +10 -4
  432. package/docs/integration-sweep-builder-blueprint-2026-07-09.md +0 -365
  433. package/docs/integration-sweep-resume-2026-07-09.md +0 -407
@@ -1,7 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import chalk from "chalk";
3
3
  import { spawnSync } from "child_process";
4
- import { chmodSync, createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, renameSync, rmSync, writeFileSync, } from "fs";
4
+ import { accessSync, chmodSync, createReadStream, createWriteStream, existsSync, constants as fsConstants, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync, } from "fs";
5
5
  import { createRequire } from "module";
6
6
  import { arch, platform } from "os";
7
7
  import { dirname, join } from "path";
@@ -9,6 +9,7 @@ import { Readable } from "stream";
9
9
  import { pipeline } from "stream/promises";
10
10
  import { pathToFileURL } from "url";
11
11
  import { APP_NAME, getAgentDir, getBinDir } from "../config.js";
12
+ import { cacheDir as agentCacheDir, cacheFile } from "../core/agent-paths.js";
12
13
  import { spawnProcess, waitForChildProcessWithTermination } from "./child-process.js";
13
14
  import { getProcessWorkRun } from "./work-directory.js";
14
15
  const TOOLS_DIR = getBinDir();
@@ -124,6 +125,95 @@ function commandExists(cmd) {
124
125
  return false;
125
126
  }
126
127
  }
128
+ function isCachedToolPath(value) {
129
+ if (typeof value !== "object" || value === null)
130
+ return false;
131
+ const candidate = value;
132
+ return typeof candidate.path === "string" && typeof candidate.mtimeMs === "number";
133
+ }
134
+ function getToolPathCacheFile() {
135
+ return cacheFile(getAgentDir(), "tool-paths.json");
136
+ }
137
+ /** Read the persisted cross-run tool-path cache. Missing/corrupt/foreign entries are dropped silently -- a cold cache just means the next resolve re-probes and repopulates it. */
138
+ function readToolPathCache() {
139
+ try {
140
+ const raw = readFileSync(getToolPathCacheFile(), "utf-8");
141
+ const parsed = JSON.parse(raw);
142
+ const cache = {};
143
+ for (const tool of Object.keys(TOOLS)) {
144
+ const entry = parsed[tool];
145
+ if (isCachedToolPath(entry))
146
+ cache[tool] = entry;
147
+ }
148
+ return cache;
149
+ }
150
+ catch {
151
+ return {};
152
+ }
153
+ }
154
+ function writeToolPathCacheEntry(tool, entry) {
155
+ try {
156
+ const cacheDir = agentCacheDir(getAgentDir());
157
+ mkdirSync(cacheDir, { recursive: true });
158
+ const cache = readToolPathCache();
159
+ cache[tool] = entry;
160
+ writeFileSync(join(cacheDir, "tool-paths.json"), JSON.stringify(cache));
161
+ }
162
+ catch {
163
+ // Best-effort: a failed cache write only costs the next run its probe, same as a cold cache.
164
+ }
165
+ }
166
+ /** A cached entry is fresh only while its file still exists at the same path with the same mtime -- a deleted/moved/replaced binary invalidates it and forces a re-probe below. */
167
+ function isCachedToolPathFresh(entry) {
168
+ try {
169
+ return statSync(entry.path).mtimeMs === entry.mtimeMs;
170
+ }
171
+ catch {
172
+ return false;
173
+ }
174
+ }
175
+ function getPathExtensionCandidates() {
176
+ if (platform() !== "win32")
177
+ return [""];
178
+ const pathExt = process.env.PATHEXT || ".COM;.EXE;.BAT;.CMD";
179
+ return ["", ...pathExt.split(";").filter(Boolean)];
180
+ }
181
+ /**
182
+ * Manually walk PATH to turn a bare command name that commandExists() already confirmed is
183
+ * runnable into an absolute, stat-checkable path. This never decides presence itself (that stays
184
+ * commandExists's job via spawnSync, unchanged) -- it only supplies the path the cross-run cache
185
+ * needs for its mtime staleness check, using stat calls instead of another spawn.
186
+ */
187
+ function resolveOnSystemPath(binaryName) {
188
+ const pathEnv = process.env.PATH ?? "";
189
+ const dirs = pathEnv.split(platform() === "win32" ? ";" : ":").filter(Boolean);
190
+ for (const dir of dirs) {
191
+ for (const ext of getPathExtensionCandidates()) {
192
+ const candidate = join(dir, binaryName + ext);
193
+ if (!existsSync(candidate))
194
+ continue;
195
+ try {
196
+ if (statSync(candidate).isDirectory())
197
+ continue;
198
+ if (platform() !== "win32")
199
+ accessSync(candidate, fsConstants.X_OK);
200
+ }
201
+ catch {
202
+ continue;
203
+ }
204
+ return candidate;
205
+ }
206
+ }
207
+ return null;
208
+ }
209
+ function cacheResolvedSystemPath(tool, resolvedPath) {
210
+ try {
211
+ writeToolPathCacheEntry(tool, { path: resolvedPath, mtimeMs: statSync(resolvedPath).mtimeMs });
212
+ }
213
+ catch {
214
+ // Stat raced with a delete between resolve and here: nothing to cache, still return the path below.
215
+ }
216
+ }
127
217
  // Get the path to a tool (system-wide or in our tools dir)
128
218
  export function getToolPath(tool) {
129
219
  const config = TOOLS[tool];
@@ -136,8 +226,29 @@ export function getToolPath(tool) {
136
226
  }
137
227
  // Check system PATH - if found, just return the command name (it's in PATH)
138
228
  const systemBinaryNames = config.systemBinaryNames ?? [config.binaryName];
229
+ // A system-PATH resolution normally requires commandExists's synchronous
230
+ // spawnSync(`<name> --version`) probe below, which is expensive to pay on every process
231
+ // startup (this runs once per tool at interactive-mode init, plus again on the first
232
+ // find/grep tool call). Persist the resolved absolute path + mtime across runs
233
+ // (<agentDir>/cache/tool-paths.json) so a warm run can skip the probe entirely and just
234
+ // stat the cached path instead. KNOWN LIMITATION: if a *different* binary of the same name
235
+ // starts shadowing the cached one earlier on PATH (e.g. a new install) while the
236
+ // originally-cached file itself is untouched, this cache keeps returning the old path until
237
+ // that file is deleted/modified -- an intentional narrow staleness window (the returned tool
238
+ // still exists and runs; it just isn't the newly-shadowing one), not a correctness bug.
239
+ const cached = readToolPathCache()[tool];
240
+ if (cached && isCachedToolPathFresh(cached)) {
241
+ return cached.path;
242
+ }
139
243
  for (const systemBinaryName of systemBinaryNames) {
140
244
  if (commandExists(systemBinaryName)) {
245
+ const resolved = resolveOnSystemPath(systemBinaryName);
246
+ if (resolved) {
247
+ cacheResolvedSystemPath(tool, resolved);
248
+ return resolved;
249
+ }
250
+ // Could not resolve an absolute path to cache (e.g. PATH env raced between the two
251
+ // lookups); still return the bare name so the caller keeps working, uncached.
141
252
  return systemBinaryName;
142
253
  }
143
254
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tools-manager.js","sourceRoot":"","sources":["../../src/utils/tools-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport chalk from \"chalk\";\nimport { type SpawnSyncReturns, spawnSync } from \"child_process\";\nimport {\n\tchmodSync,\n\tcreateReadStream,\n\tcreateWriteStream,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\trenameSync,\n\trmSync,\n\twriteFileSync,\n} from \"fs\";\nimport { createRequire } from \"module\";\nimport { arch, platform } from \"os\";\nimport { dirname, join } from \"path\";\nimport { Readable } from \"stream\";\nimport { pipeline } from \"stream/promises\";\nimport { pathToFileURL } from \"url\";\nimport { APP_NAME, getAgentDir, getBinDir } from \"../config.ts\";\nimport { spawnProcess, waitForChildProcessWithTermination } from \"./child-process.ts\";\nimport { getProcessWorkRun } from \"./work-directory.ts\";\n\nconst TOOLS_DIR = getBinDir();\nconst NETWORK_TIMEOUT_MS = 10_000;\nconst DOWNLOAD_TIMEOUT_MS = 120_000;\nconst COMMAND_PROBE_TIMEOUT_MS = 5_000;\nconst ARCHIVE_EXTRACTION_TIMEOUT_MS = 5 * 60_000;\nconst FFF_NODE_VERSION = \"0.9.6\";\nexport const UV_VERSION = \"0.11.28\";\nconst FFF_MANAGED_DIR = join(TOOLS_DIR, \"fff-node\");\nconst FFF_MANAGED_PACKAGE_JSON = join(FFF_MANAGED_DIR, \"package.json\");\n\ntype ModuleRequire = ((id: string) => unknown) & { resolve?: (id: string) => string };\n\nconst moduleRequire = createRequire(import.meta.url);\nconst executableDirRequire = createRequire(pathToFileURL(join(dirname(process.execPath), \"package.json\")).href);\n\nfunction isOfflineModeEnabled(): boolean {\n\tconst value = process.env.PI_OFFLINE;\n\tif (!value) return false;\n\treturn value === \"1\" || value.toLowerCase() === \"true\" || value.toLowerCase() === \"yes\";\n}\n\ninterface ToolConfig {\n\tname: string;\n\trepo: string; // GitHub repo (e.g., \"sharkdp/fd\")\n\tbinaryName: string; // Name of the binary inside the archive\n\tsystemBinaryNames?: string[]; // Alternative system command names to try before downloading\n\ttagPrefix: string; // Prefix for tags (e.g., \"v\" for v1.0.0, \"\" for 1.0.0)\n\tgetAssetName: (version: string, plat: string, architecture: string) => string | null;\n\tpinnedVersion?: string;\n\tsha256ByAsset?: Readonly<Record<string, string>>;\n}\n\nconst TOOLS: Record<\"fd\" | \"rg\" | \"uv\", ToolConfig> = {\n\tfd: {\n\t\tname: \"fd\",\n\t\trepo: \"sharkdp/fd\",\n\t\tbinaryName: \"fd\",\n\t\tsystemBinaryNames: [\"fd\", \"fdfind\"],\n\t\ttagPrefix: \"v\",\n\t\tgetAssetName: (version, plat, architecture) => {\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\trg: {\n\t\tname: \"ripgrep\",\n\t\trepo: \"BurntSushi/ripgrep\",\n\t\tbinaryName: \"rg\",\n\t\ttagPrefix: \"\",\n\t\tgetAssetName: (version, plat, architecture) => {\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `ripgrep-${version}-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\tif (architecture === \"arm64\") {\n\t\t\t\t\treturn `ripgrep-${version}-aarch64-unknown-linux-gnu.tar.gz`;\n\t\t\t\t}\n\t\t\t\treturn `ripgrep-${version}-x86_64-unknown-linux-musl.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `ripgrep-${version}-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\tuv: {\n\t\tname: \"uv\",\n\t\trepo: \"astral-sh/uv\",\n\t\tbinaryName: \"uv\",\n\t\tsystemBinaryNames: [\"uv\"],\n\t\ttagPrefix: \"\",\n\t\tpinnedVersion: UV_VERSION,\n\t\tgetAssetName: (_version, plat, architecture) => {\n\t\t\tif (architecture !== \"arm64\" && architecture !== \"x64\") return null;\n\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\tif (plat === \"darwin\") return `uv-${archStr}-apple-darwin.tar.gz`;\n\t\t\tif (plat === \"linux\") return `uv-${archStr}-unknown-linux-musl.tar.gz`;\n\t\t\tif (plat === \"win32\") return `uv-${archStr}-pc-windows-msvc.zip`;\n\t\t\treturn null;\n\t\t},\n\t\tsha256ByAsset: {\n\t\t\t\"uv-aarch64-apple-darwin.tar.gz\": \"33540eb7c883ab857eff79bd5ac2aa31fe27b595abecb4a9c003a2c998447232\",\n\t\t\t\"uv-aarch64-pc-windows-msvc.zip\": \"3248109afad3ec59baad299d324ff53de17e2d9a3b3e21580ffd26744b11e036\",\n\t\t\t\"uv-aarch64-unknown-linux-musl.tar.gz\": \"da10cdfa7d92212b7acb62021a0fd61bcf8580c58c3632ec915d10c3a1a7906b\",\n\t\t\t\"uv-x86_64-apple-darwin.tar.gz\": \"2ad79983127ffca7d77b77ce6a24278d7e4f7b817a1acf72fea5f8124b4aac5e\",\n\t\t\t\"uv-x86_64-pc-windows-msvc.zip\": \"0a23463216d09c6a72ff80ef5dc5a795f07dc1575cb84d24596c2f124a441b7b\",\n\t\t\t\"uv-x86_64-unknown-linux-musl.tar.gz\": \"f02146b371c35c287d860f003ece7345c86e358a3fd70a9b63700cd141ee7fb4\",\n\t\t},\n\t},\n};\n\nexport type ManagedToolName = keyof typeof TOOLS;\n\nexport interface PinnedToolAsset {\n\tversion: string;\n\tassetName: string;\n\texpectedSha256: string;\n}\n\nexport function getPinnedToolAsset(\n\ttool: ManagedToolName,\n\ttargetPlatform: string = platform(),\n\ttargetArchitecture: string = arch(),\n): PinnedToolAsset | null {\n\tconst config: ToolConfig = TOOLS[tool];\n\tif (!config.pinnedVersion || !config.sha256ByAsset) return null;\n\tconst assetName = config.getAssetName(config.pinnedVersion, targetPlatform, targetArchitecture);\n\tif (!assetName) return null;\n\tconst expectedSha256 = config.sha256ByAsset[assetName];\n\treturn expectedSha256 ? { version: config.pinnedVersion, assetName, expectedSha256 } : null;\n}\n\n// Check if a command exists in PATH by trying to run it\nfunction commandExists(cmd: string): boolean {\n\ttry {\n\t\tconst result = spawnSync(cmd, [\"--version\"], { stdio: \"pipe\", timeout: COMMAND_PROBE_TIMEOUT_MS });\n\t\t// Check for ENOENT error (command not found)\n\t\treturn result.error === undefined || result.error === null;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n// Get the path to a tool (system-wide or in our tools dir)\nexport function getToolPath(tool: ManagedToolName): string | null {\n\tconst config = TOOLS[tool];\n\tif (!config) return null;\n\n\t// Check our tools directory first\n\tconst localPath = join(TOOLS_DIR, config.binaryName + (platform() === \"win32\" ? \".exe\" : \"\"));\n\tif (existsSync(localPath)) {\n\t\treturn localPath;\n\t}\n\n\t// Check system PATH - if found, just return the command name (it's in PATH)\n\tconst systemBinaryNames = config.systemBinaryNames ?? [config.binaryName];\n\tfor (const systemBinaryName of systemBinaryNames) {\n\t\tif (commandExists(systemBinaryName)) {\n\t\t\treturn systemBinaryName;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/** Presence check for a SYSTEM tool the doctor only ever reports on -- never installs. */\nexport interface SystemToolStatus {\n\tpresent: boolean;\n\tcommand?: string;\n\tversion?: string;\n}\n\nconst PYTHON_COMMANDS = [\"python3\", \"python\"];\n\n/**\n * Detect a usable Python interpreter. SYSTEM tool (see src/core/doctor.ts):\n * the doctor reports presence/version, it never installs this itself.\n *\n * @param commands Override the candidate command names, for tests.\n */\nexport function detectPython(commands: readonly string[] = PYTHON_COMMANDS): SystemToolStatus {\n\tfor (const command of commands) {\n\t\ttry {\n\t\t\tconst result = spawnSync(command, [\"--version\"], { encoding: \"utf-8\", stdio: \"pipe\", timeout: 5_000 });\n\t\t\tif (result.error) continue;\n\t\t\t// Python 2 prints its version to stderr; Python 3 prints to stdout. Some\n\t\t\t// platforms' `python` alias is one or the other, so check both.\n\t\t\tconst version = `${result.stdout ?? \"\"}${result.stderr ?? \"\"}`.trim() || undefined;\n\t\t\tif (result.status !== 0 && !version) continue;\n\t\t\treturn { present: true, command, version };\n\t\t} catch {\n\t\t\t// Try the next candidate.\n\t\t}\n\t}\n\treturn { present: false };\n}\n\n/**\n * Runs `<command> --version` (or `versionArgs`) and returns its trimmed\n * combined stdout+stderr, or undefined if the command can't be run. Used by\n * the doctor (src/core/doctor.ts) to show a version alongside a tool it has\n * already located by some other means (e.g. getToolPath(\"rg\"), or the binary\n * path OllamaRuntime.detect() reports) -- callers that only need a yes/no\n * presence check should use commandExists/getToolPath/detectPython instead.\n */\nexport function probeVersion(command: string, versionArgs: readonly string[] = [\"--version\"]): string | undefined {\n\ttry {\n\t\tconst result = spawnSync(command, versionArgs, { encoding: \"utf-8\", stdio: \"pipe\", timeout: 5_000 });\n\t\tif (result.error) return undefined;\n\t\tconst output = `${result.stdout ?? \"\"}${result.stderr ?? \"\"}`.trim();\n\t\treturn output || undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n// Fetch latest release version from GitHub\nasync function getLatestVersion(repo: string): Promise<string> {\n\tconst response = await fetch(`https://api.github.com/repos/${repo}/releases/latest`, {\n\t\theaders: { \"User-Agent\": `${APP_NAME}-coding-agent` },\n\t\tsignal: AbortSignal.timeout(NETWORK_TIMEOUT_MS),\n\t});\n\n\tif (!response.ok) {\n\t\tthrow new Error(`GitHub API error: ${response.status}`);\n\t}\n\n\tconst data = (await response.json()) as { tag_name: string };\n\treturn data.tag_name.replace(/^v/, \"\");\n}\n\n// Download a file from URL\nasync function downloadFile(url: string, dest: string): Promise<void> {\n\tconst response = await fetch(url, {\n\t\tsignal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS),\n\t});\n\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to download: ${response.status}`);\n\t}\n\n\tif (!response.body) {\n\t\tthrow new Error(\"No response body\");\n\t}\n\n\tconst fileStream = createWriteStream(dest);\n\tawait pipeline(Readable.fromWeb(response.body as any), fileStream);\n}\n\nexport async function verifyFileSha256(filePath: string, expectedSha256: string): Promise<boolean> {\n\tconst hash = createHash(\"sha256\");\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst stream = createReadStream(filePath);\n\t\tstream.on(\"data\", (chunk) => hash.update(chunk));\n\t\tstream.once(\"error\", reject);\n\t\tstream.once(\"end\", resolve);\n\t});\n\treturn hash.digest(\"hex\") === expectedSha256.toLowerCase();\n}\n\nfunction findBinaryRecursively(rootDir: string, binaryFileName: string): string | null {\n\tconst stack: string[] = [rootDir];\n\n\twhile (stack.length > 0) {\n\t\tconst currentDir = stack.pop();\n\t\tif (!currentDir) continue;\n\n\t\tconst entries = readdirSync(currentDir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tconst fullPath = join(currentDir, entry.name);\n\t\t\tif (entry.isFile() && entry.name === binaryFileName) {\n\t\t\t\treturn fullPath;\n\t\t\t}\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tstack.push(fullPath);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction formatSpawnFailure(result: SpawnSyncReturns<Buffer>): string {\n\tif (result.error?.message) {\n\t\treturn result.error.message;\n\t}\n\tconst stderr = result.stderr?.toString().trim();\n\tif (stderr) {\n\t\treturn stderr;\n\t}\n\tconst stdout = result.stdout?.toString().trim();\n\tif (stdout) {\n\t\treturn stdout;\n\t}\n\treturn `exit status ${result.status ?? \"unknown\"}`;\n}\n\nfunction runExtractionCommand(command: string, args: string[]): string | null {\n\tconst result = spawnSync(command, args, { stdio: \"pipe\", timeout: ARCHIVE_EXTRACTION_TIMEOUT_MS });\n\tif (!result.error && result.status === 0) {\n\t\treturn null;\n\t}\n\treturn `${command}: ${formatSpawnFailure(result)}`;\n}\n\nfunction extractTarGzArchive(archivePath: string, extractDir: string, assetName: string): void {\n\tconst failure = runExtractionCommand(\"tar\", [\"xzf\", archivePath, \"-C\", extractDir]);\n\tif (failure) {\n\t\tthrow new Error(`Failed to extract ${assetName}: ${failure}`);\n\t}\n}\n\nfunction getWindowsTarCommand(): string {\n\tconst systemRoot = process.env.SystemRoot ?? process.env.WINDIR;\n\tif (systemRoot) {\n\t\tconst systemTar = join(systemRoot, \"System32\", \"tar.exe\");\n\t\tif (existsSync(systemTar)) {\n\t\t\treturn systemTar;\n\t\t}\n\t}\n\treturn \"tar.exe\";\n}\n\nfunction extractZipArchive(archivePath: string, extractDir: string, assetName: string): void {\n\tconst failures: string[] = [];\n\n\tif (platform() === \"win32\") {\n\t\t// Windows ships bsdtar as tar.exe, which supports zip files. Prefer the\n\t\t// System32 binary over Git Bash's GNU tar, which does not handle zip archives.\n\t\tconst tarFailure = runExtractionCommand(getWindowsTarCommand(), [\"xf\", archivePath, \"-C\", extractDir]);\n\t\tif (!tarFailure) return;\n\t\tfailures.push(tarFailure);\n\n\t\tconst script =\n\t\t\t\"& { param($archive, $destination) $ErrorActionPreference = 'Stop'; Expand-Archive -LiteralPath $archive -DestinationPath $destination -Force }\";\n\t\tconst powershellFailure = runExtractionCommand(\"powershell.exe\", [\n\t\t\t\"-NoLogo\",\n\t\t\t\"-NoProfile\",\n\t\t\t\"-NonInteractive\",\n\t\t\t\"-ExecutionPolicy\",\n\t\t\t\"Bypass\",\n\t\t\t\"-Command\",\n\t\t\tscript,\n\t\t\tarchivePath,\n\t\t\textractDir,\n\t\t]);\n\t\tif (!powershellFailure) return;\n\t\tfailures.push(powershellFailure);\n\t} else {\n\t\tconst unzipFailure = runExtractionCommand(\"unzip\", [\"-q\", archivePath, \"-d\", extractDir]);\n\t\tif (!unzipFailure) return;\n\t\tfailures.push(unzipFailure);\n\n\t\tconst tarFailure = runExtractionCommand(\"tar\", [\"xf\", archivePath, \"-C\", extractDir]);\n\t\tif (!tarFailure) return;\n\t\tfailures.push(tarFailure);\n\t}\n\n\tthrow new Error(`Failed to extract ${assetName}: ${failures.join(\"; \")}`);\n}\n\n// Download and install a tool\nconst toolDownloadPromises = new Map<ManagedToolName, Promise<string | undefined>>();\n\nexport function runExclusiveToolDownload(\n\ttool: ManagedToolName,\n\tinstaller: () => Promise<string | undefined>,\n): Promise<string | undefined> {\n\tconst existing = toolDownloadPromises.get(tool);\n\tif (existing) return existing;\n\tconst promise = installer().finally(() => {\n\t\tif (toolDownloadPromises.get(tool) === promise) {\n\t\t\ttoolDownloadPromises.delete(tool);\n\t\t}\n\t});\n\ttoolDownloadPromises.set(tool, promise);\n\treturn promise;\n}\n\nasync function downloadTool(tool: ManagedToolName): Promise<string> {\n\tconst config: ToolConfig = TOOLS[tool];\n\tif (!config) throw new Error(`Unknown tool: ${tool}`);\n\n\tconst plat = platform();\n\tconst architecture = arch();\n\n\t// Pinned tools are reproducible; legacy search tools retain their current latest-release behavior.\n\tlet version = config.pinnedVersion ?? (await getLatestVersion(config.repo));\n\tif (tool === \"fd\" && plat === \"darwin\" && architecture === \"x64\") {\n\t\tversion = \"10.3.0\";\n\t}\n\n\t// Get asset name for this platform\n\tconst assetName = config.getAssetName(version, plat, architecture);\n\tif (!assetName) {\n\t\tthrow new Error(`Unsupported platform: ${plat}/${architecture}`);\n\t}\n\n\t// Create tools directory\n\tmkdirSync(TOOLS_DIR, { recursive: true });\n\n\tconst downloadUrl = `https://github.com/${config.repo}/releases/download/${config.tagPrefix}${version}/${assetName}`;\n\tconst downloadWorkDir = getProcessWorkRun(getAgentDir(), \"downloads\", \"tools\").path;\n\tconst archivePath = join(downloadWorkDir, assetName);\n\tconst binaryExt = plat === \"win32\" ? \".exe\" : \"\";\n\tconst binaryPath = join(TOOLS_DIR, config.binaryName + binaryExt);\n\n\t// Download and verify pinned artifacts before extraction.\n\tawait downloadFile(downloadUrl, archivePath);\n\tconst expectedSha256 = config.sha256ByAsset?.[assetName];\n\tif (config.sha256ByAsset && !expectedSha256) {\n\t\tthrow new Error(`No pinned SHA-256 is registered for ${assetName}`);\n\t}\n\tif (expectedSha256 && !(await verifyFileSha256(archivePath, expectedSha256))) {\n\t\tthrow new Error(`SHA-256 verification failed for ${assetName}`);\n\t}\n\n\t// Extract into a unique temp directory. fd and rg downloads can run concurrently\n\t// during startup, so sharing a fixed directory causes races.\n\tconst extractDir = join(\n\t\tdownloadWorkDir,\n\t\t`extract-${config.binaryName}-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,\n\t);\n\tmkdirSync(extractDir, { recursive: true });\n\n\ttry {\n\t\tif (assetName.endsWith(\".tar.gz\")) {\n\t\t\textractTarGzArchive(archivePath, extractDir, assetName);\n\t\t} else if (assetName.endsWith(\".zip\")) {\n\t\t\textractZipArchive(archivePath, extractDir, assetName);\n\t\t} else {\n\t\t\tthrow new Error(`Unsupported archive format: ${assetName}`);\n\t\t}\n\n\t\t// Find the binary in extracted files. Some archives contain files directly\n\t\t// at root, others nest under a versioned subdirectory.\n\t\tconst binaryFileName = config.binaryName + binaryExt;\n\t\tconst extractedDir = join(extractDir, assetName.replace(/\\.(tar\\.gz|zip)$/, \"\"));\n\t\tconst extractedBinaryCandidates = [join(extractedDir, binaryFileName), join(extractDir, binaryFileName)];\n\t\tlet extractedBinary = extractedBinaryCandidates.find((candidate) => existsSync(candidate));\n\n\t\tif (!extractedBinary) {\n\t\t\textractedBinary = findBinaryRecursively(extractDir, binaryFileName) ?? undefined;\n\t\t}\n\n\t\tif (extractedBinary) {\n\t\t\trenameSync(extractedBinary, binaryPath);\n\t\t} else {\n\t\t\tthrow new Error(`Binary not found in archive: expected ${binaryFileName} under ${extractDir}`);\n\t\t}\n\n\t\t// Make executable (Unix only)\n\t\tif (plat !== \"win32\") {\n\t\t\tchmodSync(binaryPath, 0o755);\n\t\t}\n\t} finally {\n\t\t// Cleanup\n\t\trmSync(archivePath, { force: true });\n\t\trmSync(extractDir, { recursive: true, force: true });\n\t}\n\n\treturn binaryPath;\n}\n\n// Termux package names for tools\nconst TERMUX_PACKAGES: Record<ManagedToolName, string> = {\n\tfd: \"fd\",\n\trg: \"ripgrep\",\n\tuv: \"uv\",\n};\n\nconst FFF_PLATFORM_PACKAGES: Record<string, string> = {\n\t\"darwin/arm64\": \"@ff-labs/fff-bin-darwin-arm64\",\n\t\"darwin/x64\": \"@ff-labs/fff-bin-darwin-x64\",\n\t\"linux/arm64/glibc\": \"@ff-labs/fff-bin-linux-arm64-gnu\",\n\t\"linux/arm64/musl\": \"@ff-labs/fff-bin-linux-arm64-musl\",\n\t\"linux/x64/glibc\": \"@ff-labs/fff-bin-linux-x64-gnu\",\n\t\"linux/x64/musl\": \"@ff-labs/fff-bin-linux-x64-musl\",\n\t\"win32/arm64\": \"@ff-labs/fff-bin-win32-arm64\",\n\t\"win32/x64\": \"@ff-labs/fff-bin-win32-x64\",\n};\n\nlet fffNodeInstallPromise: Promise<unknown | undefined> | undefined;\n\nfunction detectLinuxLibc(): \"glibc\" | \"musl\" {\n\tlet output = \"\";\n\ttry {\n\t\tconst result = spawnSync(\"ldd\", [\"--version\"], { encoding: \"utf-8\", stdio: \"pipe\", timeout: 5000 });\n\t\toutput = `${result.stdout ?? \"\"}${result.stderr ?? \"\"}`;\n\t} catch (e: unknown) {\n\t\tconst err = e as { stdout?: string | Buffer; stderr?: string | Buffer };\n\t\toutput = `${String(err.stdout ?? \"\")}${String(err.stderr ?? \"\")}`;\n\t}\n\treturn output.toLowerCase().includes(\"musl\") ? \"musl\" : \"glibc\";\n}\n\nfunction getFffPlatformPackageName(): string | undefined {\n\tconst plat = platform();\n\tconst architecture = arch();\n\tif (plat === \"linux\") {\n\t\treturn FFF_PLATFORM_PACKAGES[`${plat}/${architecture}/${detectLinuxLibc()}`];\n\t}\n\treturn FFF_PLATFORM_PACKAGES[`${plat}/${architecture}`];\n}\n\nfunction createManagedFffRequire(): ModuleRequire | undefined {\n\tif (!existsSync(FFF_MANAGED_PACKAGE_JSON)) return undefined;\n\treturn createRequire(pathToFileURL(FFF_MANAGED_PACKAGE_JSON).href);\n}\n\nfunction findFffNodeDistEntry(startPath: string): string | undefined {\n\tlet currentDir = dirname(startPath);\n\twhile (currentDir !== dirname(currentDir)) {\n\t\tconst candidate = join(currentDir, \"node_modules\", \"@ff-labs\", \"fff-node\", \"dist\", \"src\", \"index.js\");\n\t\tif (existsSync(candidate)) return candidate;\n\t\tcurrentDir = dirname(currentDir);\n\t}\n\treturn undefined;\n}\n\nfunction loadFffNodeDistEntry(requireFff: ModuleRequire): unknown | undefined {\n\tif (!requireFff.resolve) return undefined;\n\ttry {\n\t\tconst ffiPath = requireFff.resolve(\"ffi-rs\");\n\t\tconst fffEntry = findFffNodeDistEntry(ffiPath);\n\t\treturn fffEntry ? requireFff(fffEntry) : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction loadFffNodeWith(requireFff: ModuleRequire): unknown | undefined {\n\ttry {\n\t\treturn requireFff(\"@ff-labs/fff-node\");\n\t} catch {\n\t\treturn loadFffNodeDistEntry(requireFff);\n\t}\n}\n\n/**\n * @param requires Override the resolution candidates, for tests (mirrors\n * fff-search-backend.ts's loadFffModule(requires?)). Whether this resolves\n * depends on the ambient environment -- @ff-labs/fff-node is a real npm\n * dependency (package.json), so moduleRequire succeeds wherever a normal\n * `npm install`/`npm ci` provisioned it (e.g. CI) even though it fails on a\n * dev checkout that never ran that install here (this repo resolves fff-node\n * via the separate managed-dir path instead). A test asserting \"nothing is\n * available\" must pass `[]` here rather than relying on that being true.\n */\nexport function loadAvailableFffNodePackage(requires?: readonly ModuleRequire[]): unknown | undefined {\n\tconst candidates =\n\t\trequires ??\n\t\t[moduleRequire, executableDirRequire, createManagedFffRequire()].filter((candidate): candidate is ModuleRequire =>\n\t\t\tBoolean(candidate),\n\t\t);\n\tfor (const requireFff of candidates) {\n\t\tconst loaded = loadFffNodeWith(requireFff);\n\t\tif (loaded) return loaded;\n\t}\n\treturn undefined;\n}\n\nasync function runNpmInstall(args: string[]): Promise<{ code: number | null; stderr: string }> {\n\ttry {\n\t\tconst child = spawnProcess(\"npm\", args, {\n\t\t\tdetached: process.platform !== \"win32\",\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\t\tlet stderr = \"\";\n\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\tstderr = `${stderr}${chunk.toString()}`.slice(-64 * 1024);\n\t\t});\n\t\tconst terminal = await waitForChildProcessWithTermination(child, {\n\t\t\ttimeoutMs: ARCHIVE_EXTRACTION_TIMEOUT_MS,\n\t\t\tkillGraceMs: 2_000,\n\t\t});\n\t\tif (terminal.reason === \"timeout\") {\n\t\t\tstderr = `${stderr}\\nnpm install timed out after ${ARCHIVE_EXTRACTION_TIMEOUT_MS}ms`.trim();\n\t\t}\n\t\treturn { code: terminal.code, stderr };\n\t} catch (error) {\n\t\treturn { code: 1, stderr: error instanceof Error ? error.message : String(error) };\n\t}\n}\n\n/**\n * Outcome of the most recent {@link ensureFffNodePackage} call, kept for\n * observability (e.g. a future `doctor` check) since the function itself\n * only ever returns the loaded module or `undefined` either way.\n *\n * `install-failed` is distinguished from `offline`/`unsupported-platform`\n * because it is the only one worth *retrying*: offline mode and an\n * unsupported platform are stable for the life of the process, but a real\n * install attempt can fail on a transient issue (registry hiccup, timeout)\n * that may no longer apply on the next search. See\n * DefaultFffSearchBackend.getFinder in fff-search-backend.ts, which uses\n * this distinction to decide whether a failed finder is retryable.\n */\nexport type FffInstallOutcome =\n\t| { status: \"already-available\" }\n\t| { status: \"offline\" }\n\t| { status: \"unsupported-platform\" }\n\t| { status: \"installed\" }\n\t| { status: \"install-failed\"; reason: string };\n\n/**\n * How long a genuine install failure gates out a NEW npm spawn. An agent turn\n * can fire several find/grep calls in quick succession, and each one now\n * primes the finder in the background (see tryFffFind/tryFffGrep) -- without\n * this, a persistently-failing install (registry down, disk full, ...) would\n * re-spawn npm on every single one of those calls instead of once.\n *\n * This gates the SPAWN inside ensureFffNodePackage, not whether a failed\n * finder is retryable (see isFffInstallRetryable): DefaultFffSearchBackend\n * always evicts a failed finder so the next search re-enters this function,\n * and it is THIS cooldown check -- evaluated fresh, at call time -- that\n * decides whether that re-entry is a real attempt or a fast, spawn-free bail.\n * (An earlier version conflated the two: it gated eviction itself on the\n * cooldown, which is checked once, immediately after the failure it's timing\n * -- i.e. always still within the window -- so the failed finder was never\n * evicted and the retry never got a chance to happen at all.)\n */\nexport const FFF_INSTALL_RETRY_COOLDOWN_MS = 30_000;\n\nlet lastFffInstallOutcome: FffInstallOutcome | undefined;\nlet lastFffInstallFailureAt: number | undefined;\n\n/** The outcome of the last {@link ensureFffNodePackage} call, if any. */\nexport function getLastFffInstallOutcome(): FffInstallOutcome | undefined {\n\treturn lastFffInstallOutcome;\n}\n\n/** Whether the last install outcome was a genuine failure worth retrying (as opposed to a stable \"not applicable\" result). Cooldown-independent by design -- see FFF_INSTALL_RETRY_COOLDOWN_MS. */\nexport function isFffInstallRetryable(): boolean {\n\treturn lastFffInstallOutcome?.status === \"install-failed\";\n}\n\n/**\n * Pure decision logic behind {@link isFffInstallCoolingDown}, exposed directly\n * so tests can assert the cooldown boundary without faking the system clock.\n */\nexport function computeIsFffInstallCoolingDown(\n\toutcome: FffInstallOutcome | undefined,\n\tfailedAt: number | undefined,\n\tnow: number,\n): boolean {\n\tif (outcome?.status !== \"install-failed\") return false;\n\tif (failedAt === undefined) return false;\n\treturn now - failedAt < FFF_INSTALL_RETRY_COOLDOWN_MS;\n}\n\n/** Whether a real install attempt happened too recently to try again right now. */\nfunction isFffInstallCoolingDown(): boolean {\n\treturn computeIsFffInstallCoolingDown(lastFffInstallOutcome, lastFffInstallFailureAt, Date.now());\n}\n\n/** Records a genuine install failure and stamps when it happened, so the cooldown above has a start time to measure from. */\nfunction recordFffInstallFailure(reason: string): void {\n\tlastFffInstallOutcome = { status: \"install-failed\", reason };\n\tlastFffInstallFailureAt = Date.now();\n}\n\nasync function installManagedFffNodePackage(platformPackage: string, silent: boolean): Promise<unknown | undefined> {\n\ttry {\n\t\tmkdirSync(FFF_MANAGED_DIR, { recursive: true });\n\t\tif (!existsSync(FFF_MANAGED_PACKAGE_JSON)) {\n\t\t\twriteFileSync(FFF_MANAGED_PACKAGE_JSON, '{\"name\":\"pi-managed-fff-node\",\"private\":true,\"version\":\"0.0.0\"}\\n');\n\t\t}\n\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.dim(\"FFF native search not found. Installing managed FFF package...\"));\n\t\t}\n\n\t\tconst args = [\n\t\t\t\"install\",\n\t\t\t\"--ignore-scripts\",\n\t\t\t\"--omit=dev\",\n\t\t\t\"--include=optional\",\n\t\t\t\"--no-audit\",\n\t\t\t\"--no-fund\",\n\t\t\t\"--package-lock=false\",\n\t\t\t\"--prefix\",\n\t\t\tFFF_MANAGED_DIR,\n\t\t\t`@ff-labs/fff-node@${FFF_NODE_VERSION}`,\n\t\t\t`${platformPackage}@${FFF_NODE_VERSION}`,\n\t\t];\n\t\tconst result = await runNpmInstall(args);\n\t\tif (result.code !== 0) {\n\t\t\tconst reason = result.stderr.trim() || `npm exited with code ${result.code}`;\n\t\t\tif (!silent) {\n\t\t\t\tconsole.log(chalk.yellow(`Failed to install FFF native search: ${reason}`));\n\t\t\t}\n\t\t\trecordFffInstallFailure(reason);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst loaded = loadFffNodeWith(createRequire(pathToFileURL(FFF_MANAGED_PACKAGE_JSON).href));\n\t\tif (!loaded) {\n\t\t\tconst reason = \"Managed FFF install completed but @ff-labs/fff-node could not be loaded.\";\n\t\t\tif (!silent) {\n\t\t\t\tconsole.log(chalk.yellow(reason));\n\t\t\t}\n\t\t\trecordFffInstallFailure(reason);\n\t\t\treturn undefined;\n\t\t}\n\t\tlastFffInstallOutcome = { status: \"installed\" };\n\t\treturn loaded;\n\t} catch (error) {\n\t\t// Never let a filesystem/spawn surprise (e.g. a read-only home directory)\n\t\t// crash the caller: fall back like any other install failure, but keep\n\t\t// the reason observable.\n\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`Failed to install FFF native search: ${reason}`));\n\t\t}\n\t\trecordFffInstallFailure(reason);\n\t\treturn undefined;\n\t}\n}\n\nexport async function ensureFffNodePackage(\n\tsilent: boolean = false,\n\tforceManagedInstall: boolean = false,\n\t/** Override the \"is it already available\" resolution candidates, for tests. See loadAvailableFffNodePackage's doc. */\n\trequires?: readonly ModuleRequire[],\n): Promise<unknown | undefined> {\n\tconst existing = forceManagedInstall ? undefined : loadAvailableFffNodePackage(requires);\n\tif (existing) {\n\t\tlastFffInstallOutcome = { status: \"already-available\" };\n\t\treturn existing;\n\t}\n\n\tif (isOfflineModeEnabled()) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(\"FFF native search not found. Offline mode enabled, skipping install.\"));\n\t\t}\n\t\tlastFffInstallOutcome = { status: \"offline\" };\n\t\treturn undefined;\n\t}\n\n\t// A prior attempt failed too recently to try again: bail out fast (no npm\n\t// spawn, no platform/libc probing) rather than repeating a doomed attempt.\n\t// Leaves lastFffInstallOutcome/lastFffInstallFailureAt untouched -- this\n\t// isn't a new attempt, so there's nothing new to record.\n\tif (isFffInstallCoolingDown()) {\n\t\treturn undefined;\n\t}\n\n\tconst platformPackage = getFffPlatformPackageName();\n\tif (!platformPackage) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`FFF native search is not available for ${platform()}/${arch()}.`));\n\t\t}\n\t\tlastFffInstallOutcome = { status: \"unsupported-platform\" };\n\t\treturn undefined;\n\t}\n\n\tfffNodeInstallPromise ??= installManagedFffNodePackage(platformPackage, silent).finally(() => {\n\t\tfffNodeInstallPromise = undefined;\n\t});\n\treturn fffNodeInstallPromise;\n}\n\nasync function installTermuxManagedTool(tool: ManagedToolName, silent: boolean): Promise<string | undefined> {\n\tconst packageName = TERMUX_PACKAGES[tool];\n\tif (!silent) console.log(chalk.dim(`${TOOLS[tool].name} not found. Installing with Termux pkg...`));\n\tconst child = spawnProcess(\"pkg\", [\"install\", \"-y\", packageName], {\n\t\tenv: process.env,\n\t\tstdio: silent ? \"ignore\" : \"inherit\",\n\t});\n\tconst terminal = await waitForChildProcessWithTermination(child, { timeoutMs: 300_000, killGraceMs: 5_000 });\n\tif (terminal.reason !== \"exited\" || terminal.code !== 0) {\n\t\tthrow new Error(\n\t\t\t`pkg install ${packageName} ${terminal.reason === \"timeout\" ? \"timed out\" : `exited with code ${terminal.code ?? 1}`}`,\n\t\t);\n\t}\n\treturn getToolPath(tool) ?? undefined;\n}\n\n// Ensure a tool is available, downloading if necessary\n// Returns the path to the tool, or undefined if unavailable\nexport async function ensureTool(tool: ManagedToolName, silent: boolean = false): Promise<string | undefined> {\n\tconst existingPath = getToolPath(tool);\n\tif (existingPath) {\n\t\treturn existingPath;\n\t}\n\n\tconst config = TOOLS[tool];\n\tif (!config) return undefined;\n\n\tif (isOfflineModeEnabled()) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`${config.name} not found. Offline mode enabled, skipping download.`));\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t// On Android/Termux, upstream Linux archives target glibc/musl rather than Bionic.\n\t// uv is a required managed runtime and the user explicitly authorized provisioning it;\n\t// preserve guide-only behavior for optional search tools.\n\tif (platform() === \"android\") {\n\t\tif (tool !== \"uv\") {\n\t\t\tconst packageName = TERMUX_PACKAGES[tool];\n\t\t\tif (!silent) console.log(chalk.yellow(`${config.name} not found. Install with: pkg install ${packageName}`));\n\t\t\treturn undefined;\n\t\t}\n\t\ttry {\n\t\t\treturn await runExclusiveToolDownload(tool, () => installTermuxManagedTool(tool, silent));\n\t\t} catch (error) {\n\t\t\tif (!silent) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.yellow(`Failed to install ${config.name}: ${error instanceof Error ? error.message : error}`),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t// Tool not found - download it\n\tif (!silent) {\n\t\tconsole.log(chalk.dim(`${config.name} not found. Downloading...`));\n\t}\n\n\ttry {\n\t\tconst path = await runExclusiveToolDownload(tool, () => downloadTool(tool));\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.dim(`${config.name} installed to ${path}`));\n\t\t}\n\t\treturn path;\n\t} catch (e) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`Failed to download ${config.name}: ${e instanceof Error ? e.message : e}`));\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"tools-manager.js","sourceRoot":"","sources":["../../src/utils/tools-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport chalk from \"chalk\";\nimport { type SpawnSyncReturns, spawnSync } from \"child_process\";\nimport {\n\taccessSync,\n\tchmodSync,\n\tcreateReadStream,\n\tcreateWriteStream,\n\texistsSync,\n\tconstants as fsConstants,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trenameSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from \"fs\";\nimport { createRequire } from \"module\";\nimport { arch, platform } from \"os\";\nimport { dirname, join } from \"path\";\nimport { Readable } from \"stream\";\nimport { pipeline } from \"stream/promises\";\nimport { pathToFileURL } from \"url\";\nimport { APP_NAME, getAgentDir, getBinDir } from \"../config.ts\";\nimport { cacheDir as agentCacheDir, cacheFile } from \"../core/agent-paths.ts\";\nimport { spawnProcess, waitForChildProcessWithTermination } from \"./child-process.ts\";\nimport { getProcessWorkRun } from \"./work-directory.ts\";\n\nconst TOOLS_DIR = getBinDir();\nconst NETWORK_TIMEOUT_MS = 10_000;\nconst DOWNLOAD_TIMEOUT_MS = 120_000;\nconst COMMAND_PROBE_TIMEOUT_MS = 5_000;\nconst ARCHIVE_EXTRACTION_TIMEOUT_MS = 5 * 60_000;\nconst FFF_NODE_VERSION = \"0.9.6\";\nexport const UV_VERSION = \"0.11.28\";\nconst FFF_MANAGED_DIR = join(TOOLS_DIR, \"fff-node\");\nconst FFF_MANAGED_PACKAGE_JSON = join(FFF_MANAGED_DIR, \"package.json\");\n\ntype ModuleRequire = ((id: string) => unknown) & { resolve?: (id: string) => string };\n\nconst moduleRequire = createRequire(import.meta.url);\nconst executableDirRequire = createRequire(pathToFileURL(join(dirname(process.execPath), \"package.json\")).href);\n\nfunction isOfflineModeEnabled(): boolean {\n\tconst value = process.env.PI_OFFLINE;\n\tif (!value) return false;\n\treturn value === \"1\" || value.toLowerCase() === \"true\" || value.toLowerCase() === \"yes\";\n}\n\ninterface ToolConfig {\n\tname: string;\n\trepo: string; // GitHub repo (e.g., \"sharkdp/fd\")\n\tbinaryName: string; // Name of the binary inside the archive\n\tsystemBinaryNames?: string[]; // Alternative system command names to try before downloading\n\ttagPrefix: string; // Prefix for tags (e.g., \"v\" for v1.0.0, \"\" for 1.0.0)\n\tgetAssetName: (version: string, plat: string, architecture: string) => string | null;\n\tpinnedVersion?: string;\n\tsha256ByAsset?: Readonly<Record<string, string>>;\n}\n\nconst TOOLS: Record<\"fd\" | \"rg\" | \"uv\", ToolConfig> = {\n\tfd: {\n\t\tname: \"fd\",\n\t\trepo: \"sharkdp/fd\",\n\t\tbinaryName: \"fd\",\n\t\tsystemBinaryNames: [\"fd\", \"fdfind\"],\n\t\ttagPrefix: \"v\",\n\t\tgetAssetName: (version, plat, architecture) => {\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\trg: {\n\t\tname: \"ripgrep\",\n\t\trepo: \"BurntSushi/ripgrep\",\n\t\tbinaryName: \"rg\",\n\t\ttagPrefix: \"\",\n\t\tgetAssetName: (version, plat, architecture) => {\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `ripgrep-${version}-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\tif (architecture === \"arm64\") {\n\t\t\t\t\treturn `ripgrep-${version}-aarch64-unknown-linux-gnu.tar.gz`;\n\t\t\t\t}\n\t\t\t\treturn `ripgrep-${version}-x86_64-unknown-linux-musl.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `ripgrep-${version}-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\tuv: {\n\t\tname: \"uv\",\n\t\trepo: \"astral-sh/uv\",\n\t\tbinaryName: \"uv\",\n\t\tsystemBinaryNames: [\"uv\"],\n\t\ttagPrefix: \"\",\n\t\tpinnedVersion: UV_VERSION,\n\t\tgetAssetName: (_version, plat, architecture) => {\n\t\t\tif (architecture !== \"arm64\" && architecture !== \"x64\") return null;\n\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\tif (plat === \"darwin\") return `uv-${archStr}-apple-darwin.tar.gz`;\n\t\t\tif (plat === \"linux\") return `uv-${archStr}-unknown-linux-musl.tar.gz`;\n\t\t\tif (plat === \"win32\") return `uv-${archStr}-pc-windows-msvc.zip`;\n\t\t\treturn null;\n\t\t},\n\t\tsha256ByAsset: {\n\t\t\t\"uv-aarch64-apple-darwin.tar.gz\": \"33540eb7c883ab857eff79bd5ac2aa31fe27b595abecb4a9c003a2c998447232\",\n\t\t\t\"uv-aarch64-pc-windows-msvc.zip\": \"3248109afad3ec59baad299d324ff53de17e2d9a3b3e21580ffd26744b11e036\",\n\t\t\t\"uv-aarch64-unknown-linux-musl.tar.gz\": \"da10cdfa7d92212b7acb62021a0fd61bcf8580c58c3632ec915d10c3a1a7906b\",\n\t\t\t\"uv-x86_64-apple-darwin.tar.gz\": \"2ad79983127ffca7d77b77ce6a24278d7e4f7b817a1acf72fea5f8124b4aac5e\",\n\t\t\t\"uv-x86_64-pc-windows-msvc.zip\": \"0a23463216d09c6a72ff80ef5dc5a795f07dc1575cb84d24596c2f124a441b7b\",\n\t\t\t\"uv-x86_64-unknown-linux-musl.tar.gz\": \"f02146b371c35c287d860f003ece7345c86e358a3fd70a9b63700cd141ee7fb4\",\n\t\t},\n\t},\n};\n\nexport type ManagedToolName = keyof typeof TOOLS;\n\nexport interface PinnedToolAsset {\n\tversion: string;\n\tassetName: string;\n\texpectedSha256: string;\n}\n\nexport function getPinnedToolAsset(\n\ttool: ManagedToolName,\n\ttargetPlatform: string = platform(),\n\ttargetArchitecture: string = arch(),\n): PinnedToolAsset | null {\n\tconst config: ToolConfig = TOOLS[tool];\n\tif (!config.pinnedVersion || !config.sha256ByAsset) return null;\n\tconst assetName = config.getAssetName(config.pinnedVersion, targetPlatform, targetArchitecture);\n\tif (!assetName) return null;\n\tconst expectedSha256 = config.sha256ByAsset[assetName];\n\treturn expectedSha256 ? { version: config.pinnedVersion, assetName, expectedSha256 } : null;\n}\n\n// Check if a command exists in PATH by trying to run it\nfunction commandExists(cmd: string): boolean {\n\ttry {\n\t\tconst result = spawnSync(cmd, [\"--version\"], { stdio: \"pipe\", timeout: COMMAND_PROBE_TIMEOUT_MS });\n\t\t// Check for ENOENT error (command not found)\n\t\treturn result.error === undefined || result.error === null;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\ninterface CachedToolPath {\n\tpath: string;\n\tmtimeMs: number;\n}\n\nfunction isCachedToolPath(value: unknown): value is CachedToolPath {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tconst candidate = value as Record<string, unknown>;\n\treturn typeof candidate.path === \"string\" && typeof candidate.mtimeMs === \"number\";\n}\n\nfunction getToolPathCacheFile(): string {\n\treturn cacheFile(getAgentDir(), \"tool-paths.json\");\n}\n\n/** Read the persisted cross-run tool-path cache. Missing/corrupt/foreign entries are dropped silently -- a cold cache just means the next resolve re-probes and repopulates it. */\nfunction readToolPathCache(): Partial<Record<ManagedToolName, CachedToolPath>> {\n\ttry {\n\t\tconst raw = readFileSync(getToolPathCacheFile(), \"utf-8\");\n\t\tconst parsed = JSON.parse(raw) as Record<string, unknown>;\n\t\tconst cache: Partial<Record<ManagedToolName, CachedToolPath>> = {};\n\t\tfor (const tool of Object.keys(TOOLS) as ManagedToolName[]) {\n\t\t\tconst entry = parsed[tool];\n\t\t\tif (isCachedToolPath(entry)) cache[tool] = entry;\n\t\t}\n\t\treturn cache;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction writeToolPathCacheEntry(tool: ManagedToolName, entry: CachedToolPath): void {\n\ttry {\n\t\tconst cacheDir = agentCacheDir(getAgentDir());\n\t\tmkdirSync(cacheDir, { recursive: true });\n\t\tconst cache = readToolPathCache();\n\t\tcache[tool] = entry;\n\t\twriteFileSync(join(cacheDir, \"tool-paths.json\"), JSON.stringify(cache));\n\t} catch {\n\t\t// Best-effort: a failed cache write only costs the next run its probe, same as a cold cache.\n\t}\n}\n\n/** A cached entry is fresh only while its file still exists at the same path with the same mtime -- a deleted/moved/replaced binary invalidates it and forces a re-probe below. */\nfunction isCachedToolPathFresh(entry: CachedToolPath): boolean {\n\ttry {\n\t\treturn statSync(entry.path).mtimeMs === entry.mtimeMs;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction getPathExtensionCandidates(): readonly string[] {\n\tif (platform() !== \"win32\") return [\"\"];\n\tconst pathExt = process.env.PATHEXT || \".COM;.EXE;.BAT;.CMD\";\n\treturn [\"\", ...pathExt.split(\";\").filter(Boolean)];\n}\n\n/**\n * Manually walk PATH to turn a bare command name that commandExists() already confirmed is\n * runnable into an absolute, stat-checkable path. This never decides presence itself (that stays\n * commandExists's job via spawnSync, unchanged) -- it only supplies the path the cross-run cache\n * needs for its mtime staleness check, using stat calls instead of another spawn.\n */\nfunction resolveOnSystemPath(binaryName: string): string | null {\n\tconst pathEnv = process.env.PATH ?? \"\";\n\tconst dirs = pathEnv.split(platform() === \"win32\" ? \";\" : \":\").filter(Boolean);\n\tfor (const dir of dirs) {\n\t\tfor (const ext of getPathExtensionCandidates()) {\n\t\t\tconst candidate = join(dir, binaryName + ext);\n\t\t\tif (!existsSync(candidate)) continue;\n\t\t\ttry {\n\t\t\t\tif (statSync(candidate).isDirectory()) continue;\n\t\t\t\tif (platform() !== \"win32\") accessSync(candidate, fsConstants.X_OK);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\treturn candidate;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction cacheResolvedSystemPath(tool: ManagedToolName, resolvedPath: string): void {\n\ttry {\n\t\twriteToolPathCacheEntry(tool, { path: resolvedPath, mtimeMs: statSync(resolvedPath).mtimeMs });\n\t} catch {\n\t\t// Stat raced with a delete between resolve and here: nothing to cache, still return the path below.\n\t}\n}\n\n// Get the path to a tool (system-wide or in our tools dir)\nexport function getToolPath(tool: ManagedToolName): string | null {\n\tconst config = TOOLS[tool];\n\tif (!config) return null;\n\n\t// Check our tools directory first\n\tconst localPath = join(TOOLS_DIR, config.binaryName + (platform() === \"win32\" ? \".exe\" : \"\"));\n\tif (existsSync(localPath)) {\n\t\treturn localPath;\n\t}\n\n\t// Check system PATH - if found, just return the command name (it's in PATH)\n\tconst systemBinaryNames = config.systemBinaryNames ?? [config.binaryName];\n\n\t// A system-PATH resolution normally requires commandExists's synchronous\n\t// spawnSync(`<name> --version`) probe below, which is expensive to pay on every process\n\t// startup (this runs once per tool at interactive-mode init, plus again on the first\n\t// find/grep tool call). Persist the resolved absolute path + mtime across runs\n\t// (<agentDir>/cache/tool-paths.json) so a warm run can skip the probe entirely and just\n\t// stat the cached path instead. KNOWN LIMITATION: if a *different* binary of the same name\n\t// starts shadowing the cached one earlier on PATH (e.g. a new install) while the\n\t// originally-cached file itself is untouched, this cache keeps returning the old path until\n\t// that file is deleted/modified -- an intentional narrow staleness window (the returned tool\n\t// still exists and runs; it just isn't the newly-shadowing one), not a correctness bug.\n\tconst cached = readToolPathCache()[tool];\n\tif (cached && isCachedToolPathFresh(cached)) {\n\t\treturn cached.path;\n\t}\n\n\tfor (const systemBinaryName of systemBinaryNames) {\n\t\tif (commandExists(systemBinaryName)) {\n\t\t\tconst resolved = resolveOnSystemPath(systemBinaryName);\n\t\t\tif (resolved) {\n\t\t\t\tcacheResolvedSystemPath(tool, resolved);\n\t\t\t\treturn resolved;\n\t\t\t}\n\t\t\t// Could not resolve an absolute path to cache (e.g. PATH env raced between the two\n\t\t\t// lookups); still return the bare name so the caller keeps working, uncached.\n\t\t\treturn systemBinaryName;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/** Presence check for a SYSTEM tool the doctor only ever reports on -- never installs. */\nexport interface SystemToolStatus {\n\tpresent: boolean;\n\tcommand?: string;\n\tversion?: string;\n}\n\nconst PYTHON_COMMANDS = [\"python3\", \"python\"];\n\n/**\n * Detect a usable Python interpreter. SYSTEM tool (see src/core/doctor.ts):\n * the doctor reports presence/version, it never installs this itself.\n *\n * @param commands Override the candidate command names, for tests.\n */\nexport function detectPython(commands: readonly string[] = PYTHON_COMMANDS): SystemToolStatus {\n\tfor (const command of commands) {\n\t\ttry {\n\t\t\tconst result = spawnSync(command, [\"--version\"], { encoding: \"utf-8\", stdio: \"pipe\", timeout: 5_000 });\n\t\t\tif (result.error) continue;\n\t\t\t// Python 2 prints its version to stderr; Python 3 prints to stdout. Some\n\t\t\t// platforms' `python` alias is one or the other, so check both.\n\t\t\tconst version = `${result.stdout ?? \"\"}${result.stderr ?? \"\"}`.trim() || undefined;\n\t\t\tif (result.status !== 0 && !version) continue;\n\t\t\treturn { present: true, command, version };\n\t\t} catch {\n\t\t\t// Try the next candidate.\n\t\t}\n\t}\n\treturn { present: false };\n}\n\n/**\n * Runs `<command> --version` (or `versionArgs`) and returns its trimmed\n * combined stdout+stderr, or undefined if the command can't be run. Used by\n * the doctor (src/core/doctor.ts) to show a version alongside a tool it has\n * already located by some other means (e.g. getToolPath(\"rg\"), or the binary\n * path OllamaRuntime.detect() reports) -- callers that only need a yes/no\n * presence check should use commandExists/getToolPath/detectPython instead.\n */\nexport function probeVersion(command: string, versionArgs: readonly string[] = [\"--version\"]): string | undefined {\n\ttry {\n\t\tconst result = spawnSync(command, versionArgs, { encoding: \"utf-8\", stdio: \"pipe\", timeout: 5_000 });\n\t\tif (result.error) return undefined;\n\t\tconst output = `${result.stdout ?? \"\"}${result.stderr ?? \"\"}`.trim();\n\t\treturn output || undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n// Fetch latest release version from GitHub\nasync function getLatestVersion(repo: string): Promise<string> {\n\tconst response = await fetch(`https://api.github.com/repos/${repo}/releases/latest`, {\n\t\theaders: { \"User-Agent\": `${APP_NAME}-coding-agent` },\n\t\tsignal: AbortSignal.timeout(NETWORK_TIMEOUT_MS),\n\t});\n\n\tif (!response.ok) {\n\t\tthrow new Error(`GitHub API error: ${response.status}`);\n\t}\n\n\tconst data = (await response.json()) as { tag_name: string };\n\treturn data.tag_name.replace(/^v/, \"\");\n}\n\n// Download a file from URL\nasync function downloadFile(url: string, dest: string): Promise<void> {\n\tconst response = await fetch(url, {\n\t\tsignal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS),\n\t});\n\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to download: ${response.status}`);\n\t}\n\n\tif (!response.body) {\n\t\tthrow new Error(\"No response body\");\n\t}\n\n\tconst fileStream = createWriteStream(dest);\n\tawait pipeline(Readable.fromWeb(response.body as any), fileStream);\n}\n\nexport async function verifyFileSha256(filePath: string, expectedSha256: string): Promise<boolean> {\n\tconst hash = createHash(\"sha256\");\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst stream = createReadStream(filePath);\n\t\tstream.on(\"data\", (chunk) => hash.update(chunk));\n\t\tstream.once(\"error\", reject);\n\t\tstream.once(\"end\", resolve);\n\t});\n\treturn hash.digest(\"hex\") === expectedSha256.toLowerCase();\n}\n\nfunction findBinaryRecursively(rootDir: string, binaryFileName: string): string | null {\n\tconst stack: string[] = [rootDir];\n\n\twhile (stack.length > 0) {\n\t\tconst currentDir = stack.pop();\n\t\tif (!currentDir) continue;\n\n\t\tconst entries = readdirSync(currentDir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tconst fullPath = join(currentDir, entry.name);\n\t\t\tif (entry.isFile() && entry.name === binaryFileName) {\n\t\t\t\treturn fullPath;\n\t\t\t}\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tstack.push(fullPath);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction formatSpawnFailure(result: SpawnSyncReturns<Buffer>): string {\n\tif (result.error?.message) {\n\t\treturn result.error.message;\n\t}\n\tconst stderr = result.stderr?.toString().trim();\n\tif (stderr) {\n\t\treturn stderr;\n\t}\n\tconst stdout = result.stdout?.toString().trim();\n\tif (stdout) {\n\t\treturn stdout;\n\t}\n\treturn `exit status ${result.status ?? \"unknown\"}`;\n}\n\nfunction runExtractionCommand(command: string, args: string[]): string | null {\n\tconst result = spawnSync(command, args, { stdio: \"pipe\", timeout: ARCHIVE_EXTRACTION_TIMEOUT_MS });\n\tif (!result.error && result.status === 0) {\n\t\treturn null;\n\t}\n\treturn `${command}: ${formatSpawnFailure(result)}`;\n}\n\nfunction extractTarGzArchive(archivePath: string, extractDir: string, assetName: string): void {\n\tconst failure = runExtractionCommand(\"tar\", [\"xzf\", archivePath, \"-C\", extractDir]);\n\tif (failure) {\n\t\tthrow new Error(`Failed to extract ${assetName}: ${failure}`);\n\t}\n}\n\nfunction getWindowsTarCommand(): string {\n\tconst systemRoot = process.env.SystemRoot ?? process.env.WINDIR;\n\tif (systemRoot) {\n\t\tconst systemTar = join(systemRoot, \"System32\", \"tar.exe\");\n\t\tif (existsSync(systemTar)) {\n\t\t\treturn systemTar;\n\t\t}\n\t}\n\treturn \"tar.exe\";\n}\n\nfunction extractZipArchive(archivePath: string, extractDir: string, assetName: string): void {\n\tconst failures: string[] = [];\n\n\tif (platform() === \"win32\") {\n\t\t// Windows ships bsdtar as tar.exe, which supports zip files. Prefer the\n\t\t// System32 binary over Git Bash's GNU tar, which does not handle zip archives.\n\t\tconst tarFailure = runExtractionCommand(getWindowsTarCommand(), [\"xf\", archivePath, \"-C\", extractDir]);\n\t\tif (!tarFailure) return;\n\t\tfailures.push(tarFailure);\n\n\t\tconst script =\n\t\t\t\"& { param($archive, $destination) $ErrorActionPreference = 'Stop'; Expand-Archive -LiteralPath $archive -DestinationPath $destination -Force }\";\n\t\tconst powershellFailure = runExtractionCommand(\"powershell.exe\", [\n\t\t\t\"-NoLogo\",\n\t\t\t\"-NoProfile\",\n\t\t\t\"-NonInteractive\",\n\t\t\t\"-ExecutionPolicy\",\n\t\t\t\"Bypass\",\n\t\t\t\"-Command\",\n\t\t\tscript,\n\t\t\tarchivePath,\n\t\t\textractDir,\n\t\t]);\n\t\tif (!powershellFailure) return;\n\t\tfailures.push(powershellFailure);\n\t} else {\n\t\tconst unzipFailure = runExtractionCommand(\"unzip\", [\"-q\", archivePath, \"-d\", extractDir]);\n\t\tif (!unzipFailure) return;\n\t\tfailures.push(unzipFailure);\n\n\t\tconst tarFailure = runExtractionCommand(\"tar\", [\"xf\", archivePath, \"-C\", extractDir]);\n\t\tif (!tarFailure) return;\n\t\tfailures.push(tarFailure);\n\t}\n\n\tthrow new Error(`Failed to extract ${assetName}: ${failures.join(\"; \")}`);\n}\n\n// Download and install a tool\nconst toolDownloadPromises = new Map<ManagedToolName, Promise<string | undefined>>();\n\nexport function runExclusiveToolDownload(\n\ttool: ManagedToolName,\n\tinstaller: () => Promise<string | undefined>,\n): Promise<string | undefined> {\n\tconst existing = toolDownloadPromises.get(tool);\n\tif (existing) return existing;\n\tconst promise = installer().finally(() => {\n\t\tif (toolDownloadPromises.get(tool) === promise) {\n\t\t\ttoolDownloadPromises.delete(tool);\n\t\t}\n\t});\n\ttoolDownloadPromises.set(tool, promise);\n\treturn promise;\n}\n\nasync function downloadTool(tool: ManagedToolName): Promise<string> {\n\tconst config: ToolConfig = TOOLS[tool];\n\tif (!config) throw new Error(`Unknown tool: ${tool}`);\n\n\tconst plat = platform();\n\tconst architecture = arch();\n\n\t// Pinned tools are reproducible; legacy search tools retain their current latest-release behavior.\n\tlet version = config.pinnedVersion ?? (await getLatestVersion(config.repo));\n\tif (tool === \"fd\" && plat === \"darwin\" && architecture === \"x64\") {\n\t\tversion = \"10.3.0\";\n\t}\n\n\t// Get asset name for this platform\n\tconst assetName = config.getAssetName(version, plat, architecture);\n\tif (!assetName) {\n\t\tthrow new Error(`Unsupported platform: ${plat}/${architecture}`);\n\t}\n\n\t// Create tools directory\n\tmkdirSync(TOOLS_DIR, { recursive: true });\n\n\tconst downloadUrl = `https://github.com/${config.repo}/releases/download/${config.tagPrefix}${version}/${assetName}`;\n\tconst downloadWorkDir = getProcessWorkRun(getAgentDir(), \"downloads\", \"tools\").path;\n\tconst archivePath = join(downloadWorkDir, assetName);\n\tconst binaryExt = plat === \"win32\" ? \".exe\" : \"\";\n\tconst binaryPath = join(TOOLS_DIR, config.binaryName + binaryExt);\n\n\t// Download and verify pinned artifacts before extraction.\n\tawait downloadFile(downloadUrl, archivePath);\n\tconst expectedSha256 = config.sha256ByAsset?.[assetName];\n\tif (config.sha256ByAsset && !expectedSha256) {\n\t\tthrow new Error(`No pinned SHA-256 is registered for ${assetName}`);\n\t}\n\tif (expectedSha256 && !(await verifyFileSha256(archivePath, expectedSha256))) {\n\t\tthrow new Error(`SHA-256 verification failed for ${assetName}`);\n\t}\n\n\t// Extract into a unique temp directory. fd and rg downloads can run concurrently\n\t// during startup, so sharing a fixed directory causes races.\n\tconst extractDir = join(\n\t\tdownloadWorkDir,\n\t\t`extract-${config.binaryName}-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,\n\t);\n\tmkdirSync(extractDir, { recursive: true });\n\n\ttry {\n\t\tif (assetName.endsWith(\".tar.gz\")) {\n\t\t\textractTarGzArchive(archivePath, extractDir, assetName);\n\t\t} else if (assetName.endsWith(\".zip\")) {\n\t\t\textractZipArchive(archivePath, extractDir, assetName);\n\t\t} else {\n\t\t\tthrow new Error(`Unsupported archive format: ${assetName}`);\n\t\t}\n\n\t\t// Find the binary in extracted files. Some archives contain files directly\n\t\t// at root, others nest under a versioned subdirectory.\n\t\tconst binaryFileName = config.binaryName + binaryExt;\n\t\tconst extractedDir = join(extractDir, assetName.replace(/\\.(tar\\.gz|zip)$/, \"\"));\n\t\tconst extractedBinaryCandidates = [join(extractedDir, binaryFileName), join(extractDir, binaryFileName)];\n\t\tlet extractedBinary = extractedBinaryCandidates.find((candidate) => existsSync(candidate));\n\n\t\tif (!extractedBinary) {\n\t\t\textractedBinary = findBinaryRecursively(extractDir, binaryFileName) ?? undefined;\n\t\t}\n\n\t\tif (extractedBinary) {\n\t\t\trenameSync(extractedBinary, binaryPath);\n\t\t} else {\n\t\t\tthrow new Error(`Binary not found in archive: expected ${binaryFileName} under ${extractDir}`);\n\t\t}\n\n\t\t// Make executable (Unix only)\n\t\tif (plat !== \"win32\") {\n\t\t\tchmodSync(binaryPath, 0o755);\n\t\t}\n\t} finally {\n\t\t// Cleanup\n\t\trmSync(archivePath, { force: true });\n\t\trmSync(extractDir, { recursive: true, force: true });\n\t}\n\n\treturn binaryPath;\n}\n\n// Termux package names for tools\nconst TERMUX_PACKAGES: Record<ManagedToolName, string> = {\n\tfd: \"fd\",\n\trg: \"ripgrep\",\n\tuv: \"uv\",\n};\n\nconst FFF_PLATFORM_PACKAGES: Record<string, string> = {\n\t\"darwin/arm64\": \"@ff-labs/fff-bin-darwin-arm64\",\n\t\"darwin/x64\": \"@ff-labs/fff-bin-darwin-x64\",\n\t\"linux/arm64/glibc\": \"@ff-labs/fff-bin-linux-arm64-gnu\",\n\t\"linux/arm64/musl\": \"@ff-labs/fff-bin-linux-arm64-musl\",\n\t\"linux/x64/glibc\": \"@ff-labs/fff-bin-linux-x64-gnu\",\n\t\"linux/x64/musl\": \"@ff-labs/fff-bin-linux-x64-musl\",\n\t\"win32/arm64\": \"@ff-labs/fff-bin-win32-arm64\",\n\t\"win32/x64\": \"@ff-labs/fff-bin-win32-x64\",\n};\n\nlet fffNodeInstallPromise: Promise<unknown | undefined> | undefined;\n\nfunction detectLinuxLibc(): \"glibc\" | \"musl\" {\n\tlet output = \"\";\n\ttry {\n\t\tconst result = spawnSync(\"ldd\", [\"--version\"], { encoding: \"utf-8\", stdio: \"pipe\", timeout: 5000 });\n\t\toutput = `${result.stdout ?? \"\"}${result.stderr ?? \"\"}`;\n\t} catch (e: unknown) {\n\t\tconst err = e as { stdout?: string | Buffer; stderr?: string | Buffer };\n\t\toutput = `${String(err.stdout ?? \"\")}${String(err.stderr ?? \"\")}`;\n\t}\n\treturn output.toLowerCase().includes(\"musl\") ? \"musl\" : \"glibc\";\n}\n\nfunction getFffPlatformPackageName(): string | undefined {\n\tconst plat = platform();\n\tconst architecture = arch();\n\tif (plat === \"linux\") {\n\t\treturn FFF_PLATFORM_PACKAGES[`${plat}/${architecture}/${detectLinuxLibc()}`];\n\t}\n\treturn FFF_PLATFORM_PACKAGES[`${plat}/${architecture}`];\n}\n\nfunction createManagedFffRequire(): ModuleRequire | undefined {\n\tif (!existsSync(FFF_MANAGED_PACKAGE_JSON)) return undefined;\n\treturn createRequire(pathToFileURL(FFF_MANAGED_PACKAGE_JSON).href);\n}\n\nfunction findFffNodeDistEntry(startPath: string): string | undefined {\n\tlet currentDir = dirname(startPath);\n\twhile (currentDir !== dirname(currentDir)) {\n\t\tconst candidate = join(currentDir, \"node_modules\", \"@ff-labs\", \"fff-node\", \"dist\", \"src\", \"index.js\");\n\t\tif (existsSync(candidate)) return candidate;\n\t\tcurrentDir = dirname(currentDir);\n\t}\n\treturn undefined;\n}\n\nfunction loadFffNodeDistEntry(requireFff: ModuleRequire): unknown | undefined {\n\tif (!requireFff.resolve) return undefined;\n\ttry {\n\t\tconst ffiPath = requireFff.resolve(\"ffi-rs\");\n\t\tconst fffEntry = findFffNodeDistEntry(ffiPath);\n\t\treturn fffEntry ? requireFff(fffEntry) : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction loadFffNodeWith(requireFff: ModuleRequire): unknown | undefined {\n\ttry {\n\t\treturn requireFff(\"@ff-labs/fff-node\");\n\t} catch {\n\t\treturn loadFffNodeDistEntry(requireFff);\n\t}\n}\n\n/**\n * @param requires Override the resolution candidates, for tests (mirrors\n * fff-search-backend.ts's loadFffModule(requires?)). Whether this resolves\n * depends on the ambient environment -- @ff-labs/fff-node is a real npm\n * dependency (package.json), so moduleRequire succeeds wherever a normal\n * `npm install`/`npm ci` provisioned it (e.g. CI) even though it fails on a\n * dev checkout that never ran that install here (this repo resolves fff-node\n * via the separate managed-dir path instead). A test asserting \"nothing is\n * available\" must pass `[]` here rather than relying on that being true.\n */\nexport function loadAvailableFffNodePackage(requires?: readonly ModuleRequire[]): unknown | undefined {\n\tconst candidates =\n\t\trequires ??\n\t\t[moduleRequire, executableDirRequire, createManagedFffRequire()].filter((candidate): candidate is ModuleRequire =>\n\t\t\tBoolean(candidate),\n\t\t);\n\tfor (const requireFff of candidates) {\n\t\tconst loaded = loadFffNodeWith(requireFff);\n\t\tif (loaded) return loaded;\n\t}\n\treturn undefined;\n}\n\nasync function runNpmInstall(args: string[]): Promise<{ code: number | null; stderr: string }> {\n\ttry {\n\t\tconst child = spawnProcess(\"npm\", args, {\n\t\t\tdetached: process.platform !== \"win32\",\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\t\tlet stderr = \"\";\n\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\tstderr = `${stderr}${chunk.toString()}`.slice(-64 * 1024);\n\t\t});\n\t\tconst terminal = await waitForChildProcessWithTermination(child, {\n\t\t\ttimeoutMs: ARCHIVE_EXTRACTION_TIMEOUT_MS,\n\t\t\tkillGraceMs: 2_000,\n\t\t});\n\t\tif (terminal.reason === \"timeout\") {\n\t\t\tstderr = `${stderr}\\nnpm install timed out after ${ARCHIVE_EXTRACTION_TIMEOUT_MS}ms`.trim();\n\t\t}\n\t\treturn { code: terminal.code, stderr };\n\t} catch (error) {\n\t\treturn { code: 1, stderr: error instanceof Error ? error.message : String(error) };\n\t}\n}\n\n/**\n * Outcome of the most recent {@link ensureFffNodePackage} call, kept for\n * observability (e.g. a future `doctor` check) since the function itself\n * only ever returns the loaded module or `undefined` either way.\n *\n * `install-failed` is distinguished from `offline`/`unsupported-platform`\n * because it is the only one worth *retrying*: offline mode and an\n * unsupported platform are stable for the life of the process, but a real\n * install attempt can fail on a transient issue (registry hiccup, timeout)\n * that may no longer apply on the next search. See\n * DefaultFffSearchBackend.getFinder in fff-search-backend.ts, which uses\n * this distinction to decide whether a failed finder is retryable.\n */\nexport type FffInstallOutcome =\n\t| { status: \"already-available\" }\n\t| { status: \"offline\" }\n\t| { status: \"unsupported-platform\" }\n\t| { status: \"installed\" }\n\t| { status: \"install-failed\"; reason: string };\n\n/**\n * How long a genuine install failure gates out a NEW npm spawn. An agent turn\n * can fire several find/grep calls in quick succession, and each one now\n * primes the finder in the background (see tryFffFind/tryFffGrep) -- without\n * this, a persistently-failing install (registry down, disk full, ...) would\n * re-spawn npm on every single one of those calls instead of once.\n *\n * This gates the SPAWN inside ensureFffNodePackage, not whether a failed\n * finder is retryable (see isFffInstallRetryable): DefaultFffSearchBackend\n * always evicts a failed finder so the next search re-enters this function,\n * and it is THIS cooldown check -- evaluated fresh, at call time -- that\n * decides whether that re-entry is a real attempt or a fast, spawn-free bail.\n * (An earlier version conflated the two: it gated eviction itself on the\n * cooldown, which is checked once, immediately after the failure it's timing\n * -- i.e. always still within the window -- so the failed finder was never\n * evicted and the retry never got a chance to happen at all.)\n */\nexport const FFF_INSTALL_RETRY_COOLDOWN_MS = 30_000;\n\nlet lastFffInstallOutcome: FffInstallOutcome | undefined;\nlet lastFffInstallFailureAt: number | undefined;\n\n/** The outcome of the last {@link ensureFffNodePackage} call, if any. */\nexport function getLastFffInstallOutcome(): FffInstallOutcome | undefined {\n\treturn lastFffInstallOutcome;\n}\n\n/** Whether the last install outcome was a genuine failure worth retrying (as opposed to a stable \"not applicable\" result). Cooldown-independent by design -- see FFF_INSTALL_RETRY_COOLDOWN_MS. */\nexport function isFffInstallRetryable(): boolean {\n\treturn lastFffInstallOutcome?.status === \"install-failed\";\n}\n\n/**\n * Pure decision logic behind {@link isFffInstallCoolingDown}, exposed directly\n * so tests can assert the cooldown boundary without faking the system clock.\n */\nexport function computeIsFffInstallCoolingDown(\n\toutcome: FffInstallOutcome | undefined,\n\tfailedAt: number | undefined,\n\tnow: number,\n): boolean {\n\tif (outcome?.status !== \"install-failed\") return false;\n\tif (failedAt === undefined) return false;\n\treturn now - failedAt < FFF_INSTALL_RETRY_COOLDOWN_MS;\n}\n\n/** Whether a real install attempt happened too recently to try again right now. */\nfunction isFffInstallCoolingDown(): boolean {\n\treturn computeIsFffInstallCoolingDown(lastFffInstallOutcome, lastFffInstallFailureAt, Date.now());\n}\n\n/** Records a genuine install failure and stamps when it happened, so the cooldown above has a start time to measure from. */\nfunction recordFffInstallFailure(reason: string): void {\n\tlastFffInstallOutcome = { status: \"install-failed\", reason };\n\tlastFffInstallFailureAt = Date.now();\n}\n\nasync function installManagedFffNodePackage(platformPackage: string, silent: boolean): Promise<unknown | undefined> {\n\ttry {\n\t\tmkdirSync(FFF_MANAGED_DIR, { recursive: true });\n\t\tif (!existsSync(FFF_MANAGED_PACKAGE_JSON)) {\n\t\t\twriteFileSync(FFF_MANAGED_PACKAGE_JSON, '{\"name\":\"pi-managed-fff-node\",\"private\":true,\"version\":\"0.0.0\"}\\n');\n\t\t}\n\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.dim(\"FFF native search not found. Installing managed FFF package...\"));\n\t\t}\n\n\t\tconst args = [\n\t\t\t\"install\",\n\t\t\t\"--ignore-scripts\",\n\t\t\t\"--omit=dev\",\n\t\t\t\"--include=optional\",\n\t\t\t\"--no-audit\",\n\t\t\t\"--no-fund\",\n\t\t\t\"--package-lock=false\",\n\t\t\t\"--prefix\",\n\t\t\tFFF_MANAGED_DIR,\n\t\t\t`@ff-labs/fff-node@${FFF_NODE_VERSION}`,\n\t\t\t`${platformPackage}@${FFF_NODE_VERSION}`,\n\t\t];\n\t\tconst result = await runNpmInstall(args);\n\t\tif (result.code !== 0) {\n\t\t\tconst reason = result.stderr.trim() || `npm exited with code ${result.code}`;\n\t\t\tif (!silent) {\n\t\t\t\tconsole.log(chalk.yellow(`Failed to install FFF native search: ${reason}`));\n\t\t\t}\n\t\t\trecordFffInstallFailure(reason);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst loaded = loadFffNodeWith(createRequire(pathToFileURL(FFF_MANAGED_PACKAGE_JSON).href));\n\t\tif (!loaded) {\n\t\t\tconst reason = \"Managed FFF install completed but @ff-labs/fff-node could not be loaded.\";\n\t\t\tif (!silent) {\n\t\t\t\tconsole.log(chalk.yellow(reason));\n\t\t\t}\n\t\t\trecordFffInstallFailure(reason);\n\t\t\treturn undefined;\n\t\t}\n\t\tlastFffInstallOutcome = { status: \"installed\" };\n\t\treturn loaded;\n\t} catch (error) {\n\t\t// Never let a filesystem/spawn surprise (e.g. a read-only home directory)\n\t\t// crash the caller: fall back like any other install failure, but keep\n\t\t// the reason observable.\n\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`Failed to install FFF native search: ${reason}`));\n\t\t}\n\t\trecordFffInstallFailure(reason);\n\t\treturn undefined;\n\t}\n}\n\nexport async function ensureFffNodePackage(\n\tsilent: boolean = false,\n\tforceManagedInstall: boolean = false,\n\t/** Override the \"is it already available\" resolution candidates, for tests. See loadAvailableFffNodePackage's doc. */\n\trequires?: readonly ModuleRequire[],\n): Promise<unknown | undefined> {\n\tconst existing = forceManagedInstall ? undefined : loadAvailableFffNodePackage(requires);\n\tif (existing) {\n\t\tlastFffInstallOutcome = { status: \"already-available\" };\n\t\treturn existing;\n\t}\n\n\tif (isOfflineModeEnabled()) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(\"FFF native search not found. Offline mode enabled, skipping install.\"));\n\t\t}\n\t\tlastFffInstallOutcome = { status: \"offline\" };\n\t\treturn undefined;\n\t}\n\n\t// A prior attempt failed too recently to try again: bail out fast (no npm\n\t// spawn, no platform/libc probing) rather than repeating a doomed attempt.\n\t// Leaves lastFffInstallOutcome/lastFffInstallFailureAt untouched -- this\n\t// isn't a new attempt, so there's nothing new to record.\n\tif (isFffInstallCoolingDown()) {\n\t\treturn undefined;\n\t}\n\n\tconst platformPackage = getFffPlatformPackageName();\n\tif (!platformPackage) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`FFF native search is not available for ${platform()}/${arch()}.`));\n\t\t}\n\t\tlastFffInstallOutcome = { status: \"unsupported-platform\" };\n\t\treturn undefined;\n\t}\n\n\tfffNodeInstallPromise ??= installManagedFffNodePackage(platformPackage, silent).finally(() => {\n\t\tfffNodeInstallPromise = undefined;\n\t});\n\treturn fffNodeInstallPromise;\n}\n\nasync function installTermuxManagedTool(tool: ManagedToolName, silent: boolean): Promise<string | undefined> {\n\tconst packageName = TERMUX_PACKAGES[tool];\n\tif (!silent) console.log(chalk.dim(`${TOOLS[tool].name} not found. Installing with Termux pkg...`));\n\tconst child = spawnProcess(\"pkg\", [\"install\", \"-y\", packageName], {\n\t\tenv: process.env,\n\t\tstdio: silent ? \"ignore\" : \"inherit\",\n\t});\n\tconst terminal = await waitForChildProcessWithTermination(child, { timeoutMs: 300_000, killGraceMs: 5_000 });\n\tif (terminal.reason !== \"exited\" || terminal.code !== 0) {\n\t\tthrow new Error(\n\t\t\t`pkg install ${packageName} ${terminal.reason === \"timeout\" ? \"timed out\" : `exited with code ${terminal.code ?? 1}`}`,\n\t\t);\n\t}\n\treturn getToolPath(tool) ?? undefined;\n}\n\n// Ensure a tool is available, downloading if necessary\n// Returns the path to the tool, or undefined if unavailable\nexport async function ensureTool(tool: ManagedToolName, silent: boolean = false): Promise<string | undefined> {\n\tconst existingPath = getToolPath(tool);\n\tif (existingPath) {\n\t\treturn existingPath;\n\t}\n\n\tconst config = TOOLS[tool];\n\tif (!config) return undefined;\n\n\tif (isOfflineModeEnabled()) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`${config.name} not found. Offline mode enabled, skipping download.`));\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t// On Android/Termux, upstream Linux archives target glibc/musl rather than Bionic.\n\t// uv is a required managed runtime and the user explicitly authorized provisioning it;\n\t// preserve guide-only behavior for optional search tools.\n\tif (platform() === \"android\") {\n\t\tif (tool !== \"uv\") {\n\t\t\tconst packageName = TERMUX_PACKAGES[tool];\n\t\t\tif (!silent) console.log(chalk.yellow(`${config.name} not found. Install with: pkg install ${packageName}`));\n\t\t\treturn undefined;\n\t\t}\n\t\ttry {\n\t\t\treturn await runExclusiveToolDownload(tool, () => installTermuxManagedTool(tool, silent));\n\t\t} catch (error) {\n\t\t\tif (!silent) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.yellow(`Failed to install ${config.name}: ${error instanceof Error ? error.message : error}`),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t// Tool not found - download it\n\tif (!silent) {\n\t\tconsole.log(chalk.dim(`${config.name} not found. Downloading...`));\n\t}\n\n\ttry {\n\t\tconst path = await runExclusiveToolDownload(tool, () => downloadTool(tool));\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.dim(`${config.name} installed to ${path}`));\n\t\t}\n\t\treturn path;\n\t} catch (e) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`Failed to download ${config.name}: ${e instanceof Error ? e.message : e}`));\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"]}
@@ -0,0 +1,120 @@
1
+ # process-matrix
2
+
3
+ `core/process-matrix` is a durable, restart-surviving record of every `pi` process on this
4
+ machine and how they're related: a **master** (an interactive/direct session, or the root of a
5
+ launch chain) and its **workers** (sessions launched with a known parent -- today, tmux-dispatched
6
+ agents). It answers one question reliably even across a crash: *if my parent is gone, what do I
7
+ do?* -- and a companion question on resume: *did I leave orphaned children behind, and what should
8
+ happen to them?*
9
+
10
+ The matrix is an index of process identity and lifecycle status, not a scheduler: it never decides
11
+ what work runs, only how a process winds down or gets re-parented when its relationship to another
12
+ process breaks.
13
+
14
+ ## Supervision model
15
+
16
+ Every `pi` process registers exactly one entry in the matrix, keyed by `<role>-<sessionId>`, under
17
+ `state/process-matrix/` (see `agent-paths.ts` -- durable, survives `/reload` and crashes, not the
18
+ transient `work/` tree).
19
+
20
+ - **Master** (no declared parent): writes its own entry once at startup, heartbeats it on an
21
+ interval, and -- once, at startup -- scans the matrix for **orphaned workers**: worker entries
22
+ whose recorded parent pid is dead.
23
+ - **Worker** (launched with `PI_PARENT_PID` / `--parent-pid` set): self-registers its own entry
24
+ (the only writer of that entry during normal operation) and watches its parent's liveness on a
25
+ poll interval.
26
+
27
+ ### Resume: a master never auto-kills what it finds
28
+
29
+ On startup, a master's orphan scan finds worker entries whose parent is dead. It never assumes
30
+ those workers are also dead -- a worker can outlive a crashed parent -- so it never kills or
31
+ silently repurposes anything. Instead, for each orphan, **interactively**:
32
+
33
+ 1. Ask: *"adopt worker `<entryId>` (lane `<laneKey>`)?"* Yes → this session becomes the worker's
34
+ new parent (an adoption grant is written into the worker's own entry).
35
+ 2. If declined: ask *"clean up worker `<entryId>` gracefully?"* Yes → a cooperative wind-down
36
+ request is written into the worker's entry (the worker notices and self-exits; nothing is
37
+ killed).
38
+ 3. If both declined: leave the entry untouched.
39
+
40
+ **Non-interactively** (print/RPC mode, or no TTY), the scan is report-only: it logs what it found
41
+ and writes nothing, kills nothing. The one-time startup scan is the only place a master ever
42
+ touches another session's entry, and only with explicit owner confirmation each time.
43
+
44
+ ### A worker on parent death: wind down, never vanish
45
+
46
+ A worker polls its parent's pid on `watcherPollMs`. The moment that pid is no longer alive, it:
47
+
48
+ 1. Marks its own entry `winding_down` (reason `parent_lost`), then `resumable` with a payload
49
+ (its worktree-sync lane key, if bound) describing how the task could be picked back up.
50
+ 2. Emits one steer notice into its own session.
51
+ 3. Starts a bounded grace window (`adoptionGraceMs`), polling its own entry every
52
+ `watcherPollMs` for a directive a new master may have written (see above):
53
+ - **Adopted** (entry's `parentPid` changed to a new, live pid): re-parents to the new master
54
+ and resumes normal watching -- no task loss.
55
+ - **Cooperative cleanup requested**: exits immediately.
56
+ - **Grace window expires** with no directive: exits, leaving the entry `resumable` for a future
57
+ session to notice.
58
+
59
+ "No new turns" after a parent is lost is automatic and requires no separate mechanism: a dead
60
+ parent injects no further follow-ups, so the worker simply runs out of work on its own.
61
+
62
+ ## Env + CLI flag contract
63
+
64
+ Cross-process, like `PI_WORKTREE_LANE`/`--worktree-lane`:
65
+
66
+ | Env | CLI sugar | Meaning |
67
+ |---|---|---|
68
+ | `PI_PARENT_PID` | `--parent-pid <pid>` | Declares this process as a worker of `<pid>`. A malformed or non-positive value is ignored (never a crash on bad env) -- the process falls back to acting as a master. |
69
+ | `PI_PARENT_SESSION` | `--parent-session <id>` | The parent's sessionId, recorded alongside the pid for diagnostics/adoption. |
70
+
71
+ `tmux_agent_manager`'s `fire_task` sets both automatically on every `pi`-provider child it
72
+ launches (its own pid/sessionId), the same way it threads `--worktree-lane` for a lane-first
73
+ dispatch -- see `dispatch-grant.ts`'s `LaunchProfileSource.parentPid`/`parentSession`.
74
+
75
+ ## Settings
76
+
77
+ `processMatrix` in `settings.json`:
78
+
79
+ | Key | Default | Meaning |
80
+ |---|---|---|
81
+ | `enabled` | `true` | Master switch. Explicit `false` is the hard off-switch: no entry is ever written, no scan runs, no watcher runs -- zero behavior change once set. |
82
+ | `heartbeatMs` | `30000` | Master heartbeat interval (bounds: 1000-600000). |
83
+ | `adoptionGraceMs` | `300000` | How long an orphaned worker waits for an adopt/cleanup directive before self-exiting (bounds: 5000-3600000). |
84
+ | `watcherPollMs` | `25000` | Poll cadence for parent-liveness and directive checks (bounds: 1000-600000). |
85
+
86
+ ## The zero-footprint sanction
87
+
88
+ A worker session otherwise carries a strict UAC ceiling and a zero-footprint guarantee -- see
89
+ `docs/worktree-sync.md`'s "Identity, UAC, and zero footprint". A worker's writes to its **own**
90
+ process-matrix entry are a sanctioned artifact, exactly like its own session transcript: the role
91
+ ceiling is untouched, and this is not a new escalation surface. A worker never writes any *other*
92
+ session's entry.
93
+
94
+ The one narrow exception on the master side: during the ask-gated startup orphan scan, a master
95
+ that the owner explicitly told to adopt or clean up a specific orphan writes that grant directly
96
+ into the *orphan's* own entry (never anywhere else, never without that confirmation). This mirrors
97
+ `worktree-sync`'s integration-lock takeover of a provably dead owner's resource -- a new owner may
98
+ claim what a dead owner left behind, audited (here, by the interactive confirmation itself) rather
99
+ than assumed. Outside that one handshake, a master never writes another session's entry.
100
+
101
+ ## Foreign-CLI limitation
102
+
103
+ Only a `pi`-provider child self-registers and watches -- a non-`pi` agent launched via
104
+ `tmux_agent_manager` (a foreign CLI) has no way to be handed `--parent-pid`/`PI_PARENT_PID` and
105
+ act on it. Its lifecycle stays bounded only at the launch layer (agent/budget/count), the same
106
+ documented limitation `worktree-sync` already has for foreign CLIs -- not a hidden gap, a
107
+ cooperative boundary this system cannot structurally enforce across an arbitrary external process.
108
+
109
+ ## What this does not do
110
+
111
+ - It never kills a process. Every termination is either the process's own cooperative self-exit or
112
+ an owner-confirmed grant the process itself later notices and applies.
113
+ - It does not re-attach a tmux pane or re-dispatch a lane on adoption -- adoption changes who a
114
+ worker considers its parent, nothing about its tmux session or worktree-sync lane state.
115
+ - Correctness never depends on a heartbeat or a watcher tick arriving -- a crashed process just
116
+ leaves a stale entry behind. `supervisor.ts`'s `reconcileMatrix` (prune `closed` and any
117
+ `running`/`winding_down` entry whose own pid is dead; keep `resumable`/`adopted` until they age
118
+ past a TTL) is the building block for cleaning those up; nothing in this build wires it into an
119
+ automatic sweep yet -- the matrix directory is left to grow with stale entries until a future
120
+ caller (a manual command, or a periodic sweep) invokes it.
package/docs/settings.md CHANGED
@@ -376,9 +376,12 @@ Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explic
376
376
  | `shellPath` | string | platform default | Custom platform-shell path (`pwsh.exe`/`powershell.exe` on Windows; Bash-compatible shell elsewhere) |
377
377
  | `shellCommandPrefix` | string | - | Platform-shell snippet prepended to every command (for example, `"shopt -s expand_aliases"` on Bash) |
378
378
  | `npmCommand` | string[] | - | Command argv used for npm package lookup/install operations (e.g., `["mise", "exec", "node@24", "--", "npm"]`) |
379
+ | `windowsShell.pythonEngine` | boolean | `true` | Windows only. Routes pipelines, redirection, expansion, chaining, and state-mutating commands (`cd`/`export`/`unset`) through the bundled Python shell engine. Explicit `false` restores the PowerShell-only, simple-command-only contract verbatim — the same fail-closed behavior for pipelines/redirection/expansion/chaining as before the engine existed. |
379
380
 
380
381
  Pi exposes one stable `bash` contract to the model on every platform. On Windows, the tool router parses a finite simple-command grammar, converts supported Bash-like forms to literal-path PowerShell, and rejects pipelines, redirection, expansion, chaining, nested shells, POSIX scripts, and unsupported builtin forms instead of guessing. Legacy `powershell` tool/profile references map to `bash`. The Windows backend prefers PowerShell 7 (`pwsh.exe`), falls back to Windows PowerShell, and runs with `-NoLogo -NoProfile -NonInteractive -Command` plus UTF-8 console output setup. `shellCommandPrefix` uses backend-native syntax because Pi applies it after routing. Agent, interactive, and RPC shell calls default to a 120-second wall-clock deadline; agent-tool overrides cap at one hour.
381
382
 
383
+ With `windowsShell.pythonEngine` at its default (`true`), the router also sends pipelines, redirection, expansion, chaining, and `cd`/`export`/`unset` to a bundled, uv-provisioned Python 3.13 engine implementing a bounded Bash grammar and coreutils vocabulary; state persists across calls and across the PowerShell/engine tiers. If the Python runtime cannot be resolved (uv/network unavailable), the simple-command PowerShell floor keeps working and engine-only commands return a named, actionable error — never a silent downgrade. See [Windows](windows.md) for the full supported-forms table.
384
+
382
385
  The native `python` tool is active by default and resolves Python through pinned `uv`. Pi provisions missing uv/Python during package postinstall, `pi update`, `pi doctor`, or first tool use. Python calls default to 30 seconds and cap explicit overrides at 300 seconds. See [Native Python](python.md).
383
386
 
384
387
  ```json