@bastani/atomic 0.8.13-0 → 0.8.14-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/CHANGELOG.md +24 -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
@@ -54,11 +54,24 @@ const GENERAL_IMPLEMENTATION_PATTERNS = [
54
54
  /\b(?:update|add|remove|replace|delete|create)\s+(?:the\s+)?(?:file|files|code|source|implementation|test|tests|component|function|module|class|method|logic|import|imports|readme|docs?|changelog|package\.json|config|manifest|extension|prompt|command)\b/i,
55
55
  ];
56
56
 
57
+ const READ_ONLY_BUILTIN_TOOLS = new Set([
58
+ "read",
59
+ "grep",
60
+ "find",
61
+ "ls",
62
+ "web_search",
63
+ "fetch_content",
64
+ "get_search_content",
65
+ "intercom",
66
+ "contact_supervisor",
67
+ ]);
57
68
 
58
69
  interface CompletionMutationGuardInput {
59
70
  agent: string;
60
71
  task: string;
61
72
  messages: Message[];
73
+ tools?: string[];
74
+ mcpDirectTools?: string[];
62
75
  }
63
76
 
64
77
  interface CompletionMutationGuardResult {
@@ -83,6 +96,13 @@ function stripScopedNoEditConstraints(task: string): string {
83
96
  return stripped;
84
97
  }
85
98
 
99
+ function declaresOnlyReadOnlyTools(tools: string[] | undefined, mcpDirectTools: string[] | undefined): boolean {
100
+ return tools !== undefined
101
+ && tools.length > 0
102
+ && (mcpDirectTools?.length ?? 0) === 0
103
+ && tools.every((tool) => READ_ONLY_BUILTIN_TOOLS.has(tool));
104
+ }
105
+
86
106
  export function expectsImplementationMutation(agent: string, task: string): boolean {
87
107
  const taskText = stripFrameworkInstructions(task);
88
108
  const taskTextWithoutScopedConstraints = stripScopedNoEditConstraints(taskText);
@@ -115,7 +135,9 @@ export function hasMutationToolCall(messages: Message[]): boolean {
115
135
  }
116
136
 
117
137
  export function evaluateCompletionMutationGuard(input: CompletionMutationGuardInput): CompletionMutationGuardResult {
118
- const expectedMutation = expectsImplementationMutation(input.agent, input.task);
138
+ const expectedMutation = declaresOnlyReadOnlyTools(input.tools, input.mcpDirectTools)
139
+ ? false
140
+ : expectsImplementationMutation(input.agent, input.task);
119
141
  const attemptedMutation = hasMutationToolCall(input.messages);
120
142
  return {
121
143
  expectedMutation,
@@ -0,0 +1,369 @@
1
+ import { createHash } from "node:crypto";
2
+ import * as fs from "node:fs";
3
+ import * as os from "node:os";
4
+ import * as path from "node:path";
5
+ import { getProjectConfigDirs } from "@bastani/atomic";
6
+ import { getAgentDir } from "../../shared/utils.ts";
7
+
8
+ const CACHE_VERSION = 1;
9
+ const CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
10
+ const BUILTIN_TOOL_NAMES = new Set(["read", "bash", "edit", "write", "grep", "find", "ls", "mcp"]);
11
+ const GENERIC_GLOBAL_CONFIG_PATH = path.join(os.homedir(), ".config", "mcp", "mcp.json");
12
+ const IMPORT_PATHS = {
13
+ cursor: [path.join(os.homedir(), ".cursor", "mcp.json")],
14
+ "claude-code": [
15
+ path.join(os.homedir(), ".claude", "mcp.json"),
16
+ path.join(os.homedir(), ".claude.json"),
17
+ path.join(os.homedir(), ".claude", "claude_desktop_config.json"),
18
+ ],
19
+ "claude-desktop": [path.join(os.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json")],
20
+ codex: [path.join(os.homedir(), ".codex", "config.json")],
21
+ windsurf: [path.join(os.homedir(), ".windsurf", "mcp.json")],
22
+ vscode: [".vscode/mcp.json"],
23
+ } as const;
24
+
25
+ export type ToolPrefix = "server" | "none" | "short";
26
+ type ImportKind = keyof typeof IMPORT_PATHS;
27
+
28
+ export interface ServerEntry {
29
+ command?: string;
30
+ args?: string[];
31
+ env?: Record<string, string>;
32
+ cwd?: string;
33
+ url?: string;
34
+ headers?: Record<string, string>;
35
+ auth?: "oauth" | "bearer" | false;
36
+ bearerToken?: string;
37
+ bearerTokenEnv?: string;
38
+ exposeResources?: boolean;
39
+ excludeTools?: string[];
40
+ directTools?: boolean | string[];
41
+ }
42
+
43
+ export interface McpConfig {
44
+ mcpServers: Record<string, ServerEntry>;
45
+ imports?: ImportKind[];
46
+ settings?: {
47
+ toolPrefix?: ToolPrefix;
48
+ directTools?: boolean;
49
+ };
50
+ }
51
+
52
+ export interface CachedTool {
53
+ name?: string;
54
+ }
55
+
56
+ export interface CachedResource {
57
+ uri?: string;
58
+ name?: string;
59
+ }
60
+
61
+ export interface ServerCacheEntry {
62
+ configHash?: string;
63
+ tools?: CachedTool[];
64
+ resources?: CachedResource[];
65
+ cachedAt?: number;
66
+ }
67
+
68
+ export interface MetadataCache {
69
+ version: number;
70
+ servers: Record<string, ServerCacheEntry>;
71
+ }
72
+
73
+ export function resolveMcpDirectToolNames(mcpDirectTools: string[] | undefined, cwd = process.cwd()): string[] {
74
+ if (!mcpDirectTools?.length) return [];
75
+
76
+ try {
77
+ const config = loadMcpConfig(cwd);
78
+ const cache = loadMetadataCache();
79
+ if (!cache) return [];
80
+ return resolveMcpDirectToolNamesFromConfig(config, cache, getToolPrefix(config.settings?.toolPrefix), mcpDirectTools);
81
+ } catch (error) {
82
+ console.error("Failed to resolve direct MCP tool names for subagent child allowlist:", error);
83
+ return [];
84
+ }
85
+ }
86
+
87
+ function loadMetadataCache(): MetadataCache | null {
88
+ const cachePath = path.join(getAgentDir(), "mcp-cache.json");
89
+ let parsed: unknown;
90
+ try {
91
+ parsed = JSON.parse(fs.readFileSync(cachePath, "utf-8"));
92
+ } catch {
93
+ return null;
94
+ }
95
+
96
+ if (!parsed || typeof parsed !== "object") return null;
97
+ const raw = parsed as Record<string, unknown>;
98
+ if (raw.version !== CACHE_VERSION || !raw.servers || typeof raw.servers !== "object" || Array.isArray(raw.servers)) {
99
+ return null;
100
+ }
101
+ return raw as unknown as MetadataCache;
102
+ }
103
+
104
+ function loadMcpConfig(cwd: string): McpConfig {
105
+ let config: McpConfig = { mcpServers: {} };
106
+ for (const sourcePath of getConfigPaths(cwd)) {
107
+ const loaded = readConfig(sourcePath);
108
+ if (!loaded) continue;
109
+ config = mergeConfigs(config, expandImports(loaded, cwd));
110
+ }
111
+ return config;
112
+ }
113
+
114
+ function getConfigPaths(cwd: string): string[] {
115
+ const piGlobalPath = path.join(getAgentDir(), "mcp.json");
116
+ const projectPath = path.resolve(cwd, ".mcp.json");
117
+ const projectConfigPaths = getProjectConfigDirs(cwd).map((configDir) => path.resolve(configDir, "mcp.json"));
118
+ const sources: string[] = [];
119
+ if (GENERIC_GLOBAL_CONFIG_PATH !== piGlobalPath) sources.push(GENERIC_GLOBAL_CONFIG_PATH);
120
+ sources.push(piGlobalPath);
121
+ if (projectPath !== piGlobalPath) sources.push(projectPath);
122
+ for (const projectConfigPath of projectConfigPaths) {
123
+ if (projectConfigPath !== piGlobalPath && projectConfigPath !== projectPath) sources.push(projectConfigPath);
124
+ }
125
+ return sources;
126
+ }
127
+
128
+ function readConfig(configPath: string): McpConfig | null {
129
+ let parsed: unknown;
130
+ try {
131
+ parsed = JSON.parse(fs.readFileSync(configPath, "utf-8"));
132
+ } catch {
133
+ return null;
134
+ }
135
+ return validateConfig(parsed);
136
+ }
137
+
138
+ function validateConfig(raw: unknown): McpConfig {
139
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { mcpServers: {} };
140
+ const obj = raw as Record<string, unknown>;
141
+ const servers = obj.mcpServers ?? obj["mcp-servers"] ?? {};
142
+ return {
143
+ mcpServers: servers && typeof servers === "object" && !Array.isArray(servers) ? servers as Record<string, ServerEntry> : {},
144
+ imports: Array.isArray(obj.imports) ? obj.imports.filter((value): value is ImportKind => isImportKind(value)) : undefined,
145
+ settings: obj.settings && typeof obj.settings === "object" && !Array.isArray(obj.settings)
146
+ ? obj.settings as McpConfig["settings"]
147
+ : undefined,
148
+ };
149
+ }
150
+
151
+ function mergeConfigs(base: McpConfig, next: McpConfig): McpConfig {
152
+ const imports = [...(base.imports ?? []), ...(next.imports ?? [])];
153
+ return {
154
+ mcpServers: { ...base.mcpServers, ...next.mcpServers },
155
+ imports: imports.length ? [...new Set(imports)] : undefined,
156
+ settings: next.settings ? { ...base.settings, ...next.settings } : base.settings,
157
+ };
158
+ }
159
+
160
+ function expandImports(config: McpConfig, cwd: string): McpConfig {
161
+ if (!config.imports?.length) return config;
162
+
163
+ const importedServers: Record<string, ServerEntry> = {};
164
+ for (const importKind of config.imports) {
165
+ const importPath = resolveImportPath(importKind, cwd);
166
+ if (!importPath) continue;
167
+ let imported: unknown;
168
+ try {
169
+ imported = JSON.parse(fs.readFileSync(importPath, "utf-8"));
170
+ } catch {
171
+ continue;
172
+ }
173
+ for (const [name, definition] of Object.entries(extractServers(imported, importKind))) {
174
+ if (!importedServers[name]) importedServers[name] = definition;
175
+ }
176
+ }
177
+
178
+ return {
179
+ imports: config.imports,
180
+ settings: config.settings,
181
+ mcpServers: { ...importedServers, ...config.mcpServers },
182
+ };
183
+ }
184
+
185
+ function resolveImportPath(importKind: ImportKind, cwd: string): string | null {
186
+ for (const candidate of IMPORT_PATHS[importKind]) {
187
+ const fullPath = candidate.startsWith(".") ? path.resolve(cwd, candidate) : candidate;
188
+ if (fs.existsSync(fullPath)) return fullPath;
189
+ }
190
+ return null;
191
+ }
192
+
193
+ function extractServers(config: unknown, kind: ImportKind): Record<string, ServerEntry> {
194
+ if (!config || typeof config !== "object" || Array.isArray(config)) return {};
195
+ const obj = config as Record<string, unknown>;
196
+ const servers = kind === "cursor" || kind === "windsurf" || kind === "vscode"
197
+ ? obj.mcpServers ?? obj["mcp-servers"]
198
+ : obj.mcpServers;
199
+ return servers && typeof servers === "object" && !Array.isArray(servers) ? servers as Record<string, ServerEntry> : {};
200
+ }
201
+
202
+ export function resolveMcpDirectToolNamesFromConfig(config: McpConfig, cache: MetadataCache, prefix: ToolPrefix, envOverride: string[]): string[] {
203
+ const names: string[] = [];
204
+ const seenNames = new Set<string>();
205
+ const { servers: selectedServers, tools: selectedTools } = parseMcpDirectToolSelections(envOverride);
206
+
207
+ for (const [serverName, definition] of Object.entries(config.mcpServers)) {
208
+ const serverCache = cache.servers[serverName];
209
+ if (!isServerCacheValid(serverCache, definition)) continue;
210
+
211
+ const toolFilter = selectedServers.has(serverName)
212
+ ? true
213
+ : selectedTools.get(serverName);
214
+ if (!toolFilter) continue;
215
+
216
+ for (const tool of Array.isArray(serverCache.tools) ? serverCache.tools : []) {
217
+ if (typeof tool?.name !== "string" || !tool.name) continue;
218
+ if (toolFilter !== true && !toolFilter.has(tool.name)) continue;
219
+ if (isToolExcluded(tool.name, serverName, prefix, definition.excludeTools)) continue;
220
+ const prefixedName = formatToolName(tool.name, serverName, prefix);
221
+ if (BUILTIN_TOOL_NAMES.has(prefixedName) || seenNames.has(prefixedName)) continue;
222
+ seenNames.add(prefixedName);
223
+ names.push(prefixedName);
224
+ }
225
+
226
+ if (definition.exposeResources === false) continue;
227
+ for (const resource of Array.isArray(serverCache.resources) ? serverCache.resources : []) {
228
+ if (typeof resource?.name !== "string" || !resource.name || typeof resource.uri !== "string" || !resource.uri) continue;
229
+ const baseName = `get_${resourceNameToToolName(resource.name)}`;
230
+ if (toolFilter !== true && !toolFilter.has(baseName)) continue;
231
+ if (isToolExcluded(baseName, serverName, prefix, definition.excludeTools)) continue;
232
+ const prefixedName = formatToolName(baseName, serverName, prefix);
233
+ if (BUILTIN_TOOL_NAMES.has(prefixedName) || seenNames.has(prefixedName)) continue;
234
+ seenNames.add(prefixedName);
235
+ names.push(prefixedName);
236
+ }
237
+ }
238
+
239
+ return names;
240
+ }
241
+
242
+ export function parseMcpDirectToolSelections(selections: string[]): { servers: Set<string>; tools: Map<string, Set<string>> } {
243
+ const servers = new Set<string>();
244
+ const tools = new Map<string, Set<string>>();
245
+ for (let item of selections) {
246
+ item = item.replace(/\/+$/, "");
247
+ if (item.includes("/")) {
248
+ const [server, tool] = item.split("/", 2);
249
+ if (server && tool) {
250
+ if (!tools.has(server)) tools.set(server, new Set());
251
+ tools.get(server)!.add(tool);
252
+ } else if (server) {
253
+ servers.add(server);
254
+ }
255
+ } else if (item) {
256
+ servers.add(item);
257
+ }
258
+ }
259
+ return { servers, tools };
260
+ }
261
+
262
+ function isServerCacheValid(entry: ServerCacheEntry | undefined, definition: ServerEntry): entry is ServerCacheEntry {
263
+ if (!entry || entry.configHash !== computeMcpServerHash(definition)) return false;
264
+ if (!entry.cachedAt || typeof entry.cachedAt !== "number") return false;
265
+ return Date.now() - entry.cachedAt <= CACHE_MAX_AGE_MS;
266
+ }
267
+
268
+ export function computeMcpServerHash(definition: ServerEntry): string {
269
+ const identity: Record<string, unknown> = {
270
+ command: definition.command,
271
+ args: definition.args,
272
+ env: interpolateEnvRecord(definition.env),
273
+ cwd: resolveConfigPath(definition.cwd),
274
+ url: definition.url,
275
+ headers: interpolateEnvRecord(definition.headers),
276
+ auth: definition.auth,
277
+ bearerTokenPresent: hasBearerToken(definition),
278
+ bearerTokenEnv: definition.bearerTokenEnv,
279
+ exposeResources: definition.exposeResources,
280
+ excludeTools: definition.excludeTools,
281
+ };
282
+ return createHash("sha256").update(stableStringify(identity)).digest("hex");
283
+ }
284
+
285
+ function getToolPrefix(value: unknown): ToolPrefix {
286
+ return value === "none" || value === "short" || value === "server" ? value : "server";
287
+ }
288
+
289
+ function isImportKind(value: unknown): value is ImportKind {
290
+ return typeof value === "string" && Object.hasOwn(IMPORT_PATHS, value);
291
+ }
292
+
293
+ function getServerPrefix(serverName: string, mode: ToolPrefix): string {
294
+ if (mode === "none") return "";
295
+ if (mode === "short") {
296
+ const short = serverName.replace(/-?mcp$/i, "").replace(/-/g, "_");
297
+ return short || "mcp";
298
+ }
299
+ return serverName.replace(/-/g, "_");
300
+ }
301
+
302
+ function formatToolName(toolName: string, serverName: string, prefix: ToolPrefix): string {
303
+ const serverPrefix = getServerPrefix(serverName, prefix);
304
+ return serverPrefix ? `${serverPrefix}_${toolName}` : toolName;
305
+ }
306
+
307
+ function isToolExcluded(toolName: string, serverName: string, prefix: ToolPrefix, excludeTools: unknown): boolean {
308
+ if (!Array.isArray(excludeTools) || excludeTools.length === 0) return false;
309
+ const candidates = new Set([
310
+ normalizeToolName(toolName),
311
+ normalizeToolName(formatToolName(toolName, serverName, prefix)),
312
+ normalizeToolName(formatToolName(toolName, serverName, "server")),
313
+ normalizeToolName(formatToolName(toolName, serverName, "short")),
314
+ ]);
315
+ return excludeTools.some((excluded) => typeof excluded === "string" && candidates.has(normalizeToolName(excluded)));
316
+ }
317
+
318
+ function normalizeToolName(value: string): string {
319
+ return value.replace(/-/g, "_");
320
+ }
321
+
322
+ function resourceNameToToolName(name: string): string {
323
+ let result = name
324
+ .replace(/[^a-zA-Z0-9]/g, "_")
325
+ .replace(/_+/g, "_")
326
+ .replace(/^_+/, "")
327
+ .replace(/_+$/, "")
328
+ .toLowerCase();
329
+ if (!result || /^\d/.test(result)) result = `resource${result ? `_${result}` : ""}`;
330
+ return result;
331
+ }
332
+
333
+ function interpolateEnvRecord(values: Record<string, string> | undefined): Record<string, string> | undefined {
334
+ if (!values || typeof values !== "object" || Array.isArray(values)) return undefined;
335
+ const resolved: Record<string, string> = {};
336
+ for (const [key, value] of Object.entries(values)) {
337
+ if (typeof value === "string") resolved[key] = interpolateEnvVars(value);
338
+ }
339
+ return resolved;
340
+ }
341
+
342
+ function interpolateEnvVars(value: string): string {
343
+ return value
344
+ .replace(/\$\{(\w+)\}/g, (_, name: string) => process.env[name] ?? "")
345
+ .replace(/\$env:(\w+)/g, (_, name: string) => process.env[name] ?? "");
346
+ }
347
+
348
+ function resolveConfigPath(value: string | undefined): string | undefined {
349
+ if (typeof value !== "string") return undefined;
350
+ const resolved = interpolateEnvVars(value);
351
+ if (resolved === "~") return os.homedir();
352
+ if (resolved.startsWith("~/") || resolved.startsWith("~\\")) return path.join(os.homedir(), resolved.slice(2));
353
+ return resolved;
354
+ }
355
+
356
+ function hasBearerToken(definition: Pick<ServerEntry, "bearerToken" | "bearerTokenEnv">): boolean {
357
+ if (typeof definition.bearerToken === "string") return interpolateEnvVars(definition.bearerToken).length > 0;
358
+ return typeof definition.bearerTokenEnv === "string" && Boolean(process.env[definition.bearerTokenEnv]);
359
+ }
360
+
361
+ function stableStringify(value: unknown): string {
362
+ if (value === null || value === undefined || typeof value !== "object") {
363
+ const serialized = JSON.stringify(value);
364
+ return serialized === undefined ? "undefined" : serialized;
365
+ }
366
+ if (Array.isArray(value)) return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
367
+ const obj = value as Record<string, unknown>;
368
+ return `{${Object.keys(obj).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(obj[key])}`).join(",")}}`;
369
+ }