lsd-pi 1.2.4 → 1.3.6

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 (357) hide show
  1. package/README.md +22 -16
  2. package/dist/app-paths.d.ts +4 -0
  3. package/dist/app-paths.js +4 -0
  4. package/dist/bedrock-auth.d.ts +4 -0
  5. package/dist/bedrock-auth.js +4 -0
  6. package/dist/bundled-extension-paths.d.ts +4 -0
  7. package/dist/bundled-extension-paths.js +4 -0
  8. package/dist/cli-theme.d.ts +2 -2
  9. package/dist/cli-theme.js +13 -14
  10. package/dist/cli.js +43 -3
  11. package/dist/codex-rotate-settings.d.ts +4 -0
  12. package/dist/codex-rotate-settings.js +4 -0
  13. package/dist/help-text.d.ts +4 -0
  14. package/dist/help-text.js +4 -0
  15. package/dist/lsd-brand.d.ts +4 -0
  16. package/dist/lsd-brand.js +4 -0
  17. package/dist/onboarding-llm.d.ts +5 -0
  18. package/dist/onboarding-llm.js +5 -0
  19. package/dist/project-sessions.d.ts +4 -0
  20. package/dist/project-sessions.js +4 -0
  21. package/dist/resources/agents/generic.md +1 -0
  22. package/dist/resources/agents/scout.md +8 -1
  23. package/dist/resources/agents/worker.md +1 -0
  24. package/dist/resources/extensions/ask-user-questions.js +70 -0
  25. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +6 -16
  26. package/dist/resources/extensions/browser-tools/tools/codegen.js +5 -5
  27. package/dist/resources/extensions/browser-tools/tools/navigation.js +107 -178
  28. package/dist/resources/extensions/browser-tools/tools/network-mock.js +112 -167
  29. package/dist/resources/extensions/browser-tools/tools/pages.js +182 -234
  30. package/dist/resources/extensions/browser-tools/tools/refs.js +202 -461
  31. package/dist/resources/extensions/browser-tools/tools/session.js +176 -323
  32. package/dist/resources/extensions/browser-tools/tools/state-persistence.js +91 -154
  33. package/dist/resources/extensions/browser-tools/utils.js +1 -1
  34. package/dist/resources/extensions/mac-tools/index.js +19 -34
  35. package/dist/resources/extensions/memory/index.js +20 -2
  36. package/dist/resources/extensions/shared/interview-ui.js +103 -20
  37. package/dist/resources/extensions/slash-commands/extension-manifest.json +2 -2
  38. package/dist/resources/extensions/slash-commands/fast.js +73 -0
  39. package/dist/resources/extensions/slash-commands/index.js +2 -0
  40. package/dist/resources/extensions/slash-commands/plan.js +54 -28
  41. package/dist/resources/extensions/slash-commands/tools.js +40 -4
  42. package/dist/resources/extensions/subagent/agent-switcher-component.js +208 -0
  43. package/dist/resources/extensions/subagent/agent-switcher-model.js +107 -0
  44. package/dist/resources/extensions/subagent/background-job-manager.js +24 -6
  45. package/dist/resources/extensions/subagent/background-runner.js +4 -0
  46. package/dist/resources/extensions/subagent/in-process-runner.js +387 -0
  47. package/dist/resources/extensions/subagent/index.js +715 -370
  48. package/dist/resources/extensions/subagent/launch-helpers.js +19 -5
  49. package/dist/resources/extensions/subagent/legacy-runner.js +503 -0
  50. package/dist/resources/extensions/voice/index.js +96 -36
  51. package/dist/resources/extensions/voice/push-to-talk.js +26 -0
  52. package/dist/shared-paths.d.ts +4 -0
  53. package/dist/shared-paths.js +4 -0
  54. package/dist/shared-preferences.d.ts +4 -0
  55. package/dist/shared-preferences.js +4 -0
  56. package/dist/startup-model-validation.d.ts +1 -1
  57. package/dist/startup-timings.d.ts +4 -0
  58. package/dist/startup-timings.js +4 -0
  59. package/dist/update-check.d.ts +4 -0
  60. package/dist/update-check.js +4 -0
  61. package/dist/update-cmd.d.ts +4 -0
  62. package/dist/update-cmd.js +4 -0
  63. package/dist/welcome-screen.js +4 -4
  64. package/dist/wizard.d.ts +4 -0
  65. package/dist/wizard.js +4 -0
  66. package/package.json +1 -1
  67. package/packages/pi-agent-core/dist/agent.d.ts +28 -0
  68. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  69. package/packages/pi-agent-core/dist/agent.js +105 -5
  70. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  71. package/packages/pi-agent-core/dist/types.d.ts +13 -2
  72. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  73. package/packages/pi-agent-core/dist/types.js.map +1 -1
  74. package/packages/pi-agent-core/src/agent.ts +142 -6
  75. package/packages/pi-agent-core/src/types.ts +12 -3
  76. package/packages/pi-ai/dist/adaptive/classifier.d.ts +29 -0
  77. package/packages/pi-ai/dist/adaptive/classifier.d.ts.map +1 -0
  78. package/packages/pi-ai/dist/adaptive/classifier.js +72 -0
  79. package/packages/pi-ai/dist/adaptive/classifier.js.map +1 -0
  80. package/packages/pi-ai/dist/adaptive/classifier.test.d.ts +2 -0
  81. package/packages/pi-ai/dist/adaptive/classifier.test.d.ts.map +1 -0
  82. package/packages/pi-ai/dist/adaptive/classifier.test.js +32 -0
  83. package/packages/pi-ai/dist/adaptive/classifier.test.js.map +1 -0
  84. package/packages/pi-ai/dist/index.d.ts +1 -0
  85. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  86. package/packages/pi-ai/dist/index.js +1 -0
  87. package/packages/pi-ai/dist/index.js.map +1 -1
  88. package/packages/pi-ai/dist/providers/amazon-bedrock.js +0 -2
  89. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  90. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  91. package/packages/pi-ai/dist/providers/anthropic-shared.js +0 -2
  92. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  93. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts +1 -1
  94. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  95. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  96. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  97. package/packages/pi-ai/dist/providers/google-gemini-cli.js +0 -4
  98. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  99. package/packages/pi-ai/dist/providers/google-vertex.js +0 -5
  100. package/packages/pi-ai/dist/providers/google-vertex.js.map +1 -1
  101. package/packages/pi-ai/dist/providers/google.js +0 -5
  102. package/packages/pi-ai/dist/providers/google.js.map +1 -1
  103. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts +35 -2
  104. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  105. package/packages/pi-ai/dist/providers/openai-codex-responses.js +32 -6
  106. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  107. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +127 -16
  108. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -1
  109. package/packages/pi-ai/dist/providers/openai-completions.d.ts +1 -1
  110. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  111. package/packages/pi-ai/dist/providers/openai-completions.js +0 -1
  112. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  113. package/packages/pi-ai/dist/providers/openai-responses.d.ts +9 -2
  114. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  115. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts +2 -0
  116. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts.map +1 -0
  117. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js +67 -0
  118. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js.map +1 -0
  119. package/packages/pi-ai/dist/providers/openai-responses.js +21 -3
  120. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  121. package/packages/pi-ai/dist/providers/openai-shared.d.ts +0 -1
  122. package/packages/pi-ai/dist/providers/openai-shared.d.ts.map +1 -1
  123. package/packages/pi-ai/dist/providers/openai-shared.js +0 -4
  124. package/packages/pi-ai/dist/providers/openai-shared.js.map +1 -1
  125. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  126. package/packages/pi-ai/dist/providers/simple-options.js +2 -1
  127. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  128. package/packages/pi-ai/dist/types.d.ts +6 -2
  129. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  130. package/packages/pi-ai/dist/types.js.map +1 -1
  131. package/packages/pi-ai/src/adaptive/classifier.test.ts +38 -0
  132. package/packages/pi-ai/src/adaptive/classifier.ts +107 -0
  133. package/packages/pi-ai/src/index.ts +1 -0
  134. package/packages/pi-ai/src/providers/amazon-bedrock.ts +0 -2
  135. package/packages/pi-ai/src/providers/anthropic-shared.ts +0 -2
  136. package/packages/pi-ai/src/providers/azure-openai-responses.ts +1 -1
  137. package/packages/pi-ai/src/providers/google-gemini-cli.ts +0 -4
  138. package/packages/pi-ai/src/providers/google-vertex.ts +0 -5
  139. package/packages/pi-ai/src/providers/google.ts +0 -5
  140. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +143 -20
  141. package/packages/pi-ai/src/providers/openai-codex-responses.ts +48 -7
  142. package/packages/pi-ai/src/providers/openai-completions.ts +1 -2
  143. package/packages/pi-ai/src/providers/openai-responses.fast-mode.test.ts +73 -0
  144. package/packages/pi-ai/src/providers/openai-responses.ts +27 -4
  145. package/packages/pi-ai/src/providers/openai-shared.ts +0 -3
  146. package/packages/pi-ai/src/providers/simple-options.ts +2 -1
  147. package/packages/pi-ai/src/types.ts +6 -2
  148. package/packages/pi-coding-agent/dist/cli/args.js +2 -2
  149. package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
  150. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +7 -2
  151. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  152. package/packages/pi-coding-agent/dist/core/agent-session.js +53 -20
  153. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  154. package/packages/pi-coding-agent/dist/core/keybindings.d.ts +1 -1
  155. package/packages/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
  156. package/packages/pi-coding-agent/dist/core/keybindings.js +2 -0
  157. package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
  158. package/packages/pi-coding-agent/dist/core/lsp/lsp.md +3 -1
  159. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/sdk.js +36 -8
  161. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/sdk.test.js +37 -0
  163. package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
  164. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +8 -0
  165. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/session-manager.js +4 -0
  167. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  168. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +18 -7
  169. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  170. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts +2 -0
  171. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts.map +1 -0
  172. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js +35 -0
  173. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js.map +1 -0
  174. package/packages/pi-coding-agent/dist/core/settings-manager.js +32 -2
  175. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  176. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  177. package/packages/pi-coding-agent/dist/core/skills.js +4 -1
  178. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  179. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  180. package/packages/pi-coding-agent/dist/core/slash-commands.js +2 -1
  181. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  182. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/system-prompt.js +12 -3
  184. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/tool-priority.d.ts +4 -0
  186. package/packages/pi-coding-agent/dist/core/tool-priority.d.ts.map +1 -0
  187. package/packages/pi-coding-agent/dist/core/tool-priority.js +18 -0
  188. package/packages/pi-coding-agent/dist/core/tool-priority.js.map +1 -0
  189. package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts +2 -0
  190. package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts.map +1 -0
  191. package/packages/pi-coding-agent/dist/core/tool-priority.test.js +27 -0
  192. package/packages/pi-coding-agent/dist/core/tool-priority.test.js.map +1 -0
  193. package/packages/pi-coding-agent/dist/core/tools/grep.js +1 -1
  194. package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  195. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -0
  196. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  197. package/packages/pi-coding-agent/dist/core/tools/index.js +2 -0
  198. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  199. package/packages/pi-coding-agent/dist/core/tools/pty.d.ts +10 -1
  200. package/packages/pi-coding-agent/dist/core/tools/pty.d.ts.map +1 -1
  201. package/packages/pi-coding-agent/dist/core/tools/pty.js +29 -3
  202. package/packages/pi-coding-agent/dist/core/tools/pty.js.map +1 -1
  203. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.d.ts +2 -0
  204. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.d.ts.map +1 -0
  205. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js +26 -0
  206. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js.map +1 -0
  207. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts +45 -0
  208. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts.map +1 -0
  209. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js +314 -0
  210. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js.map +1 -0
  211. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts +2 -0
  212. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts.map +1 -0
  213. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js +122 -0
  214. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js.map +1 -0
  215. package/packages/pi-coding-agent/dist/modes/interactive/components/embedded-terminal.js +1 -1
  216. package/packages/pi-coding-agent/dist/modes/interactive/components/embedded-terminal.js.map +1 -1
  217. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +2 -0
  218. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  219. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +19 -2
  220. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  221. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +11 -2
  222. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  223. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +49 -6
  224. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  225. package/packages/pi-coding-agent/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  226. package/packages/pi-coding-agent/dist/modes/interactive/components/thinking-selector.js +1 -2
  227. package/packages/pi-coding-agent/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  228. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +6 -0
  229. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  230. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +18 -4
  231. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  232. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts +13 -0
  233. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts.map +1 -0
  234. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js +49 -0
  235. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js.map +1 -0
  236. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts +2 -0
  237. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts.map +1 -0
  238. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js +197 -0
  239. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js.map +1 -0
  240. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  241. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +106 -0
  242. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  243. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  244. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -0
  245. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  246. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +3 -0
  247. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  248. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  249. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
  250. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  251. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +88 -2
  252. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  254. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +41 -0
  255. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  256. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +2 -2
  257. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +10 -6
  259. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +1 -1
  261. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  263. package/packages/pi-coding-agent/dist/modes/print-mode.js +6 -0
  264. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  265. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +20 -0
  267. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/tests/path-display.test.js +15 -0
  269. package/packages/pi-coding-agent/dist/tests/path-display.test.js.map +1 -1
  270. package/packages/pi-coding-agent/package.json +1 -1
  271. package/packages/pi-coding-agent/src/cli/args.ts +2 -2
  272. package/packages/pi-coding-agent/src/core/agent-session.ts +58 -21
  273. package/packages/pi-coding-agent/src/core/keybindings.ts +4 -1
  274. package/packages/pi-coding-agent/src/core/lsp/lsp.md +3 -1
  275. package/packages/pi-coding-agent/src/core/sdk.test.ts +45 -0
  276. package/packages/pi-coding-agent/src/core/sdk.ts +39 -8
  277. package/packages/pi-coding-agent/src/core/session-manager.ts +12 -0
  278. package/packages/pi-coding-agent/src/core/settings-manager.fast-mode.test.ts +46 -0
  279. package/packages/pi-coding-agent/src/core/settings-manager.ts +50 -9
  280. package/packages/pi-coding-agent/src/core/skills.ts +4 -1
  281. package/packages/pi-coding-agent/src/core/slash-commands.ts +2 -1
  282. package/packages/pi-coding-agent/src/core/system-prompt.ts +14 -3
  283. package/packages/pi-coding-agent/src/core/tool-priority.test.ts +30 -0
  284. package/packages/pi-coding-agent/src/core/tool-priority.ts +17 -0
  285. package/packages/pi-coding-agent/src/core/tools/grep.ts +1 -1
  286. package/packages/pi-coding-agent/src/core/tools/index.ts +3 -0
  287. package/packages/pi-coding-agent/src/core/tools/pty.ts +45 -6
  288. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-summary-line.test.ts +31 -0
  289. package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.test.ts +172 -0
  290. package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.ts +402 -0
  291. package/packages/pi-coding-agent/src/modes/interactive/components/embedded-terminal.ts +1 -1
  292. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +18 -2
  293. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +63 -9
  294. package/packages/pi-coding-agent/src/modes/interactive/components/thinking-selector.ts +1 -2
  295. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1154 -1136
  296. package/packages/pi-coding-agent/src/modes/interactive/components/tool-summary-line.ts +64 -0
  297. package/packages/pi-coding-agent/src/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.ts +228 -0
  298. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +494 -389
  299. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +7 -0
  300. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +3 -0
  301. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +103 -3
  302. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +60 -1
  303. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +11 -7
  304. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +1 -1
  305. package/packages/pi-coding-agent/src/modes/print-mode.ts +6 -0
  306. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +29 -0
  307. package/packages/pi-coding-agent/src/tests/path-display.test.ts +17 -0
  308. package/packages/pi-tui/dist/components/loader.d.ts +5 -2
  309. package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
  310. package/packages/pi-tui/dist/components/loader.js +33 -3
  311. package/packages/pi-tui/dist/components/loader.js.map +1 -1
  312. package/packages/pi-tui/src/components/loader.ts +31 -3
  313. package/packages/rpc-client/src/index.ts +1 -1
  314. package/packages/rpc-client/src/rpc-client.ts +29 -0
  315. package/packages/rpc-client/src/rpc-types.ts +1 -1
  316. package/pkg/dist/modes/interactive/theme/theme.d.ts +2 -2
  317. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  318. package/pkg/dist/modes/interactive/theme/theme.js +10 -6
  319. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  320. package/pkg/dist/modes/interactive/theme/themes.js +1 -1
  321. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  322. package/pkg/package.json +1 -1
  323. package/src/resources/agents/generic.md +1 -0
  324. package/src/resources/agents/scout.md +8 -1
  325. package/src/resources/agents/worker.md +1 -0
  326. package/src/resources/extensions/ask-user-questions.ts +88 -0
  327. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +6 -16
  328. package/src/resources/extensions/browser-tools/tools/codegen.ts +5 -5
  329. package/src/resources/extensions/browser-tools/tools/navigation.ts +118 -196
  330. package/src/resources/extensions/browser-tools/tools/network-mock.ts +114 -205
  331. package/src/resources/extensions/browser-tools/tools/pages.ts +183 -237
  332. package/src/resources/extensions/browser-tools/tools/refs.ts +193 -507
  333. package/src/resources/extensions/browser-tools/tools/session.ts +182 -321
  334. package/src/resources/extensions/browser-tools/tools/state-persistence.ts +94 -172
  335. package/src/resources/extensions/browser-tools/utils.ts +1 -1
  336. package/src/resources/extensions/mac-tools/index.ts +19 -34
  337. package/src/resources/extensions/memory/index.ts +22 -2
  338. package/src/resources/extensions/shared/interview-ui.ts +108 -15
  339. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +61 -0
  340. package/src/resources/extensions/shared/tests/custom-ui-fallbacks.test.ts +46 -0
  341. package/src/resources/extensions/slash-commands/extension-manifest.json +2 -2
  342. package/src/resources/extensions/slash-commands/fast.ts +89 -0
  343. package/src/resources/extensions/slash-commands/index.ts +2 -0
  344. package/src/resources/extensions/slash-commands/plan.ts +59 -30
  345. package/src/resources/extensions/slash-commands/tools.ts +43 -4
  346. package/src/resources/extensions/subagent/agent-switcher-component.ts +228 -0
  347. package/src/resources/extensions/subagent/agent-switcher-model.ts +160 -0
  348. package/src/resources/extensions/subagent/background-job-manager.ts +57 -6
  349. package/src/resources/extensions/subagent/background-runner.ts +8 -0
  350. package/src/resources/extensions/subagent/background-types.ts +4 -0
  351. package/src/resources/extensions/subagent/in-process-runner.ts +534 -0
  352. package/src/resources/extensions/subagent/index.ts +998 -493
  353. package/src/resources/extensions/subagent/launch-helpers.ts +15 -4
  354. package/src/resources/extensions/subagent/legacy-runner.ts +607 -0
  355. package/src/resources/extensions/voice/index.ts +308 -238
  356. package/src/resources/extensions/voice/push-to-talk.ts +42 -0
  357. package/src/resources/extensions/voice/tests/push-to-talk.test.ts +109 -0
@@ -11,15 +11,29 @@ export function getBundledExtensionPathsFromEnv(env = process.env) {
11
11
  }
12
12
  return Array.from(unique);
13
13
  }
14
- export function buildSubagentProcessArgs(agent, task, tmpPromptPath, model) {
15
- const args = ["--mode", "json", "-p", "--no-session"];
14
+ export function buildSubagentProcessArgs(agent, task, tmpPromptPath, model, options) {
15
+ const mode = options?.mode ?? "json";
16
+ const args = ["--mode", mode];
17
+ if (mode === "json")
18
+ args.push("-p");
19
+ if (options?.noSession ?? true)
20
+ args.push("--no-session");
21
+ if (options?.parentSessionFile)
22
+ args.push("--parent-session", options.parentSessionFile);
23
+ args.push("--subagent-name", agent.name);
24
+ args.push("--subagent-task", task);
25
+ const uniqueTools = agent.tools?.filter((tool, index, all) => all.indexOf(tool) === index);
26
+ if (uniqueTools && uniqueTools.length > 0)
27
+ args.push("--subagent-tools", uniqueTools.join(","));
16
28
  if (model)
17
29
  args.push("--model", model);
18
- const uniqueTools = agent.tools?.filter((tool, index, all) => all.indexOf(tool) === index);
19
30
  if (uniqueTools && uniqueTools.length > 0)
20
31
  args.push("--tools", uniqueTools.join(","));
21
- if (tmpPromptPath)
32
+ if (tmpPromptPath) {
22
33
  args.push("--append-system-prompt", tmpPromptPath);
23
- args.push(`Task: ${task}`);
34
+ args.push("--subagent-system-prompt-file", tmpPromptPath);
35
+ }
36
+ if (mode === "json")
37
+ args.push(`Task: ${task}`);
24
38
  return args;
25
39
  }
@@ -0,0 +1,503 @@
1
+ import { spawn, execFileSync } from "node:child_process";
2
+ import * as fs from "node:fs";
3
+ import * as os from "node:os";
4
+ import * as path from "node:path";
5
+ import { getAgentDir } from "@gsd/pi-coding-agent";
6
+ import { buildSubagentProcessArgs, getBundledExtensionPathsFromEnv } from "./launch-helpers.js";
7
+ import { handleSubagentPermissionRequest, isSubagentPermissionRequest } from "./approval-proxy.js";
8
+ import { resolveConfiguredSubagentModel } from "./configured-model.js";
9
+ import { normalizeSubagentModel, resolveSubagentModel } from "./model-resolution.js";
10
+ import { loadEffectivePreferences } from "../shared/preferences.js";
11
+ const liveSubagentProcesses = new Set();
12
+ export function readBudgetSubagentModelFromSettings() {
13
+ try {
14
+ const settingsPath = path.join(getAgentDir(), "settings.json");
15
+ if (!fs.existsSync(settingsPath))
16
+ return undefined;
17
+ const raw = fs.readFileSync(settingsPath, "utf-8");
18
+ const parsed = JSON.parse(raw);
19
+ return typeof parsed.budgetSubagentModel === "string"
20
+ ? normalizeSubagentModel(parsed.budgetSubagentModel)
21
+ : undefined;
22
+ }
23
+ catch {
24
+ return undefined;
25
+ }
26
+ }
27
+ export async function stopLegacySubagents() {
28
+ const active = Array.from(liveSubagentProcesses);
29
+ if (active.length === 0)
30
+ return;
31
+ for (const proc of active) {
32
+ try {
33
+ proc.kill("SIGTERM");
34
+ }
35
+ catch {
36
+ /* ignore */
37
+ }
38
+ }
39
+ await Promise.all(active.map((proc) => new Promise((resolve) => {
40
+ const done = () => resolve();
41
+ const timer = setTimeout(done, 500);
42
+ proc.once("exit", () => {
43
+ clearTimeout(timer);
44
+ resolve();
45
+ });
46
+ })));
47
+ for (const proc of active) {
48
+ if (proc.exitCode === null) {
49
+ try {
50
+ proc.kill("SIGKILL");
51
+ }
52
+ catch {
53
+ /* ignore */
54
+ }
55
+ }
56
+ }
57
+ }
58
+ function listSessionFiles(sessionDir) {
59
+ if (!fs.existsSync(sessionDir))
60
+ return [];
61
+ try {
62
+ return fs
63
+ .readdirSync(sessionDir)
64
+ .filter((name) => name.endsWith(".jsonl"))
65
+ .map((name) => path.join(sessionDir, name));
66
+ }
67
+ catch {
68
+ return [];
69
+ }
70
+ }
71
+ function detectNewSubagentSessionFile(sessionDir, before, startedAt) {
72
+ const after = listSessionFiles(sessionDir);
73
+ const created = after.filter((file) => !before.has(file));
74
+ const candidates = created.length > 0 ? created : after;
75
+ const ranked = candidates
76
+ .map((file) => {
77
+ let mtime = 0;
78
+ try {
79
+ mtime = fs.statSync(file).mtimeMs;
80
+ }
81
+ catch {
82
+ mtime = 0;
83
+ }
84
+ return { file, mtime };
85
+ })
86
+ .filter((entry) => entry.mtime >= startedAt - 5000)
87
+ .sort((a, b) => b.mtime - a.mtime);
88
+ return ranked[0]?.file;
89
+ }
90
+ function resolveSubagentCliPath(defaultCwd) {
91
+ const candidates = [process.env.GSD_BIN_PATH, process.env.LSD_BIN_PATH, process.argv[1]]
92
+ .map((value) => value?.trim())
93
+ .filter((value) => Boolean(value && value !== "undefined"));
94
+ for (const candidate of candidates) {
95
+ if (path.isAbsolute(candidate) && fs.existsSync(candidate))
96
+ return candidate;
97
+ }
98
+ const cwdCandidates = [path.join(defaultCwd, "dist", "loader.js"), path.join(defaultCwd, "scripts", "dev-cli.js")];
99
+ for (const candidate of cwdCandidates) {
100
+ if (fs.existsSync(candidate))
101
+ return candidate;
102
+ }
103
+ for (const binName of ["lsd", "gsd"]) {
104
+ try {
105
+ const resolved = execFileSync("which", [binName], { encoding: "utf-8" }).trim();
106
+ if (resolved)
107
+ return resolved;
108
+ }
109
+ catch {
110
+ /* ignore */
111
+ }
112
+ }
113
+ return null;
114
+ }
115
+ function processSubagentEventLine(line, currentResult, emitUpdate, proc, onSessionInfo, onEventType, onParsedEvent) {
116
+ if (!line.trim())
117
+ return false;
118
+ let event;
119
+ try {
120
+ event = JSON.parse(line);
121
+ }
122
+ catch {
123
+ return false;
124
+ }
125
+ const eventType = typeof event.type === "string" ? event.type : "unknown";
126
+ onEventType?.(eventType);
127
+ onParsedEvent?.(event);
128
+ if (event.type === "subagent_session_info") {
129
+ let changed = false;
130
+ if (typeof event.sessionFile === "string" && event.sessionFile) {
131
+ if (currentResult.sessionFile !== event.sessionFile)
132
+ changed = true;
133
+ currentResult.sessionFile = event.sessionFile;
134
+ }
135
+ if (typeof event.parentSessionFile === "string" && event.parentSessionFile) {
136
+ if (currentResult.parentSessionFile !== event.parentSessionFile)
137
+ changed = true;
138
+ currentResult.parentSessionFile = event.parentSessionFile;
139
+ }
140
+ if (changed) {
141
+ onSessionInfo?.({
142
+ sessionFile: currentResult.sessionFile,
143
+ parentSessionFile: currentResult.parentSessionFile,
144
+ });
145
+ }
146
+ return false;
147
+ }
148
+ if (proc && isSubagentPermissionRequest(event)) {
149
+ void handleSubagentPermissionRequest(event, proc);
150
+ return false;
151
+ }
152
+ if ((event.type === "message_end" || event.type === "turn_end") && event.message) {
153
+ const msg = event.message;
154
+ currentResult.messages.push(msg);
155
+ if (msg.role === "assistant") {
156
+ currentResult.usage.turns++;
157
+ const usage = msg.usage;
158
+ if (usage) {
159
+ currentResult.usage.input += usage.input || 0;
160
+ currentResult.usage.output += usage.output || 0;
161
+ currentResult.usage.cacheRead += usage.cacheRead || 0;
162
+ currentResult.usage.cacheWrite += usage.cacheWrite || 0;
163
+ currentResult.usage.cost += usage.cost?.total || 0;
164
+ currentResult.usage.contextTokens = usage.totalTokens || 0;
165
+ }
166
+ if (msg.model && (!currentResult.model || msg.model.includes("/")))
167
+ currentResult.model = msg.model;
168
+ if (msg.stopReason)
169
+ currentResult.stopReason = msg.stopReason;
170
+ if (msg.errorMessage)
171
+ currentResult.errorMessage = msg.errorMessage;
172
+ }
173
+ emitUpdate();
174
+ }
175
+ if (event.type === "tool_result_end" && event.message) {
176
+ currentResult.messages.push(event.message);
177
+ emitUpdate();
178
+ }
179
+ return event.type === "agent_end";
180
+ }
181
+ function writePromptToTempFile(agentName, prompt) {
182
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagent-"));
183
+ const safeName = agentName.replace(/[^\w.-]+/g, "_");
184
+ const filePath = path.join(tmpDir, `prompt-${safeName}.md`);
185
+ fs.writeFileSync(filePath, prompt, { encoding: "utf-8", mode: 0o600 });
186
+ return { dir: tmpDir, filePath };
187
+ }
188
+ function getFinalOutput(messages) {
189
+ for (let i = messages.length - 1; i >= 0; i--) {
190
+ const msg = messages[i];
191
+ if (msg.role === "assistant") {
192
+ for (const part of msg.content) {
193
+ if (part.type === "text")
194
+ return part.text;
195
+ }
196
+ }
197
+ }
198
+ return "";
199
+ }
200
+ export async function runLegacySingleAgent(defaultCwd, agents, agentName, task, cwd, step, modelOverride, parentModel, signal, onUpdate, makeDetails, parentSessionFile, attachableSession, onSessionInfo, onSubagentEvent, foregroundHooks) {
201
+ const agent = agents.find((a) => a.name === agentName);
202
+ if (!agent) {
203
+ const available = agents.map((a) => `"${a.name}"`).join(", ") || "none";
204
+ return {
205
+ agent: agentName,
206
+ agentSource: "unknown",
207
+ task,
208
+ exitCode: 1,
209
+ messages: [],
210
+ stderr: `Unknown agent: "${agentName}". Available agents: ${available}.`,
211
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
212
+ step,
213
+ };
214
+ }
215
+ let tmpPromptDir = null;
216
+ let tmpPromptPath = null;
217
+ const preferences = loadEffectivePreferences()?.preferences;
218
+ const settingsBudgetModel = readBudgetSubagentModelFromSettings();
219
+ const resolvedModel = resolveConfiguredSubagentModel(agent, preferences, settingsBudgetModel);
220
+ const inferredModel = resolveSubagentModel({ name: agent.name, model: resolvedModel }, { overrideModel: modelOverride, parentModel });
221
+ const currentResult = {
222
+ agent: agentName,
223
+ agentSource: agent.source,
224
+ task,
225
+ exitCode: 0,
226
+ messages: [],
227
+ stderr: "",
228
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
229
+ model: inferredModel,
230
+ step,
231
+ parentSessionFile,
232
+ };
233
+ const emitUpdate = () => {
234
+ if (onUpdate) {
235
+ onUpdate({
236
+ content: [{ type: "text", text: getFinalOutput(currentResult.messages) || "(running...)" }],
237
+ details: makeDetails([currentResult]),
238
+ });
239
+ }
240
+ };
241
+ let wasAborted = false;
242
+ let deferTempPromptCleanup = false;
243
+ let tempPromptCleanupDone = false;
244
+ const cleanupTempPromptFiles = () => {
245
+ if (tempPromptCleanupDone)
246
+ return;
247
+ tempPromptCleanupDone = true;
248
+ if (tmpPromptPath)
249
+ try {
250
+ fs.unlinkSync(tmpPromptPath);
251
+ }
252
+ catch {
253
+ /* ignore */
254
+ }
255
+ if (tmpPromptDir)
256
+ try {
257
+ fs.rmdirSync(tmpPromptDir);
258
+ }
259
+ catch {
260
+ /* ignore */
261
+ }
262
+ };
263
+ try {
264
+ if (agent.systemPrompt.trim()) {
265
+ const tmp = writePromptToTempFile(agent.name, agent.systemPrompt);
266
+ tmpPromptDir = tmp.dir;
267
+ tmpPromptPath = tmp.filePath;
268
+ }
269
+ const effectiveCwd = cwd ?? defaultCwd;
270
+ const subagentSessionDir = parentSessionFile ? path.dirname(parentSessionFile) : undefined;
271
+ const sessionFilesBefore = attachableSession && subagentSessionDir
272
+ ? new Set(listSessionFiles(subagentSessionDir))
273
+ : undefined;
274
+ const launchStartedAt = Date.now();
275
+ const args = buildSubagentProcessArgs(agent, task, tmpPromptPath, inferredModel, {
276
+ noSession: !attachableSession,
277
+ parentSessionFile: parentSessionFile,
278
+ mode: attachableSession ? "rpc" : "json",
279
+ });
280
+ const exitCode = await new Promise((resolve) => {
281
+ const bundledPaths = getBundledExtensionPathsFromEnv();
282
+ const extensionArgs = bundledPaths.flatMap((p) => ["--extension", p]);
283
+ const cliPath = resolveSubagentCliPath(effectiveCwd);
284
+ if (!cliPath) {
285
+ currentResult.stderr += "Unable to resolve LSD/GSD CLI path for subagent launch.";
286
+ resolve(1);
287
+ return;
288
+ }
289
+ const proc = spawn(process.execPath, [cliPath, ...extensionArgs, ...args], { cwd: effectiveCwd, shell: false, stdio: ["pipe", "pipe", "pipe"] });
290
+ liveSubagentProcesses.add(proc);
291
+ let buffer = "";
292
+ let completionSeen = false;
293
+ let resolved = false;
294
+ let foregroundReleased = false;
295
+ let isBusy = false;
296
+ let commandSeq = 0;
297
+ const pendingCommandResponses = new Map();
298
+ const procAbortController = new AbortController();
299
+ let resolveBackgroundResult;
300
+ let rejectBackgroundResult;
301
+ const backgroundResultPromise = new Promise((resolveBg, rejectBg) => {
302
+ resolveBackgroundResult = resolveBg;
303
+ rejectBackgroundResult = rejectBg;
304
+ });
305
+ const sendRpcCommand = async (command) => {
306
+ const id = `sa_cmd_${++commandSeq}`;
307
+ if (!proc.stdin)
308
+ throw new Error("Subagent RPC stdin is not available.");
309
+ return new Promise((resolveCmd, rejectCmd) => {
310
+ pendingCommandResponses.set(id, { resolve: resolveCmd, reject: rejectCmd });
311
+ proc.stdin.write(JSON.stringify({ id, ...command }) + "\n");
312
+ });
313
+ };
314
+ const finishForeground = (code) => {
315
+ if (resolved)
316
+ return;
317
+ resolved = true;
318
+ resolve(code);
319
+ };
320
+ const adoptToBackground = (jobId) => {
321
+ if (resolved || foregroundReleased)
322
+ return false;
323
+ foregroundReleased = true;
324
+ deferTempPromptCleanup = true;
325
+ currentResult.backgroundJobId = jobId;
326
+ finishForeground(0);
327
+ return true;
328
+ };
329
+ backgroundResultPromise.finally(() => {
330
+ if (deferTempPromptCleanup)
331
+ cleanupTempPromptFiles();
332
+ });
333
+ foregroundHooks?.onStart?.({
334
+ agentName,
335
+ task,
336
+ cwd: cwd ?? defaultCwd,
337
+ parentSessionFile,
338
+ abortController: procAbortController,
339
+ resultPromise: backgroundResultPromise,
340
+ adoptToBackground,
341
+ sendPrompt: attachableSession
342
+ ? async (text, images) => {
343
+ await sendRpcCommand({ type: "prompt", message: text, images });
344
+ }
345
+ : undefined,
346
+ sendSteer: attachableSession
347
+ ? async (text, images) => {
348
+ await sendRpcCommand({ type: "steer", message: text, images });
349
+ }
350
+ : undefined,
351
+ sendFollowUp: attachableSession
352
+ ? async (text, images) => {
353
+ await sendRpcCommand({ type: "follow_up", message: text, images });
354
+ }
355
+ : undefined,
356
+ isBusy: attachableSession ? () => isBusy : undefined,
357
+ });
358
+ proc.stdout.on("data", (data) => {
359
+ buffer += data.toString();
360
+ const lines = buffer.split("\n");
361
+ buffer = lines.pop() || "";
362
+ for (const line of lines) {
363
+ const trimmed = line.trim();
364
+ if (!trimmed)
365
+ continue;
366
+ if (attachableSession) {
367
+ try {
368
+ const parsed = JSON.parse(trimmed);
369
+ if (parsed?.type === "response" && typeof parsed.id === "string" && pendingCommandResponses.has(parsed.id)) {
370
+ const pending = pendingCommandResponses.get(parsed.id);
371
+ pendingCommandResponses.delete(parsed.id);
372
+ if (parsed.success === false) {
373
+ pending.reject(new Error(typeof parsed.error === "string" ? parsed.error : "Subagent RPC command failed."));
374
+ }
375
+ else {
376
+ pending.resolve(parsed.data);
377
+ }
378
+ continue;
379
+ }
380
+ }
381
+ catch {
382
+ // Fall through to generic event processing.
383
+ }
384
+ }
385
+ if (processSubagentEventLine(trimmed, currentResult, emitUpdate, proc, onSessionInfo, (eventType) => {
386
+ if (eventType === "agent_start")
387
+ isBusy = true;
388
+ if (eventType === "agent_end")
389
+ isBusy = false;
390
+ }, (event) => onSubagentEvent?.(event, currentResult))) {
391
+ completionSeen = true;
392
+ try {
393
+ proc.kill("SIGTERM");
394
+ }
395
+ catch {
396
+ /* ignore */
397
+ }
398
+ }
399
+ }
400
+ });
401
+ proc.stderr.on("data", (data) => {
402
+ currentResult.stderr += data.toString();
403
+ });
404
+ proc.on("close", (code) => {
405
+ liveSubagentProcesses.delete(proc);
406
+ if (buffer.trim()) {
407
+ const completedOnFlush = processSubagentEventLine(buffer, currentResult, emitUpdate, proc, onSessionInfo, (eventType) => {
408
+ if (eventType === "agent_start")
409
+ isBusy = true;
410
+ if (eventType === "agent_end")
411
+ isBusy = false;
412
+ }, (event) => onSubagentEvent?.(event, currentResult));
413
+ completionSeen = completionSeen || completedOnFlush;
414
+ }
415
+ isBusy = false;
416
+ for (const pending of pendingCommandResponses.values()) {
417
+ pending.reject(new Error("Subagent process closed before command response."));
418
+ }
419
+ pendingCommandResponses.clear();
420
+ const finalExitCode = completionSeen && (code === null || code === 143 || code === 15) ? 0 : (code ?? 0);
421
+ currentResult.exitCode = finalExitCode;
422
+ if (attachableSession && sessionFilesBefore && subagentSessionDir && !currentResult.sessionFile) {
423
+ const detected = detectNewSubagentSessionFile(subagentSessionDir, sessionFilesBefore, launchStartedAt);
424
+ if (detected)
425
+ currentResult.sessionFile = detected;
426
+ }
427
+ resolveBackgroundResult?.({
428
+ summary: getFinalOutput(currentResult.messages),
429
+ stderr: currentResult.stderr,
430
+ exitCode: finalExitCode,
431
+ model: currentResult.model,
432
+ sessionFile: currentResult.sessionFile,
433
+ parentSessionFile: currentResult.parentSessionFile,
434
+ });
435
+ foregroundHooks?.onFinish?.();
436
+ finishForeground(finalExitCode);
437
+ });
438
+ proc.on("error", (error) => {
439
+ liveSubagentProcesses.delete(proc);
440
+ isBusy = false;
441
+ for (const pending of pendingCommandResponses.values()) {
442
+ pending.reject(error instanceof Error ? error : new Error(String(error)));
443
+ }
444
+ pendingCommandResponses.clear();
445
+ rejectBackgroundResult?.(error);
446
+ foregroundHooks?.onFinish?.();
447
+ finishForeground(1);
448
+ });
449
+ if (attachableSession) {
450
+ void sendRpcCommand({ type: "prompt", message: task }).catch((error) => {
451
+ currentResult.stderr += error instanceof Error ? error.message : String(error);
452
+ try {
453
+ proc.kill("SIGTERM");
454
+ }
455
+ catch {
456
+ /* ignore */
457
+ }
458
+ });
459
+ }
460
+ const killProc = () => {
461
+ wasAborted = true;
462
+ procAbortController.abort();
463
+ proc.kill("SIGTERM");
464
+ setTimeout(() => {
465
+ if (!proc.killed)
466
+ proc.kill("SIGKILL");
467
+ }, 5000);
468
+ };
469
+ if (signal) {
470
+ if (signal.aborted)
471
+ killProc();
472
+ else
473
+ signal.addEventListener("abort", killProc, { once: true });
474
+ }
475
+ if (procAbortController.signal.aborted) {
476
+ killProc();
477
+ }
478
+ else {
479
+ procAbortController.signal.addEventListener("abort", () => {
480
+ proc.kill("SIGTERM");
481
+ setTimeout(() => {
482
+ if (!proc.killed)
483
+ proc.kill("SIGKILL");
484
+ }, 5000);
485
+ }, { once: true });
486
+ }
487
+ });
488
+ currentResult.exitCode = exitCode;
489
+ if (attachableSession && sessionFilesBefore && subagentSessionDir) {
490
+ const detected = detectNewSubagentSessionFile(subagentSessionDir, sessionFilesBefore, launchStartedAt);
491
+ if (detected) {
492
+ currentResult.sessionFile = detected;
493
+ }
494
+ }
495
+ if (wasAborted)
496
+ throw new Error("Subagent was aborted");
497
+ return currentResult;
498
+ }
499
+ finally {
500
+ if (!deferTempPromptCleanup)
501
+ cleanupTempPromptFiles();
502
+ }
503
+ }