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

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 (296) hide show
  1. package/CHANGELOG.md +102 -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 +45 -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/web-access/CHANGELOG.md +24 -0
  43. package/dist/builtin/web-access/package.json +2 -2
  44. package/dist/builtin/workflows/CHANGELOG.md +48 -0
  45. package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +24 -22
  46. package/dist/builtin/workflows/builtin/goal-runner.ts +12 -23
  47. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +4 -4
  48. package/dist/builtin/workflows/builtin/ralph-models.ts +53 -75
  49. package/dist/builtin/workflows/package.json +2 -2
  50. package/dist/builtin/workflows/src/runs/shared/model-fallback-failures.ts +59 -1
  51. package/dist/bun/cli.d.ts.map +1 -1
  52. package/dist/bun/cli.js +3 -2
  53. package/dist/bun/cli.js.map +1 -1
  54. package/dist/cli/file-processor.d.ts.map +1 -1
  55. package/dist/cli/file-processor.js +13 -25
  56. package/dist/cli/file-processor.js.map +1 -1
  57. package/dist/cli.d.ts.map +1 -1
  58. package/dist/cli.js +15 -5
  59. package/dist/cli.js.map +1 -1
  60. package/dist/config.d.ts +10 -3
  61. package/dist/config.d.ts.map +1 -1
  62. package/dist/config.js +18 -1
  63. package/dist/config.js.map +1 -1
  64. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  65. package/dist/core/agent-session-auto-compaction.js +8 -1
  66. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  67. package/dist/core/agent-session-events.d.ts.map +1 -1
  68. package/dist/core/agent-session-events.js +14 -8
  69. package/dist/core/agent-session-events.js.map +1 -1
  70. package/dist/core/agent-session-export.d.ts.map +1 -1
  71. package/dist/core/agent-session-export.js +4 -2
  72. package/dist/core/agent-session-export.js.map +1 -1
  73. package/dist/core/agent-session-extension-bindings.d.ts +5 -1
  74. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  75. package/dist/core/agent-session-extension-bindings.js +18 -7
  76. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  77. package/dist/core/agent-session-methods.d.ts +9 -2
  78. package/dist/core/agent-session-methods.d.ts.map +1 -1
  79. package/dist/core/agent-session-methods.js.map +1 -1
  80. package/dist/core/agent-session-prompt.d.ts +2 -0
  81. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  82. package/dist/core/agent-session-prompt.js +15 -2
  83. package/dist/core/agent-session-prompt.js.map +1 -1
  84. package/dist/core/agent-session-retry.d.ts +2 -0
  85. package/dist/core/agent-session-retry.d.ts.map +1 -1
  86. package/dist/core/agent-session-retry.js +66 -7
  87. package/dist/core/agent-session-retry.js.map +1 -1
  88. package/dist/core/agent-session-state.d.ts.map +1 -1
  89. package/dist/core/agent-session-state.js +2 -2
  90. package/dist/core/agent-session-state.js.map +1 -1
  91. package/dist/core/agent-session-tool-hooks.d.ts +7 -1
  92. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  93. package/dist/core/agent-session-tool-hooks.js +26 -4
  94. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  95. package/dist/core/agent-session-tree.d.ts.map +1 -1
  96. package/dist/core/agent-session-tree.js +3 -1
  97. package/dist/core/agent-session-tree.js.map +1 -1
  98. package/dist/core/agent-session-types.d.ts +4 -0
  99. package/dist/core/agent-session-types.d.ts.map +1 -1
  100. package/dist/core/agent-session-types.js.map +1 -1
  101. package/dist/core/agent-session.d.ts +1 -0
  102. package/dist/core/agent-session.d.ts.map +1 -1
  103. package/dist/core/agent-session.js +1 -0
  104. package/dist/core/agent-session.js.map +1 -1
  105. package/dist/core/copilot-model-catalog.d.ts +38 -74
  106. package/dist/core/copilot-model-catalog.d.ts.map +1 -1
  107. package/dist/core/copilot-model-catalog.js +177 -68
  108. package/dist/core/copilot-model-catalog.js.map +1 -1
  109. package/dist/core/copilot-model-static-fallbacks.d.ts +43 -0
  110. package/dist/core/copilot-model-static-fallbacks.d.ts.map +1 -0
  111. package/dist/core/copilot-model-static-fallbacks.js +50 -0
  112. package/dist/core/copilot-model-static-fallbacks.js.map +1 -0
  113. package/dist/core/copilot-model-synthesis.d.ts +10 -0
  114. package/dist/core/copilot-model-synthesis.d.ts.map +1 -0
  115. package/dist/core/copilot-model-synthesis.js +89 -0
  116. package/dist/core/copilot-model-synthesis.js.map +1 -0
  117. package/dist/core/extensions/api-types.d.ts +2 -1
  118. package/dist/core/extensions/api-types.d.ts.map +1 -1
  119. package/dist/core/extensions/api-types.js.map +1 -1
  120. package/dist/core/extensions/index.d.ts +1 -1
  121. package/dist/core/extensions/index.d.ts.map +1 -1
  122. package/dist/core/extensions/index.js.map +1 -1
  123. package/dist/core/extensions/loader-core.d.ts.map +1 -1
  124. package/dist/core/extensions/loader-core.js +3 -3
  125. package/dist/core/extensions/loader-core.js.map +1 -1
  126. package/dist/core/extensions/loader-virtual-modules.d.ts +11 -0
  127. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  128. package/dist/core/extensions/loader-virtual-modules.js +79 -11
  129. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  130. package/dist/core/extensions/session-events.d.ts +7 -1
  131. package/dist/core/extensions/session-events.d.ts.map +1 -1
  132. package/dist/core/extensions/session-events.js.map +1 -1
  133. package/dist/core/http-dispatcher.d.ts +2 -0
  134. package/dist/core/http-dispatcher.d.ts.map +1 -1
  135. package/dist/core/http-dispatcher.js +38 -5
  136. package/dist/core/http-dispatcher.js.map +1 -1
  137. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  138. package/dist/core/model-registry-builtins.js +40 -6
  139. package/dist/core/model-registry-builtins.js.map +1 -1
  140. package/dist/core/model-registry.d.ts.map +1 -1
  141. package/dist/core/model-registry.js +4 -3
  142. package/dist/core/model-registry.js.map +1 -1
  143. package/dist/core/model-resolver-defaults.d.ts.map +1 -1
  144. package/dist/core/model-resolver-defaults.js +1 -1
  145. package/dist/core/model-resolver-defaults.js.map +1 -1
  146. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  147. package/dist/core/resource-loader-reload.js +6 -3
  148. package/dist/core/resource-loader-reload.js.map +1 -1
  149. package/dist/core/resource-loader-types.d.ts +6 -0
  150. package/dist/core/resource-loader-types.d.ts.map +1 -1
  151. package/dist/core/resource-loader-types.js.map +1 -1
  152. package/dist/core/session-manager-core.d.ts +2 -12
  153. package/dist/core/session-manager-core.d.ts.map +1 -1
  154. package/dist/core/session-manager-core.js +8 -16
  155. package/dist/core/session-manager-core.js.map +1 -1
  156. package/dist/core/settings-manager-resource-accessors.d.ts +1 -0
  157. package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
  158. package/dist/core/settings-manager-resource-accessors.js +11 -0
  159. package/dist/core/settings-manager-resource-accessors.js.map +1 -1
  160. package/dist/core/settings-manager-ui-accessors.d.ts +2 -0
  161. package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
  162. package/dist/core/settings-manager-ui-accessors.js +9 -0
  163. package/dist/core/settings-manager-ui-accessors.js.map +1 -1
  164. package/dist/core/settings-types.d.ts +2 -0
  165. package/dist/core/settings-types.d.ts.map +1 -1
  166. package/dist/core/settings-types.js.map +1 -1
  167. package/dist/core/timings.d.ts +7 -5
  168. package/dist/core/timings.d.ts.map +1 -1
  169. package/dist/core/timings.js +42 -24
  170. package/dist/core/timings.js.map +1 -1
  171. package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
  172. package/dist/core/tools/bash-pty-native.js +2 -2
  173. package/dist/core/tools/bash-pty-native.js.map +1 -1
  174. package/dist/core/tools/read-selectors.d.ts.map +1 -1
  175. package/dist/core/tools/read-selectors.js +19 -1
  176. package/dist/core/tools/read-selectors.js.map +1 -1
  177. package/dist/core/tools/read.d.ts.map +1 -1
  178. package/dist/core/tools/read.js +12 -23
  179. package/dist/core/tools/read.js.map +1 -1
  180. package/dist/core/tools/search-native.d.ts.map +1 -1
  181. package/dist/core/tools/search-native.js +2 -2
  182. package/dist/core/tools/search-native.js.map +1 -1
  183. package/dist/index-extensions.d.ts +1 -1
  184. package/dist/index-extensions.d.ts.map +1 -1
  185. package/dist/index-extensions.js.map +1 -1
  186. package/dist/index.d.ts +1 -1
  187. package/dist/index.d.ts.map +1 -1
  188. package/dist/index.js.map +1 -1
  189. package/dist/main-session.d.ts.map +1 -1
  190. package/dist/main-session.js +14 -5
  191. package/dist/main-session.js.map +1 -1
  192. package/dist/main.d.ts.map +1 -1
  193. package/dist/main.js +56 -32
  194. package/dist/main.js.map +1 -1
  195. package/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  196. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  197. package/dist/modes/interactive/components/assistant-message.js +22 -15
  198. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  199. package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -0
  200. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  201. package/dist/modes/interactive/components/chat-message-renderer.js +5 -5
  202. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  203. package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
  204. package/dist/modes/interactive/components/chat-session-host-events.js +8 -0
  205. package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
  206. package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
  207. package/dist/modes/interactive/components/chat-session-host-rendering.js +1 -0
  208. package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
  209. package/dist/modes/interactive/components/user-message.d.ts +6 -2
  210. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  211. package/dist/modes/interactive/components/user-message.js +16 -5
  212. package/dist/modes/interactive/components/user-message.js.map +1 -1
  213. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  214. package/dist/modes/interactive/interactive-agent-events.js +6 -1
  215. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  216. package/dist/modes/interactive/interactive-deferred-startup.d.ts +2 -0
  217. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -0
  218. package/dist/modes/interactive/interactive-deferred-startup.js +59 -0
  219. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -0
  220. package/dist/modes/interactive/interactive-editor-actions.d.ts.map +1 -1
  221. package/dist/modes/interactive/interactive-editor-actions.js +1 -0
  222. package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
  223. package/dist/modes/interactive/interactive-extension-context.d.ts.map +1 -1
  224. package/dist/modes/interactive/interactive-extension-context.js +1 -0
  225. package/dist/modes/interactive/interactive-extension-context.js.map +1 -1
  226. package/dist/modes/interactive/interactive-mode-base.d.ts +3 -0
  227. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  228. package/dist/modes/interactive/interactive-mode-base.js +6 -0
  229. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  230. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  231. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  232. package/dist/modes/interactive/interactive-mode-deps.js +1 -1
  233. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  234. package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -0
  235. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  236. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  237. package/dist/modes/interactive/interactive-mode-types.d.ts +2 -0
  238. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  239. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  240. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  241. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  242. package/dist/modes/interactive/interactive-mode.js +1 -0
  243. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  244. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  245. package/dist/modes/interactive/interactive-model-routing.js +2 -4
  246. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  247. package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
  248. package/dist/modes/interactive/interactive-render-chat.js +4 -3
  249. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  250. package/dist/modes/interactive/interactive-session-runtime.d.ts.map +1 -1
  251. package/dist/modes/interactive/interactive-session-runtime.js +5 -2
  252. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  253. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  254. package/dist/modes/interactive/interactive-startup.js +11 -1
  255. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  256. package/dist/modes/rpc/rpc-client.d.ts +28 -51
  257. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  258. package/dist/modes/rpc/rpc-client.js +27 -51
  259. package/dist/modes/rpc/rpc-client.js.map +1 -1
  260. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  261. package/dist/modes/rpc/rpc-command-handler.js +19 -0
  262. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  263. package/dist/modes/rpc/rpc-types.d.ts +26 -0
  264. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  265. package/dist/modes/rpc/rpc-types.js.map +1 -1
  266. package/dist/rpc-entry.d.ts +3 -0
  267. package/dist/rpc-entry.d.ts.map +1 -0
  268. package/dist/rpc-entry.js +12 -0
  269. package/dist/rpc-entry.js.map +1 -0
  270. package/dist/utils/image-convert.d.ts +1 -0
  271. package/dist/utils/image-convert.d.ts.map +1 -1
  272. package/dist/utils/image-convert.js +21 -15
  273. package/dist/utils/image-convert.js.map +1 -1
  274. package/dist/utils/image-process.d.ts +18 -0
  275. package/dist/utils/image-process.d.ts.map +1 -0
  276. package/dist/utils/image-process.js +83 -0
  277. package/dist/utils/image-process.js.map +1 -0
  278. package/dist/utils/mime.d.ts.map +1 -1
  279. package/dist/utils/mime.js +41 -0
  280. package/dist/utils/mime.js.map +1 -1
  281. package/dist/utils/module-require.d.ts +11 -0
  282. package/dist/utils/module-require.d.ts.map +1 -0
  283. package/dist/utils/module-require.js +16 -0
  284. package/dist/utils/module-require.js.map +1 -0
  285. package/docs/compaction.md +2 -0
  286. package/docs/development.md +10 -0
  287. package/docs/extensions.md +11 -0
  288. package/docs/models.md +3 -3
  289. package/docs/providers.md +2 -1
  290. package/docs/rpc.md +60 -2
  291. package/docs/sdk.md +1 -1
  292. package/docs/settings.md +4 -1
  293. package/docs/subagents.md +6 -0
  294. package/docs/workflows.md +4 -2
  295. package/npm-shrinkwrap.json +138 -171
  296. 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.10",
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);
@@ -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`;
@@ -1 +1 @@
1
- {"version":3,"file":"file-processor.js","sourceRoot":"","sources":["../../src/cli/file-processor.ts"],"names":[],"mappings":"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","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.js","sourceRoot":"","sources":["../../src/cli/file-processor.ts"],"names":[],"mappings":"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","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"]}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point for the refactored coding agent.\n * Uses main.ts with AgentSession and new mode modules.\n *\n * Test with: npx tsx src/cli-new.ts [args...]\n */\nimport { configureHttpDispatcher } from \"./core/http-dispatcher.ts\";\nimport { APP_NAME } from \"./config.ts\";\nimport { main } from \"./main.ts\";\n\nprocess.title = APP_NAME;\nprocess.env[`${APP_NAME.toUpperCase()}_CODING_AGENT`] = \"true\";\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nconfigureHttpDispatcher();\n\nmain(process.argv.slice(2));\n"]}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point for the refactored coding agent.\n * Uses main.ts with AgentSession and new mode modules.\n *\n * Test with: npx tsx src/cli-new.ts [args...]\n *\n * Deliberately imports only config.ts statically: the full CLI module graph is\n * loaded dynamically so metadata fast paths (e.g. --version) skip it entirely.\n */\nimport { APP_NAME, VERSION } from \"./config.ts\";\n\nprocess.title = APP_NAME;\nprocess.env[`${APP_NAME.toUpperCase()}_CODING_AGENT`] = \"true\";\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nconst args = process.argv.slice(2);\n\nif (args[0] === \"--version\" || args[0] === \"-v\") {\n\tconsole.log(VERSION);\n\tprocess.exit(0);\n}\n\n// No top-level await: the compiled binary is built with --bytecode (CJS),\n// which forbids TLA anywhere in the bundled graph.\nvoid Promise.all([import(\"./core/http-dispatcher.ts\"), import(\"./main.ts\")]).then(\n\t([{ configureHttpDispatcher }, { main }]) => {\n\t\tconfigureHttpDispatcher();\n\t\tmain(args);\n\t},\n);\n"]}
package/dist/cli.js CHANGED
@@ -4,13 +4,23 @@
4
4
  * Uses main.ts with AgentSession and new mode modules.
5
5
  *
6
6
  * Test with: npx tsx src/cli-new.ts [args...]
7
+ *
8
+ * Deliberately imports only config.ts statically: the full CLI module graph is
9
+ * loaded dynamically so metadata fast paths (e.g. --version) skip it entirely.
7
10
  */
8
- import { configureHttpDispatcher } from "./core/http-dispatcher.js";
9
- import { APP_NAME } from "./config.js";
10
- import { main } from "./main.js";
11
+ import { APP_NAME, VERSION } from "./config.js";
11
12
  process.title = APP_NAME;
12
13
  process.env[`${APP_NAME.toUpperCase()}_CODING_AGENT`] = "true";
13
14
  process.emitWarning = (() => { });
14
- configureHttpDispatcher();
15
- main(process.argv.slice(2));
15
+ const args = process.argv.slice(2);
16
+ if (args[0] === "--version" || args[0] === "-v") {
17
+ console.log(VERSION);
18
+ process.exit(0);
19
+ }
20
+ // No top-level await: the compiled binary is built with --bytecode (CJS),
21
+ // which forbids TLA anywhere in the bundled graph.
22
+ void Promise.all([import("./core/http-dispatcher.js"), import("./main.js")]).then(([{ configureHttpDispatcher }, { main }]) => {
23
+ configureHttpDispatcher();
24
+ main(args);
25
+ });
16
26
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;AACzB,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC,GAAG,MAAM,CAAC;AAC/D,OAAO,CAAC,WAAW,GAAG,CAAC,GAAG,EAAE,GAAE,CAAC,CAA+B,CAAC;AAE/D,uBAAuB,EAAE,CAAC;AAE1B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point for the refactored coding agent.\n * Uses main.ts with AgentSession and new mode modules.\n *\n * Test with: npx tsx src/cli-new.ts [args...]\n */\nimport { configureHttpDispatcher } from \"./core/http-dispatcher.ts\";\nimport { APP_NAME } from \"./config.ts\";\nimport { main } from \"./main.ts\";\n\nprocess.title = APP_NAME;\nprocess.env[`${APP_NAME.toUpperCase()}_CODING_AGENT`] = \"true\";\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nconfigureHttpDispatcher();\n\nmain(process.argv.slice(2));\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;AACzB,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC,GAAG,MAAM,CAAC;AAC/D,OAAO,CAAC,WAAW,GAAG,CAAC,GAAG,EAAE,GAAE,CAAC,CAA+B,CAAC;AAE/D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,0EAA0E;AAC1E,mDAAmD;AACnD,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,2BAA2B,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAChF,CAAC,CAAC,EAAE,uBAAuB,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE;IAC3C,uBAAuB,EAAE,CAAC;IAC1B,IAAI,CAAC,IAAI,CAAC,CAAC;AACZ,CAAC,CACD,CAAC","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point for the refactored coding agent.\n * Uses main.ts with AgentSession and new mode modules.\n *\n * Test with: npx tsx src/cli-new.ts [args...]\n *\n * Deliberately imports only config.ts statically: the full CLI module graph is\n * loaded dynamically so metadata fast paths (e.g. --version) skip it entirely.\n */\nimport { APP_NAME, VERSION } from \"./config.ts\";\n\nprocess.title = APP_NAME;\nprocess.env[`${APP_NAME.toUpperCase()}_CODING_AGENT`] = \"true\";\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nconst args = process.argv.slice(2);\n\nif (args[0] === \"--version\" || args[0] === \"-v\") {\n\tconsole.log(VERSION);\n\tprocess.exit(0);\n}\n\n// No top-level await: the compiled binary is built with --bytecode (CJS),\n// which forbids TLA anywhere in the bundled graph.\nvoid Promise.all([import(\"./core/http-dispatcher.ts\"), import(\"./main.ts\")]).then(\n\t([{ configureHttpDispatcher }, { main }]) => {\n\t\tconfigureHttpDispatcher();\n\t\tmain(args);\n\t},\n);\n"]}
package/dist/config.d.ts CHANGED
@@ -1,8 +1,10 @@
1
+ export declare const isBunBinary: boolean;
1
2
  /**
2
- * Detect if we're running as a Bun compiled binary.
3
- * Bun binaries have import.meta.url containing "$bunfs", "~BUN", or "%7EBUN" (Bun's virtual filesystem path)
3
+ * Detect if we're running from a single-file bundle produced by `bun run bundle:dev`.
4
+ * The bundle build inlines this env var via `--define`, so it is a compile-time
5
+ * constant there and undefined everywhere else.
4
6
  */
5
- export declare const isBunBinary: boolean;
7
+ export declare const isBundledBuild: boolean;
6
8
  /** Detect if Bun is the runtime (compiled binary or bun run) */
7
9
  export declare const isBunRuntime: boolean;
8
10
  export type { InstallMethod, SelfUpdateCommand } from "./config-self-update.ts";
@@ -115,6 +117,11 @@ export declare function getSettingsPath(): string;
115
117
  export declare function getToolsDir(): string;
116
118
  /** Get path to managed binaries directory (fd, rg) */
117
119
  export declare function getBinDir(): string;
120
+ /**
121
+ * Get path to the extension transpile cache directory (jiti fsCache).
122
+ * Scoped by version so release upgrades never read stale transpiled output.
123
+ */
124
+ export declare function getExtensionTranspileCacheDir(): string;
118
125
  /** Get path to prompt templates directory */
119
126
  export declare function getPromptsDir(): string;
120
127
  /** Get path to sessions directory */