@bastani/atomic 0.8.13 → 0.8.14

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 (355) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/builtin/intercom/package.json +1 -1
  3. package/dist/builtin/mcp/host-html-template.ts +1 -1
  4. package/dist/builtin/mcp/init.ts +15 -2
  5. package/dist/builtin/mcp/mcp-callback-server.ts +10 -9
  6. package/dist/builtin/mcp/package.json +1 -1
  7. package/dist/builtin/mcp/ui-session.ts +9 -6
  8. package/dist/builtin/subagents/CHANGELOG.md +8 -1
  9. package/dist/builtin/subagents/README.md +39 -32
  10. package/dist/builtin/subagents/package.json +1 -1
  11. package/dist/builtin/subagents/skills/subagent/SKILL.md +11 -11
  12. package/dist/builtin/subagents/src/agents/agent-management.ts +6 -1
  13. package/dist/builtin/subagents/src/agents/agent-serializer.ts +2 -0
  14. package/dist/builtin/subagents/src/agents/agents.ts +44 -19
  15. package/dist/builtin/subagents/src/extension/config.ts +16 -0
  16. package/dist/builtin/subagents/src/extension/fanout-child.ts +246 -0
  17. package/dist/builtin/subagents/src/extension/index.ts +466 -603
  18. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +6 -4
  19. package/dist/builtin/subagents/src/intercom/result-intercom.ts +109 -1
  20. package/dist/builtin/subagents/src/runs/background/async-execution.ts +124 -19
  21. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +41 -6
  22. package/dist/builtin/subagents/src/runs/background/async-resume.ts +28 -15
  23. package/dist/builtin/subagents/src/runs/background/async-status.ts +60 -30
  24. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +111 -54
  25. package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +83 -0
  26. package/dist/builtin/subagents/src/runs/background/run-status.ts +79 -3
  27. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +46 -1
  28. package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +66 -14
  29. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +10 -3
  30. package/dist/builtin/subagents/src/runs/foreground/execution.ts +14 -2
  31. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +320 -23
  32. package/dist/builtin/subagents/src/runs/shared/completion-guard.ts +23 -1
  33. package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +369 -0
  34. package/dist/builtin/subagents/src/runs/shared/nested-events.ts +935 -0
  35. package/dist/builtin/subagents/src/runs/shared/nested-path.ts +52 -0
  36. package/dist/builtin/subagents/src/runs/shared/nested-render.ts +115 -0
  37. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +1 -0
  38. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +82 -9
  39. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +1 -1
  40. package/dist/builtin/subagents/src/runs/shared/single-output.ts +12 -2
  41. package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +32 -10
  42. package/dist/builtin/subagents/src/runs/shared/worktree.ts +3 -2
  43. package/dist/builtin/subagents/src/shared/artifacts.ts +0 -1
  44. package/dist/builtin/subagents/src/shared/types.ts +96 -1
  45. package/dist/builtin/subagents/src/shared/utils.ts +10 -2
  46. package/dist/builtin/subagents/src/slash/slash-commands.ts +468 -625
  47. package/dist/builtin/subagents/src/tui/render.ts +1227 -2093
  48. package/dist/builtin/web-access/package.json +1 -1
  49. package/dist/builtin/workflows/CHANGELOG.md +24 -0
  50. package/dist/builtin/workflows/README.md +28 -11
  51. package/dist/builtin/workflows/builtin/deep-research-codebase.ts +323 -40
  52. package/dist/builtin/workflows/builtin/ralph.ts +362 -176
  53. package/dist/builtin/workflows/package.json +2 -5
  54. package/dist/builtin/workflows/skills/research-codebase/SKILL.md +1 -1
  55. package/dist/builtin/workflows/skills/skill-creator/LICENSE.txt +202 -0
  56. package/dist/builtin/workflows/skills/skill-creator/SKILL.md +489 -0
  57. package/dist/builtin/workflows/skills/skill-creator/agents/analyzer.md +274 -0
  58. package/dist/builtin/workflows/skills/skill-creator/agents/comparator.md +202 -0
  59. package/dist/builtin/workflows/skills/skill-creator/agents/grader.md +223 -0
  60. package/dist/builtin/workflows/skills/skill-creator/assets/eval_review.html +146 -0
  61. package/dist/builtin/workflows/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  62. package/dist/builtin/workflows/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  63. package/dist/builtin/workflows/skills/skill-creator/references/schemas.md +430 -0
  64. package/dist/builtin/workflows/skills/skill-creator/scripts/__init__.py +0 -0
  65. package/dist/builtin/workflows/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  66. package/dist/builtin/workflows/skills/skill-creator/scripts/generate_report.py +326 -0
  67. package/dist/builtin/workflows/skills/skill-creator/scripts/improve_description.py +247 -0
  68. package/dist/builtin/workflows/skills/skill-creator/scripts/package_skill.py +136 -0
  69. package/dist/builtin/workflows/skills/skill-creator/scripts/quick_validate.py +103 -0
  70. package/dist/builtin/workflows/skills/skill-creator/scripts/run_eval.py +310 -0
  71. package/dist/builtin/workflows/skills/skill-creator/scripts/run_loop.py +328 -0
  72. package/dist/builtin/workflows/skills/skill-creator/scripts/utils.py +47 -0
  73. package/dist/builtin/workflows/src/extension/index.ts +869 -93
  74. package/dist/builtin/workflows/src/extension/render-call.ts +34 -1
  75. package/dist/builtin/workflows/src/extension/render-result.ts +126 -21
  76. package/dist/builtin/workflows/src/extension/runtime.ts +91 -3
  77. package/dist/builtin/workflows/src/extension/wiring.ts +38 -12
  78. package/dist/builtin/workflows/src/extension/workflow-schema.ts +62 -5
  79. package/dist/builtin/workflows/src/runs/background/runner.ts +3 -3
  80. package/dist/builtin/workflows/src/runs/background/status.ts +42 -8
  81. package/dist/builtin/workflows/src/runs/foreground/executor.ts +410 -95
  82. package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +5 -2
  83. package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +8 -0
  84. package/dist/builtin/workflows/src/runs/shared/model-fallback.ts +6 -4
  85. package/dist/builtin/workflows/src/runs/shared/worktree.ts +3 -2
  86. package/dist/builtin/workflows/src/shared/persistence-restore.ts +138 -5
  87. package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +30 -0
  88. package/dist/builtin/workflows/src/shared/render-inputs-schema.ts +78 -120
  89. package/dist/builtin/workflows/src/shared/stage-ui-broker.ts +193 -0
  90. package/dist/builtin/workflows/src/shared/store-types.ts +26 -1
  91. package/dist/builtin/workflows/src/shared/store.ts +145 -17
  92. package/dist/builtin/workflows/src/shared/timing.ts +6 -2
  93. package/dist/builtin/workflows/src/shared/workflow-failures.ts +375 -0
  94. package/dist/builtin/workflows/src/tui/chat-surface.ts +68 -17
  95. package/dist/builtin/workflows/src/tui/connectors.ts +2 -2
  96. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +24 -26
  97. package/dist/builtin/workflows/src/tui/graph-canvas.ts +4 -8
  98. package/dist/builtin/workflows/src/tui/graph-view.ts +17 -14
  99. package/dist/builtin/workflows/src/tui/header.ts +38 -0
  100. package/dist/builtin/workflows/src/tui/inline-form-card.ts +161 -238
  101. package/dist/builtin/workflows/src/tui/inline-form-editor.ts +68 -73
  102. package/dist/builtin/workflows/src/tui/inline-form-overlay.ts +2 -3
  103. package/dist/builtin/workflows/src/tui/inline-form-store.ts +2 -1
  104. package/dist/builtin/workflows/src/tui/inputs-overlay.ts +1 -3
  105. package/dist/builtin/workflows/src/tui/inputs-picker.ts +286 -399
  106. package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +11 -0
  107. package/dist/builtin/workflows/src/tui/node-card.ts +2 -1
  108. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +9 -1
  109. package/dist/builtin/workflows/src/tui/prompt-card.ts +46 -19
  110. package/dist/builtin/workflows/src/tui/run-detail.ts +63 -80
  111. package/dist/builtin/workflows/src/tui/session-confirm.ts +9 -3
  112. package/dist/builtin/workflows/src/tui/session-picker.ts +19 -16
  113. package/dist/builtin/workflows/src/tui/stage-chat-layout.ts +88 -0
  114. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +368 -879
  115. package/dist/builtin/workflows/src/tui/status-helpers.ts +4 -0
  116. package/dist/builtin/workflows/src/tui/status-list.ts +67 -75
  117. package/dist/builtin/workflows/src/tui/store-widget-installer.ts +50 -12
  118. package/dist/builtin/workflows/src/tui/submit-pane.ts +164 -0
  119. package/dist/builtin/workflows/src/tui/switcher.ts +27 -4
  120. package/dist/builtin/workflows/src/tui/text-helpers.ts +98 -4
  121. package/dist/builtin/workflows/src/tui/widget.ts +90 -68
  122. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +23 -2
  123. package/dist/builtin/workflows/src/tui/workflow-list.ts +44 -68
  124. package/dist/cli/file-processor.d.ts.map +1 -1
  125. package/dist/cli/file-processor.js +2 -3
  126. package/dist/cli/file-processor.js.map +1 -1
  127. package/dist/config.d.ts.map +1 -1
  128. package/dist/config.js +3 -10
  129. package/dist/config.js.map +1 -1
  130. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  131. package/dist/core/agent-session-runtime.js +2 -1
  132. package/dist/core/agent-session-runtime.js.map +1 -1
  133. package/dist/core/agent-session-services.d.ts.map +1 -1
  134. package/dist/core/agent-session-services.js +3 -2
  135. package/dist/core/agent-session-services.js.map +1 -1
  136. package/dist/core/agent-session.d.ts +6 -0
  137. package/dist/core/agent-session.d.ts.map +1 -1
  138. package/dist/core/agent-session.js +16 -2
  139. package/dist/core/agent-session.js.map +1 -1
  140. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  141. package/dist/core/atomic-guide-command.js +8 -9
  142. package/dist/core/atomic-guide-command.js.map +1 -1
  143. package/dist/core/auth-storage.d.ts.map +1 -1
  144. package/dist/core/auth-storage.js +3 -2
  145. package/dist/core/auth-storage.js.map +1 -1
  146. package/dist/core/bash-executor.d.ts.map +1 -1
  147. package/dist/core/bash-executor.js +2 -1
  148. package/dist/core/bash-executor.js.map +1 -1
  149. package/dist/core/export-html/index.d.ts.map +1 -1
  150. package/dist/core/export-html/index.js +8 -6
  151. package/dist/core/export-html/index.js.map +1 -1
  152. package/dist/core/export-html/template.js +6 -3
  153. package/dist/core/extensions/loader.d.ts.map +1 -1
  154. package/dist/core/extensions/loader.js +12 -29
  155. package/dist/core/extensions/loader.js.map +1 -1
  156. package/dist/core/model-registry.d.ts.map +1 -1
  157. package/dist/core/model-registry.js +5 -1
  158. package/dist/core/model-registry.js.map +1 -1
  159. package/dist/core/package-manager.d.ts +8 -0
  160. package/dist/core/package-manager.d.ts.map +1 -1
  161. package/dist/core/package-manager.js +145 -58
  162. package/dist/core/package-manager.js.map +1 -1
  163. package/dist/core/prompt-templates.d.ts.map +1 -1
  164. package/dist/core/prompt-templates.js +6 -20
  165. package/dist/core/prompt-templates.js.map +1 -1
  166. package/dist/core/resource-loader.d.ts.map +1 -1
  167. package/dist/core/resource-loader.js +38 -31
  168. package/dist/core/resource-loader.js.map +1 -1
  169. package/dist/core/sdk.d.ts.map +1 -1
  170. package/dist/core/sdk.js +9 -4
  171. package/dist/core/sdk.js.map +1 -1
  172. package/dist/core/session-manager.d.ts.map +1 -1
  173. package/dist/core/session-manager.js +32 -24
  174. package/dist/core/session-manager.js.map +1 -1
  175. package/dist/core/settings-manager.d.ts.map +1 -1
  176. package/dist/core/settings-manager.js +8 -15
  177. package/dist/core/settings-manager.js.map +1 -1
  178. package/dist/core/skills.d.ts.map +1 -1
  179. package/dist/core/skills.js +8 -22
  180. package/dist/core/skills.js.map +1 -1
  181. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts +5 -4
  182. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts.map +1 -1
  183. package/dist/core/tools/ask-user-question/state/questionnaire-session.js +34 -11
  184. package/dist/core/tools/ask-user-question/state/questionnaire-session.js.map +1 -1
  185. package/dist/core/tools/ask-user-question/state/selectors/contract.d.ts +1 -0
  186. package/dist/core/tools/ask-user-question/state/selectors/contract.d.ts.map +1 -1
  187. package/dist/core/tools/ask-user-question/state/selectors/contract.js.map +1 -1
  188. package/dist/core/tools/ask-user-question/state/selectors/projections.d.ts.map +1 -1
  189. package/dist/core/tools/ask-user-question/state/selectors/projections.js +1 -0
  190. package/dist/core/tools/ask-user-question/state/selectors/projections.js.map +1 -1
  191. package/dist/core/tools/ask-user-question/state/state-reducer.d.ts +1 -2
  192. package/dist/core/tools/ask-user-question/state/state-reducer.d.ts.map +1 -1
  193. package/dist/core/tools/ask-user-question/state/state-reducer.js +26 -9
  194. package/dist/core/tools/ask-user-question/state/state-reducer.js.map +1 -1
  195. package/dist/core/tools/ask-user-question/state/state.d.ts +4 -0
  196. package/dist/core/tools/ask-user-question/state/state.d.ts.map +1 -1
  197. package/dist/core/tools/ask-user-question/state/state.js.map +1 -1
  198. package/dist/core/tools/ask-user-question/view/components/option-list-view.d.ts +1 -0
  199. package/dist/core/tools/ask-user-question/view/components/option-list-view.d.ts.map +1 -1
  200. package/dist/core/tools/ask-user-question/view/components/option-list-view.js +1 -0
  201. package/dist/core/tools/ask-user-question/view/components/option-list-view.js.map +1 -1
  202. package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts +9 -6
  203. package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts.map +1 -1
  204. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js +28 -7
  205. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js.map +1 -1
  206. package/dist/core/tools/ask-user-question/view/props-adapter.d.ts.map +1 -1
  207. package/dist/core/tools/ask-user-question/view/props-adapter.js +4 -1
  208. package/dist/core/tools/ask-user-question/view/props-adapter.js.map +1 -1
  209. package/dist/core/tools/bash.d.ts.map +1 -1
  210. package/dist/core/tools/bash.js +56 -53
  211. package/dist/core/tools/bash.js.map +1 -1
  212. package/dist/core/tools/edit-diff.d.ts +3 -1
  213. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  214. package/dist/core/tools/edit-diff.js +8 -1
  215. package/dist/core/tools/edit-diff.js.map +1 -1
  216. package/dist/core/tools/edit.d.ts +3 -1
  217. package/dist/core/tools/edit.d.ts.map +1 -1
  218. package/dist/core/tools/edit.js +44 -81
  219. package/dist/core/tools/edit.js.map +1 -1
  220. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  221. package/dist/core/tools/file-mutation-queue.js +27 -12
  222. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  223. package/dist/core/tools/find.d.ts.map +1 -1
  224. package/dist/core/tools/find.js +2 -3
  225. package/dist/core/tools/find.js.map +1 -1
  226. package/dist/core/tools/grep.d.ts.map +1 -1
  227. package/dist/core/tools/grep.js +3 -3
  228. package/dist/core/tools/grep.js.map +1 -1
  229. package/dist/core/tools/ls.d.ts.map +1 -1
  230. package/dist/core/tools/ls.js +5 -5
  231. package/dist/core/tools/ls.js.map +1 -1
  232. package/dist/core/tools/output-accumulator.d.ts +2 -0
  233. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  234. package/dist/core/tools/output-accumulator.js +11 -4
  235. package/dist/core/tools/output-accumulator.js.map +1 -1
  236. package/dist/core/tools/path-utils.d.ts +2 -0
  237. package/dist/core/tools/path-utils.d.ts.map +1 -1
  238. package/dist/core/tools/path-utils.js +39 -21
  239. package/dist/core/tools/path-utils.js.map +1 -1
  240. package/dist/core/tools/read.d.ts.map +1 -1
  241. package/dist/core/tools/read.js +9 -8
  242. package/dist/core/tools/read.js.map +1 -1
  243. package/dist/core/tools/truncate.d.ts.map +1 -1
  244. package/dist/core/tools/truncate.js +12 -2
  245. package/dist/core/tools/truncate.js.map +1 -1
  246. package/dist/core/tools/write.d.ts.map +1 -1
  247. package/dist/core/tools/write.js +20 -35
  248. package/dist/core/tools/write.js.map +1 -1
  249. package/dist/index.d.ts +2 -1
  250. package/dist/index.d.ts.map +1 -1
  251. package/dist/index.js +4 -1
  252. package/dist/index.js.map +1 -1
  253. package/dist/main.d.ts.map +1 -1
  254. package/dist/main.js +5 -6
  255. package/dist/main.js.map +1 -1
  256. package/dist/modes/interactive/chat-input-actions.d.ts +24 -0
  257. package/dist/modes/interactive/chat-input-actions.d.ts.map +1 -0
  258. package/dist/modes/interactive/chat-input-actions.js +179 -0
  259. package/dist/modes/interactive/chat-input-actions.js.map +1 -0
  260. package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -0
  261. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  262. package/dist/modes/interactive/components/chat-message-renderer.js +14 -3
  263. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  264. package/dist/modes/interactive/components/chat-session-host.d.ts +157 -0
  265. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -0
  266. package/dist/modes/interactive/components/chat-session-host.js +1007 -0
  267. package/dist/modes/interactive/components/chat-session-host.js.map +1 -0
  268. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  269. package/dist/modes/interactive/components/config-selector.js +1 -1
  270. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  271. package/dist/modes/interactive/components/footer.d.ts +1 -0
  272. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  273. package/dist/modes/interactive/components/footer.js +14 -5
  274. package/dist/modes/interactive/components/footer.js.map +1 -1
  275. package/dist/modes/interactive/components/index.d.ts +1 -0
  276. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  277. package/dist/modes/interactive/components/index.js +1 -0
  278. package/dist/modes/interactive/components/index.js.map +1 -1
  279. package/dist/modes/interactive/components/login-dialog.d.ts +9 -1
  280. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  281. package/dist/modes/interactive/components/login-dialog.js +29 -4
  282. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  283. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  284. package/dist/modes/interactive/interactive-mode.js +18 -67
  285. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  286. package/dist/utils/child-process.d.ts +1 -0
  287. package/dist/utils/child-process.d.ts.map +1 -1
  288. package/dist/utils/child-process.js +8 -0
  289. package/dist/utils/child-process.js.map +1 -1
  290. package/dist/utils/clipboard-native.d.ts +3 -1
  291. package/dist/utils/clipboard-native.d.ts.map +1 -1
  292. package/dist/utils/clipboard-native.js +14 -8
  293. package/dist/utils/clipboard-native.js.map +1 -1
  294. package/dist/utils/image-resize-core.d.ts +30 -0
  295. package/dist/utils/image-resize-core.d.ts.map +1 -0
  296. package/dist/utils/image-resize-core.js +124 -0
  297. package/dist/utils/image-resize-core.js.map +1 -0
  298. package/dist/utils/image-resize-worker.d.ts +2 -0
  299. package/dist/utils/image-resize-worker.d.ts.map +1 -0
  300. package/dist/utils/image-resize-worker.js +31 -0
  301. package/dist/utils/image-resize-worker.js.map +1 -0
  302. package/dist/utils/image-resize.d.ts +7 -27
  303. package/dist/utils/image-resize.d.ts.map +1 -1
  304. package/dist/utils/image-resize.js +75 -115
  305. package/dist/utils/image-resize.js.map +1 -1
  306. package/dist/utils/paths.d.ts +16 -1
  307. package/dist/utils/paths.d.ts.map +1 -1
  308. package/dist/utils/paths.js +49 -7
  309. package/dist/utils/paths.js.map +1 -1
  310. package/docs/changelog.mdx +29 -0
  311. package/docs/compaction.md +1 -1
  312. package/docs/custom-provider.md +2 -2
  313. package/docs/development.md +1 -1
  314. package/docs/docs.json +98 -143
  315. package/docs/extensions.md +29 -16
  316. package/docs/favicon.svg +29 -0
  317. package/docs/images/interactive-mode.png +0 -0
  318. package/docs/images/tree-view.png +0 -0
  319. package/docs/images/workflow-command.png +0 -0
  320. package/docs/images/workflow-graph.png +0 -0
  321. package/docs/images/workflow-input-picker.png +0 -0
  322. package/docs/images/workflow-list.png +0 -0
  323. package/docs/index.md +10 -1
  324. package/docs/logo.svg +59 -0
  325. package/docs/packages.md +3 -3
  326. package/docs/providers.md +1 -1
  327. package/docs/quickstart.md +98 -2
  328. package/docs/rpc.md +8 -8
  329. package/docs/sdk.md +23 -12
  330. package/docs/sessions.md +1 -1
  331. package/docs/skills.md +15 -1
  332. package/docs/termux.md +11 -1
  333. package/docs/themes.md +6 -6
  334. package/docs/tui.md +18 -18
  335. package/docs/usage.md +1 -1
  336. package/docs/workflows.md +172 -2
  337. package/examples/extensions/subagent/index.ts +2 -1
  338. package/package.json +6 -6
  339. /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/SKILL.md +0 -0
  340. /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/element-attributes.md +0 -0
  341. /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/playwright-tests.md +0 -0
  342. /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/request-mocking.md +0 -0
  343. /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/running-code.md +0 -0
  344. /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/session-management.md +0 -0
  345. /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/spec-driven-testing.md +0 -0
  346. /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/storage-state.md +0 -0
  347. /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/test-generation.md +0 -0
  348. /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/tracing.md +0 -0
  349. /package/dist/builtin/{workflows → subagents}/skills/playwright-cli/references/video-recording.md +0 -0
  350. /package/dist/builtin/{workflows → subagents}/skills/tdd/SKILL.md +0 -0
  351. /package/dist/builtin/{workflows → subagents}/skills/tdd/deep-modules.md +0 -0
  352. /package/dist/builtin/{workflows → subagents}/skills/tdd/interface-design.md +0 -0
  353. /package/dist/builtin/{workflows → subagents}/skills/tdd/mocking.md +0 -0
  354. /package/dist/builtin/{workflows → subagents}/skills/tdd/refactoring.md +0 -0
  355. /package/dist/builtin/{workflows → subagents}/skills/tdd/tests.md +0 -0
@@ -6,7 +6,7 @@ import * as fs from "node:fs";
6
6
  import * as os from "node:os";
7
7
  import * as path from "node:path";
8
8
  import { fileURLToPath } from "node:url";
9
- import { CONFIG_DIR_NAME, getAgentConfigPaths, getProjectConfigDirs } from "@bastani/atomic";
9
+ import { CONFIG_DIR_NAME, getAgentConfigPaths, getEnvValue, getProjectConfigDirs } from "@bastani/atomic";
10
10
  import type { OutputMode } from "../shared/types.ts";
11
11
  import { KNOWN_FIELDS } from "./agent-serializer.ts";
12
12
  import { parseChain } from "./chain-serializer.ts";
@@ -46,6 +46,7 @@ export interface BuiltinAgentOverrideBase {
46
46
  skills?: string[];
47
47
  tools?: string[];
48
48
  mcpDirectTools?: string[];
49
+ completionGuard?: boolean;
49
50
  }
50
51
 
51
52
  interface BuiltinAgentOverrideConfig {
@@ -60,6 +61,7 @@ interface BuiltinAgentOverrideConfig {
60
61
  systemPrompt?: string;
61
62
  skills?: string[] | false;
62
63
  tools?: string[] | false;
64
+ completionGuard?: boolean;
63
65
  }
64
66
 
65
67
  interface BuiltinAgentOverrideInfo {
@@ -92,6 +94,7 @@ export interface AgentConfig {
92
94
  defaultProgress?: boolean;
93
95
  interactive?: boolean;
94
96
  maxSubagentDepth?: number;
97
+ completionGuard?: boolean;
95
98
  disabled?: boolean;
96
99
  extraFields?: Record<string, string>;
97
100
  override?: BuiltinAgentOverrideInfo;
@@ -191,6 +194,7 @@ function cloneOverrideBase(agent: AgentConfig): BuiltinAgentOverrideBase {
191
194
  skills: agent.skills ? [...agent.skills] : undefined,
192
195
  tools: agent.tools ? [...agent.tools] : undefined,
193
196
  mcpDirectTools: agent.mcpDirectTools ? [...agent.mcpDirectTools] : undefined,
197
+ completionGuard: agent.completionGuard,
194
198
  };
195
199
  }
196
200
 
@@ -209,6 +213,7 @@ function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentO
209
213
  ...(override.systemPrompt !== undefined ? { systemPrompt: override.systemPrompt } : {}),
210
214
  ...(override.skills !== undefined ? { skills: override.skills === false ? false : [...override.skills] } : {}),
211
215
  ...(override.tools !== undefined ? { tools: override.tools === false ? false : [...override.tools] } : {}),
216
+ ...(override.completionGuard !== undefined ? { completionGuard: override.completionGuard } : {}),
212
217
  };
213
218
  }
214
219
 
@@ -354,6 +359,14 @@ function parseBuiltinOverrideEntry(
354
359
  }
355
360
  }
356
361
 
362
+ if ("completionGuard" in input) {
363
+ if (typeof input.completionGuard === "boolean") {
364
+ override.completionGuard = input.completionGuard;
365
+ } else {
366
+ throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'completionGuard'; expected a boolean.`);
367
+ }
368
+ }
369
+
357
370
  if ("systemPrompt" in input) {
358
371
  if (typeof input.systemPrompt === "string") override.systemPrompt = input.systemPrompt;
359
372
  else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'systemPrompt'; expected a string.`);
@@ -399,6 +412,22 @@ function readSubagentSettings(filePath: string | null): SubagentSettings {
399
412
  return { overrides: parsed, disableBuiltins };
400
413
  }
401
414
 
415
+ function readMergedSubagentSettings(filePaths: string[]): { settings: SubagentSettings; path: string | null } {
416
+ let settings = EMPTY_SUBAGENT_SETTINGS;
417
+ let path: string | null = null;
418
+ for (let i = filePaths.length - 1; i >= 0; i--) {
419
+ const filePath = filePaths[i]!;
420
+ if (!fs.existsSync(filePath)) continue;
421
+ const next = readSubagentSettings(filePath);
422
+ settings = {
423
+ disableBuiltins: next.disableBuiltins ?? settings.disableBuiltins,
424
+ overrides: { ...settings.overrides, ...next.overrides },
425
+ };
426
+ path = filePath;
427
+ }
428
+ return { settings, path };
429
+ }
430
+
402
431
  function applyBuiltinOverride(
403
432
  agent: AgentConfig,
404
433
  override: BuiltinAgentOverrideConfig,
@@ -426,26 +455,11 @@ function applyBuiltinOverride(
426
455
  next.tools = tools;
427
456
  next.mcpDirectTools = mcpDirectTools;
428
457
  }
458
+ if (override.completionGuard !== undefined) next.completionGuard = override.completionGuard;
429
459
 
430
460
  return next;
431
461
  }
432
462
 
433
- function readMergedSubagentSettings(filePaths: string[]): { settings: SubagentSettings; path: string | null } {
434
- let settings = EMPTY_SUBAGENT_SETTINGS;
435
- let path: string | null = null;
436
- for (let i = filePaths.length - 1; i >= 0; i--) {
437
- const filePath = filePaths[i]!;
438
- if (!fs.existsSync(filePath)) continue;
439
- const next = readSubagentSettings(filePath);
440
- settings = {
441
- disableBuiltins: next.disableBuiltins ?? settings.disableBuiltins,
442
- overrides: { ...settings.overrides, ...next.overrides },
443
- };
444
- path = filePath;
445
- }
446
- return { settings, path };
447
- }
448
-
449
463
  function applyBuiltinOverrides(
450
464
  builtinAgents: AgentConfig[],
451
465
  userSettings: SubagentSettings,
@@ -481,7 +495,7 @@ function applyBuiltinOverrides(
481
495
 
482
496
  export function buildBuiltinOverrideConfig(
483
497
  base: BuiltinAgentOverrideBase,
484
- draft: Pick<AgentConfig, "model" | "fallbackModels" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools">,
498
+ draft: Pick<AgentConfig, "model" | "fallbackModels" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools" | "completionGuard">,
485
499
  ): BuiltinAgentOverrideConfig | undefined {
486
500
  const override: BuiltinAgentOverrideConfig = {};
487
501
 
@@ -499,6 +513,9 @@ export function buildBuiltinOverrideConfig(
499
513
  const baseTools = joinToolList(base);
500
514
  const draftTools = joinToolList(draft);
501
515
  if (!arraysEqual(draftTools, baseTools)) override.tools = draftTools ? [...draftTools] : false;
516
+ if ((draft.completionGuard !== false) !== (base.completionGuard !== false)) {
517
+ override.completionGuard = draft.completionGuard !== false;
518
+ }
502
519
 
503
520
  return Object.keys(override).length > 0 ? override : undefined;
504
521
  }
@@ -664,6 +681,11 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
664
681
  }
665
682
 
666
683
  const parsedMaxSubagentDepth = Number(frontmatter.maxSubagentDepth);
684
+ const completionGuard = frontmatter.completionGuard === "false"
685
+ ? false
686
+ : frontmatter.completionGuard === "true"
687
+ ? true
688
+ : undefined;
667
689
 
668
690
  agents.push({
669
691
  name: runtimeName,
@@ -692,6 +714,7 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
692
714
  Number.isInteger(parsedMaxSubagentDepth) && parsedMaxSubagentDepth >= 0
693
715
  ? parsedMaxSubagentDepth
694
716
  : undefined,
717
+ completionGuard,
695
718
  extraFields: Object.keys(extraFields).length > 0 ? extraFields : undefined,
696
719
  });
697
720
  }
@@ -843,7 +866,9 @@ export function discoverAgentsAll(cwd: string): {
843
866
  ...Array.from(chainMap.values()),
844
867
  ];
845
868
 
846
- const userDir = fs.existsSync(userDirNew) ? userDirNew : userDirOld[0]!;
869
+ const legacyUserAgentDir = userDirOld[0]!;
870
+ // ATOMIC_CODING_AGENT_DIR is already applied by getUserAgentDirs(); prefer that resolved path over ~/.agents.
871
+ const userDir = getEnvValue("ATOMIC_CODING_AGENT_DIR") ? legacyUserAgentDir : fs.existsSync(userDirNew) ? userDirNew : legacyUserAgentDir;
847
872
 
848
873
  return { builtin, user, project, chains, userDir, projectDir, userChainDir, projectChainDir, userSettingsPath, projectSettingsPath };
849
874
  }
@@ -0,0 +1,16 @@
1
+ import * as fs from "node:fs";
2
+ import { getAgentConfigPaths } from "@bastani/atomic";
3
+ import type { ExtensionConfig } from "../shared/types.ts";
4
+
5
+ export function loadConfig(): ExtensionConfig {
6
+ for (const configPath of getAgentConfigPaths("extensions", "subagent", "config.json")) {
7
+ try {
8
+ if (fs.existsSync(configPath)) {
9
+ return JSON.parse(fs.readFileSync(configPath, "utf-8")) as ExtensionConfig;
10
+ }
11
+ } catch (error) {
12
+ console.error(`Failed to load subagent config from '${configPath}':`, error);
13
+ }
14
+ }
15
+ return {};
16
+ }
@@ -0,0 +1,246 @@
1
+ import * as fs from "node:fs";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+
5
+ import { APP_NAME, getEnvValue } from "@bastani/atomic";
6
+ import type { ExtensionAPI, ToolDefinition } from "@bastani/atomic";
7
+
8
+ import { discoverAgents } from "../agents/agents.ts";
9
+ import { resolveSubagentIntercomTarget } from "../intercom/intercom-bridge.ts";
10
+ import { deliverSubagentIntercomMessageEvent } from "../intercom/result-intercom.ts";
11
+ import { createSubagentExecutor, type SubagentParamsLike } from "../runs/foreground/subagent-executor.ts";
12
+ import { readNestedControlRequests, resolveNestedRouteFromEnv, writeNestedControlResult, type NestedRoute } from "../runs/shared/nested-events.ts";
13
+ import { SUBAGENT_CHILD_ENV, SUBAGENT_FANOUT_CHILD_ENV } from "../runs/shared/pi-args.ts";
14
+ import { getArtifactsDir } from "../shared/artifacts.ts";
15
+ import { type Details, type SubagentState } from "../shared/types.ts";
16
+ import { loadConfig } from "./config.ts";
17
+ import { SubagentParams } from "./schemas.ts";
18
+
19
+ function getSubagentSessionRoot(parentSessionFile: string | null): string {
20
+ if (parentSessionFile) {
21
+ const baseName = path.basename(parentSessionFile, ".jsonl");
22
+ const sessionsDir = path.dirname(parentSessionFile);
23
+ return path.join(sessionsDir, baseName);
24
+ }
25
+ return fs.mkdtempSync(path.join(os.tmpdir(), `${APP_NAME}-subagent-session-`));
26
+ }
27
+
28
+ function expandTilde(p: string): string {
29
+ return p.startsWith("~/") ? path.join(os.homedir(), p.slice(2)) : p;
30
+ }
31
+
32
+ export function createChildSafeState(): SubagentState {
33
+ return {
34
+ baseCwd: "",
35
+ currentSessionId: null,
36
+ asyncJobs: new Map(),
37
+ foregroundRuns: new Map(),
38
+ foregroundControls: new Map(),
39
+ lastForegroundControlId: null,
40
+ pendingForegroundControlNotices: new Map(),
41
+ cleanupTimers: new Map(),
42
+ lastUiContext: null,
43
+ poller: null,
44
+ completionSeen: new Map(),
45
+ watcher: null,
46
+ watcherRestartTimer: null,
47
+ // Child-safe stub: the parent extension owns watcher/coalescer/cleanup state.
48
+ resultFileCoalescer: {
49
+ schedule: () => false,
50
+ clear: () => {},
51
+ },
52
+ };
53
+ }
54
+
55
+ const MAX_SEEN_REQUEST_IDS = 1024;
56
+ const TRIMMED_SEEN_REQUEST_IDS = 512;
57
+ const MAX_PENDING_RESULTS = 256;
58
+ const MAX_PENDING_RESULT_ATTEMPTS = 10;
59
+ const MAX_PENDING_RESULT_AGE_MS = 60_000;
60
+ const NESTED_CONTROL_INBOX_TIMER_KEY = "fanout-child:nested-control-inbox";
61
+
62
+ type NestedControlResultPayload = Parameters<typeof writeNestedControlResult>[1];
63
+
64
+ interface PendingControlResult {
65
+ result: NestedControlResultPayload;
66
+ firstFailureAt: number;
67
+ attempts: number;
68
+ }
69
+
70
+ function rememberSeenRequest(seen: Set<string>, requestId: string): void {
71
+ seen.add(requestId);
72
+ if (seen.size <= MAX_SEEN_REQUEST_IDS) return;
73
+ const keep = [...seen].slice(-TRIMMED_SEEN_REQUEST_IDS);
74
+ seen.clear();
75
+ for (const id of keep) seen.add(id);
76
+ }
77
+
78
+ function dropControlRequestFile(filePath: string, requestId: string): void {
79
+ try {
80
+ fs.unlinkSync(filePath);
81
+ } catch (error) {
82
+ console.error(`Failed to remove processed nested control request '${requestId}' at '${filePath}':`, error);
83
+ }
84
+ }
85
+
86
+ function shouldDropPendingResult(pending: PendingControlResult, pendingSize: number, now: number): boolean {
87
+ return pending.attempts >= MAX_PENDING_RESULT_ATTEMPTS
88
+ || now - pending.firstFailureAt >= MAX_PENDING_RESULT_AGE_MS
89
+ || pendingSize > MAX_PENDING_RESULTS;
90
+ }
91
+
92
+ function buildNestedControlResult(
93
+ pi: ExtensionAPI,
94
+ state: SubagentState,
95
+ request: ReturnType<typeof readNestedControlRequests>[number],
96
+ ): Promise<NestedControlResultPayload> {
97
+ return (async () => {
98
+ let ok = false;
99
+ let message = "Control request failed.";
100
+ try {
101
+ const control = state.foregroundControls.get(request.targetRunId);
102
+ if (!control) {
103
+ message = `Nested run ${request.targetRunId} is not active in this fanout child.`;
104
+ } else if (request.action === "interrupt") {
105
+ ok = control.interrupt?.() === true;
106
+ message = ok
107
+ ? `Interrupt requested for nested run ${request.targetRunId}.`
108
+ : `Nested run ${request.targetRunId} has no active child step to interrupt.`;
109
+ } else if (!request.message?.trim()) {
110
+ message = "Nested resume requires message.";
111
+ } else if (!control.currentAgent) {
112
+ message = `Nested run ${request.targetRunId} has no active child message route.`;
113
+ } else {
114
+ const index = control.currentIndex ?? 0;
115
+ const target = resolveSubagentIntercomTarget(request.targetRunId, control.currentAgent, index);
116
+ ok = await deliverSubagentIntercomMessageEvent(
117
+ pi.events,
118
+ target,
119
+ `Follow-up for nested run ${request.targetRunId} (${control.currentAgent}):\n\n${request.message.trim()}`,
120
+ 500,
121
+ { source: "nested-resume", runId: request.targetRunId, agent: control.currentAgent, index },
122
+ );
123
+ message = ok
124
+ ? `Delivered follow-up to live nested run ${request.targetRunId}.`
125
+ : `Nested child intercom target is not registered: ${target}`;
126
+ }
127
+ } catch (error) {
128
+ message = error instanceof Error ? error.message : String(error);
129
+ }
130
+ return { ts: Date.now(), requestId: request.requestId, targetRunId: request.targetRunId, ok, message };
131
+ })();
132
+ }
133
+
134
+ export function startNestedControlInboxListener(pi: ExtensionAPI, state: SubagentState): NodeJS.Timeout | undefined {
135
+ let route: NestedRoute | undefined;
136
+ try {
137
+ route = resolveNestedRouteFromEnv();
138
+ } catch {
139
+ return undefined;
140
+ }
141
+ if (!route) return undefined;
142
+ const seen = new Set<string>();
143
+ const inFlight = new Set<string>();
144
+ const pendingResults = new Map<string, PendingControlResult>();
145
+ const timer = setInterval(() => {
146
+ try {
147
+ for (const request of readNestedControlRequests(route)) {
148
+ if (seen.has(request.requestId) || inFlight.has(request.requestId)) continue;
149
+ inFlight.add(request.requestId);
150
+ void (async () => {
151
+ try {
152
+ const pending = pendingResults.get(request.requestId);
153
+ const result = pending?.result ?? await buildNestedControlResult(pi, state, request);
154
+ try {
155
+ writeNestedControlResult(route, result);
156
+ } catch (error) {
157
+ const now = Date.now();
158
+ const nextPending: PendingControlResult = {
159
+ result,
160
+ firstFailureAt: pending?.firstFailureAt ?? now,
161
+ attempts: (pending?.attempts ?? 0) + 1,
162
+ };
163
+ pendingResults.set(request.requestId, nextPending);
164
+ if (shouldDropPendingResult(nextPending, pendingResults.size, now)) {
165
+ pendingResults.delete(request.requestId);
166
+ rememberSeenRequest(seen, request.requestId);
167
+ dropControlRequestFile(request.filePath, request.requestId);
168
+ console.error(`Dropping nested control result for request '${request.requestId}' targeting '${request.targetRunId}' after ${nextPending.attempts} failed write attempts via inbox '${route.controlInbox}':`, error);
169
+ } else if (nextPending.attempts === 1) {
170
+ console.error(`Failed to write nested control result for request '${request.requestId}' targeting '${request.targetRunId}' via inbox '${route.controlInbox}'; keeping request for retry:`, error);
171
+ }
172
+ return;
173
+ }
174
+ pendingResults.delete(request.requestId);
175
+ rememberSeenRequest(seen, request.requestId);
176
+ dropControlRequestFile(request.filePath, request.requestId);
177
+ } finally {
178
+ inFlight.delete(request.requestId);
179
+ }
180
+ })();
181
+ }
182
+ } catch (error) {
183
+ console.error(`Failed to poll nested control inbox '${route.controlInbox}' for root '${route.rootRunId}':`, error);
184
+ }
185
+ }, 200);
186
+ timer.unref?.();
187
+ state.cleanupTimers.set(NESTED_CONTROL_INBOX_TIMER_KEY, timer);
188
+ return timer;
189
+ }
190
+
191
+ export default function registerFanoutChildSubagentExtension(pi: ExtensionAPI): void {
192
+ if (getEnvValue(SUBAGENT_CHILD_ENV) !== "1" || getEnvValue(SUBAGENT_FANOUT_CHILD_ENV) !== "1") return;
193
+
194
+ const globalStore = globalThis as Record<string, unknown>;
195
+ const registeredKey = "__atomicSubagentFanoutChildRegisteredApis";
196
+ const cleanupKey = "__atomicSubagentFanoutChildRuntimeCleanup";
197
+ const registeredApis = globalStore[registeredKey] instanceof WeakSet
198
+ ? globalStore[registeredKey] as WeakSet<ExtensionAPI>
199
+ : new WeakSet<ExtensionAPI>();
200
+ globalStore[registeredKey] = registeredApis;
201
+ if (registeredApis.has(pi)) return;
202
+ const previousRuntimeCleanup = globalStore[cleanupKey];
203
+ if (typeof previousRuntimeCleanup === "function") {
204
+ try {
205
+ previousRuntimeCleanup();
206
+ } catch {
207
+ // Best effort cleanup for stale fanout-child timers from an older reload.
208
+ }
209
+ }
210
+ registeredApis.add(pi);
211
+
212
+ const config = loadConfig();
213
+ const state = createChildSafeState();
214
+ const executor = createSubagentExecutor({
215
+ pi,
216
+ state,
217
+ config,
218
+ asyncByDefault: config.asyncByDefault === true,
219
+ tempArtifactsDir: getArtifactsDir(null),
220
+ getSubagentSessionRoot,
221
+ expandTilde,
222
+ discoverAgents,
223
+ allowMutatingManagementActions: false,
224
+ });
225
+
226
+ const tool: ToolDefinition<typeof SubagentParams, Details> = {
227
+ name: "subagent",
228
+ label: "Subagent",
229
+ description: [
230
+ "Delegate to subagents from child-safe fanout mode.",
231
+ "Allowed management/control actions: list, get, status, interrupt, resume, doctor.",
232
+ "Agent config mutation actions create, update, and delete are blocked in this mode.",
233
+ ].join("\n"),
234
+ parameters: SubagentParams,
235
+ execute(id, params, signal, onUpdate, ctx) {
236
+ return executor.execute(id, params as SubagentParamsLike, signal, onUpdate, ctx);
237
+ },
238
+ };
239
+
240
+ pi.registerTool(tool);
241
+ startNestedControlInboxListener(pi, state);
242
+ globalStore[cleanupKey] = () => {
243
+ for (const timer of state.cleanupTimers.values()) clearInterval(timer);
244
+ state.cleanupTimers.clear();
245
+ };
246
+ }