@bastani/atomic 0.9.4-alpha.1 → 0.9.4-alpha.11

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 (345) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/dist/builtin/cursor/CHANGELOG.md +24 -0
  3. package/dist/builtin/cursor/package.json +4 -4
  4. package/dist/builtin/intercom/CHANGELOG.md +24 -0
  5. package/dist/builtin/intercom/package.json +2 -2
  6. package/dist/builtin/mcp/CHANGELOG.md +24 -0
  7. package/dist/builtin/mcp/package.json +4 -4
  8. package/dist/builtin/subagents/CHANGELOG.md +52 -0
  9. package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
  10. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
  11. package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
  12. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
  13. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
  14. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
  15. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
  16. package/dist/builtin/subagents/agents/debugger.md +1 -1
  17. package/dist/builtin/subagents/agents/worker.md +2 -2
  18. package/dist/builtin/subagents/package.json +4 -4
  19. package/dist/builtin/subagents/src/runs/background/async-execution-chain.ts +11 -1
  20. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +11 -1
  21. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +2 -0
  22. package/dist/builtin/subagents/src/runs/background/subagent-runner-step.ts +27 -4
  23. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +25 -0
  24. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
  25. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
  26. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
  27. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +1 -0
  28. package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +2 -0
  29. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +3 -1
  30. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +22 -0
  31. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +15 -5
  32. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +5 -1
  33. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
  34. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +4 -1
  35. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +4 -1
  36. package/dist/builtin/subagents/src/runs/shared/attempt-watchdog.ts +126 -0
  37. package/dist/builtin/subagents/src/runs/shared/model-candidate-filter.ts +53 -0
  38. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +52 -53
  39. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +2 -0
  40. package/dist/builtin/subagents/src/shared/model-info.ts +16 -0
  41. package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
  42. package/dist/builtin/subagents/src/slash/slash-commands.ts +2 -2
  43. package/dist/builtin/subagents/src/tui/render-result-compact.ts +3 -2
  44. package/dist/builtin/subagents/src/tui/render-result.ts +3 -3
  45. package/dist/builtin/subagents/src/tui/render-widget-graph.ts +4 -3
  46. package/dist/builtin/subagents/src/tui/render-widget.ts +10 -4
  47. package/dist/builtin/web-access/CHANGELOG.md +24 -0
  48. package/dist/builtin/web-access/package.json +2 -2
  49. package/dist/builtin/workflows/CHANGELOG.md +54 -0
  50. package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +24 -22
  51. package/dist/builtin/workflows/builtin/goal-runner.ts +12 -23
  52. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +4 -4
  53. package/dist/builtin/workflows/builtin/ralph-models.ts +53 -75
  54. package/dist/builtin/workflows/package.json +2 -2
  55. package/dist/builtin/workflows/src/runs/shared/model-fallback-failures.ts +59 -1
  56. package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +4 -0
  57. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +4 -0
  58. package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +12 -1
  59. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +2 -0
  60. package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +6 -0
  61. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +4 -0
  62. package/dist/builtin/workflows/src/tui/workflow-attach-pane-types.ts +4 -0
  63. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +8 -9
  64. package/dist/bun/cli.d.ts.map +1 -1
  65. package/dist/bun/cli.js +3 -2
  66. package/dist/bun/cli.js.map +1 -1
  67. package/dist/cli/file-processor.d.ts.map +1 -1
  68. package/dist/cli/file-processor.js +13 -25
  69. package/dist/cli/file-processor.js.map +1 -1
  70. package/dist/cli.d.ts.map +1 -1
  71. package/dist/cli.js +15 -5
  72. package/dist/cli.js.map +1 -1
  73. package/dist/config.d.ts +10 -3
  74. package/dist/config.d.ts.map +1 -1
  75. package/dist/config.js +18 -1
  76. package/dist/config.js.map +1 -1
  77. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  78. package/dist/core/agent-session-auto-compaction.js +8 -1
  79. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  80. package/dist/core/agent-session-events.d.ts.map +1 -1
  81. package/dist/core/agent-session-events.js +16 -8
  82. package/dist/core/agent-session-events.js.map +1 -1
  83. package/dist/core/agent-session-export.d.ts.map +1 -1
  84. package/dist/core/agent-session-export.js +4 -2
  85. package/dist/core/agent-session-export.js.map +1 -1
  86. package/dist/core/agent-session-extension-bindings.d.ts +5 -1
  87. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  88. package/dist/core/agent-session-extension-bindings.js +18 -7
  89. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  90. package/dist/core/agent-session-methods.d.ts +13 -3
  91. package/dist/core/agent-session-methods.d.ts.map +1 -1
  92. package/dist/core/agent-session-methods.js.map +1 -1
  93. package/dist/core/agent-session-prompt.d.ts +2 -0
  94. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  95. package/dist/core/agent-session-prompt.js +15 -2
  96. package/dist/core/agent-session-prompt.js.map +1 -1
  97. package/dist/core/agent-session-retry.d.ts +2 -0
  98. package/dist/core/agent-session-retry.d.ts.map +1 -1
  99. package/dist/core/agent-session-retry.js +66 -7
  100. package/dist/core/agent-session-retry.js.map +1 -1
  101. package/dist/core/agent-session-state.d.ts.map +1 -1
  102. package/dist/core/agent-session-state.js +2 -2
  103. package/dist/core/agent-session-state.js.map +1 -1
  104. package/dist/core/agent-session-tool-hooks.d.ts +7 -1
  105. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  106. package/dist/core/agent-session-tool-hooks.js +26 -4
  107. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  108. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  109. package/dist/core/agent-session-tool-registry.js +4 -0
  110. package/dist/core/agent-session-tool-registry.js.map +1 -1
  111. package/dist/core/agent-session-tree.d.ts.map +1 -1
  112. package/dist/core/agent-session-tree.js +3 -1
  113. package/dist/core/agent-session-tree.js.map +1 -1
  114. package/dist/core/agent-session-types.d.ts +4 -0
  115. package/dist/core/agent-session-types.d.ts.map +1 -1
  116. package/dist/core/agent-session-types.js.map +1 -1
  117. package/dist/core/agent-session.d.ts +5 -1
  118. package/dist/core/agent-session.d.ts.map +1 -1
  119. package/dist/core/agent-session.js +5 -0
  120. package/dist/core/agent-session.js.map +1 -1
  121. package/dist/core/async/format.d.ts +3 -0
  122. package/dist/core/async/format.d.ts.map +1 -0
  123. package/dist/core/async/format.js +50 -0
  124. package/dist/core/async/format.js.map +1 -0
  125. package/dist/core/async/job-manager.d.ts +39 -0
  126. package/dist/core/async/job-manager.d.ts.map +1 -0
  127. package/dist/core/async/job-manager.js +254 -0
  128. package/dist/core/async/job-manager.js.map +1 -0
  129. package/dist/core/async/session-manager.d.ts +18 -0
  130. package/dist/core/async/session-manager.d.ts.map +1 -0
  131. package/dist/core/async/session-manager.js +61 -0
  132. package/dist/core/async/session-manager.js.map +1 -0
  133. package/dist/core/async/types.d.ts +23 -0
  134. package/dist/core/async/types.d.ts.map +1 -0
  135. package/dist/core/async/types.js +2 -0
  136. package/dist/core/async/types.js.map +1 -0
  137. package/dist/core/copilot-model-catalog.d.ts +38 -74
  138. package/dist/core/copilot-model-catalog.d.ts.map +1 -1
  139. package/dist/core/copilot-model-catalog.js +177 -68
  140. package/dist/core/copilot-model-catalog.js.map +1 -1
  141. package/dist/core/copilot-model-static-fallbacks.d.ts +43 -0
  142. package/dist/core/copilot-model-static-fallbacks.d.ts.map +1 -0
  143. package/dist/core/copilot-model-static-fallbacks.js +50 -0
  144. package/dist/core/copilot-model-static-fallbacks.js.map +1 -0
  145. package/dist/core/copilot-model-synthesis.d.ts +10 -0
  146. package/dist/core/copilot-model-synthesis.d.ts.map +1 -0
  147. package/dist/core/copilot-model-synthesis.js +89 -0
  148. package/dist/core/copilot-model-synthesis.js.map +1 -0
  149. package/dist/core/extensions/api-types.d.ts +2 -1
  150. package/dist/core/extensions/api-types.d.ts.map +1 -1
  151. package/dist/core/extensions/api-types.js.map +1 -1
  152. package/dist/core/extensions/index.d.ts +1 -1
  153. package/dist/core/extensions/index.d.ts.map +1 -1
  154. package/dist/core/extensions/index.js.map +1 -1
  155. package/dist/core/extensions/loader-core.d.ts.map +1 -1
  156. package/dist/core/extensions/loader-core.js +3 -3
  157. package/dist/core/extensions/loader-core.js.map +1 -1
  158. package/dist/core/extensions/loader-virtual-modules.d.ts +11 -0
  159. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  160. package/dist/core/extensions/loader-virtual-modules.js +79 -11
  161. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  162. package/dist/core/extensions/session-events.d.ts +7 -1
  163. package/dist/core/extensions/session-events.d.ts.map +1 -1
  164. package/dist/core/extensions/session-events.js.map +1 -1
  165. package/dist/core/http-dispatcher.d.ts +2 -0
  166. package/dist/core/http-dispatcher.d.ts.map +1 -1
  167. package/dist/core/http-dispatcher.js +38 -5
  168. package/dist/core/http-dispatcher.js.map +1 -1
  169. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  170. package/dist/core/model-registry-builtins.js +40 -6
  171. package/dist/core/model-registry-builtins.js.map +1 -1
  172. package/dist/core/model-registry.d.ts.map +1 -1
  173. package/dist/core/model-registry.js +4 -3
  174. package/dist/core/model-registry.js.map +1 -1
  175. package/dist/core/model-resolver-defaults.d.ts.map +1 -1
  176. package/dist/core/model-resolver-defaults.js +1 -1
  177. package/dist/core/model-resolver-defaults.js.map +1 -1
  178. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  179. package/dist/core/resource-loader-reload.js +6 -3
  180. package/dist/core/resource-loader-reload.js.map +1 -1
  181. package/dist/core/resource-loader-types.d.ts +6 -0
  182. package/dist/core/resource-loader-types.d.ts.map +1 -1
  183. package/dist/core/resource-loader-types.js.map +1 -1
  184. package/dist/core/session-manager-core.d.ts +2 -12
  185. package/dist/core/session-manager-core.d.ts.map +1 -1
  186. package/dist/core/session-manager-core.js +8 -16
  187. package/dist/core/session-manager-core.js.map +1 -1
  188. package/dist/core/settings-manager-resource-accessors.d.ts +1 -0
  189. package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
  190. package/dist/core/settings-manager-resource-accessors.js +11 -0
  191. package/dist/core/settings-manager-resource-accessors.js.map +1 -1
  192. package/dist/core/settings-manager-ui-accessors.d.ts +2 -0
  193. package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
  194. package/dist/core/settings-manager-ui-accessors.js +9 -0
  195. package/dist/core/settings-manager-ui-accessors.js.map +1 -1
  196. package/dist/core/settings-types.d.ts +2 -0
  197. package/dist/core/settings-types.d.ts.map +1 -1
  198. package/dist/core/settings-types.js.map +1 -1
  199. package/dist/core/timings.d.ts +7 -5
  200. package/dist/core/timings.d.ts.map +1 -1
  201. package/dist/core/timings.js +42 -24
  202. package/dist/core/timings.js.map +1 -1
  203. package/dist/core/tools/bash-async-execution.d.ts +25 -0
  204. package/dist/core/tools/bash-async-execution.d.ts.map +1 -0
  205. package/dist/core/tools/bash-async-execution.js +71 -0
  206. package/dist/core/tools/bash-async-execution.js.map +1 -0
  207. package/dist/core/tools/bash-async-jobs.d.ts +10 -0
  208. package/dist/core/tools/bash-async-jobs.d.ts.map +1 -1
  209. package/dist/core/tools/bash-async-jobs.js +18 -2
  210. package/dist/core/tools/bash-async-jobs.js.map +1 -1
  211. package/dist/core/tools/bash-async-output.d.ts +3 -1
  212. package/dist/core/tools/bash-async-output.d.ts.map +1 -1
  213. package/dist/core/tools/bash-async-output.js +4 -1
  214. package/dist/core/tools/bash-async-output.js.map +1 -1
  215. package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
  216. package/dist/core/tools/bash-pty-native.js +2 -2
  217. package/dist/core/tools/bash-pty-native.js.map +1 -1
  218. package/dist/core/tools/bash.d.ts +10 -4
  219. package/dist/core/tools/bash.d.ts.map +1 -1
  220. package/dist/core/tools/bash.js +20 -38
  221. package/dist/core/tools/bash.js.map +1 -1
  222. package/dist/core/tools/read-selectors.d.ts.map +1 -1
  223. package/dist/core/tools/read-selectors.js +19 -1
  224. package/dist/core/tools/read-selectors.js.map +1 -1
  225. package/dist/core/tools/read.d.ts.map +1 -1
  226. package/dist/core/tools/read.js +12 -23
  227. package/dist/core/tools/read.js.map +1 -1
  228. package/dist/core/tools/search-native.d.ts.map +1 -1
  229. package/dist/core/tools/search-native.js +2 -2
  230. package/dist/core/tools/search-native.js.map +1 -1
  231. package/dist/index-extensions.d.ts +1 -1
  232. package/dist/index-extensions.d.ts.map +1 -1
  233. package/dist/index-extensions.js.map +1 -1
  234. package/dist/index.d.ts +1 -1
  235. package/dist/index.d.ts.map +1 -1
  236. package/dist/index.js.map +1 -1
  237. package/dist/main-session.d.ts.map +1 -1
  238. package/dist/main-session.js +14 -5
  239. package/dist/main-session.js.map +1 -1
  240. package/dist/main.d.ts.map +1 -1
  241. package/dist/main.js +56 -32
  242. package/dist/main.js.map +1 -1
  243. package/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  244. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  245. package/dist/modes/interactive/components/assistant-message.js +22 -15
  246. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  247. package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -0
  248. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  249. package/dist/modes/interactive/components/chat-message-renderer.js +5 -5
  250. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  251. package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
  252. package/dist/modes/interactive/components/chat-session-host-events.js +8 -0
  253. package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
  254. package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
  255. package/dist/modes/interactive/components/chat-session-host-rendering.js +1 -0
  256. package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
  257. package/dist/modes/interactive/components/user-message.d.ts +6 -2
  258. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  259. package/dist/modes/interactive/components/user-message.js +16 -5
  260. package/dist/modes/interactive/components/user-message.js.map +1 -1
  261. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  262. package/dist/modes/interactive/interactive-agent-events.js +6 -1
  263. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  264. package/dist/modes/interactive/interactive-deferred-startup.d.ts +2 -0
  265. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -0
  266. package/dist/modes/interactive/interactive-deferred-startup.js +59 -0
  267. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -0
  268. package/dist/modes/interactive/interactive-editor-actions.d.ts.map +1 -1
  269. package/dist/modes/interactive/interactive-editor-actions.js +1 -0
  270. package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
  271. package/dist/modes/interactive/interactive-extension-context.d.ts.map +1 -1
  272. package/dist/modes/interactive/interactive-extension-context.js +1 -0
  273. package/dist/modes/interactive/interactive-extension-context.js.map +1 -1
  274. package/dist/modes/interactive/interactive-mode-base.d.ts +3 -0
  275. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  276. package/dist/modes/interactive/interactive-mode-base.js +6 -0
  277. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  278. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  279. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  280. package/dist/modes/interactive/interactive-mode-deps.js +1 -1
  281. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  282. package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -0
  283. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  284. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  285. package/dist/modes/interactive/interactive-mode-types.d.ts +2 -0
  286. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  287. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  288. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  289. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  290. package/dist/modes/interactive/interactive-mode.js +1 -0
  291. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  292. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  293. package/dist/modes/interactive/interactive-model-routing.js +2 -4
  294. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  295. package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
  296. package/dist/modes/interactive/interactive-render-chat.js +4 -3
  297. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  298. package/dist/modes/interactive/interactive-session-runtime.d.ts.map +1 -1
  299. package/dist/modes/interactive/interactive-session-runtime.js +5 -2
  300. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  301. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  302. package/dist/modes/interactive/interactive-startup.js +11 -1
  303. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  304. package/dist/modes/rpc/rpc-client.d.ts +28 -51
  305. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  306. package/dist/modes/rpc/rpc-client.js +27 -51
  307. package/dist/modes/rpc/rpc-client.js.map +1 -1
  308. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  309. package/dist/modes/rpc/rpc-command-handler.js +19 -0
  310. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  311. package/dist/modes/rpc/rpc-types.d.ts +26 -0
  312. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  313. package/dist/modes/rpc/rpc-types.js.map +1 -1
  314. package/dist/rpc-entry.d.ts +3 -0
  315. package/dist/rpc-entry.d.ts.map +1 -0
  316. package/dist/rpc-entry.js +12 -0
  317. package/dist/rpc-entry.js.map +1 -0
  318. package/dist/utils/image-convert.d.ts +1 -0
  319. package/dist/utils/image-convert.d.ts.map +1 -1
  320. package/dist/utils/image-convert.js +21 -15
  321. package/dist/utils/image-convert.js.map +1 -1
  322. package/dist/utils/image-process.d.ts +18 -0
  323. package/dist/utils/image-process.d.ts.map +1 -0
  324. package/dist/utils/image-process.js +83 -0
  325. package/dist/utils/image-process.js.map +1 -0
  326. package/dist/utils/mime.d.ts.map +1 -1
  327. package/dist/utils/mime.js +41 -0
  328. package/dist/utils/mime.js.map +1 -1
  329. package/dist/utils/module-require.d.ts +11 -0
  330. package/dist/utils/module-require.d.ts.map +1 -0
  331. package/dist/utils/module-require.js +16 -0
  332. package/dist/utils/module-require.js.map +1 -0
  333. package/docs/compaction.md +2 -0
  334. package/docs/development.md +10 -0
  335. package/docs/extensions.md +11 -0
  336. package/docs/models.md +3 -3
  337. package/docs/providers.md +2 -1
  338. package/docs/rpc.md +60 -2
  339. package/docs/sdk.md +1 -1
  340. package/docs/settings.md +4 -1
  341. package/docs/subagents.md +6 -0
  342. package/docs/tools.md +4 -2
  343. package/docs/workflows.md +4 -2
  344. package/npm-shrinkwrap.json +138 -171
  345. package/package.json +19 -12
@@ -1,27 +1,42 @@
1
1
  import { reviewDecisionSchema } from "./ralph-core.js";
2
2
 
3
+ // Model chains are curated from Atomic's agentic-coding benchmark
4
+ // (pass@1 / avg $ per task, 2026-07-02):
5
+ // - Placement principle: REVIEWERS get best-in-class verification quality
6
+ // (fable-5:xhigh 70%/$13.41 leads reviewer-A and the goal reviewer);
7
+ // EVERY OTHER stage gets the best measured performance-per-dollar
8
+ // (gpt-5.5:xhigh 67%/$7.23 for hard stages, gpt-5.5:medium 54%/$2.75 for
9
+ // workhorse stages, gpt-5.5:low $1.20 for retrieval).
10
+ // - Pareto frontier: gpt-5.5 low ($1.20/27%) → gpt-5.5 medium ($2.75/54%) →
11
+ // fable-5 low ($3.76/60%) → gpt-5.5 high ($5.10/64%) → fable-5 medium
12
+ // ($6.09/65%) → gpt-5.5 xhigh ($7.23/67%) → fable-5 high ($9.18/69%) →
13
+ // fable-5 xhigh ($13.41/70%).
14
+ // - Dropped as strictly dominated: claude-sonnet-5 (40-54% at $4-26, up to
15
+ // 268 steps), claude-sonnet-4.6 (30%/$5.52), gemini-3.1-pro (12%/$9.48),
16
+ // gemini-3.5-flash (37%/$7.34, 276k output tokens).
17
+ // - claude-opus-4.8 rides at :high — its value point (52%/$4.28); :xhigh
18
+ // doubles the cost for +2pts.
19
+ // - glm-5.2 is reviewer-C's diversity primary only (third model family
20
+ // decorrelates review errors); elsewhere it is a budget fallback. Note:
21
+ // GLM-5.2 has only two real reasoning tiers — its thinkingLevelMap collapses
22
+ // minimal/low/medium/high to "high" and xhigh to "max" — so chains only use
23
+ // :high (budget tier, 36%/$2.84) or :xhigh (best tier, 44%/$3.92); the
24
+ // openrouter/z-ai mirror maps :xhigh exclusively, so it is always :xhigh.
25
+
3
26
  export const promptEngineerModelConfig = {
4
- model: "anthropic/claude-fable-5:xhigh",
27
+ model: "openai-codex/gpt-5.5:xhigh",
5
28
  fallbackModels: [
6
- "openai-codex/gpt-5.5:xhigh",
7
29
  "github-copilot/gpt-5.5:xhigh",
8
30
  "openai/gpt-5.5:xhigh",
9
- "github-copilot/claude-opus-4.8 (1m):xhigh",
10
- "anthropic/claude-opus-4-8:xhigh",
31
+ "anthropic/claude-fable-5:xhigh",
32
+ "github-copilot/claude-opus-4.8 (1m):high",
33
+ "anthropic/claude-opus-4-8:high",
11
34
  "zai/glm-5.2:xhigh",
12
35
  "zai-coding-cn/glm-5.2:xhigh",
13
- "github-copilot/gemini-3.5-flash (1m):high",
14
- "google/gemini-3.5-flash:high",
15
- "google-vertex/gemini-3.5-flash:high",
16
- "github-copilot/gemini-3.1-pro-preview (1m):high",
17
- "google/gemini-3.1-pro-preview:high",
18
- "google-vertex/gemini-3.1-pro-preview:high",
19
- "openrouter/anthropic/claude-fable-5:xhigh",
20
36
  "openrouter/openai/gpt-5.5:xhigh",
21
- "openrouter/anthropic/claude-opus-4-8:xhigh",
22
- "openrouter/z-ai/glm-5.2:xhigh",
23
- "openrouter/google/gemini-3.5-flash:high",
24
- "openrouter/google/gemini-3.1-pro-preview:high"
37
+ "openrouter/anthropic/claude-fable-5:xhigh",
38
+ "openrouter/anthropic/claude-opus-4-8:high",
39
+ "openrouter/z-ai/glm-5.2:xhigh"
25
40
  ],
26
41
  excludedTools: ["ask_user_question"],
27
42
  };
@@ -31,21 +46,15 @@ export const researchModelConfig = {
31
46
  fallbackModels: [
32
47
  "github-copilot/gpt-5.5:medium",
33
48
  "openai/gpt-5.5:medium",
49
+ "anthropic/claude-fable-5:low",
34
50
  "github-copilot/claude-opus-4.8 (1m):medium",
35
51
  "anthropic/claude-opus-4-8:medium",
36
- "zai/glm-5.2:medium",
37
- "zai-coding-cn/glm-5.2:medium",
38
- "github-copilot/gemini-3.5-flash (1m):medium",
39
- "google/gemini-3.5-flash:medium",
40
- "google-vertex/gemini-3.5-flash:medium",
41
- "github-copilot/gemini-3.1-pro-preview (1m):medium",
42
- "google/gemini-3.1-pro-preview:medium",
43
- "google-vertex/gemini-3.1-pro-preview:medium",
52
+ "zai/glm-5.2:high",
53
+ "zai-coding-cn/glm-5.2:high",
44
54
  "openrouter/openai/gpt-5.5:medium",
55
+ "openrouter/anthropic/claude-fable-5:low",
45
56
  "openrouter/anthropic/claude-opus-4-8:medium",
46
- "openrouter/z-ai/glm-5.2:medium",
47
- "openrouter/google/gemini-3.5-flash:medium",
48
- "openrouter/google/gemini-3.1-pro-preview:medium"
57
+ "openrouter/z-ai/glm-5.2:xhigh"
49
58
  ],
50
59
  excludedTools: ["ask_user_question"],
51
60
  };
@@ -55,21 +64,15 @@ export const orchestratorModelConfig = {
55
64
  fallbackModels: [
56
65
  "github-copilot/gpt-5.5:medium",
57
66
  "openai/gpt-5.5:medium",
67
+ "anthropic/claude-fable-5:low",
58
68
  "github-copilot/claude-opus-4.8 (1m):medium",
59
69
  "anthropic/claude-opus-4-8:medium",
60
- "zai/glm-5.2:medium",
61
- "zai-coding-cn/glm-5.2:medium",
62
- "github-copilot/gemini-3.5-flash (1m):medium",
63
- "google/gemini-3.5-flash:medium",
64
- "google-vertex/gemini-3.5-flash:medium",
65
- "github-copilot/gemini-3.1-pro-preview (1m):medium",
66
- "google/gemini-3.1-pro-preview:medium",
67
- "google-vertex/gemini-3.1-pro-preview:medium",
70
+ "zai/glm-5.2:high",
71
+ "zai-coding-cn/glm-5.2:high",
68
72
  "openrouter/openai/gpt-5.5:medium",
73
+ "openrouter/anthropic/claude-fable-5:low",
69
74
  "openrouter/anthropic/claude-opus-4-8:medium",
70
- "openrouter/z-ai/glm-5.2:medium",
71
- "openrouter/google/gemini-3.5-flash:medium",
72
- "openrouter/google/gemini-3.1-pro-preview:medium"
75
+ "openrouter/z-ai/glm-5.2:xhigh"
73
76
  ],
74
77
  excludedTools: ["ask_user_question"],
75
78
  };
@@ -77,25 +80,17 @@ export const orchestratorModelConfig = {
77
80
  export const reviewerAModelConfig = {
78
81
  model: "anthropic/claude-fable-5:xhigh",
79
82
  fallbackModels: [
80
- "github-copilot/claude-opus-4.8 (1m):xhigh",
81
- "anthropic/claude-opus-4-8:xhigh",
82
83
  "openai-codex/gpt-5.5:xhigh",
83
84
  "github-copilot/gpt-5.5:xhigh",
84
85
  "openai/gpt-5.5:xhigh",
86
+ "github-copilot/claude-opus-4.8 (1m):high",
87
+ "anthropic/claude-opus-4-8:high",
85
88
  "zai/glm-5.2:xhigh",
86
89
  "zai-coding-cn/glm-5.2:xhigh",
87
- "github-copilot/gemini-3.5-flash (1m):high",
88
- "google/gemini-3.5-flash:high",
89
- "google-vertex/gemini-3.5-flash:high",
90
- "github-copilot/gemini-3.1-pro-preview (1m):high",
91
- "google/gemini-3.1-pro-preview:high",
92
- "google-vertex/gemini-3.1-pro-preview:high",
93
90
  "openrouter/anthropic/claude-fable-5:xhigh",
94
- "openrouter/anthropic/claude-opus-4-8:xhigh",
95
91
  "openrouter/openai/gpt-5.5:xhigh",
96
- "openrouter/z-ai/glm-5.2:xhigh",
97
- "openrouter/google/gemini-3.5-flash:high",
98
- "openrouter/google/gemini-3.1-pro-preview:high"
92
+ "openrouter/anthropic/claude-opus-4-8:high",
93
+ "openrouter/z-ai/glm-5.2:xhigh"
99
94
  ],
100
95
  excludedTools: ["ask_user_question"],
101
96
  schema: reviewDecisionSchema,
@@ -107,22 +102,14 @@ export const reviewerBModelConfig = {
107
102
  "github-copilot/gpt-5.5:xhigh",
108
103
  "openai/gpt-5.5:xhigh",
109
104
  "anthropic/claude-fable-5:xhigh",
110
- "github-copilot/claude-opus-4.8 (1m):xhigh",
111
- "anthropic/claude-opus-4-8:xhigh",
105
+ "github-copilot/claude-opus-4.8 (1m):high",
106
+ "anthropic/claude-opus-4-8:high",
112
107
  "zai/glm-5.2:xhigh",
113
108
  "zai-coding-cn/glm-5.2:xhigh",
114
- "github-copilot/gemini-3.5-flash (1m):high",
115
- "google/gemini-3.5-flash:high",
116
- "google-vertex/gemini-3.5-flash:high",
117
- "github-copilot/gemini-3.1-pro-preview (1m):high",
118
- "google/gemini-3.1-pro-preview:high",
119
- "google-vertex/gemini-3.1-pro-preview:high",
120
109
  "openrouter/openai/gpt-5.5:xhigh",
121
110
  "openrouter/anthropic/claude-fable-5:xhigh",
122
- "openrouter/anthropic/claude-opus-4-8:xhigh",
123
- "openrouter/z-ai/glm-5.2:xhigh",
124
- "openrouter/google/gemini-3.5-flash:high",
125
- "openrouter/google/gemini-3.1-pro-preview:high"
111
+ "openrouter/anthropic/claude-opus-4-8:high",
112
+ "openrouter/z-ai/glm-5.2:xhigh"
126
113
  ],
127
114
  excludedTools: ["ask_user_question"],
128
115
  schema: reviewDecisionSchema,
@@ -132,26 +119,17 @@ export const reviewerCModelConfig = {
132
119
  model: "zai/glm-5.2:xhigh",
133
120
  fallbackModels: [
134
121
  "zai-coding-cn/glm-5.2:xhigh",
135
- "github-copilot/gemini-3.5-flash (1m):high",
136
- "google/gemini-3.5-flash:high",
137
- "google-vertex/gemini-3.5-flash:high",
138
- "github-copilot/gemini-3.1-pro-preview (1m):high",
139
- "google/gemini-3.1-pro-preview:high",
140
- "google-vertex/gemini-3.1-pro-preview:high",
122
+ "openrouter/z-ai/glm-5.2:xhigh",
141
123
  "openai-codex/gpt-5.5:xhigh",
142
124
  "github-copilot/gpt-5.5:xhigh",
143
125
  "openai/gpt-5.5:xhigh",
144
126
  "anthropic/claude-fable-5:xhigh",
145
- "github-copilot/claude-opus-4.8 (1m):xhigh",
146
- "anthropic/claude-opus-4-8:xhigh",
147
- "openrouter/anthropic/claude-fable-5:xhigh",
148
- "openrouter/anthropic/claude-opus-4-8:xhigh",
127
+ "github-copilot/claude-opus-4.8 (1m):high",
128
+ "anthropic/claude-opus-4-8:high",
149
129
  "openrouter/openai/gpt-5.5:xhigh",
150
- "openrouter/z-ai/glm-5.2:xhigh",
151
- "openrouter/google/gemini-3.5-flash:high",
152
- "openrouter/google/gemini-3.1-pro-preview:high"
130
+ "openrouter/anthropic/claude-fable-5:xhigh",
131
+ "openrouter/anthropic/claude-opus-4-8:high"
153
132
  ],
154
133
  excludedTools: ["ask_user_question"],
155
134
  schema: reviewDecisionSchema,
156
135
  };
157
-
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/workflows",
3
- "version": "0.9.4-alpha.1",
3
+ "version": "0.9.4-alpha.11",
4
4
  "private": true,
5
5
  "description": "Atomic extension for multi-stage workflow authoring and execution.",
6
6
  "contributors": [
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "peerDependencies": {
85
85
  "@bastani/atomic": "*",
86
- "@earendil-works/pi-tui": "^0.80.2"
86
+ "@earendil-works/pi-tui": "^0.80.3"
87
87
  },
88
88
  "peerDependenciesMeta": {
89
89
  "@bastani/atomic": {
@@ -49,7 +49,9 @@ export type ModelFallbackFailureKind =
49
49
  | "rate_limit"
50
50
  | "provider_unavailable"
51
51
  | "network_timeout"
52
+ | "transport_error"
52
53
  | "model_unavailable"
54
+ | "request_incompatible"
53
55
  | "cancelled"
54
56
  | "task_failure"
55
57
  | "unknown";
@@ -76,7 +78,9 @@ const FALLBACKABLE_FAILURE_KINDS: ReadonlySet<ModelFallbackFailureKind> = new Se
76
78
  "rate_limit",
77
79
  "provider_unavailable",
78
80
  "network_timeout",
81
+ "transport_error",
79
82
  "model_unavailable",
83
+ "request_incompatible",
80
84
  ]);
81
85
 
82
86
  function asRecord(value: unknown): Record<string, unknown> | undefined {
@@ -155,6 +159,9 @@ function normalizeCode(value: string | number | undefined): string | undefined {
155
159
 
156
160
  function kindFromStatus(status: number | undefined): ModelFallbackFailureKind | undefined {
157
161
  switch (status) {
162
+ case 400:
163
+ case 413: case 422:
164
+ return "request_incompatible";
158
165
  case 401:
159
166
  case 403:
160
167
  return "auth_on_candidate_provider";
@@ -191,6 +198,15 @@ function refusalKindFromCode(code: string | number | undefined): ModelFallbackFa
191
198
  }
192
199
  }
193
200
 
201
+ const REQUEST_INCOMPATIBLE_CODES: ReadonlySet<string> = new Set([
202
+ "invalid_request", "invalid_request_error", "bad_request", "context_length_exceeded",
203
+ "request_too_large", "too_large", "request_entity_too_large", "max_tokens",
204
+ "max_context_length", "context_window_exceeded",
205
+ ]);
206
+ function requestIncompatibleKindFromCode(code: string | number | undefined): ModelFallbackFailureKind | undefined {
207
+ const normalizedCode = normalizeCode(code);
208
+ return normalizedCode !== undefined && REQUEST_INCOMPATIBLE_CODES.has(normalizedCode) ? "request_incompatible" : undefined;
209
+ }
194
210
  function kindFromCode(code: string | number | undefined): ModelFallbackFailureKind | undefined {
195
211
  const normalizedCode = normalizeCode(code);
196
212
  if (normalizedCode === undefined) return undefined;
@@ -198,6 +214,8 @@ function kindFromCode(code: string | number | undefined): ModelFallbackFailureKi
198
214
  if (refusalKind !== undefined) return refusalKind;
199
215
  const httpStatusKind = kindFromStatus(integerFrom(code));
200
216
  if (httpStatusKind !== undefined) return httpStatusKind;
217
+ const requestIncompatibleKind = requestIncompatibleKindFromCode(code);
218
+ if (requestIncompatibleKind !== undefined) return requestIncompatibleKind;
201
219
 
202
220
  switch (normalizedCode) {
203
221
  case "auth":
@@ -246,6 +264,18 @@ function kindFromCode(code: string | number | undefined): ModelFallbackFailureKi
246
264
  }
247
265
  }
248
266
 
267
+ const REQUEST_INCOMPATIBLE_FAILURE_PATTERNS: readonly RegExp[] = [
268
+ /\bcontext[_\s-]?length(?:[_\s-]?exceeded)?\b/i,
269
+ /\bcontext[_\s-]?window(?:[_\s-]?exceeded)?\b/i,
270
+ /\bmax[_\s-]?context\b/i,
271
+ /\bmax[_\s-]?tokens?\b/i,
272
+ /\brequest(?:[_\s-]?entity)?[_\s-]?too[_\s-]?large\b/i,
273
+ /\btoo[_\s-]?large\b/i,
274
+ /\b(?:unsupported|unknown|invalid)\s+(?:tool|parameter|function)\b/i,
275
+ /\b(?:tool|parameter|function)\s+(?:not\s+(?:supported|found|allowed)|unknown|invalid)\b/i,
276
+ /\binvalid[_\s-]?request(?:[_\s-]?error)?\b/i,
277
+ /\bbad[_\s-]?request\b/i,
278
+ ];
249
279
  const PROVIDER_REFUSAL_FAILURE_PATTERNS: readonly RegExp[] = [
250
280
  /\bfinish[_\s-]?reason\b[^\n]*\bcontent[_\s-]?filter\b/i,
251
281
  /\bcontent[_\s-]?filter(?:ed|ing)?\b/i,
@@ -258,6 +288,17 @@ const PROVIDER_REFUSAL_FAILURE_PATTERNS: readonly RegExp[] = [
258
288
  /\bprovider\b[^\n]*\brefus(?:e|al|ed|es|ing)?\b[^\n]*\b(?:prompt|request|content|policy|safety)\b/i,
259
289
  ];
260
290
 
291
+ const TRANSPORT_OUTAGE_FAILURE_PATTERNS: readonly RegExp[] = [
292
+ /^connection\s+error\.?$/i,
293
+ /^fetch\s+failed\.?$/i,
294
+ ];
295
+
296
+ function transportOutageKindFromMessage(message: string): ModelFallbackFailureKind | undefined {
297
+ return TRANSPORT_OUTAGE_FAILURE_PATTERNS.some((pattern) => pattern.test(message.trim()))
298
+ ? "transport_error"
299
+ : undefined;
300
+ }
301
+
261
302
  function refusalKindFromMessage(message: string): ModelFallbackFailureKind | undefined {
262
303
  if (CANCELLED_FAILURE_PATTERNS.some((pattern) => pattern.test(message))) return "cancelled";
263
304
  if (NON_RETRYABLE_FAILURE_PATTERNS.some((pattern) => pattern.test(message))) return "task_failure";
@@ -268,6 +309,9 @@ function refusalKindFromMessage(message: string): ModelFallbackFailureKind | und
268
309
  function fallbackKindFromMessage(message: string, name: string | undefined): ModelFallbackFailureKind | undefined {
269
310
  const refusalKind = refusalKindFromMessage(message);
270
311
  if (refusalKind !== undefined) return refusalKind;
312
+ const transportOutageKind = transportOutageKindFromMessage(message);
313
+ if (transportOutageKind !== undefined) return transportOutageKind;
314
+ if (REQUEST_INCOMPATIBLE_FAILURE_PATTERNS.some((pattern) => pattern.test(message))) return "request_incompatible";
271
315
  const nameKind = kindFromCode(name);
272
316
  if (nameKind !== undefined) return nameKind;
273
317
  if (!RETRYABLE_MODEL_FAILURE_PATTERNS.some((pattern) => pattern.test(message))) return undefined;
@@ -305,6 +349,16 @@ function makeSignal(
305
349
  };
306
350
  }
307
351
 
352
+ function fallbackSignalFromDirectMessage(
353
+ value: unknown,
354
+ source: ModelFallbackFailureSource | undefined,
355
+ ): ModelFallbackFailureSignal | undefined {
356
+ const message = directMessageFrom(value);
357
+ if (message === undefined) return undefined;
358
+ const kind = fallbackKindFromMessage(message, errorName(value));
359
+ return kind === undefined ? undefined : makeSignal(kind, value, source);
360
+ }
361
+
308
362
  function fallbackSignalFromMessage(
309
363
  value: unknown,
310
364
  source: ModelFallbackFailureSource | undefined,
@@ -359,7 +413,6 @@ function structuredSignal(
359
413
  if (isRefusalSignal(diagnosticSignal)) return diagnosticSignal;
360
414
  firstNestedFallbackSignal ??= diagnosticSignal;
361
415
  }
362
-
363
416
  const cause = causeOf(value);
364
417
  const causeSignal = structuredSignal(cause, nestedSeen, source)
365
418
  ?? fallbackSignalFromMessage(cause, source);
@@ -368,6 +421,11 @@ function structuredSignal(
368
421
  firstNestedFallbackSignal ??= causeSignal;
369
422
  }
370
423
 
424
+ // Direct-message classification runs after nested traversal so a generic wrapper
425
+ // ("invalid request"/"400 bad request") cannot mask a non-retryable nested signal.
426
+ const directMessageSignal = fallbackSignalFromDirectMessage(value, source);
427
+ if (directMessageSignal !== undefined) return directMessageSignal;
428
+
371
429
  const statusKind = kindFromStatus(statusFrom(value));
372
430
  if (statusKind !== undefined) return makeSignal(statusKind, value, source);
373
431
  if (codeKind !== undefined) return makeSignal(codeKind, value, source);
@@ -38,6 +38,10 @@ export interface KeybindingsLike {
38
38
  matches(data: string, action: string): boolean;
39
39
  }
40
40
 
41
+ export const APP_ACTION = {
42
+ toolsExpand: "app.tools.expand",
43
+ } as const;
44
+
41
45
  export const TUI_ACTION = {
42
46
  editorCursorUp: "tui.editor.cursorUp",
43
47
  editorCursorDown: "tui.editor.cursorDown",
@@ -48,6 +48,8 @@ export interface OverlayUISurface {
48
48
  focusHostInlineCustomUi?: () => boolean;
49
49
  getEditorComponent?: () => PiEditorFactory | undefined;
50
50
  getChatRenderSettings?: () => OverlayChatRenderSettings | undefined;
51
+ getToolsExpanded?: () => boolean;
52
+ setToolsExpanded?: (expanded: boolean) => void;
51
53
  getFooterDataProvider?: () => ReadonlyFooterDataProvider;
52
54
  setStatus?: (key: string, value: string | undefined) => void;
53
55
  }
@@ -334,6 +336,8 @@ export function buildGraphOverlayAdapter(
334
336
  piKeybindings: keybindings,
335
337
  piEditorFactory: ui?.getEditorComponent?.(),
336
338
  getChatRenderSettings: ui?.getChatRenderSettings,
339
+ getToolsExpanded: ui?.getToolsExpanded,
340
+ setToolsExpanded: ui?.setToolsExpanded,
337
341
  footerData: ui?.getFooterDataProvider?.(),
338
342
  // Pi-tui owns terminal dimensions; thread its row count down
339
343
  // so the overlay frame fills the actual viewport rather than
@@ -3,7 +3,7 @@ import {
3
3
  handlePromptCardInput,
4
4
  isPromptEscapeInput,
5
5
  } from "./prompt-card.js";
6
- import { isKeybindingsLike } from "./keybindings-adapter.js";
6
+ import { APP_ACTION, isKeybindingsLike, matchesAction } from "./keybindings-adapter.js";
7
7
  import {
8
8
  setComponentFocused,
9
9
  setEditorFocused,
@@ -35,6 +35,7 @@ export function handleStageChatInput(
35
35
  ctx.requestRender?.();
36
36
  return true;
37
37
  }
38
+ if (handleToolsExpandInput(ctx, data)) return true;
38
39
  if (ctx.mountedCustomUi) {
39
40
  return handleMountedCustomUiInput(ctx, data);
40
41
  }
@@ -87,6 +88,16 @@ export function handleStageChatInput(
87
88
  return ctx.chatHost.handleInput(data);
88
89
  }
89
90
 
91
+ function handleToolsExpandInput(ctx: StageChatViewContext, data: string): boolean {
92
+ const keybindings = isKeybindingsLike(ctx.piKeybindings) ? ctx.piKeybindings : undefined;
93
+ if (!matchesAction(keybindings, data, APP_ACTION.toolsExpand)) return false;
94
+ const expanded = ctx.getToolsExpanded?.() === true;
95
+ ctx.setToolsExpanded?.(!expanded);
96
+ ctx.chatHost.invalidate();
97
+ ctx.requestRender?.();
98
+ return true;
99
+ }
100
+
90
101
  function handleMountedCustomUiInput(
91
102
  ctx: StageChatViewContext,
92
103
  data: string,
@@ -57,6 +57,8 @@ export function initializeStageChatView(
57
57
  ctx.piTheme = opts.piTheme;
58
58
  ctx.piKeybindings = opts.piKeybindings;
59
59
  ctx.piEditorFactory = opts.piEditorFactory;
60
+ ctx.getToolsExpanded = opts.getToolsExpanded;
61
+ ctx.setToolsExpanded = opts.setToolsExpanded;
60
62
  ctx.stageUiBroker = opts.stageUiBroker ?? stageUiBroker;
61
63
  ctx.canSubmitPrompt = opts.canSubmitPrompt;
62
64
  ctx.mountedCustomUi = null;
@@ -63,6 +63,10 @@ export interface StageChatViewOpts {
63
63
  getChatRenderSettings?: () =>
64
64
  | Partial<Omit<ChatMessageRenderOptions, "ui" | "cwd">>
65
65
  | undefined;
66
+ /** Parent host expansion state for tool-output/live-detail widgets. */
67
+ getToolsExpanded?: () => boolean;
68
+ /** Toggle parent host expansion state for tool-output/live-detail widgets. */
69
+ setToolsExpanded?: (expanded: boolean) => void;
66
70
  /** Parent footer data provider inherited from the host UI for core footer/usage rendering. */
67
71
  footerData?: ReadonlyFooterDataProvider;
68
72
  /**
@@ -133,6 +137,8 @@ export interface StageChatViewContext {
133
137
  piTheme: unknown;
134
138
  piKeybindings: unknown;
135
139
  piEditorFactory: StageChatViewOpts["piEditorFactory"] | undefined;
140
+ getToolsExpanded: (() => boolean) | undefined;
141
+ setToolsExpanded: ((expanded: boolean) => void) | undefined;
136
142
  chatHost: ChatSessionHost<NoticeEntry>;
137
143
  stageUiBroker: StageUiBroker;
138
144
  canSubmitPrompt: ((runId: string, stageId: string, promptId: string) => boolean) | undefined;
@@ -83,6 +83,8 @@ export class StageChatView implements Component, Focusable {
83
83
  private piTheme!: StageChatViewContext["piTheme"];
84
84
  private piKeybindings!: StageChatViewContext["piKeybindings"];
85
85
  private piEditorFactory!: StageChatViewContext["piEditorFactory"];
86
+ private getToolsExpanded!: StageChatViewContext["getToolsExpanded"];
87
+ private setToolsExpanded!: StageChatViewContext["setToolsExpanded"];
86
88
  private chatHost!: StageChatViewContext["chatHost"];
87
89
  private stageUiBroker!: StageChatViewContext["stageUiBroker"];
88
90
  private canSubmitPrompt!: StageChatViewContext["canSubmitPrompt"];
@@ -213,6 +215,8 @@ export class StageChatView implements Component, Focusable {
213
215
  void this.piTheme;
214
216
  void this.piKeybindings;
215
217
  void this.piEditorFactory;
218
+ void this.getToolsExpanded;
219
+ void this.setToolsExpanded;
216
220
  void this.stageUiBroker;
217
221
  void this.canSubmitPrompt;
218
222
  void this.mountingRequestId;
@@ -41,6 +41,10 @@ export interface WorkflowAttachPaneOpts {
41
41
  piEditorFactory?: (tui: TUI, theme: EditorTheme, keybindings: unknown) => EditorComponent;
42
42
  /** Parent chat rendering settings and extension renderers, inherited from the host UI. */
43
43
  getChatRenderSettings?: () => Partial<Omit<ChatMessageRenderOptions, "ui" | "cwd">> | undefined;
44
+ /** Parent host tool-output/live-detail expansion state, inherited from the host UI. */
45
+ getToolsExpanded?: () => boolean;
46
+ /** Parent host tool-output/live-detail expansion setter, inherited from the host UI. */
47
+ setToolsExpanded?: (expanded: boolean) => void;
44
48
  /** Parent footer data provider, inherited so attached chats can render the core coding-agent footer. */
45
49
  footerData?: ReadonlyFooterDataProvider;
46
50
  /**
@@ -24,16 +24,9 @@ import type { ChatMessageRenderOptions, ReadonlyFooterDataProvider } from "@bast
24
24
  import type { Store } from "../shared/store.js";
25
25
  import type { GraphTheme } from "./graph-theme.js";
26
26
  import { GraphView } from "./graph-view.js";
27
- import {
28
- StageChatView,
29
- type StageChatDetachMetadata,
30
- type StageChatDetachReason,
31
- } from "./stage-chat-view.js";
27
+ import { StageChatView, type StageChatDetachMetadata, type StageChatDetachReason } from "./stage-chat-view.js";
32
28
  import { Key, matchesKey } from "./text-helpers.js";
33
- import type {
34
- StageControlHandle,
35
- StageControlRegistry,
36
- } from "../runs/foreground/stage-control-registry.js";
29
+ import type { StageControlHandle, StageControlRegistry } from "../runs/foreground/stage-control-registry.js";
37
30
  import type { StageUiBroker } from "../shared/stage-ui-broker.js";
38
31
  import type { StageSnapshot, StoreSnapshot } from "../shared/store-types.js";
39
32
  import { expandWorkflowGraph } from "../shared/expanded-workflow-graph.js";
@@ -68,6 +61,8 @@ export class WorkflowAttachPane implements Component {
68
61
  private piKeybindings?: unknown;
69
62
  private piEditorFactory?: (tui: TUI, theme: EditorTheme, keybindings: unknown) => EditorComponent;
70
63
  private getChatRenderSettings?: () => Partial<Omit<ChatMessageRenderOptions, "ui" | "cwd">> | undefined;
64
+ private getToolsExpanded?: () => boolean;
65
+ private setToolsExpanded?: (expanded: boolean) => void;
71
66
  private footerData?: ReadonlyFooterDataProvider;
72
67
  private now: () => number;
73
68
  private mode: WorkflowAttachPaneMode = "graph";
@@ -104,6 +99,8 @@ export class WorkflowAttachPane implements Component {
104
99
  this.piKeybindings = opts.piKeybindings;
105
100
  this.piEditorFactory = opts.piEditorFactory;
106
101
  this.getChatRenderSettings = opts.getChatRenderSettings;
102
+ this.getToolsExpanded = opts.getToolsExpanded;
103
+ this.setToolsExpanded = opts.setToolsExpanded;
107
104
  this.footerData = opts.footerData;
108
105
  this.now = opts.now ?? Date.now;
109
106
  this.unsubscribeStore = this.store.subscribe((snapshot) => this._handleStoreUpdate(snapshot));
@@ -197,6 +194,8 @@ export class WorkflowAttachPane implements Component {
197
194
  piKeybindings: this.piKeybindings,
198
195
  piEditorFactory: this.piEditorFactory,
199
196
  getChatRenderSettings: this.getChatRenderSettings,
197
+ getToolsExpanded: this.getToolsExpanded,
198
+ setToolsExpanded: this.setToolsExpanded,
200
199
  footerData: this.footerData,
201
200
  getViewportRows: this.getViewportRows,
202
201
  stageUiBroker: this.stageUiBroker,
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { APP_NAME } from \"../config.ts\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.ts\";\n\nrestoreSandboxEnv();\n\nawait import(\"./register-bedrock.ts\");\nawait import(\"../cli.ts\");\n"]}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { APP_NAME } from \"../config.ts\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.ts\";\n\nrestoreSandboxEnv();\n\n// No top-level await: the compiled binary is built with --bytecode (CJS),\n// which forbids TLA anywhere in the bundled graph.\nvoid import(\"./register-bedrock.ts\").then(() => import(\"../cli.ts\"));\n"]}
package/dist/bun/cli.js CHANGED
@@ -4,6 +4,7 @@ process.title = APP_NAME;
4
4
  process.emitWarning = (() => { });
5
5
  import { restoreSandboxEnv } from "./restore-sandbox-env.js";
6
6
  restoreSandboxEnv();
7
- await import("./register-bedrock.js");
8
- await import("../cli.js");
7
+ // No top-level await: the compiled binary is built with --bytecode (CJS),
8
+ // which forbids TLA anywhere in the bundled graph.
9
+ void import("./register-bedrock.js").then(() => import("../cli.js"));
9
10
  //# sourceMappingURL=cli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;AACzB,OAAO,CAAC,WAAW,GAAG,CAAC,GAAG,EAAE,GAAE,CAAC,CAA+B,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,iBAAiB,EAAE,CAAC;AAEpB,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;AACtC,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { APP_NAME } from \"../config.ts\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.ts\";\n\nrestoreSandboxEnv();\n\nawait import(\"./register-bedrock.ts\");\nawait import(\"../cli.ts\");\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;AACzB,OAAO,CAAC,WAAW,GAAG,CAAC,GAAG,EAAE,GAAE,CAAC,CAA+B,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,iBAAiB,EAAE,CAAC;AAEpB,0EAA0E;AAC1E,mDAAmD;AACnD,KAAK,MAAM,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { APP_NAME } from \"../config.ts\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.ts\";\n\nrestoreSandboxEnv();\n\n// No top-level await: the compiled binary is built with --bytecode (CJS),\n// which forbids TLA anywhere in the bundled graph.\nvoid import(\"./register-bedrock.ts\").then(() => import(\"../cli.ts\"));\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"file-processor.d.ts","sourceRoot":"","sources":["../../src/cli/file-processor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAOjE,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAClC,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,sEAAsE;AACtE,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CA2EpH","sourcesContent":["/**\n * Process @file CLI arguments into text content and image attachments\n */\n\nimport { access, readFile, stat } from \"node:fs/promises\";\nimport type { ImageContent } from \"@earendil-works/pi-ai/compat\";\nimport chalk from \"chalk\";\nimport { resolve } from \"path\";\nimport { resolveReadPath } from \"../core/tools/path-utils.ts\";\nimport { formatDimensionNote, resizeImage } from \"../utils/image-resize.ts\";\nimport { detectSupportedImageMimeTypeFromFile } from \"../utils/mime.ts\";\n\nexport interface ProcessedFiles {\n\ttext: string;\n\timages: ImageContent[];\n}\n\nexport interface ProcessFileOptions {\n\t/** Whether to auto-resize images to 2000x2000 max. Default: true */\n\tautoResizeImages?: boolean;\n}\n\n/** Process @file arguments into text content and image attachments */\nexport async function processFileArguments(fileArgs: string[], options?: ProcessFileOptions): Promise<ProcessedFiles> {\n\tconst autoResizeImages = options?.autoResizeImages ?? true;\n\tlet text = \"\";\n\tconst images: ImageContent[] = [];\n\n\tfor (const fileArg of fileArgs) {\n\t\t// Expand and resolve path (handles ~ expansion and macOS screenshot Unicode spaces)\n\t\tconst absolutePath = resolve(resolveReadPath(fileArg, process.cwd()));\n\n\t\t// Check if file exists\n\t\ttry {\n\t\t\tawait access(absolutePath);\n\t\t} catch {\n\t\t\tconsole.error(chalk.red(`Error: File not found: ${absolutePath}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Check if file is empty\n\t\tconst stats = await stat(absolutePath);\n\t\tif (stats.size === 0) {\n\t\t\t// Skip empty files\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst mimeType = await detectSupportedImageMimeTypeFromFile(absolutePath);\n\n\t\tif (mimeType) {\n\t\t\t// Handle image file\n\t\t\tconst content = await readFile(absolutePath);\n\n\t\t\tlet attachment: ImageContent;\n\t\t\tlet dimensionNote: string | undefined;\n\n\t\t\tif (autoResizeImages) {\n\t\t\t\tconst resized = await resizeImage(content, mimeType);\n\t\t\t\tif (!resized) {\n\t\t\t\t\ttext += `<file name=\"${absolutePath}\">[Image omitted: could not be resized below the inline image size limit.]</file>\\n`;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tdimensionNote = formatDimensionNote(resized);\n\t\t\t\tattachment = {\n\t\t\t\t\ttype: \"image\",\n\t\t\t\t\tmimeType: resized.mimeType,\n\t\t\t\t\tdata: resized.data,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tattachment = {\n\t\t\t\t\ttype: \"image\",\n\t\t\t\t\tmimeType,\n\t\t\t\t\tdata: content.toString(\"base64\"),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\timages.push(attachment);\n\n\t\t\t// Add text reference to image with optional dimension note\n\t\t\tif (dimensionNote) {\n\t\t\t\ttext += `<file name=\"${absolutePath}\">${dimensionNote}</file>\\n`;\n\t\t\t} else {\n\t\t\t\ttext += `<file name=\"${absolutePath}\"></file>\\n`;\n\t\t\t}\n\t\t} else {\n\t\t\t// Handle text file\n\t\t\ttry {\n\t\t\t\tconst content = await readFile(absolutePath, \"utf-8\");\n\t\t\t\ttext += `<file name=\"${absolutePath}\">\\n${content}\\n</file>\\n`;\n\t\t\t} catch (error: unknown) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tconsole.error(chalk.red(`Error: Could not read file ${absolutePath}: ${message}`));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { text, images };\n}\n"]}
1
+ {"version":3,"file":"file-processor.d.ts","sourceRoot":"","sources":["../../src/cli/file-processor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAOjE,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAClC,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,sEAAsE;AACtE,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CA+DpH","sourcesContent":["/**\n * Process @file CLI arguments into text content and image attachments\n */\n\nimport { access, readFile, stat } from \"node:fs/promises\";\nimport type { ImageContent } from \"@earendil-works/pi-ai/compat\";\nimport chalk from \"chalk\";\nimport { resolve } from \"path\";\nimport { resolveReadPath } from \"../core/tools/path-utils.ts\";\nimport { processImage } from \"../utils/image-process.ts\";\nimport { detectSupportedImageMimeTypeFromFile } from \"../utils/mime.ts\";\n\nexport interface ProcessedFiles {\n\ttext: string;\n\timages: ImageContent[];\n}\n\nexport interface ProcessFileOptions {\n\t/** Whether to auto-resize images to 2000x2000 max. Default: true */\n\tautoResizeImages?: boolean;\n}\n\n/** Process @file arguments into text content and image attachments */\nexport async function processFileArguments(fileArgs: string[], options?: ProcessFileOptions): Promise<ProcessedFiles> {\n\tconst autoResizeImages = options?.autoResizeImages ?? true;\n\tlet text = \"\";\n\tconst images: ImageContent[] = [];\n\n\tfor (const fileArg of fileArgs) {\n\t\t// Expand and resolve path (handles ~ expansion and macOS screenshot Unicode spaces)\n\t\tconst absolutePath = resolve(resolveReadPath(fileArg, process.cwd()));\n\n\t\t// Check if file exists\n\t\ttry {\n\t\t\tawait access(absolutePath);\n\t\t} catch {\n\t\t\tconsole.error(chalk.red(`Error: File not found: ${absolutePath}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Check if file is empty\n\t\tconst stats = await stat(absolutePath);\n\t\tif (stats.size === 0) {\n\t\t\t// Skip empty files\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst mimeType = await detectSupportedImageMimeTypeFromFile(absolutePath);\n\n\t\tif (mimeType) {\n\t\t\t// Handle image file\n\t\t\tconst content = await readFile(absolutePath);\n\t\t\tconst processed = await processImage(content, mimeType, { autoResizeImages });\n\n\t\t\tif (!processed.ok) {\n\t\t\t\ttext += `<file name=\"${absolutePath}\">${processed.message}</file>\\n`;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst attachment: ImageContent = {\n\t\t\t\ttype: \"image\",\n\t\t\t\tmimeType: processed.mimeType,\n\t\t\t\tdata: processed.data,\n\t\t\t};\n\t\t\timages.push(attachment);\n\n\t\t\t// Add text reference to image with optional processing hints\n\t\t\tif (processed.hints.length > 0) {\n\t\t\t\ttext += `<file name=\"${absolutePath}\">${processed.hints.join(\"\\n\")}</file>\\n`;\n\t\t\t} else {\n\t\t\t\ttext += `<file name=\"${absolutePath}\"></file>\\n`;\n\t\t\t}\n\t\t} else {\n\t\t\t// Handle text file\n\t\t\ttry {\n\t\t\t\tconst content = await readFile(absolutePath, \"utf-8\");\n\t\t\t\ttext += `<file name=\"${absolutePath}\">\\n${content}\\n</file>\\n`;\n\t\t\t} catch (error: unknown) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tconsole.error(chalk.red(`Error: Could not read file ${absolutePath}: ${message}`));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { text, images };\n}\n"]}
@@ -5,7 +5,7 @@ import { access, readFile, stat } from "node:fs/promises";
5
5
  import chalk from "chalk";
6
6
  import { resolve } from "path";
7
7
  import { resolveReadPath } from "../core/tools/path-utils.js";
8
- import { formatDimensionNote, resizeImage } from "../utils/image-resize.js";
8
+ import { processImage } from "../utils/image-process.js";
9
9
  import { detectSupportedImageMimeTypeFromFile } from "../utils/mime.js";
10
10
  /** Process @file arguments into text content and image attachments */
11
11
  export async function processFileArguments(fileArgs, options) {
@@ -33,32 +33,20 @@ export async function processFileArguments(fileArgs, options) {
33
33
  if (mimeType) {
34
34
  // Handle image file
35
35
  const content = await readFile(absolutePath);
36
- let attachment;
37
- let dimensionNote;
38
- if (autoResizeImages) {
39
- const resized = await resizeImage(content, mimeType);
40
- if (!resized) {
41
- text += `<file name="${absolutePath}">[Image omitted: could not be resized below the inline image size limit.]</file>\n`;
42
- continue;
43
- }
44
- dimensionNote = formatDimensionNote(resized);
45
- attachment = {
46
- type: "image",
47
- mimeType: resized.mimeType,
48
- data: resized.data,
49
- };
50
- }
51
- else {
52
- attachment = {
53
- type: "image",
54
- mimeType,
55
- data: content.toString("base64"),
56
- };
36
+ const processed = await processImage(content, mimeType, { autoResizeImages });
37
+ if (!processed.ok) {
38
+ text += `<file name="${absolutePath}">${processed.message}</file>\n`;
39
+ continue;
57
40
  }
41
+ const attachment = {
42
+ type: "image",
43
+ mimeType: processed.mimeType,
44
+ data: processed.data,
45
+ };
58
46
  images.push(attachment);
59
- // Add text reference to image with optional dimension note
60
- if (dimensionNote) {
61
- text += `<file name="${absolutePath}">${dimensionNote}</file>\n`;
47
+ // Add text reference to image with optional processing hints
48
+ if (processed.hints.length > 0) {
49
+ text += `<file name="${absolutePath}">${processed.hints.join("\n")}</file>\n`;
62
50
  }
63
51
  else {
64
52
  text += `<file name="${absolutePath}"></file>\n`;