@bastani/atomic 0.9.5-alpha.9 → 0.9.5

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 (377) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/README.md +2 -2
  3. package/dist/builtin/cursor/CHANGELOG.md +12 -0
  4. package/dist/builtin/cursor/package.json +3 -3
  5. package/dist/builtin/cursor/src/model-mapper.ts +6 -3
  6. package/dist/builtin/intercom/CHANGELOG.md +37 -0
  7. package/dist/builtin/intercom/README.md +4 -2
  8. package/dist/builtin/intercom/broker/broker.ts +6 -114
  9. package/dist/builtin/intercom/broker/client.ts +29 -54
  10. package/dist/builtin/intercom/broker/delivered-message-cache.ts +44 -0
  11. package/dist/builtin/intercom/broker/pending-send-registry.ts +142 -0
  12. package/dist/builtin/intercom/broker/send-handler.ts +106 -0
  13. package/dist/builtin/intercom/broker/send-signature.ts +37 -0
  14. package/dist/builtin/intercom/foreground-detach-handoff.ts +136 -0
  15. package/dist/builtin/intercom/index-heavy.ts +49 -53
  16. package/dist/builtin/intercom/index.ts +278 -262
  17. package/dist/builtin/intercom/lazy-heavy-proxy.ts +114 -0
  18. package/dist/builtin/intercom/lazy-subagent-ack.ts +20 -0
  19. package/dist/builtin/intercom/lazy-tool-execution.ts +39 -0
  20. package/dist/builtin/intercom/lifecycle-lease.ts +51 -0
  21. package/dist/builtin/intercom/lifecycle.ts +37 -20
  22. package/dist/builtin/intercom/package.json +3 -6
  23. package/dist/builtin/intercom/reply-routing.ts +17 -0
  24. package/dist/builtin/intercom/subagent-relay.ts +58 -12
  25. package/dist/builtin/intercom/types.ts +3 -3
  26. package/dist/builtin/mcp/CHANGELOG.md +27 -0
  27. package/dist/builtin/mcp/OAUTH.md +1 -0
  28. package/dist/builtin/mcp/README.md +4 -0
  29. package/dist/builtin/mcp/apps-cancellation.ts +32 -0
  30. package/dist/builtin/mcp/call-tool-result.ts +9 -0
  31. package/dist/builtin/mcp/caller-wait.ts +50 -0
  32. package/dist/builtin/mcp/command-registration.ts +82 -0
  33. package/dist/builtin/mcp/direct-tool-executor.ts +279 -0
  34. package/dist/builtin/mcp/direct-tools.ts +6 -239
  35. package/dist/builtin/mcp/host-html-template.ts +4 -2
  36. package/dist/builtin/mcp/index.ts +258 -250
  37. package/dist/builtin/mcp/init.ts +96 -87
  38. package/dist/builtin/mcp/mcp-auth-flow.ts +247 -237
  39. package/dist/builtin/mcp/mcp-callback-server.ts +89 -68
  40. package/dist/builtin/mcp/mcp-oauth-provider.ts +23 -1
  41. package/dist/builtin/mcp/metadata-hydration.ts +21 -6
  42. package/dist/builtin/mcp/package.json +3 -3
  43. package/dist/builtin/mcp/proxy-auth.ts +4 -4
  44. package/dist/builtin/mcp/proxy-call.ts +111 -40
  45. package/dist/builtin/mcp/proxy-connect.ts +35 -15
  46. package/dist/builtin/mcp/proxy-info-modes.ts +49 -19
  47. package/dist/builtin/mcp/proxy-modes.ts +3 -3
  48. package/dist/builtin/mcp/session-cleanup-barrier.ts +43 -0
  49. package/dist/builtin/mcp/state-lease.ts +12 -0
  50. package/dist/builtin/mcp/ui-server.ts +8 -8
  51. package/dist/builtin/mcp/ui-session.ts +9 -18
  52. package/dist/builtin/subagents/CHANGELOG.md +66 -0
  53. package/dist/builtin/subagents/README.md +30 -29
  54. package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
  55. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
  56. package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
  57. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
  58. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
  59. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
  60. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
  61. package/dist/builtin/subagents/agents/debugger.md +2 -2
  62. package/dist/builtin/subagents/agents/worker.md +2 -2
  63. package/dist/builtin/subagents/package.json +5 -5
  64. package/dist/builtin/subagents/prompts/review-loop.md +1 -1
  65. package/dist/builtin/subagents/skills/subagent/SKILL.md +37 -36
  66. package/dist/builtin/subagents/src/extension/api-lifecycle.ts +64 -0
  67. package/dist/builtin/subagents/src/extension/fanout-child.ts +44 -51
  68. package/dist/builtin/subagents/src/extension/index.ts +287 -307
  69. package/dist/builtin/subagents/src/extension/prompt-guidance.ts +7 -10
  70. package/dist/builtin/subagents/src/extension/schemas.ts +22 -5
  71. package/dist/builtin/subagents/src/extension/tool-description.ts +29 -0
  72. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +13 -2
  73. package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -4
  74. package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +106 -0
  75. package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +3 -2
  76. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +13 -2
  77. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +3 -0
  78. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -1
  79. package/dist/builtin/subagents/src/runs/background/completion-claims.ts +189 -0
  80. package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +44 -7
  81. package/dist/builtin/subagents/src/runs/background/completion-notification.ts +34 -0
  82. package/dist/builtin/subagents/src/runs/background/notify.ts +72 -22
  83. package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +232 -0
  84. package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +151 -0
  85. package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +72 -0
  86. package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +48 -0
  87. package/dist/builtin/subagents/src/runs/background/result-status.ts +81 -0
  88. package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +59 -0
  89. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +172 -238
  90. package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +3 -2
  91. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +73 -14
  92. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +17 -13
  93. package/dist/builtin/subagents/src/runs/background/top-level-async.ts +1 -2
  94. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
  95. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
  96. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
  97. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +7 -9
  98. package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +3 -13
  99. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +2 -15
  100. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +2 -2
  101. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +53 -44
  102. package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +48 -0
  103. package/dist/builtin/subagents/src/runs/foreground/execution-detach-route.ts +17 -0
  104. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +39 -26
  105. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +3 -1
  106. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +3 -51
  107. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +6 -11
  108. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +11 -2
  109. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
  110. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +5 -112
  111. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +2 -0
  112. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +68 -118
  113. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +79 -7
  114. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +2 -2
  115. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +3 -0
  116. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -2
  117. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +27 -11
  118. package/dist/builtin/subagents/src/shared/artifacts.ts +22 -11
  119. package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +294 -0
  120. package/dist/builtin/subagents/src/shared/exclusive-file-publication.ts +44 -0
  121. package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -0
  122. package/dist/builtin/subagents/src/shared/model-info.ts +2 -2
  123. package/dist/builtin/subagents/src/shared/settings.ts +20 -10
  124. package/dist/builtin/subagents/src/shared/types-async.ts +3 -1
  125. package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
  126. package/dist/builtin/subagents/src/shared/types-runtime.ts +3 -2
  127. package/dist/builtin/subagents/src/slash/slash-commands.ts +9 -12
  128. package/dist/builtin/subagents/src/slash/slash-live-state.ts +63 -32
  129. package/dist/builtin/subagents/src/tui/render-result.ts +7 -0
  130. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -0
  131. package/dist/builtin/subagents/src/tui/render-widget.ts +128 -89
  132. package/dist/builtin/web-access/CHANGELOG.md +28 -0
  133. package/dist/builtin/web-access/README.md +4 -0
  134. package/dist/builtin/web-access/content-tools.ts +8 -3
  135. package/dist/builtin/web-access/index-heavy.ts +1 -1
  136. package/dist/builtin/web-access/index.ts +190 -46
  137. package/dist/builtin/web-access/lifecycle-lease.ts +38 -0
  138. package/dist/builtin/web-access/package.json +2 -2
  139. package/dist/builtin/web-access/result-renderers.ts +1 -1
  140. package/dist/builtin/web-access/summary-review.ts +1 -1
  141. package/dist/builtin/web-access/web-search-activity.ts +1 -1
  142. package/dist/builtin/web-access/web-search-return.ts +7 -0
  143. package/dist/builtin/web-access/web-search-summary.ts +1 -1
  144. package/dist/builtin/web-access/web-search-tool.ts +4 -2
  145. package/dist/builtin/workflows/CHANGELOG.md +68 -0
  146. package/dist/builtin/workflows/README.md +4 -4
  147. package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +27 -4
  148. package/dist/builtin/workflows/builtin/goal-runner.ts +47 -26
  149. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +10 -0
  150. package/dist/builtin/workflows/builtin/ralph-core.ts +9 -9
  151. package/dist/builtin/workflows/builtin/ralph-models.ts +71 -36
  152. package/dist/builtin/workflows/builtin/ralph-runner.ts +20 -31
  153. package/dist/builtin/workflows/package.json +2 -2
  154. package/dist/builtin/workflows/src/durable/stage-primitive.ts +2 -1
  155. package/dist/builtin/workflows/src/engine/primitives/task.ts +2 -1
  156. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +17 -22
  157. package/dist/builtin/workflows/src/extension/workflow-schema.ts +15 -2
  158. package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +1 -2
  159. package/dist/builtin/workflows/src/runs/shared/model-fallback-candidates.ts +1 -1
  160. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -2
  161. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +2 -2
  162. package/dist/builtin/workflows/src/shared/resume-continuation.ts +2 -0
  163. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +1 -23
  164. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +54 -9
  165. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +5 -2
  166. package/dist/cli/args.d.ts.map +1 -1
  167. package/dist/cli/args.js +2 -2
  168. package/dist/cli/args.js.map +1 -1
  169. package/dist/core/agent-session-events.d.ts.map +1 -1
  170. package/dist/core/agent-session-events.js +2 -1
  171. package/dist/core/agent-session-events.js.map +1 -1
  172. package/dist/core/agent-session-message-queue.d.ts.map +1 -1
  173. package/dist/core/agent-session-message-queue.js +1 -1
  174. package/dist/core/agent-session-message-queue.js.map +1 -1
  175. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  176. package/dist/core/agent-session-prompt.js +1 -1
  177. package/dist/core/agent-session-prompt.js.map +1 -1
  178. package/dist/core/agent-session-retry.d.ts.map +1 -1
  179. package/dist/core/agent-session-retry.js +1 -1
  180. package/dist/core/agent-session-retry.js.map +1 -1
  181. package/dist/core/agent-session-services.d.ts.map +1 -1
  182. package/dist/core/agent-session-services.js +3 -2
  183. package/dist/core/agent-session-services.js.map +1 -1
  184. package/dist/core/agent-session-types.d.ts.map +1 -1
  185. package/dist/core/agent-session-types.js +1 -1
  186. package/dist/core/agent-session-types.js.map +1 -1
  187. package/dist/core/anthropic-thinking-guard.d.ts +5 -5
  188. package/dist/core/anthropic-thinking-guard.d.ts.map +1 -1
  189. package/dist/core/anthropic-thinking-guard.js +42 -32
  190. package/dist/core/anthropic-thinking-guard.js.map +1 -1
  191. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  192. package/dist/core/atomic-guide-command.js +15 -15
  193. package/dist/core/atomic-guide-command.js.map +1 -1
  194. package/dist/core/auth-storage.d.ts.map +1 -1
  195. package/dist/core/auth-storage.js +14 -9
  196. package/dist/core/auth-storage.js.map +1 -1
  197. package/dist/core/compaction/compaction.d.ts +2 -0
  198. package/dist/core/compaction/compaction.d.ts.map +1 -1
  199. package/dist/core/compaction/compaction.js +79 -46
  200. package/dist/core/compaction/compaction.js.map +1 -1
  201. package/dist/core/compaction/context-assistant-turns.d.ts +42 -0
  202. package/dist/core/compaction/context-assistant-turns.d.ts.map +1 -0
  203. package/dist/core/compaction/context-assistant-turns.js +87 -0
  204. package/dist/core/compaction/context-assistant-turns.js.map +1 -0
  205. package/dist/core/compaction/context-compaction-critical.d.ts +1 -1
  206. package/dist/core/compaction/context-compaction-critical.d.ts.map +1 -1
  207. package/dist/core/compaction/context-compaction-critical.js +2 -2
  208. package/dist/core/compaction/context-compaction-critical.js.map +1 -1
  209. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts +18 -0
  210. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts.map +1 -0
  211. package/dist/core/compaction/context-compaction-eviction-alternates.js +186 -0
  212. package/dist/core/compaction/context-compaction-eviction-alternates.js.map +1 -0
  213. package/dist/core/compaction/context-compaction-eviction.d.ts +10 -2
  214. package/dist/core/compaction/context-compaction-eviction.d.ts.map +1 -1
  215. package/dist/core/compaction/context-compaction-eviction.js +196 -146
  216. package/dist/core/compaction/context-compaction-eviction.js.map +1 -1
  217. package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
  218. package/dist/core/compaction/context-compaction-prompt.js +1 -1
  219. package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
  220. package/dist/core/compaction/context-compaction-types.d.ts +2 -0
  221. package/dist/core/compaction/context-compaction-types.d.ts.map +1 -1
  222. package/dist/core/compaction/context-compaction-types.js.map +1 -1
  223. package/dist/core/compaction/context-deletion-application.d.ts +5 -4
  224. package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
  225. package/dist/core/compaction/context-deletion-application.js +17 -15
  226. package/dist/core/compaction/context-deletion-application.js.map +1 -1
  227. package/dist/core/compaction/context-deletion-store.d.ts.map +1 -1
  228. package/dist/core/compaction/context-deletion-store.js +1 -1
  229. package/dist/core/compaction/context-deletion-store.js.map +1 -1
  230. package/dist/core/compaction/context-deletion-targets.d.ts +2 -1
  231. package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
  232. package/dist/core/compaction/context-deletion-targets.js +36 -31
  233. package/dist/core/compaction/context-deletion-targets.js.map +1 -1
  234. package/dist/core/compaction/context-deletion-tool-helpers.d.ts.map +1 -1
  235. package/dist/core/compaction/context-deletion-tool-helpers.js +116 -43
  236. package/dist/core/compaction/context-deletion-tool-helpers.js.map +1 -1
  237. package/dist/core/compaction/context-transcript-analysis.d.ts +1 -2
  238. package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
  239. package/dist/core/compaction/context-transcript-analysis.js +33 -37
  240. package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
  241. package/dist/core/copilot-model-synthesis.d.ts.map +1 -1
  242. package/dist/core/copilot-model-synthesis.js +3 -1
  243. package/dist/core/copilot-model-synthesis.js.map +1 -1
  244. package/dist/core/extensions/provider-types.d.ts +2 -7
  245. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  246. package/dist/core/extensions/provider-types.js.map +1 -1
  247. package/dist/core/messages.d.ts +9 -0
  248. package/dist/core/messages.d.ts.map +1 -1
  249. package/dist/core/messages.js +100 -18
  250. package/dist/core/messages.js.map +1 -1
  251. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  252. package/dist/core/model-registry-builtins.js +5 -0
  253. package/dist/core/model-registry-builtins.js.map +1 -1
  254. package/dist/core/model-registry-custom-loader.d.ts.map +1 -1
  255. package/dist/core/model-registry-custom-loader.js +49 -8
  256. package/dist/core/model-registry-custom-loader.js.map +1 -1
  257. package/dist/core/model-registry-dynamic.d.ts.map +1 -1
  258. package/dist/core/model-registry-dynamic.js +11 -5
  259. package/dist/core/model-registry-dynamic.js.map +1 -1
  260. package/dist/core/model-registry-loader.d.ts.map +1 -1
  261. package/dist/core/model-registry-loader.js +8 -0
  262. package/dist/core/model-registry-loader.js.map +1 -1
  263. package/dist/core/model-registry-schemas.d.ts +93 -8
  264. package/dist/core/model-registry-schemas.d.ts.map +1 -1
  265. package/dist/core/model-registry-schemas.js +24 -12
  266. package/dist/core/model-registry-schemas.js.map +1 -1
  267. package/dist/core/model-registry-types.d.ts +7 -6
  268. package/dist/core/model-registry-types.d.ts.map +1 -1
  269. package/dist/core/model-registry-types.js.map +1 -1
  270. package/dist/core/model-registry.d.ts +5 -0
  271. package/dist/core/model-registry.d.ts.map +1 -1
  272. package/dist/core/model-registry.js +23 -0
  273. package/dist/core/model-registry.js.map +1 -1
  274. package/dist/core/model-resolver-cli.d.ts.map +1 -1
  275. package/dist/core/model-resolver-cli.js +33 -5
  276. package/dist/core/model-resolver-cli.js.map +1 -1
  277. package/dist/core/model-resolver-initial.d.ts +6 -1
  278. package/dist/core/model-resolver-initial.d.ts.map +1 -1
  279. package/dist/core/model-resolver-initial.js +12 -7
  280. package/dist/core/model-resolver-initial.js.map +1 -1
  281. package/dist/core/model-resolver.d.ts +1 -1
  282. package/dist/core/model-resolver.d.ts.map +1 -1
  283. package/dist/core/model-resolver.js +1 -1
  284. package/dist/core/model-resolver.js.map +1 -1
  285. package/dist/core/resource-loader-context-files.d.ts +1 -0
  286. package/dist/core/resource-loader-context-files.d.ts.map +1 -1
  287. package/dist/core/resource-loader-context-files.js +13 -10
  288. package/dist/core/resource-loader-context-files.js.map +1 -1
  289. package/dist/core/sdk.d.ts.map +1 -1
  290. package/dist/core/sdk.js +2 -2
  291. package/dist/core/sdk.js.map +1 -1
  292. package/dist/core/session-entry-normalization.d.ts +7 -0
  293. package/dist/core/session-entry-normalization.d.ts.map +1 -0
  294. package/dist/core/session-entry-normalization.js +14 -0
  295. package/dist/core/session-entry-normalization.js.map +1 -0
  296. package/dist/core/session-manager-core.d.ts.map +1 -1
  297. package/dist/core/session-manager-core.js +1 -0
  298. package/dist/core/session-manager-core.js.map +1 -1
  299. package/dist/core/session-manager-history.d.ts +2 -2
  300. package/dist/core/session-manager-history.d.ts.map +1 -1
  301. package/dist/core/session-manager-history.js +127 -108
  302. package/dist/core/session-manager-history.js.map +1 -1
  303. package/dist/core/settings-manager-basic-accessors.d.ts +2 -2
  304. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  305. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  306. package/dist/core/settings-types.d.ts +1 -1
  307. package/dist/core/settings-types.d.ts.map +1 -1
  308. package/dist/core/settings-types.js.map +1 -1
  309. package/dist/core/tools/bash.d.ts.map +1 -1
  310. package/dist/core/tools/bash.js +11 -8
  311. package/dist/core/tools/bash.js.map +1 -1
  312. package/dist/main-session.d.ts.map +1 -1
  313. package/dist/main-session.js +1 -0
  314. package/dist/main-session.js.map +1 -1
  315. package/dist/modes/interactive/components/settings-selector-options.d.ts.map +1 -1
  316. package/dist/modes/interactive/components/settings-selector-options.js +3 -1
  317. package/dist/modes/interactive/components/settings-selector-options.js.map +1 -1
  318. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  319. package/dist/modes/interactive/components/thinking-selector.js +2 -1
  320. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  321. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  322. package/dist/modes/interactive/interactive-agent-events.js +2 -1
  323. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  324. package/dist/modes/interactive/interactive-child-ordering.d.ts +7 -0
  325. package/dist/modes/interactive/interactive-child-ordering.d.ts.map +1 -0
  326. package/dist/modes/interactive/interactive-child-ordering.js +26 -0
  327. package/dist/modes/interactive/interactive-child-ordering.js.map +1 -0
  328. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  329. package/dist/modes/interactive/interactive-deferred-startup.js +2 -2
  330. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  331. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  332. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  333. package/dist/modes/interactive/interactive-mode-deps.js +1 -1
  334. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  335. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  336. package/dist/modes/interactive/interactive-model-routing.js +8 -3
  337. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  338. package/dist/modes/interactive/theme/theme-class.d.ts +1 -1
  339. package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
  340. package/dist/modes/interactive/theme/theme-class.js +2 -0
  341. package/dist/modes/interactive/theme/theme-class.js.map +1 -1
  342. package/dist/utils/clipboard-image.d.ts.map +1 -1
  343. package/dist/utils/clipboard-image.js +3 -0
  344. package/dist/utils/clipboard-image.js.map +1 -1
  345. package/docs/changelog.mdx +19 -0
  346. package/docs/compaction.md +55 -48
  347. package/docs/custom-provider.md +18 -5
  348. package/docs/extensions.md +7 -3
  349. package/docs/models.md +69 -10
  350. package/docs/providers.md +1 -1
  351. package/docs/quickstart.md +11 -7
  352. package/docs/rpc.md +2 -2
  353. package/docs/sdk.md +1 -1
  354. package/docs/settings.md +3 -3
  355. package/docs/subagents.md +36 -5
  356. package/docs/tools.md +1 -1
  357. package/docs/usage.md +4 -2
  358. package/docs/workflows.md +26 -43
  359. package/examples/extensions/preset.ts +2 -2
  360. package/examples/extensions/subagent/README.md +2 -2
  361. package/examples/extensions/subagent/index.ts +1 -2
  362. package/examples/extensions/subagent/schemas.ts +4 -1
  363. package/examples/sdk/12-full-control.ts +1 -1
  364. package/npm-shrinkwrap.json +48 -51
  365. package/package.json +7 -7
  366. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-behavior.ts +0 -75
  367. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-component.ts +0 -202
  368. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-edit.ts +0 -97
  369. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-editor.ts +0 -160
  370. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-frame.ts +0 -72
  371. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-modes.ts +0 -161
  372. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-selectors.ts +0 -203
  373. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-selectors.ts +0 -234
  374. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-state.ts +0 -103
  375. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-types.ts +0 -29
  376. package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +0 -9
  377. package/dist/builtin/subagents/src/runs/foreground/chain-execution-clarify.ts +0 -117
@@ -1,13 +1,12 @@
1
- import { randomUUID } from "node:crypto";
2
- import { APP_NAME } from "@bastani/atomic";
3
- import { ChainClarifyComponent, type ChainClarifyResult } from "./chain-clarify.ts";
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
4
3
  import { currentModelFullId, resolveModelCandidate } from "../shared/model-fallback.ts";
5
4
  import { collectKnownModelProviders, toModelInfo, type ModelInfo } from "../../shared/model-info.ts";
6
- import { discoverAvailableSkills, normalizeSkillInput } from "../../agents/skills.ts";
5
+ import { normalizeSkillInput } from "../../agents/skills.ts";
6
+ import { injectSingleProgressInstruction, resolveSingleProgress, writeInitialProgressFile } from "../../shared/settings.ts";
7
7
  import { recordRun } from "../shared/run-history.ts";
8
8
  import { getSingleResultOutput, compactForegroundDetails } from "../../shared/utils.ts";
9
9
  import { updateForegroundNestedProjection } from "../shared/nested-events.ts";
10
- import { resolveStepBehavior } from "../../shared/settings.ts";
11
10
  import {
12
11
  INTERCOM_BRIDGE_MARKER,
13
12
  resolveSubagentIntercomTarget,
@@ -29,7 +28,7 @@ import {
29
28
  type SubagentToolResult,
30
29
  } from "../../shared/types.ts";
31
30
  import type { ExecutionContextData, ResolvedExecutorDeps } from "./subagent-executor-types.ts";
32
- import { createForegroundControlNotifier, maybeBuildForegroundIntercomReceipt, rememberForegroundRun } from "./subagent-executor-status.ts";
31
+ import { createForegroundControlNotifier, maybeBuildForegroundIntercomReceipt, rememberForegroundRun, replaceForegroundRunChild } from "./subagent-executor-status.ts";
33
32
 
34
33
  function formatFailedSingleRunOutput(result: SingleResult, displayOutput: string): string {
35
34
  const error = result.error || "Failed";
@@ -44,6 +43,15 @@ function formatFailedSingleRunOutput(result: SingleResult, displayOutput: string
44
43
  return lines.join("\n");
45
44
  }
46
45
 
46
+ function cleanupTransientProgress(progressDir: string | undefined, artifactsEnabled: boolean): void {
47
+ if (!progressDir || artifactsEnabled) return;
48
+ try {
49
+ fs.rmSync(progressDir, { recursive: true, force: true });
50
+ } catch {
51
+ // Scratch cleanup must never replace the child run's result or original error.
52
+ }
53
+ }
54
+
47
55
  export async function runSinglePath(data: ExecutionContextData, deps: ResolvedExecutorDeps): Promise<SubagentToolResult> {
48
56
  const {
49
57
  params,
@@ -58,7 +66,6 @@ export async function runSinglePath(data: ExecutionContextData, deps: ResolvedEx
58
66
  artifactConfig,
59
67
  artifactsDir,
60
68
  onUpdate,
61
- sessionRoot,
62
69
  controlConfig,
63
70
  } = data;
64
71
  const onControlEvent = createForegroundControlNotifier(data, deps);
@@ -78,96 +85,20 @@ export async function runSinglePath(data: ExecutionContextData, deps: ResolvedEx
78
85
  const availableModels: ModelInfo[] = ctx.modelRegistry.getAvailable().map(toModelInfo);
79
86
  const knownModelProviders = collectKnownModelProviders(ctx.modelRegistry);
80
87
  let task = params.task ?? "";
81
- let modelOverride: string | undefined = resolveModelCandidate(
88
+ const modelOverride: string | undefined = resolveModelCandidate(
82
89
  (params.model as string | undefined) ?? agentConfig.model,
83
90
  availableModels,
84
91
  currentProvider,
85
92
  );
86
- let skillOverride: string[] | false | undefined = normalizeSkillInput(params.skill);
93
+ const skillOverride: string[] | false | undefined = normalizeSkillInput(params.skill);
87
94
  const rawOutput = params.output !== undefined ? params.output : agentConfig.output;
88
- let effectiveOutput = normalizeSingleOutputOverride(rawOutput, agentConfig.output);
95
+ const effectiveOutput = normalizeSingleOutputOverride(rawOutput, agentConfig.output);
89
96
  const effectiveOutputMode = params.outputMode ?? "inline";
90
97
  const depthPolicy = resolveSubagentDepthPolicy(ctx, deps.config.maxSubagentDepth);
91
98
  const currentMaxSubagentDepth = depthPolicy.maxSubagentDepth;
92
99
  const workflowStageSubagentGuard = depthPolicy.workflowStageSubagentGuard;
93
100
  const maxSubagentDepth = resolveChildMaxSubagentDepth(currentMaxSubagentDepth, agentConfig.maxSubagentDepth);
94
-
95
- if (params.clarify === true && ctx.hasUI) {
96
- const behavior = resolveStepBehavior(agentConfig, { output: effectiveOutput, skills: skillOverride });
97
- const availableSkills = discoverAvailableSkills(effectiveCwd);
98
-
99
- const result = await ctx.ui.custom<ChainClarifyResult>(
100
- (tui, theme, _kb, done) =>
101
- new ChainClarifyComponent(
102
- tui, theme,
103
- [agentConfig],
104
- [task],
105
- task,
106
- undefined,
107
- [behavior],
108
- availableModels,
109
- currentProvider,
110
- availableSkills,
111
- done,
112
- "single",
113
- ),
114
- { overlay: true, overlayOptions: { anchor: "center", width: 84, maxHeight: "80%" } },
115
- );
116
-
117
- if (!result || !result.confirmed) {
118
- return { content: [{ type: "text", text: "Cancelled" }], details: { mode: "single", results: [] } };
119
- }
120
-
121
- task = result.templates[0]!;
122
- const override = result.behaviorOverrides[0];
123
- if (override?.model) modelOverride = override.model;
124
- if (override?.output !== undefined) effectiveOutput = normalizeSingleOutputOverride(override.output, agentConfig.output);
125
- if (override?.skills !== undefined) skillOverride = override.skills;
126
-
127
- if (result.runInBackground) {
128
- if (!deps.runtime.isAsyncAvailable()) {
129
- return {
130
- content: [{ type: "text", text: `Background mode requires upstream jiti for TypeScript execution but it could not be found. Ensure the ${APP_NAME}-subagents package dependencies are installed.` }],
131
- isError: true,
132
- details: { mode: "single" as const, results: [] },
133
- };
134
- }
135
- const id = randomUUID();
136
- const asyncCtx = {
137
- pi: deps.pi,
138
- cwd: ctx.cwd,
139
- currentSessionId: deps.state.currentSessionId!,
140
- currentModelProvider: ctx.model?.provider,
141
- currentModel: currentModelFullId(ctx.model),
142
- };
143
- return deps.runtime.executeAsyncSingle(id, {
144
- agent: params.agent!,
145
- task: params.context === "fork" ? wrapForkTask(task) : task,
146
- agentConfig,
147
- ctx: asyncCtx,
148
- availableModels,
149
- knownModelProviders,
150
- cwd: effectiveCwd,
151
- maxOutput: params.maxOutput,
152
- artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
153
- artifactConfig,
154
- shareEnabled,
155
- sessionRoot,
156
- sessionFile: sessionFileForIndex(0),
157
- skills: skillOverride === false ? [] : skillOverride,
158
- output: effectiveOutput,
159
- outputMode: effectiveOutputMode,
160
- modelOverride,
161
- maxSubagentDepth,
162
- workflowStageSubagentGuard,
163
- worktreeSetupHook: deps.config.worktreeSetupHook,
164
- worktreeSetupHookTimeoutMs: deps.config.worktreeSetupHookTimeoutMs,
165
- controlConfig,
166
- controlIntercomTarget: data.intercomBridge.active ? data.intercomBridge.orchestratorTarget : undefined,
167
- childIntercomTarget: data.intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(id, agent, index) : undefined,
168
- });
169
- }
170
- }
101
+ const progress = resolveSingleProgress(agentConfig, params.progress, task);
171
102
 
172
103
  if (params.context === "fork") {
173
104
  task = wrapForkTask(task);
@@ -178,6 +109,13 @@ export async function runSinglePath(data: ExecutionContextData, deps: ResolvedEx
178
109
  if (validationError) {
179
110
  return { content: [{ type: "text", text: validationError }], isError: true, details: { mode: "single", results: [] } };
180
111
  }
112
+ // Single-agent progress is isolated by run so the injected contract cannot
113
+ // overwrite a project's own progress.md or collide with another child.
114
+ const progressDir = progress ? path.join(artifactsDir, "progress", runId) : undefined;
115
+ if (progressDir) {
116
+ writeInitialProgressFile(progressDir);
117
+ task = injectSingleProgressInstruction(task, progressDir);
118
+ }
181
119
  task = injectSingleOutputInstruction(task, outputPath);
182
120
 
183
121
  let effectiveSkills: string[] | undefined;
@@ -222,37 +160,49 @@ export async function runSinglePath(data: ExecutionContextData, deps: ResolvedEx
222
160
  }
223
161
  : undefined;
224
162
 
225
- const r = await deps.runtime.runSync(ctx.cwd, agents, params.agent!, task, {
226
- cwd: effectiveCwd,
227
- signal,
228
- interruptSignal: interruptController.signal,
229
- allowIntercomDetach: agentConfig.systemPrompt?.includes(INTERCOM_BRIDGE_MARKER) === true,
230
- intercomEvents: deps.pi.events,
231
- runId,
232
- sessionDir: sessionDirForIndex(0),
233
- sessionFile: sessionFileForIndex(0),
234
- share: shareEnabled,
235
- artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
236
- artifactConfig,
237
- maxOutput: params.maxOutput,
238
- outputPath,
239
- outputMode: effectiveOutputMode,
240
- maxSubagentDepth,
241
- workflowStageSubagentGuard,
242
- onUpdate: forwardSingleUpdate,
243
- controlConfig,
244
- onControlEvent,
245
- intercomSessionName: childIntercomTarget,
246
- orchestratorIntercomTarget: data.intercomBridge.active ? data.intercomBridge.orchestratorTarget : undefined,
247
- nestedRoute: foregroundControl?.nestedRoute,
248
- index: 0,
249
- modelOverride,
250
- availableModels,
251
- knownModelProviders,
252
- preferredModelProvider: currentProvider,
253
- currentModel: currentModelFullId(ctx.model),
254
- skills: effectiveSkills,
255
- });
163
+ let r: SingleResult;
164
+ try {
165
+ r = await deps.runtime.runSync(ctx.cwd, agents, params.agent!, task, {
166
+ cwd: effectiveCwd,
167
+ signal,
168
+ interruptSignal: interruptController.signal,
169
+ allowIntercomDetach: agentConfig.systemPrompt?.includes(INTERCOM_BRIDGE_MARKER) === true,
170
+ intercomEvents: deps.pi.events,
171
+ runId,
172
+ sessionDir: sessionDirForIndex(0),
173
+ sessionFile: sessionFileForIndex(0),
174
+ share: shareEnabled,
175
+ artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
176
+ artifactConfig,
177
+ maxOutput: params.maxOutput,
178
+ outputPath,
179
+ outputMode: effectiveOutputMode,
180
+ maxSubagentDepth,
181
+ workflowStageSubagentGuard,
182
+ onUpdate: forwardSingleUpdate,
183
+ controlConfig,
184
+ onControlEvent,
185
+ intercomSessionName: childIntercomTarget,
186
+ orchestratorIntercomTarget: data.intercomBridge.active ? data.intercomBridge.orchestratorTarget : undefined,
187
+ nestedRoute: foregroundControl?.nestedRoute,
188
+ onDetachedExit: (result) => {
189
+ cleanupTransientProgress(progressDir, artifactConfig.enabled);
190
+ if (result) replaceForegroundRunChild(deps.state, runId, 0, result);
191
+ },
192
+ index: 0,
193
+ modelOverride,
194
+ availableModels,
195
+ knownModelProviders,
196
+ preferredModelProvider: currentProvider,
197
+ currentModel: currentModelFullId(ctx.model),
198
+ skills: effectiveSkills,
199
+ });
200
+ } catch (error) {
201
+ cleanupTransientProgress(progressDir, artifactConfig.enabled);
202
+ throw error;
203
+ }
204
+ // Detached children still own this storage until their process closes.
205
+ if (!r.detached) cleanupTransientProgress(progressDir, artifactConfig.enabled);
256
206
  if (foregroundControl?.currentIndex === 0) {
257
207
  foregroundControl.interrupt = undefined;
258
208
  foregroundControl.currentActivityState = r.progress?.activityState;
@@ -1,5 +1,5 @@
1
1
  import type { ExtensionAPI } from "@bastani/atomic";
2
- import { compactForegroundDetails, getSingleResultOutput } from "../../shared/utils.ts";
2
+ import { compactForegroundDetails, compactForegroundResult, getSingleResultOutput } from "../../shared/utils.ts";
3
3
  import {
4
4
  attachNestedChildrenToResultChildren,
5
5
  buildSubagentResultIntercomPayload,
@@ -77,6 +77,39 @@ export function foregroundStatusResult(control: ForegroundControl): SubagentTool
77
77
  return { content: [{ type: "text", text: lines.join("\n") }], details: { mode: "management", results: [] } };
78
78
  }
79
79
 
80
+ export function retainedForegroundStatusResult(state: SubagentState, runId: string): SubagentToolResult | undefined {
81
+ const run = state.foregroundRuns?.get(runId);
82
+ if (!run) return undefined;
83
+ const statuses = run.children.map((child) => child.status);
84
+ const stateLabel = statuses.includes("detached") ? "detached"
85
+ : statuses.includes("failed") ? "failed"
86
+ : statuses.includes("paused") ? "paused"
87
+ : statuses.every((status) => status === "completed") ? "completed"
88
+ : statuses[0] ?? "unknown";
89
+ const lines = [`Run: ${run.runId}`, `State: ${stateLabel}`, `Mode: ${run.mode}`];
90
+ for (const child of run.children) {
91
+ lines.push(`Child ${child.index + 1}: ${child.agent} (${child.status})`);
92
+ const output = child.result ? getSingleResultOutput(child.result) : "";
93
+ if (output) lines.push(output);
94
+ else if (child.result?.error) lines.push(child.result.error);
95
+ }
96
+ return { content: [{ type: "text", text: lines.join("\n") }], details: { mode: "management", results: [] } };
97
+ }
98
+
99
+ const earlyDetachedResults = new WeakMap<SubagentState, Map<string, Map<number, SingleResult>>>();
100
+ const MAX_EARLY_DETACHED_RUNS = 50;
101
+ const MAX_EARLY_DETACHED_CHILDREN_PER_RUN = 50;
102
+
103
+
104
+ function takeEarlyDetachedResult(state: SubagentState, runId: string, index: number): SingleResult | undefined {
105
+ const byRun = earlyDetachedResults.get(state);
106
+ const byIndex = byRun?.get(runId);
107
+ const result = byIndex?.get(index);
108
+ byIndex?.delete(index);
109
+ if (byIndex?.size === 0) byRun?.delete(runId);
110
+ return result;
111
+ }
112
+
80
113
  export function rememberForegroundRun(state: SubagentState, input: { runId: string; mode: "single" | "parallel" | "chain"; cwd: string; results: SingleResult[] }): void {
81
114
  state.foregroundRuns ??= new Map();
82
115
  state.foregroundRuns.set(input.runId, {
@@ -84,12 +117,16 @@ export function rememberForegroundRun(state: SubagentState, input: { runId: stri
84
117
  mode: input.mode,
85
118
  cwd: input.cwd,
86
119
  updatedAt: Date.now(),
87
- children: input.results.map((result, index) => ({
88
- agent: result.agent,
89
- index,
90
- status: resolveSubagentResultStatus({ exitCode: result.exitCode, interrupted: result.interrupted, detached: result.detached }),
91
- ...(result.sessionFile ? { sessionFile: result.sessionFile } : {}),
92
- })),
120
+ children: input.results.map((originalResult, index) => {
121
+ const result = takeEarlyDetachedResult(state, input.runId, index) ?? originalResult;
122
+ return {
123
+ agent: result.agent,
124
+ index,
125
+ status: resolveSubagentResultStatus({ exitCode: result.exitCode, interrupted: result.interrupted, detached: result.detached }),
126
+ ...(result.sessionFile ? { sessionFile: result.sessionFile } : {}),
127
+ result,
128
+ };
129
+ }),
93
130
  });
94
131
  while (state.foregroundRuns.size > 50) {
95
132
  const oldest = [...state.foregroundRuns.values()].sort((left, right) => left.updatedAt - right.updatedAt)[0];
@@ -98,6 +135,41 @@ export function rememberForegroundRun(state: SubagentState, input: { runId: stri
98
135
  }
99
136
  }
100
137
 
138
+ export function replaceForegroundRunChild(state: SubagentState, runId: string, index: number, result: SingleResult): void {
139
+ const retainedResult = compactForegroundResult(result);
140
+ const run = state.foregroundRuns?.get(runId);
141
+ if (!run) {
142
+ let byRun = earlyDetachedResults.get(state);
143
+ if (!byRun) {
144
+ byRun = new Map();
145
+ earlyDetachedResults.set(state, byRun);
146
+ }
147
+ let byIndex = byRun.get(runId);
148
+ if (!byIndex) {
149
+ byIndex = new Map();
150
+ byRun.set(runId, byIndex);
151
+ }
152
+ byIndex.set(index, retainedResult);
153
+ while (byIndex.size > MAX_EARLY_DETACHED_CHILDREN_PER_RUN) {
154
+ const oldestIndex = byIndex.keys().next().value;
155
+ if (oldestIndex === undefined) break;
156
+ byIndex.delete(oldestIndex);
157
+ }
158
+ while (byRun.size > MAX_EARLY_DETACHED_RUNS) {
159
+ const oldestRun = byRun.keys().next().value;
160
+ if (oldestRun === undefined) break;
161
+ byRun.delete(oldestRun);
162
+ }
163
+ return;
164
+ }
165
+ const child = run.children.find((entry) => entry.index === index);
166
+ if (!child || child.status !== "detached") return;
167
+ child.status = resolveSubagentResultStatus({ exitCode: retainedResult.exitCode, interrupted: retainedResult.interrupted, detached: retainedResult.detached });
168
+ child.result = retainedResult;
169
+ if (retainedResult.sessionFile) child.sessionFile = retainedResult.sessionFile;
170
+ run.updatedAt = Date.now();
171
+ }
172
+
101
173
  export function emitControlNotification(input: {
102
174
  pi: ExtensionAPI;
103
175
  controlConfig: ExecutionContextData["controlConfig"];
@@ -37,7 +37,6 @@ export interface SubagentParamsLike {
37
37
  worktree?: boolean;
38
38
  context?: "fresh" | "fork";
39
39
  async?: boolean;
40
- clarify?: boolean;
41
40
  share?: boolean;
42
41
  control?: ControlConfig;
43
42
  sessionDir?: string;
@@ -49,6 +48,8 @@ export interface SubagentParamsLike {
49
48
  skill?: string | string[] | boolean;
50
49
  output?: string | boolean;
51
50
  outputMode?: "inline" | "file-only";
51
+ reads?: string[] | false;
52
+ progress?: boolean;
52
53
  agentScope?: string;
53
54
  chainDir?: string;
54
55
  }
@@ -92,7 +93,6 @@ export interface ExecutionContextData {
92
93
  sessionFileForIndex: (idx?: number) => string | undefined;
93
94
  artifactConfig: ArtifactConfig;
94
95
  artifactsDir: string;
95
- backgroundRequestedWhileClarifying: boolean;
96
96
  effectiveAsync: boolean;
97
97
  controlConfig: ResolvedControlConfig;
98
98
  intercomBridge: IntercomBridgeState;
@@ -26,6 +26,7 @@ import { runSinglePath } from "./subagent-executor-single.ts";
26
26
  import {
27
27
  foregroundStatusResult,
28
28
  getForegroundControl,
29
+ retainedForegroundStatusResult,
29
30
  } from "./subagent-executor-status.ts";
30
31
  import type {
31
32
  ExecutorDeps,
@@ -91,6 +92,8 @@ async function handleManagementRequest(input: {
91
92
  if (resolved?.kind === "foreground") {
92
93
  const foreground = getForegroundControl(deps.state, resolved.id);
93
94
  if (foreground) return foregroundStatusResult(foreground);
95
+ const retained = retainedForegroundStatusResult(deps.state, resolved.id);
96
+ if (retained) return retained;
94
97
  }
95
98
  } catch (error) {
96
99
  const message = error instanceof Error ? error.message : String(error);
@@ -14,8 +14,8 @@ import { resolveMcpDirectToolNames } from "./mcp-direct-tool-allowlist.ts";
14
14
  import { STRUCTURED_OUTPUT_CAPTURE_ENV, STRUCTURED_OUTPUT_SCHEMA_ENV } from "./structured-output.ts";
15
15
  import type { JsonSchemaObject } from "../../shared/types.ts";
16
16
  import { MAX_SUBAGENT_NESTING_DEPTH } from "../../shared/types-runtime.ts";
17
+ import { THINKING_LEVELS } from "../../shared/model-info.ts";
17
18
 
18
- const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"];
19
19
  const TASK_ARG_LIMIT = 8000;
20
20
  export const SUBAGENT_PARENT_MAX_DEPTH = MAX_SUBAGENT_NESTING_DEPTH;
21
21
  export const PROMPT_RUNTIME_EXTENSION_PATH = path.join(path.dirname(fileURLToPath(import.meta.url)), "subagent-prompt-runtime.ts");
@@ -88,7 +88,7 @@ interface BuildPiArgsResult {
88
88
  export function applyThinkingSuffix(model: string | undefined, thinking: string | undefined): string | undefined {
89
89
  if (!model || !thinking || thinking === "off") return model;
90
90
  const colonIdx = model.lastIndexOf(":");
91
- if (colonIdx !== -1 && THINKING_LEVELS.includes(model.substring(colonIdx + 1))) return model;
91
+ if (colonIdx !== -1 && THINKING_LEVELS.some((level) => level === model.substring(colonIdx + 1))) return model;
92
92
  return `${model}:${thinking}`;
93
93
  }
94
94
 
@@ -76,23 +76,39 @@ export interface PiSpawnCommand {
76
76
  args: string[];
77
77
  }
78
78
 
79
- function isRunnableNodeScript(filePath: string, existsSync: (filePath: string) => boolean): boolean {
79
+ function isGenericBunRuntime(execPath: string, platform: NodeJS.Platform): boolean {
80
+ const pathImpl = platform === "win32" ? path.win32 : path;
81
+ const executableName = pathImpl.basename(execPath).toLowerCase();
82
+ return executableName === "bun" || executableName === "bun.exe";
83
+ }
84
+
85
+ function isRunnableCliScript(
86
+ filePath: string,
87
+ execPath: string,
88
+ platform: NodeJS.Platform,
89
+ existsSync: (filePath: string) => boolean,
90
+ ): boolean {
80
91
  if (!existsSync(filePath)) return false;
81
- return /\.(?:mjs|cjs|js)$/i.test(filePath);
92
+ if (/\.(?:mjs|cjs|js)$/i.test(filePath)) return true;
93
+ return /\.ts$/i.test(filePath) && isGenericBunRuntime(execPath, platform);
82
94
  }
83
95
 
84
- function normalizePath(filePath: string): string {
85
- return path.isAbsolute(filePath) ? filePath : path.resolve(filePath);
96
+ function normalizePath(filePath: string, platform: NodeJS.Platform): string {
97
+ const pathImpl = platform === "win32" ? path.win32 : path;
98
+ return pathImpl.isAbsolute(filePath) ? filePath : pathImpl.resolve(filePath);
86
99
  }
87
100
 
88
101
  export function resolvePiCliScript(deps: PiSpawnDeps = {}): string | undefined {
89
102
  const existsSync = deps.existsSync ?? fs.existsSync;
90
103
  const readFileSync = deps.readFileSync ?? ((filePath, encoding) => fs.readFileSync(filePath, encoding));
91
- const argv1 = deps.argv1 ?? process.argv[1];
104
+ const platform = deps.platform ?? process.platform;
105
+ const execPath = deps.execPath ?? process.execPath;
106
+ const argv1 = Object.hasOwn(deps, "argv1") ? deps.argv1 : process.argv[1];
107
+ const pathImpl = platform === "win32" ? path.win32 : path;
92
108
 
93
109
  if (argv1) {
94
- const argvPath = normalizePath(argv1);
95
- if (isRunnableNodeScript(argvPath, existsSync)) {
110
+ const argvPath = normalizePath(argv1, platform);
111
+ if (isRunnableCliScript(argvPath, execPath, platform, existsSync)) {
96
112
  return argvPath;
97
113
  }
98
114
  }
@@ -100,12 +116,12 @@ export function resolvePiCliScript(deps: PiSpawnDeps = {}): string | undefined {
100
116
  try {
101
117
  const resolvePackageJson = deps.resolvePackageJson ?? (() => {
102
118
  const root = deps.piPackageRoot ?? resolvePiPackageRoot();
103
- if (root) return path.join(root, "package.json");
119
+ if (root) return pathImpl.join(root, "package.json");
104
120
  const packageRoot = deps.resolvePackageEntry
105
121
  ? findPiPackageRootFromEntry(deps.resolvePackageEntry())
106
122
  : resolveInstalledPiPackageRoot();
107
123
  if (!packageRoot) throw new Error(`Could not resolve ${CODING_AGENT_PACKAGE} package root`);
108
- return path.join(packageRoot, "package.json");
124
+ return pathImpl.join(packageRoot, "package.json");
109
125
  });
110
126
  const packageJsonPath = resolvePackageJson();
111
127
  const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8")) as {
@@ -116,8 +132,8 @@ export function resolvePiCliScript(deps: PiSpawnDeps = {}): string | undefined {
116
132
  ? binField
117
133
  : binField?.[APP_NAME] ?? binField?.pi ?? Object.values(binField ?? {})[0];
118
134
  if (!binPath) return undefined;
119
- const candidate = path.resolve(path.dirname(packageJsonPath), binPath);
120
- if (isRunnableNodeScript(candidate, existsSync)) {
135
+ const candidate = pathImpl.resolve(pathImpl.dirname(packageJsonPath), binPath);
136
+ if (isRunnableCliScript(candidate, execPath, platform, existsSync)) {
121
137
  return candidate;
122
138
  }
123
139
  } catch {
@@ -1,6 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { getAgentConfigPaths } from "@bastani/atomic";
4
+ import { appendToActiveEventWriter } from "./event-jsonl-writer.ts";
4
5
  import { TEMP_ARTIFACTS_DIR, type ArtifactPaths } from "./types.ts";
5
6
  const CLEANUP_MARKER_FILE = ".last-cleanup";
6
7
 
@@ -37,7 +38,26 @@ export function writeMetadata(filePath: string, metadata: object): void {
37
38
  }
38
39
 
39
40
  export function appendJsonl(filePath: string, line: string): void {
40
- fs.appendFileSync(filePath, `${line}\n`);
41
+ if (!appendToActiveEventWriter(filePath, line)) fs.appendFileSync(filePath, `${line}\n`);
42
+ }
43
+
44
+ function cleanupOldArtifactEntry(entryPath: string, cutoff: number): void {
45
+ try {
46
+ const stat = fs.lstatSync(entryPath);
47
+ if (stat.isDirectory()) {
48
+ for (const child of fs.readdirSync(entryPath)) {
49
+ cleanupOldArtifactEntry(path.join(entryPath, child), cutoff);
50
+ }
51
+ if (fs.readdirSync(entryPath).length === 0 && stat.mtimeMs < cutoff) {
52
+ fs.rmSync(entryPath, { recursive: true, force: true });
53
+ }
54
+ return;
55
+ }
56
+ if (stat.mtimeMs < cutoff) fs.unlinkSync(entryPath);
57
+ } catch {
58
+ // Artifact cleanup is best-effort housekeeping. Skip entries that disappear
59
+ // or become unreadable while scanning so one bad entry does not block the rest.
60
+ }
41
61
  }
42
62
 
43
63
  export function cleanupOldArtifacts(dir: string, maxAgeDays: number): void {
@@ -56,16 +76,7 @@ export function cleanupOldArtifacts(dir: string, maxAgeDays: number): void {
56
76
 
57
77
  for (const file of fs.readdirSync(dir)) {
58
78
  if (file === CLEANUP_MARKER_FILE) continue;
59
- const filePath = path.join(dir, file);
60
- try {
61
- const stat = fs.statSync(filePath);
62
- if (stat.mtimeMs < cutoff) {
63
- fs.unlinkSync(filePath);
64
- }
65
- } catch {
66
- // Artifact cleanup is best-effort housekeeping. Skip files that disappear
67
- // or become unreadable while scanning so one bad entry does not block the rest.
68
- }
79
+ cleanupOldArtifactEntry(path.join(dir, file), cutoff);
69
80
  }
70
81
 
71
82
  fs.writeFileSync(markerPath, String(now));