@bastani/atomic 0.9.12 → 0.9.13-alpha.2

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 (1187) hide show
  1. package/CHANGELOG.md +150 -0
  2. package/README.md +35 -17
  3. package/dist/builtin/i-have-adhd/CHANGELOG.md +17 -0
  4. package/dist/builtin/i-have-adhd/LICENSE +21 -0
  5. package/dist/builtin/i-have-adhd/README.md +18 -0
  6. package/dist/builtin/i-have-adhd/index.ts +238 -0
  7. package/dist/builtin/i-have-adhd/package.json +56 -0
  8. package/dist/builtin/i-have-adhd/skills/i-have-adhd/SKILL.md +140 -0
  9. package/dist/builtin/intercom/CHANGELOG.md +25 -0
  10. package/dist/builtin/intercom/README.md +30 -16
  11. package/dist/builtin/intercom/broker/bounded-stderr-install.ts +18 -0
  12. package/dist/builtin/intercom/broker/bounded-stderr.ts +132 -0
  13. package/dist/builtin/intercom/broker/broker.ts +12 -23
  14. package/dist/builtin/intercom/broker/client.ts +81 -5
  15. package/dist/builtin/intercom/broker/paths.ts +9 -0
  16. package/dist/builtin/intercom/broker/presence-handler.ts +103 -0
  17. package/dist/builtin/intercom/broker/spawn.ts +128 -29
  18. package/dist/builtin/intercom/contact-supervisor-tool.ts +13 -3
  19. package/dist/builtin/intercom/foreground-detach-handoff.ts +30 -14
  20. package/dist/builtin/intercom/group.ts +64 -25
  21. package/dist/builtin/intercom/index-heavy.ts +51 -8
  22. package/dist/builtin/intercom/index.ts +50 -22
  23. package/dist/builtin/intercom/intercom-tool.ts +82 -5
  24. package/dist/builtin/intercom/intercom-utils.ts +15 -29
  25. package/dist/builtin/intercom/lazy-subagent-ack.ts +11 -6
  26. package/dist/builtin/intercom/package.json +2 -3
  27. package/dist/builtin/intercom/runtime-group.ts +13 -0
  28. package/dist/builtin/intercom/skills/intercom/SKILL.md +30 -2
  29. package/dist/builtin/intercom/source-ownership.ts +9 -12
  30. package/dist/builtin/intercom/subagent-relay.ts +32 -16
  31. package/dist/builtin/intercom/terminal-ordering-barrier.ts +21 -4
  32. package/dist/builtin/intercom/types.ts +3 -1
  33. package/dist/builtin/intercom/ui/compose.ts +8 -6
  34. package/dist/builtin/intercom/ui/session-list.ts +7 -5
  35. package/dist/builtin/mcp/CHANGELOG.md +19 -0
  36. package/dist/builtin/mcp/README.md +3 -1
  37. package/dist/builtin/mcp/glimpse-ui.ts +2 -1
  38. package/dist/builtin/mcp/index.ts +10 -26
  39. package/dist/builtin/mcp/mcp-panel.ts +35 -34
  40. package/dist/builtin/mcp/mcp-setup-panel.ts +35 -33
  41. package/dist/builtin/mcp/npx-resolver.ts +3 -2
  42. package/dist/builtin/mcp/package.json +3 -3
  43. package/dist/builtin/mcp/sampling-handler.ts +5 -1
  44. package/dist/builtin/mcp/server-manager.ts +4 -7
  45. package/dist/builtin/mcp/startup-warmup.ts +20 -8
  46. package/dist/builtin/subagents/CHANGELOG.md +63 -0
  47. package/dist/builtin/subagents/README.md +144 -351
  48. package/dist/builtin/subagents/agents/worker.md +1 -1
  49. package/dist/builtin/subagents/package.json +5 -5
  50. package/dist/builtin/subagents/prompts/parallel-context-build.md +2 -2
  51. package/dist/builtin/subagents/prompts/parallel-handoff-plan.md +4 -4
  52. package/dist/builtin/subagents/prompts/review-loop.md +1 -1
  53. package/dist/builtin/subagents/skills/subagent/SKILL.md +39 -102
  54. package/dist/builtin/subagents/src/agents/agent-discovery.ts +1 -29
  55. package/dist/builtin/subagents/src/agents/agent-loaders.ts +1 -40
  56. package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +6 -135
  57. package/dist/builtin/subagents/src/agents/agent-management.ts +52 -282
  58. package/dist/builtin/subagents/src/agents/agent-paths.ts +0 -22
  59. package/dist/builtin/subagents/src/agents/agent-types.ts +0 -40
  60. package/dist/builtin/subagents/src/agents/agents.ts +0 -3
  61. package/dist/builtin/subagents/src/agents/identity.ts +2 -4
  62. package/dist/builtin/subagents/src/agents/skills-paths.ts +8 -1
  63. package/dist/builtin/subagents/src/extension/doctor.ts +4 -24
  64. package/dist/builtin/subagents/src/extension/fanout-child.ts +76 -56
  65. package/dist/builtin/subagents/src/extension/index.ts +32 -39
  66. package/dist/builtin/subagents/src/extension/prompt-guidance.ts +2 -2
  67. package/dist/builtin/subagents/src/extension/schemas.ts +1 -157
  68. package/dist/builtin/subagents/src/extension/startup-maintenance.ts +25 -46
  69. package/dist/builtin/subagents/src/extension/tool-description.ts +4 -13
  70. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +6 -2
  71. package/dist/builtin/subagents/src/intercom/result-intercom.ts +27 -29
  72. package/dist/builtin/subagents/src/intercom/supervisor-authorization.ts +9 -2
  73. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +248 -435
  74. package/dist/builtin/subagents/src/runs/background/completion-notification.ts +8 -3
  75. package/dist/builtin/subagents/src/runs/background/notify.ts +83 -26
  76. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +1 -281
  77. package/dist/builtin/subagents/src/runs/foreground/execution-updates.ts +0 -5
  78. package/dist/builtin/subagents/src/runs/foreground/execution.ts +1 -4
  79. package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +559 -0
  80. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +103 -259
  81. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +29 -31
  82. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +10 -173
  83. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +7 -5
  84. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +13 -6
  85. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +1 -646
  86. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-runtime.ts +2 -7
  87. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +14 -7
  88. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +39 -20
  89. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +16 -11
  90. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-worktree.ts +1 -14
  91. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +194 -104
  92. package/dist/builtin/subagents/src/runs/inprocess/background-single.ts +195 -0
  93. package/dist/builtin/subagents/src/runs/inprocess/background.ts +90 -0
  94. package/dist/builtin/subagents/src/runs/inprocess/child-policy.ts +27 -0
  95. package/dist/builtin/subagents/src/runs/inprocess/control-registry.ts +55 -0
  96. package/dist/builtin/subagents/src/runs/inprocess/control-status.ts +106 -0
  97. package/dist/builtin/subagents/src/runs/inprocess/index.ts +50 -0
  98. package/dist/builtin/subagents/src/runs/inprocess/nested-routing.ts +218 -0
  99. package/dist/builtin/subagents/src/runs/{shared/subagent-prompt-runtime.ts → inprocess/prompt-behavior.ts} +37 -75
  100. package/dist/builtin/subagents/src/runs/inprocess/runner.ts +1392 -0
  101. package/dist/builtin/subagents/src/runs/{shared/nested-events.ts → inprocess/runtime-support/nested-api.ts} +13 -7
  102. package/dist/builtin/subagents/src/runs/{shared/nested-events-control.ts → inprocess/runtime-support/nested-control.ts} +18 -17
  103. package/dist/builtin/subagents/src/runs/{shared/nested-events-core.ts → inprocess/runtime-support/nested-core.ts} +14 -61
  104. package/dist/builtin/subagents/src/runs/{shared/nested-events-projection.ts → inprocess/runtime-support/nested-projection.ts} +4 -12
  105. package/dist/builtin/subagents/src/runs/{shared/nested-events-registry.ts → inprocess/runtime-support/nested-registry.ts} +19 -4
  106. package/dist/builtin/subagents/src/runs/{shared/nested-render.ts → inprocess/runtime-support/nested-rendering.ts} +3 -3
  107. package/dist/builtin/subagents/src/runs/{shared/nested-events-sanitize.ts → inprocess/runtime-support/nested-sanitize.ts} +4 -6
  108. package/dist/builtin/subagents/src/runs/inprocess.ts +1 -0
  109. package/dist/builtin/subagents/src/runs/shared/intercom-group.ts +23 -7
  110. package/dist/builtin/subagents/src/runs/shared/model-candidate-filter.ts +0 -1
  111. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +15 -492
  112. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +13 -97
  113. package/dist/builtin/subagents/src/runs/shared/run-history.ts +3 -5
  114. package/dist/builtin/subagents/src/runs/shared/single-output.ts +4 -4
  115. package/dist/builtin/subagents/src/runs/shared/worktree.ts +7 -2
  116. package/dist/builtin/subagents/src/shared/formatters.ts +2 -56
  117. package/dist/builtin/subagents/src/shared/settings.ts +14 -350
  118. package/dist/builtin/subagents/src/shared/types-async.ts +8 -32
  119. package/dist/builtin/subagents/src/shared/types-config.ts +29 -13
  120. package/dist/builtin/subagents/src/shared/types-depth.ts +30 -56
  121. package/dist/builtin/subagents/src/shared/types-results.ts +18 -60
  122. package/dist/builtin/subagents/src/shared/types-runtime.ts +0 -1
  123. package/dist/builtin/subagents/src/shared/utils.ts +5 -0
  124. package/dist/builtin/subagents/src/slash/bridge-settlement.ts +87 -0
  125. package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +49 -10
  126. package/dist/builtin/subagents/src/slash/slash-bridge.ts +27 -7
  127. package/dist/builtin/subagents/src/slash/slash-commands.ts +37 -82
  128. package/dist/builtin/subagents/src/slash/slash-live-state.ts +3 -94
  129. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +3 -35
  130. package/dist/builtin/subagents/src/tui/render-progress.ts +89 -0
  131. package/dist/builtin/subagents/src/tui/render-result-compact.ts +77 -68
  132. package/dist/builtin/subagents/src/tui/render-result.ts +79 -99
  133. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -6
  134. package/dist/builtin/subagents/src/tui/render-status-progress.ts +8 -5
  135. package/dist/builtin/subagents/src/tui/render-widget-graph.ts +6 -63
  136. package/dist/builtin/subagents/src/tui/render-widget.ts +0 -24
  137. package/dist/builtin/web-access/CHANGELOG.md +14 -0
  138. package/dist/builtin/web-access/chrome-cookies.ts +3 -2
  139. package/dist/builtin/web-access/github-api.ts +7 -6
  140. package/dist/builtin/web-access/github-extract.ts +2 -1
  141. package/dist/builtin/web-access/package.json +3 -3
  142. package/dist/builtin/web-access/subprocess.ts +3 -1
  143. package/dist/builtin/web-access/summary-review.ts +2 -2
  144. package/dist/builtin/web-access/web-search-features.ts +38 -22
  145. package/dist/builtin/web-access/web-search-summary.ts +2 -2
  146. package/dist/builtin/workflows/CHANGELOG.md +70 -0
  147. package/dist/builtin/workflows/README.md +54 -4
  148. package/dist/builtin/workflows/builtin/open-claude-design-utils.ts +3 -0
  149. package/dist/builtin/workflows/builtin/ralph-models.ts +25 -20
  150. package/dist/builtin/workflows/builtin/shared-prompts.ts +5 -2
  151. package/dist/builtin/workflows/package.json +2 -2
  152. package/dist/builtin/workflows/src/durable/backend.ts +25 -1
  153. package/dist/builtin/workflows/src/durable/completed-catalog-stage-groups.ts +60 -3
  154. package/dist/builtin/workflows/src/durable/completed-catalog.ts +67 -1
  155. package/dist/builtin/workflows/src/durable/completed-subtree.ts +22 -7
  156. package/dist/builtin/workflows/src/durable/dbos-metadata.ts +15 -1
  157. package/dist/builtin/workflows/src/durable/local-command.ts +2 -1
  158. package/dist/builtin/workflows/src/durable/resume-runtime.ts +1 -0
  159. package/dist/builtin/workflows/src/durable/tool-primitive.ts +4 -28
  160. package/dist/builtin/workflows/src/durable/types.ts +22 -1
  161. package/dist/builtin/workflows/src/durable/workflow-child-result.ts +3 -1
  162. package/dist/builtin/workflows/src/engine/primitives/workflow.ts +1 -1
  163. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +10 -2
  164. package/dist/builtin/workflows/src/engine/run-durable-topology.ts +9 -2
  165. package/dist/builtin/workflows/src/engine/run.ts +17 -1
  166. package/dist/builtin/workflows/src/extension/atomic-stage-session.ts +18 -39
  167. package/dist/builtin/workflows/src/extension/companions.ts +1 -1
  168. package/dist/builtin/workflows/src/extension/config-file-loader.ts +10 -1
  169. package/dist/builtin/workflows/src/extension/config-loader.ts +1 -1
  170. package/dist/builtin/workflows/src/extension/dispatcher.ts +4 -0
  171. package/dist/builtin/workflows/src/extension/index.bundle.mjs +2095 -1181
  172. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +332 -39
  173. package/dist/builtin/workflows/src/extension/mcp.ts +13 -2
  174. package/dist/builtin/workflows/src/extension/render-result.ts +5 -0
  175. package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +6 -3
  176. package/dist/builtin/workflows/src/extension/runtime.ts +7 -1
  177. package/dist/builtin/workflows/src/extension/ui-surface.ts +7 -20
  178. package/dist/builtin/workflows/src/extension/wiring.ts +86 -17
  179. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +12 -3
  180. package/dist/builtin/workflows/src/extension/workflow-durable-resume-command.ts +5 -2
  181. package/dist/builtin/workflows/src/extension/workflow-ports.ts +14 -6
  182. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +11 -6
  183. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +17 -7
  184. package/dist/builtin/workflows/src/extension/workflow-status-summary.ts +11 -0
  185. package/dist/builtin/workflows/src/extension/workflow-tool-content.ts +18 -1
  186. package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +12 -8
  187. package/dist/builtin/workflows/src/extension/workflow-tool.ts +9 -4
  188. package/dist/builtin/workflows/src/intercom/intercom-routing.ts +12 -6
  189. package/dist/builtin/workflows/src/intercom/result-intercom.ts +35 -4
  190. package/dist/builtin/workflows/src/runs/background/quit.ts +28 -4
  191. package/dist/builtin/workflows/src/runs/background/resume-acknowledgements.ts +2 -1
  192. package/dist/builtin/workflows/src/runs/background/status.ts +70 -8
  193. package/dist/builtin/workflows/src/runs/foreground/executor-abort.ts +11 -3
  194. package/dist/builtin/workflows/src/runs/foreground/executor-child-boundary.ts +2 -1
  195. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +4 -0
  196. package/dist/builtin/workflows/src/runs/foreground/executor-exit-manager.ts +26 -2
  197. package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +3 -1
  198. package/dist/builtin/workflows/src/runs/foreground/executor-run-finalizers.ts +3 -2
  199. package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +1 -1
  200. package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +1 -1
  201. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +688 -38
  202. package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +3 -1
  203. package/dist/builtin/workflows/src/runs/shared/model-fallback-failures.ts +19 -514
  204. package/dist/builtin/workflows/src/runs/shared/retry.ts +44 -0
  205. package/dist/builtin/workflows/src/runs/shared/worktree-git-runner.ts +5 -2
  206. package/dist/builtin/workflows/src/runs/shared/worktree-setup.ts +2 -0
  207. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +10 -3
  208. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +11 -3
  209. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +5 -1
  210. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +5 -0
  211. package/dist/builtin/workflows/src/shared/graph-store-snapshot.ts +34 -2
  212. package/dist/builtin/workflows/src/shared/persistence-restore-helpers.ts +28 -6
  213. package/dist/builtin/workflows/src/shared/persistence-restore.ts +3 -0
  214. package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +4 -0
  215. package/dist/builtin/workflows/src/shared/run-indicator-status.ts +75 -0
  216. package/dist/builtin/workflows/src/shared/stage-ui-broker.ts +10 -4
  217. package/dist/builtin/workflows/src/shared/store-public-types.ts +47 -9
  218. package/dist/builtin/workflows/src/shared/store-run-methods.ts +42 -8
  219. package/dist/builtin/workflows/src/shared/store-stage-methods.ts +31 -8
  220. package/dist/builtin/workflows/src/shared/store-types.ts +35 -1
  221. package/dist/builtin/workflows/src/shared/timing.ts +10 -0
  222. package/dist/builtin/workflows/src/shared/workflow-artifact-env.ts +21 -0
  223. package/dist/builtin/workflows/src/shared/workflow-artifacts.ts +2 -5
  224. package/dist/builtin/workflows/src/tui/chat-surface-message.ts +22 -2
  225. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +37 -2
  226. package/dist/builtin/workflows/src/tui/graph-view-constants.ts +0 -15
  227. package/dist/builtin/workflows/src/tui/graph-view-graph-render.ts +38 -47
  228. package/dist/builtin/workflows/src/tui/graph-view-input.ts +48 -45
  229. package/dist/builtin/workflows/src/tui/graph-view-layout.ts +266 -0
  230. package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +1 -86
  231. package/dist/builtin/workflows/src/tui/graph-view-render.ts +209 -91
  232. package/dist/builtin/workflows/src/tui/graph-view-state.ts +5 -7
  233. package/dist/builtin/workflows/src/tui/graph-view-types.ts +13 -7
  234. package/dist/builtin/workflows/src/tui/inline-form-editor.ts +8 -6
  235. package/dist/builtin/workflows/src/tui/inline-form-overlay.ts +2 -1
  236. package/dist/builtin/workflows/src/tui/inputs-overlay.ts +7 -4
  237. package/dist/builtin/workflows/src/tui/inputs-picker-input.ts +66 -0
  238. package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +1 -0
  239. package/dist/builtin/workflows/src/tui/node-card.ts +1 -1
  240. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +18 -46
  241. package/dist/builtin/workflows/src/tui/overlay-terminal-modes.ts +15 -26
  242. package/dist/builtin/workflows/src/tui/session-list.ts +1 -1
  243. package/dist/builtin/workflows/src/tui/session-overlays.ts +19 -12
  244. package/dist/builtin/workflows/src/tui/session-picker.ts +47 -4
  245. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +5 -14
  246. package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +8 -7
  247. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +12 -3
  248. package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +1 -11
  249. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +0 -8
  250. package/dist/builtin/workflows/src/tui/status-list.ts +32 -47
  251. package/dist/builtin/workflows/src/tui/store-widget-installer.ts +9 -5
  252. package/dist/builtin/workflows/src/tui/widget.ts +16 -46
  253. package/dist/builtin/workflows/src/tui/workflow-attach-pane-types.ts +0 -15
  254. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +2 -26
  255. package/dist/builtin/workflows/src/tui/workflow-status.ts +3 -3
  256. package/dist/bun/split-loader.js +2 -0
  257. package/dist/bun/split-loader.js.map +1 -1
  258. package/dist/cli/args.d.ts.map +1 -1
  259. package/dist/cli/args.js +6 -2
  260. package/dist/cli/args.js.map +1 -1
  261. package/dist/cli/auth-check.d.ts +35 -0
  262. package/dist/cli/auth-check.d.ts.map +1 -0
  263. package/dist/cli/auth-check.js +100 -0
  264. package/dist/cli/auth-check.js.map +1 -0
  265. package/dist/cli/auth-command.d.ts +27 -0
  266. package/dist/cli/auth-command.d.ts.map +1 -0
  267. package/dist/cli/auth-command.js +150 -0
  268. package/dist/cli/auth-command.js.map +1 -0
  269. package/dist/cli/config-selector.js +2 -2
  270. package/dist/cli/config-selector.js.map +1 -1
  271. package/dist/cli/credential-print.d.ts +18 -23
  272. package/dist/cli/credential-print.d.ts.map +1 -1
  273. package/dist/cli/credential-print.js +42 -88
  274. package/dist/cli/credential-print.js.map +1 -1
  275. package/dist/cli/experimental/auth.d.ts +16 -0
  276. package/dist/cli/experimental/auth.d.ts.map +1 -0
  277. package/dist/cli/experimental/auth.js +13 -0
  278. package/dist/cli/experimental/auth.js.map +1 -0
  279. package/dist/cli/experimental/cli.d.ts +6 -0
  280. package/dist/cli/experimental/cli.d.ts.map +1 -0
  281. package/dist/cli/experimental/cli.js +5 -0
  282. package/dist/cli/experimental/cli.js.map +1 -0
  283. package/dist/cli/experimental/command-options.d.ts +17 -0
  284. package/dist/cli/experimental/command-options.d.ts.map +1 -0
  285. package/dist/cli/experimental/command-options.js +35 -0
  286. package/dist/cli/experimental/command-options.js.map +1 -0
  287. package/dist/cli/experimental/command.d.ts +63 -0
  288. package/dist/cli/experimental/command.d.ts.map +1 -0
  289. package/dist/cli/experimental/command.js +127 -0
  290. package/dist/cli/experimental/command.js.map +1 -0
  291. package/dist/cli/experimental/commands/client.d.ts +13 -0
  292. package/dist/cli/experimental/commands/client.d.ts.map +1 -0
  293. package/dist/cli/experimental/commands/client.js +25 -0
  294. package/dist/cli/experimental/commands/client.js.map +1 -0
  295. package/dist/cli/experimental/commands/pi.d.ts +15 -0
  296. package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
  297. package/dist/cli/experimental/commands/pi.js +28 -0
  298. package/dist/cli/experimental/commands/pi.js.map +1 -0
  299. package/dist/cli/experimental/commands/server.d.ts +13 -0
  300. package/dist/cli/experimental/commands/server.d.ts.map +1 -0
  301. package/dist/cli/experimental/commands/server.js +25 -0
  302. package/dist/cli/experimental/commands/server.js.map +1 -0
  303. package/dist/cli/experimental/transport-address.d.ts +10 -0
  304. package/dist/cli/experimental/transport-address.d.ts.map +1 -0
  305. package/dist/cli/experimental/transport-address.js +38 -0
  306. package/dist/cli/experimental/transport-address.js.map +1 -0
  307. package/dist/cli/session-picker.js +2 -2
  308. package/dist/cli/session-picker.js.map +1 -1
  309. package/dist/cli/startup-ui.d.ts.map +1 -1
  310. package/dist/cli/startup-ui.js +4 -10
  311. package/dist/cli/startup-ui.js.map +1 -1
  312. package/dist/cli.js +2 -0
  313. package/dist/cli.js.map +1 -1
  314. package/dist/client/index.d.ts +3 -0
  315. package/dist/client/index.d.ts.map +1 -0
  316. package/dist/client/index.js +3 -0
  317. package/dist/client/index.js.map +1 -0
  318. package/dist/client/remote-session.d.ts +64 -0
  319. package/dist/client/remote-session.d.ts.map +1 -0
  320. package/dist/client/remote-session.js +351 -0
  321. package/dist/client/remote-session.js.map +1 -0
  322. package/dist/client/transcript.d.ts +12 -0
  323. package/dist/client/transcript.d.ts.map +1 -0
  324. package/dist/client/transcript.js +98 -0
  325. package/dist/client/transcript.js.map +1 -0
  326. package/dist/core/agent-session-auto-compaction.d.ts +17 -13
  327. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  328. package/dist/core/agent-session-auto-compaction.js +192 -67
  329. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  330. package/dist/core/agent-session-bash.d.ts.map +1 -1
  331. package/dist/core/agent-session-bash.js +2 -0
  332. package/dist/core/agent-session-bash.js.map +1 -1
  333. package/dist/core/agent-session-compaction.d.ts +3 -6
  334. package/dist/core/agent-session-compaction.d.ts.map +1 -1
  335. package/dist/core/agent-session-compaction.js +64 -28
  336. package/dist/core/agent-session-compaction.js.map +1 -1
  337. package/dist/core/agent-session-events.d.ts +1 -11
  338. package/dist/core/agent-session-events.d.ts.map +1 -1
  339. package/dist/core/agent-session-events.js +64 -37
  340. package/dist/core/agent-session-events.js.map +1 -1
  341. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  342. package/dist/core/agent-session-extension-bindings.js +4 -2
  343. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  344. package/dist/core/agent-session-methods.d.ts +19 -2
  345. package/dist/core/agent-session-methods.d.ts.map +1 -1
  346. package/dist/core/agent-session-methods.js.map +1 -1
  347. package/dist/core/agent-session-models.d.ts +1 -0
  348. package/dist/core/agent-session-models.d.ts.map +1 -1
  349. package/dist/core/agent-session-models.js +23 -5
  350. package/dist/core/agent-session-models.js.map +1 -1
  351. package/dist/core/agent-session-post-tool-compaction.d.ts.map +1 -1
  352. package/dist/core/agent-session-post-tool-compaction.js +22 -6
  353. package/dist/core/agent-session-post-tool-compaction.js.map +1 -1
  354. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  355. package/dist/core/agent-session-prompt.js +4 -0
  356. package/dist/core/agent-session-prompt.js.map +1 -1
  357. package/dist/core/agent-session-retry.d.ts +21 -4
  358. package/dist/core/agent-session-retry.d.ts.map +1 -1
  359. package/dist/core/agent-session-retry.js +232 -106
  360. package/dist/core/agent-session-retry.js.map +1 -1
  361. package/dist/core/agent-session-runtime-auth.d.ts.map +1 -1
  362. package/dist/core/agent-session-runtime-auth.js +3 -0
  363. package/dist/core/agent-session-runtime-auth.js.map +1 -1
  364. package/dist/core/agent-session-state.d.ts.map +1 -1
  365. package/dist/core/agent-session-state.js +2 -1
  366. package/dist/core/agent-session-state.js.map +1 -1
  367. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  368. package/dist/core/agent-session-tool-hooks.js +37 -14
  369. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  370. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  371. package/dist/core/agent-session-tool-registry.js +5 -1
  372. package/dist/core/agent-session-tool-registry.js.map +1 -1
  373. package/dist/core/agent-session-types.d.ts +5 -1
  374. package/dist/core/agent-session-types.d.ts.map +1 -1
  375. package/dist/core/agent-session-types.js.map +1 -1
  376. package/dist/core/agent-session.d.ts +18 -1
  377. package/dist/core/agent-session.d.ts.map +1 -1
  378. package/dist/core/agent-session.js +37 -0
  379. package/dist/core/agent-session.js.map +1 -1
  380. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  381. package/dist/core/atomic-guide-command.js +2 -3
  382. package/dist/core/atomic-guide-command.js.map +1 -1
  383. package/dist/core/auth-storage.d.ts +18 -1
  384. package/dist/core/auth-storage.d.ts.map +1 -1
  385. package/dist/core/auth-storage.js +83 -0
  386. package/dist/core/auth-storage.js.map +1 -1
  387. package/dist/core/bash-executor.d.ts +5 -0
  388. package/dist/core/bash-executor.d.ts.map +1 -1
  389. package/dist/core/bash-executor.js +43 -19
  390. package/dist/core/bash-executor.js.map +1 -1
  391. package/dist/core/builtin-packages.d.ts.map +1 -1
  392. package/dist/core/builtin-packages.js +6 -0
  393. package/dist/core/builtin-packages.js.map +1 -1
  394. package/dist/core/codex-fast-mode.d.ts.map +1 -1
  395. package/dist/core/codex-fast-mode.js +8 -3
  396. package/dist/core/codex-fast-mode.js.map +1 -1
  397. package/dist/core/exec.d.ts.map +1 -1
  398. package/dist/core/exec.js +4 -3
  399. package/dist/core/exec.js.map +1 -1
  400. package/dist/core/extensions/agent-events.d.ts +0 -1
  401. package/dist/core/extensions/agent-events.d.ts.map +1 -1
  402. package/dist/core/extensions/agent-events.js.map +1 -1
  403. package/dist/core/extensions/api-types.d.ts +5 -3
  404. package/dist/core/extensions/api-types.d.ts.map +1 -1
  405. package/dist/core/extensions/api-types.js.map +1 -1
  406. package/dist/core/extensions/context-types.d.ts +40 -0
  407. package/dist/core/extensions/context-types.d.ts.map +1 -1
  408. package/dist/core/extensions/context-types.js.map +1 -1
  409. package/dist/core/extensions/event-results.d.ts +5 -0
  410. package/dist/core/extensions/event-results.d.ts.map +1 -1
  411. package/dist/core/extensions/event-results.js.map +1 -1
  412. package/dist/core/extensions/index.d.ts +2 -1
  413. package/dist/core/extensions/index.d.ts.map +1 -1
  414. package/dist/core/extensions/index.js +1 -0
  415. package/dist/core/extensions/index.js.map +1 -1
  416. package/dist/core/extensions/loader-api.d.ts.map +1 -1
  417. package/dist/core/extensions/loader-api.js +14 -1
  418. package/dist/core/extensions/loader-api.js.map +1 -1
  419. package/dist/core/extensions/loader-discovery.d.ts.map +1 -1
  420. package/dist/core/extensions/loader-discovery.js +3 -23
  421. package/dist/core/extensions/loader-discovery.js.map +1 -1
  422. package/dist/core/extensions/loader-runtime.d.ts.map +1 -1
  423. package/dist/core/extensions/loader-runtime.js +20 -3
  424. package/dist/core/extensions/loader-runtime.js.map +1 -1
  425. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  426. package/dist/core/extensions/loader-virtual-modules.js +7 -1
  427. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  428. package/dist/core/extensions/message-types.d.ts +6 -0
  429. package/dist/core/extensions/message-types.d.ts.map +1 -1
  430. package/dist/core/extensions/message-types.js.map +1 -1
  431. package/dist/core/extensions/provider-types.d.ts +9 -3
  432. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  433. package/dist/core/extensions/provider-types.js.map +1 -1
  434. package/dist/core/extensions/runner-context.d.ts +2 -1
  435. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  436. package/dist/core/extensions/runner-context.js +4 -0
  437. package/dist/core/extensions/runner-context.js.map +1 -1
  438. package/dist/core/extensions/runner-registries.d.ts +2 -1
  439. package/dist/core/extensions/runner-registries.d.ts.map +1 -1
  440. package/dist/core/extensions/runner-registries.js +3 -0
  441. package/dist/core/extensions/runner-registries.js.map +1 -1
  442. package/dist/core/extensions/runner-ui.d.ts.map +1 -1
  443. package/dist/core/extensions/runner-ui.js +1 -0
  444. package/dist/core/extensions/runner-ui.js.map +1 -1
  445. package/dist/core/extensions/runner.d.ts +4 -2
  446. package/dist/core/extensions/runner.d.ts.map +1 -1
  447. package/dist/core/extensions/runner.js +9 -3
  448. package/dist/core/extensions/runner.js.map +1 -1
  449. package/dist/core/extensions/runtime-types.d.ts +4 -1
  450. package/dist/core/extensions/runtime-types.d.ts.map +1 -1
  451. package/dist/core/extensions/runtime-types.js.map +1 -1
  452. package/dist/core/extensions/stale-context.d.ts +5 -0
  453. package/dist/core/extensions/stale-context.d.ts.map +1 -0
  454. package/dist/core/extensions/stale-context.js +11 -0
  455. package/dist/core/extensions/stale-context.js.map +1 -0
  456. package/dist/core/extensions/ui-types.d.ts +14 -11
  457. package/dist/core/extensions/ui-types.d.ts.map +1 -1
  458. package/dist/core/extensions/ui-types.js.map +1 -1
  459. package/dist/core/footer-data-provider.d.ts.map +1 -1
  460. package/dist/core/footer-data-provider.js +3 -2
  461. package/dist/core/footer-data-provider.js.map +1 -1
  462. package/dist/core/index.d.ts +1 -1
  463. package/dist/core/index.d.ts.map +1 -1
  464. package/dist/core/index.js.map +1 -1
  465. package/dist/core/intercom-runtime-group.d.ts +13 -0
  466. package/dist/core/intercom-runtime-group.d.ts.map +1 -0
  467. package/dist/core/intercom-runtime-group.js +23 -0
  468. package/dist/core/intercom-runtime-group.js.map +1 -0
  469. package/dist/core/keybindings.d.ts +44 -4
  470. package/dist/core/keybindings.d.ts.map +1 -1
  471. package/dist/core/model-config.d.ts +39 -5
  472. package/dist/core/model-config.d.ts.map +1 -1
  473. package/dist/core/model-config.js +6 -0
  474. package/dist/core/model-config.js.map +1 -1
  475. package/dist/core/model-fallback-failures.d.ts +30 -0
  476. package/dist/core/model-fallback-failures.d.ts.map +1 -0
  477. package/dist/core/model-fallback-failures.js +610 -0
  478. package/dist/core/model-fallback-failures.js.map +1 -0
  479. package/dist/core/model-registry.d.ts +12 -5
  480. package/dist/core/model-registry.d.ts.map +1 -1
  481. package/dist/core/model-registry.js +20 -12
  482. package/dist/core/model-registry.js.map +1 -1
  483. package/dist/core/model-resolver-cli.d.ts.map +1 -1
  484. package/dist/core/model-resolver-cli.js +46 -14
  485. package/dist/core/model-resolver-cli.js.map +1 -1
  486. package/dist/core/model-resolver-defaults.d.ts.map +1 -1
  487. package/dist/core/model-resolver-defaults.js +2 -0
  488. package/dist/core/model-resolver-defaults.js.map +1 -1
  489. package/dist/core/model-resolver-scope.d.ts +2 -0
  490. package/dist/core/model-resolver-scope.d.ts.map +1 -1
  491. package/dist/core/model-resolver-scope.js +12 -9
  492. package/dist/core/model-resolver-scope.js.map +1 -1
  493. package/dist/core/model-resolver.d.ts +1 -1
  494. package/dist/core/model-resolver.d.ts.map +1 -1
  495. package/dist/core/model-resolver.js +1 -1
  496. package/dist/core/model-resolver.js.map +1 -1
  497. package/dist/core/model-runtime-snapshot.d.ts +10 -0
  498. package/dist/core/model-runtime-snapshot.d.ts.map +1 -1
  499. package/dist/core/model-runtime-snapshot.js +14 -1
  500. package/dist/core/model-runtime-snapshot.js.map +1 -1
  501. package/dist/core/model-runtime-streaming.d.ts +3 -1
  502. package/dist/core/model-runtime-streaming.d.ts.map +1 -1
  503. package/dist/core/model-runtime-streaming.js +16 -0
  504. package/dist/core/model-runtime-streaming.js.map +1 -1
  505. package/dist/core/model-runtime-types.d.ts +2 -0
  506. package/dist/core/model-runtime-types.d.ts.map +1 -1
  507. package/dist/core/model-runtime-types.js.map +1 -1
  508. package/dist/core/model-runtime.d.ts +37 -10
  509. package/dist/core/model-runtime.d.ts.map +1 -1
  510. package/dist/core/model-runtime.js +312 -113
  511. package/dist/core/model-runtime.js.map +1 -1
  512. package/dist/core/oauth-login.d.ts.map +1 -1
  513. package/dist/core/oauth-login.js +2 -1
  514. package/dist/core/oauth-login.js.map +1 -1
  515. package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -1
  516. package/dist/core/openai-responses-payload-sanitizer.js +18 -2
  517. package/dist/core/openai-responses-payload-sanitizer.js.map +1 -1
  518. package/dist/core/package-manager-git.d.ts.map +1 -1
  519. package/dist/core/package-manager-git.js +56 -10
  520. package/dist/core/package-manager-git.js.map +1 -1
  521. package/dist/core/package-manager-manifest.d.ts +1 -1
  522. package/dist/core/package-manager-manifest.d.ts.map +1 -1
  523. package/dist/core/package-manager-manifest.js +19 -9
  524. package/dist/core/package-manager-manifest.js.map +1 -1
  525. package/dist/core/package-manager-resource-collector.js.map +1 -1
  526. package/dist/core/package-manager-resource-files.d.ts.map +1 -1
  527. package/dist/core/package-manager-resource-files.js +1 -2
  528. package/dist/core/package-manager-resource-files.js.map +1 -1
  529. package/dist/core/provider-composer-internal.d.ts +10 -2
  530. package/dist/core/provider-composer-internal.d.ts.map +1 -1
  531. package/dist/core/provider-composer-internal.js +7 -3
  532. package/dist/core/provider-composer-internal.js.map +1 -1
  533. package/dist/core/provider-composer.d.ts.map +1 -1
  534. package/dist/core/provider-composer.js +19 -12
  535. package/dist/core/provider-composer.js.map +1 -1
  536. package/dist/core/provider-display-names.d.ts.map +1 -1
  537. package/dist/core/provider-display-names.js +2 -0
  538. package/dist/core/provider-display-names.js.map +1 -1
  539. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  540. package/dist/core/remote-catalog-provider.js +77 -67
  541. package/dist/core/remote-catalog-provider.js.map +1 -1
  542. package/dist/core/resolve-config-value.d.ts.map +1 -1
  543. package/dist/core/resolve-config-value.js +3 -0
  544. package/dist/core/resolve-config-value.js.map +1 -1
  545. package/dist/core/resource-loader-context-files.d.ts.map +1 -1
  546. package/dist/core/resource-loader-context-files.js +13 -5
  547. package/dist/core/resource-loader-context-files.js.map +1 -1
  548. package/dist/core/retry-policy.d.ts +30 -0
  549. package/dist/core/retry-policy.d.ts.map +1 -0
  550. package/dist/core/retry-policy.js +25 -0
  551. package/dist/core/retry-policy.js.map +1 -0
  552. package/dist/core/runtime-credentials.d.ts +5 -5
  553. package/dist/core/runtime-credentials.d.ts.map +1 -1
  554. package/dist/core/runtime-credentials.js +8 -8
  555. package/dist/core/runtime-credentials.js.map +1 -1
  556. package/dist/core/sdk-types.d.ts +8 -2
  557. package/dist/core/sdk-types.d.ts.map +1 -1
  558. package/dist/core/sdk-types.js.map +1 -1
  559. package/dist/core/sdk.d.ts.map +1 -1
  560. package/dist/core/sdk.js +6 -1
  561. package/dist/core/sdk.js.map +1 -1
  562. package/dist/core/session-manager-core.d.ts +2 -0
  563. package/dist/core/session-manager-core.d.ts.map +1 -1
  564. package/dist/core/session-manager-core.js +7 -0
  565. package/dist/core/session-manager-core.js.map +1 -1
  566. package/dist/core/session-manager-list.d.ts.map +1 -1
  567. package/dist/core/session-manager-list.js +3 -1
  568. package/dist/core/session-manager-list.js.map +1 -1
  569. package/dist/core/settings-manager-ui-accessors.d.ts +8 -1
  570. package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
  571. package/dist/core/settings-manager-ui-accessors.js +31 -0
  572. package/dist/core/settings-manager-ui-accessors.js.map +1 -1
  573. package/dist/core/settings-manager.d.ts +2 -1
  574. package/dist/core/settings-manager.d.ts.map +1 -1
  575. package/dist/core/settings-manager.js.map +1 -1
  576. package/dist/core/settings-merge.d.ts.map +1 -1
  577. package/dist/core/settings-merge.js +13 -16
  578. package/dist/core/settings-merge.js.map +1 -1
  579. package/dist/core/settings-types.d.ts +5 -0
  580. package/dist/core/settings-types.d.ts.map +1 -1
  581. package/dist/core/settings-types.js.map +1 -1
  582. package/dist/core/slash-commands.d.ts.map +1 -1
  583. package/dist/core/slash-commands.js +0 -2
  584. package/dist/core/slash-commands.js.map +1 -1
  585. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts +2 -2
  586. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts.map +1 -1
  587. package/dist/core/tools/ask-user-question/state/questionnaire-session.js +39 -2
  588. package/dist/core/tools/ask-user-question/state/questionnaire-session.js.map +1 -1
  589. package/dist/core/tools/bash-async-execution.d.ts +2 -0
  590. package/dist/core/tools/bash-async-execution.d.ts.map +1 -1
  591. package/dist/core/tools/bash-async-execution.js +4 -1
  592. package/dist/core/tools/bash-async-execution.js.map +1 -1
  593. package/dist/core/tools/bash-async-output.d.ts +1 -0
  594. package/dist/core/tools/bash-async-output.d.ts.map +1 -1
  595. package/dist/core/tools/bash-async-output.js +62 -27
  596. package/dist/core/tools/bash-async-output.js.map +1 -1
  597. package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
  598. package/dist/core/tools/bash-pty-native.js +2 -1
  599. package/dist/core/tools/bash-pty-native.js.map +1 -1
  600. package/dist/core/tools/bash.d.ts +9 -0
  601. package/dist/core/tools/bash.d.ts.map +1 -1
  602. package/dist/core/tools/bash.js +34 -16
  603. package/dist/core/tools/bash.js.map +1 -1
  604. package/dist/core/tools/directory-tree.d.ts +11 -0
  605. package/dist/core/tools/directory-tree.d.ts.map +1 -1
  606. package/dist/core/tools/directory-tree.js +26 -0
  607. package/dist/core/tools/directory-tree.js.map +1 -1
  608. package/dist/core/tools/edit.d.ts +4 -0
  609. package/dist/core/tools/edit.d.ts.map +1 -1
  610. package/dist/core/tools/edit.js +12 -8
  611. package/dist/core/tools/edit.js.map +1 -1
  612. package/dist/core/tools/errno.d.ts +25 -0
  613. package/dist/core/tools/errno.d.ts.map +1 -0
  614. package/dist/core/tools/errno.js +29 -0
  615. package/dist/core/tools/errno.js.map +1 -0
  616. package/dist/core/tools/find.d.ts +8 -1
  617. package/dist/core/tools/find.d.ts.map +1 -1
  618. package/dist/core/tools/find.js +20 -15
  619. package/dist/core/tools/find.js.map +1 -1
  620. package/dist/core/tools/grep.d.ts.map +1 -1
  621. package/dist/core/tools/grep.js +5 -1
  622. package/dist/core/tools/grep.js.map +1 -1
  623. package/dist/core/tools/index.d.ts +7 -7
  624. package/dist/core/tools/index.d.ts.map +1 -1
  625. package/dist/core/tools/index.js +7 -7
  626. package/dist/core/tools/index.js.map +1 -1
  627. package/dist/core/tools/ls.d.ts +4 -0
  628. package/dist/core/tools/ls.d.ts.map +1 -1
  629. package/dist/core/tools/ls.js +5 -1
  630. package/dist/core/tools/ls.js.map +1 -1
  631. package/dist/core/tools/output-accumulator.d.ts +8 -1
  632. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  633. package/dist/core/tools/output-accumulator.js +50 -28
  634. package/dist/core/tools/output-accumulator.js.map +1 -1
  635. package/dist/core/tools/oversized-tool-result.d.ts.map +1 -1
  636. package/dist/core/tools/oversized-tool-result.js +129 -22
  637. package/dist/core/tools/oversized-tool-result.js.map +1 -1
  638. package/dist/core/tools/persisted-output-file.d.ts +80 -0
  639. package/dist/core/tools/persisted-output-file.d.ts.map +1 -0
  640. package/dist/core/tools/persisted-output-file.js +284 -0
  641. package/dist/core/tools/persisted-output-file.js.map +1 -0
  642. package/dist/core/tools/read.d.ts +10 -0
  643. package/dist/core/tools/read.d.ts.map +1 -1
  644. package/dist/core/tools/read.js +20 -8
  645. package/dist/core/tools/read.js.map +1 -1
  646. package/dist/core/tools/search.d.ts +4 -0
  647. package/dist/core/tools/search.d.ts.map +1 -1
  648. package/dist/core/tools/search.js +5 -1
  649. package/dist/core/tools/search.js.map +1 -1
  650. package/dist/core/tools/session-temp-cleanup.d.ts +133 -0
  651. package/dist/core/tools/session-temp-cleanup.d.ts.map +1 -0
  652. package/dist/core/tools/session-temp-cleanup.js +669 -0
  653. package/dist/core/tools/session-temp-cleanup.js.map +1 -0
  654. package/dist/core/tools/session-temp-dir.d.ts +116 -0
  655. package/dist/core/tools/session-temp-dir.d.ts.map +1 -0
  656. package/dist/core/tools/session-temp-dir.js +409 -0
  657. package/dist/core/tools/session-temp-dir.js.map +1 -0
  658. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  659. package/dist/core/tools/tool-definition-wrapper.js +2 -0
  660. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  661. package/dist/core/tools/tool-limits.d.ts +11 -0
  662. package/dist/core/tools/tool-limits.d.ts.map +1 -1
  663. package/dist/core/tools/tool-limits.js +11 -0
  664. package/dist/core/tools/tool-limits.js.map +1 -1
  665. package/dist/core/tools/windows-directory-security.d.ts +82 -0
  666. package/dist/core/tools/windows-directory-security.d.ts.map +1 -0
  667. package/dist/core/tools/windows-directory-security.js +238 -0
  668. package/dist/core/tools/windows-directory-security.js.map +1 -0
  669. package/dist/core/tools/write.d.ts +4 -0
  670. package/dist/core/tools/write.d.ts.map +1 -1
  671. package/dist/core/tools/write.js +8 -4
  672. package/dist/core/tools/write.js.map +1 -1
  673. package/dist/core/trust-manager.js +1 -1
  674. package/dist/core/trust-manager.js.map +1 -1
  675. package/dist/extensions/llama/huggingface-ui.d.ts +1 -1
  676. package/dist/extensions/llama/huggingface-ui.d.ts.map +1 -1
  677. package/dist/extensions/llama/huggingface-ui.js +6 -5
  678. package/dist/extensions/llama/huggingface-ui.js.map +1 -1
  679. package/dist/extensions/llama/index.d.ts.map +1 -1
  680. package/dist/extensions/llama/index.js +11 -2
  681. package/dist/extensions/llama/index.js.map +1 -1
  682. package/dist/extensions/llama/provider.d.ts.map +1 -1
  683. package/dist/extensions/llama/provider.js +24 -8
  684. package/dist/extensions/llama/provider.js.map +1 -1
  685. package/dist/extensions/llama/ui.d.ts.map +1 -1
  686. package/dist/extensions/llama/ui.js +5 -2
  687. package/dist/extensions/llama/ui.js.map +1 -1
  688. package/dist/index-extensions.d.ts +2 -2
  689. package/dist/index-extensions.d.ts.map +1 -1
  690. package/dist/index-extensions.js +1 -1
  691. package/dist/index-extensions.js.map +1 -1
  692. package/dist/index.d.ts +8 -2
  693. package/dist/index.d.ts.map +1 -1
  694. package/dist/index.js +8 -2
  695. package/dist/index.js.map +1 -1
  696. package/dist/main-runtime-api-key.d.ts +2 -2
  697. package/dist/main-runtime-api-key.d.ts.map +1 -1
  698. package/dist/main-runtime-api-key.js +7 -2
  699. package/dist/main-runtime-api-key.js.map +1 -1
  700. package/dist/main-session.js +2 -2
  701. package/dist/main-session.js.map +1 -1
  702. package/dist/main.d.ts.map +1 -1
  703. package/dist/main.js +130 -26
  704. package/dist/main.js.map +1 -1
  705. package/dist/modes/index.d.ts +1 -0
  706. package/dist/modes/index.d.ts.map +1 -1
  707. package/dist/modes/index.js.map +1 -1
  708. package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
  709. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  710. package/dist/modes/interactive/components/assistant-message.js +18 -5
  711. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  712. package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
  713. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  714. package/dist/modes/interactive/components/bordered-loader.js +5 -4
  715. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  716. package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
  717. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  718. package/dist/modes/interactive/components/branch-summary-message.js +3 -2
  719. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  720. package/dist/modes/interactive/components/chat-message-renderer.d.ts +17 -7
  721. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  722. package/dist/modes/interactive/components/chat-message-renderer.js +35 -69
  723. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  724. package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
  725. package/dist/modes/interactive/components/chat-session-host-actions.js +11 -3
  726. package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
  727. package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
  728. package/dist/modes/interactive/components/chat-session-host-events.js +25 -15
  729. package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
  730. package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
  731. package/dist/modes/interactive/components/chat-session-host-rendering.js +9 -4
  732. package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
  733. package/dist/modes/interactive/components/chat-session-host-state.d.ts +2 -0
  734. package/dist/modes/interactive/components/chat-session-host-state.d.ts.map +1 -1
  735. package/dist/modes/interactive/components/chat-session-host-state.js +2 -0
  736. package/dist/modes/interactive/components/chat-session-host-state.js.map +1 -1
  737. package/dist/modes/interactive/components/chat-session-host.d.ts +9 -0
  738. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  739. package/dist/modes/interactive/components/chat-session-host.js +14 -0
  740. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  741. package/dist/modes/interactive/components/chat-transcript.d.ts +32 -0
  742. package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -1
  743. package/dist/modes/interactive/components/chat-transcript.js +173 -5
  744. package/dist/modes/interactive/components/chat-transcript.js.map +1 -1
  745. package/dist/modes/interactive/components/config-selector-list.d.ts +1 -1
  746. package/dist/modes/interactive/components/config-selector-list.d.ts.map +1 -1
  747. package/dist/modes/interactive/components/config-selector-list.js +9 -8
  748. package/dist/modes/interactive/components/config-selector-list.js.map +1 -1
  749. package/dist/modes/interactive/components/custom-editor.d.ts +1 -1
  750. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  751. package/dist/modes/interactive/components/custom-editor.js +32 -10
  752. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  753. package/dist/modes/interactive/components/custom-message.d.ts +2 -1
  754. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  755. package/dist/modes/interactive/components/custom-message.js +3 -2
  756. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  757. package/dist/modes/interactive/components/extension-editor.d.ts +1 -1
  758. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  759. package/dist/modes/interactive/components/extension-editor.js +3 -2
  760. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  761. package/dist/modes/interactive/components/extension-input.d.ts +1 -1
  762. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  763. package/dist/modes/interactive/components/extension-input.js +1 -0
  764. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  765. package/dist/modes/interactive/components/extension-selector.d.ts +1 -1
  766. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  767. package/dist/modes/interactive/components/extension-selector.js +4 -0
  768. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  769. package/dist/modes/interactive/components/fast-mode-selector.d.ts +1 -1
  770. package/dist/modes/interactive/components/fast-mode-selector.d.ts.map +1 -1
  771. package/dist/modes/interactive/components/fast-mode-selector.js +7 -5
  772. package/dist/modes/interactive/components/fast-mode-selector.js.map +1 -1
  773. package/dist/modes/interactive/components/first-time-setup.d.ts +1 -1
  774. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  775. package/dist/modes/interactive/components/first-time-setup.js +3 -0
  776. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  777. package/dist/modes/interactive/components/footer.js +1 -1
  778. package/dist/modes/interactive/components/footer.js.map +1 -1
  779. package/dist/modes/interactive/components/host-input-form.d.ts +1 -1
  780. package/dist/modes/interactive/components/host-input-form.d.ts.map +1 -1
  781. package/dist/modes/interactive/components/host-input-form.js +6 -5
  782. package/dist/modes/interactive/components/host-input-form.js.map +1 -1
  783. package/dist/modes/interactive/components/index.d.ts +1 -1
  784. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  785. package/dist/modes/interactive/components/index.js.map +1 -1
  786. package/dist/modes/interactive/components/login-dialog.d.ts +1 -1
  787. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  788. package/dist/modes/interactive/components/login-dialog.js +2 -1
  789. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  790. package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
  791. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
  792. package/dist/modes/interactive/components/markdown-transform.js +19 -0
  793. package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
  794. package/dist/modes/interactive/components/mermaid.d.ts +11 -0
  795. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  796. package/dist/modes/interactive/components/mermaid.js +81 -0
  797. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  798. package/dist/modes/interactive/components/model-selector.d.ts +2 -2
  799. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  800. package/dist/modes/interactive/components/model-selector.js +9 -6
  801. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  802. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
  803. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  804. package/dist/modes/interactive/components/oauth-selector.js +3 -2
  805. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  806. package/dist/modes/interactive/components/scoped-models-selector.d.ts +6 -2
  807. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  808. package/dist/modes/interactive/components/scoped-models-selector.js +39 -13
  809. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  810. package/dist/modes/interactive/components/session-selector-delete.d.ts.map +1 -1
  811. package/dist/modes/interactive/components/session-selector-delete.js +2 -1
  812. package/dist/modes/interactive/components/session-selector-delete.js.map +1 -1
  813. package/dist/modes/interactive/components/session-selector-list.d.ts +1 -1
  814. package/dist/modes/interactive/components/session-selector-list.d.ts.map +1 -1
  815. package/dist/modes/interactive/components/session-selector-list.js +12 -11
  816. package/dist/modes/interactive/components/session-selector-list.js.map +1 -1
  817. package/dist/modes/interactive/components/session-selector.d.ts +1 -1
  818. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  819. package/dist/modes/interactive/components/session-selector.js +3 -3
  820. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  821. package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
  822. package/dist/modes/interactive/components/settings-selector-handlers.js +9 -0
  823. package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
  824. package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
  825. package/dist/modes/interactive/components/settings-selector-items.js +21 -0
  826. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  827. package/dist/modes/interactive/components/settings-selector-submenus.d.ts +3 -3
  828. package/dist/modes/interactive/components/settings-selector-submenus.d.ts.map +1 -1
  829. package/dist/modes/interactive/components/settings-selector-submenus.js +6 -1
  830. package/dist/modes/interactive/components/settings-selector-submenus.js.map +1 -1
  831. package/dist/modes/interactive/components/settings-selector-types.d.ts +8 -1
  832. package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
  833. package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
  834. package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
  835. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  836. package/dist/modes/interactive/components/skill-invocation-message.js +3 -2
  837. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  838. package/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  839. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  840. package/dist/modes/interactive/components/tool-execution.js +50 -27
  841. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  842. package/dist/modes/interactive/components/tree-selector-component.d.ts +1 -1
  843. package/dist/modes/interactive/components/tree-selector-component.d.ts.map +1 -1
  844. package/dist/modes/interactive/components/tree-selector-component.js +2 -3
  845. package/dist/modes/interactive/components/tree-selector-component.js.map +1 -1
  846. package/dist/modes/interactive/components/tree-selector-help.d.ts +1 -1
  847. package/dist/modes/interactive/components/tree-selector-help.d.ts.map +1 -1
  848. package/dist/modes/interactive/components/tree-selector-help.js +3 -1
  849. package/dist/modes/interactive/components/tree-selector-help.js.map +1 -1
  850. package/dist/modes/interactive/components/tree-selector-label-input.d.ts +1 -1
  851. package/dist/modes/interactive/components/tree-selector-label-input.d.ts.map +1 -1
  852. package/dist/modes/interactive/components/tree-selector-label-input.js +1 -0
  853. package/dist/modes/interactive/components/tree-selector-label-input.js.map +1 -1
  854. package/dist/modes/interactive/components/tree-selector-list.d.ts +1 -1
  855. package/dist/modes/interactive/components/tree-selector-list.d.ts.map +1 -1
  856. package/dist/modes/interactive/components/tree-selector-list.js +3 -0
  857. package/dist/modes/interactive/components/tree-selector-list.js.map +1 -1
  858. package/dist/modes/interactive/components/trust-selector.d.ts +1 -1
  859. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
  860. package/dist/modes/interactive/components/trust-selector.js +4 -0
  861. package/dist/modes/interactive/components/trust-selector.js.map +1 -1
  862. package/dist/modes/interactive/components/user-message-selector.d.ts +1 -1
  863. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  864. package/dist/modes/interactive/components/user-message-selector.js +4 -0
  865. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  866. package/dist/modes/interactive/components/user-message.d.ts +4 -1
  867. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  868. package/dist/modes/interactive/components/user-message.js +10 -2
  869. package/dist/modes/interactive/components/user-message.js.map +1 -1
  870. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  871. package/dist/modes/interactive/external-editor.js +2 -1
  872. package/dist/modes/interactive/external-editor.js.map +1 -1
  873. package/dist/modes/interactive/interactive-agent-events.js +36 -18
  874. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  875. package/dist/modes/interactive/interactive-auth-login.js +9 -2
  876. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  877. package/dist/modes/interactive/interactive-auth-routing.d.ts.map +1 -1
  878. package/dist/modes/interactive/interactive-auth-routing.js +5 -1
  879. package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
  880. package/dist/modes/interactive/interactive-bash-compact.js +16 -4
  881. package/dist/modes/interactive/interactive-bash-compact.js.map +1 -1
  882. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  883. package/dist/modes/interactive/interactive-deferred-startup.js +3 -0
  884. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  885. package/dist/modes/interactive/interactive-editor-actions.js +2 -0
  886. package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
  887. package/dist/modes/interactive/interactive-extension-context.js +12 -7
  888. package/dist/modes/interactive/interactive-extension-context.js.map +1 -1
  889. package/dist/modes/interactive/interactive-extension-custom-ui.js +1 -0
  890. package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
  891. package/dist/modes/interactive/interactive-extension-dialogs.js +7 -0
  892. package/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  893. package/dist/modes/interactive/interactive-extension-widgets.js +7 -24
  894. package/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  895. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  896. package/dist/modes/interactive/interactive-input-handling.js +9 -8
  897. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  898. package/dist/modes/interactive/interactive-mode-base.d.ts +52 -3
  899. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  900. package/dist/modes/interactive/interactive-mode-base.js +143 -5
  901. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  902. package/dist/modes/interactive/interactive-mode-deps.d.ts +2 -2
  903. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  904. package/dist/modes/interactive/interactive-mode-deps.js +2 -2
  905. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  906. package/dist/modes/interactive/interactive-mode-surface.d.ts +9 -3
  907. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  908. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  909. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  910. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  911. package/dist/modes/interactive/interactive-mode.js +1 -0
  912. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  913. package/dist/modes/interactive/interactive-model-routing.js +107 -41
  914. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  915. package/dist/modes/interactive/interactive-process-lifecycle.js +1 -1
  916. package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
  917. package/dist/modes/interactive/interactive-render-chat.js +24 -6
  918. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  919. package/dist/modes/interactive/interactive-selectors.js +44 -5
  920. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  921. package/dist/modes/interactive/interactive-session-runtime.js +1 -0
  922. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  923. package/dist/modes/interactive/interactive-slash-commands.js +9 -4
  924. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  925. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  926. package/dist/modes/interactive/interactive-startup.js +37 -18
  927. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  928. package/dist/modes/interactive/interactive-tui.d.ts +21 -0
  929. package/dist/modes/interactive/interactive-tui.d.ts.map +1 -0
  930. package/dist/modes/interactive/interactive-tui.js +279 -0
  931. package/dist/modes/interactive/interactive-tui.js.map +1 -0
  932. package/dist/modes/interactive/streaming-assistant-message.d.ts +34 -0
  933. package/dist/modes/interactive/streaming-assistant-message.d.ts.map +1 -0
  934. package/dist/modes/interactive/streaming-assistant-message.js +76 -0
  935. package/dist/modes/interactive/streaming-assistant-message.js.map +1 -0
  936. package/dist/modes/interactive/theme/catppuccin-frappe.json +1 -0
  937. package/dist/modes/interactive/theme/catppuccin-latte.json +1 -0
  938. package/dist/modes/interactive/theme/catppuccin-macchiato.json +1 -0
  939. package/dist/modes/interactive/theme/catppuccin-mocha.json +1 -0
  940. package/dist/modes/interactive/theme/dark.json +1 -0
  941. package/dist/modes/interactive/theme/light.json +1 -0
  942. package/dist/modes/interactive/theme/terminal-detection.d.ts +10 -0
  943. package/dist/modes/interactive/theme/terminal-detection.d.ts.map +1 -1
  944. package/dist/modes/interactive/theme/terminal-detection.js +19 -0
  945. package/dist/modes/interactive/theme/terminal-detection.js.map +1 -1
  946. package/dist/modes/interactive/theme/theme-class.d.ts +2 -2
  947. package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
  948. package/dist/modes/interactive/theme/theme-class.js +5 -1
  949. package/dist/modes/interactive/theme/theme-class.js.map +1 -1
  950. package/dist/modes/interactive/theme/theme-controller.d.ts +3 -1
  951. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  952. package/dist/modes/interactive/theme/theme-controller.js +10 -13
  953. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  954. package/dist/modes/interactive/theme/theme-loading.d.ts.map +1 -1
  955. package/dist/modes/interactive/theme/theme-loading.js +1 -0
  956. package/dist/modes/interactive/theme/theme-loading.js.map +1 -1
  957. package/dist/modes/interactive/theme/theme-schema.d.ts +4 -0
  958. package/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  959. package/dist/modes/interactive/theme/theme-schema.js +2 -1
  960. package/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  961. package/dist/modes/interactive/theme/theme-schema.json +5 -1
  962. package/dist/modes/interactive/theme/theme.d.ts +1 -1
  963. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  964. package/dist/modes/interactive/theme/theme.js +1 -1
  965. package/dist/modes/interactive/theme/theme.js.map +1 -1
  966. package/dist/modes/interactive-engine/engine-custom-ui.d.ts +1 -1
  967. package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
  968. package/dist/modes/interactive-engine/engine-custom-ui.js +28 -11
  969. package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
  970. package/dist/modes/interactive-engine/engine-render-service.js +3 -3
  971. package/dist/modes/interactive-engine/engine-render-service.js.map +1 -1
  972. package/dist/modes/interactive-engine/extension-ui-bridge.d.ts +2 -1
  973. package/dist/modes/interactive-engine/extension-ui-bridge.d.ts.map +1 -1
  974. package/dist/modes/interactive-engine/extension-ui-bridge.js +2 -2
  975. package/dist/modes/interactive-engine/extension-ui-bridge.js.map +1 -1
  976. package/dist/modes/interactive-engine/isolated-runtime.d.ts +7 -0
  977. package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
  978. package/dist/modes/interactive-engine/isolated-runtime.js +7 -0
  979. package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
  980. package/dist/modes/interactive-engine/protocol.d.ts +12 -10
  981. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
  982. package/dist/modes/interactive-engine/protocol.js +14 -11
  983. package/dist/modes/interactive-engine/protocol.js.map +1 -1
  984. package/dist/modes/interactive-engine/remote-component.d.ts +11 -1
  985. package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
  986. package/dist/modes/interactive-engine/remote-component.js +48 -8
  987. package/dist/modes/interactive-engine/remote-component.js.map +1 -1
  988. package/dist/modes/interactive-engine/terminal-mode-controller.d.ts +19 -12
  989. package/dist/modes/interactive-engine/terminal-mode-controller.d.ts.map +1 -1
  990. package/dist/modes/interactive-engine/terminal-mode-controller.js +54 -35
  991. package/dist/modes/interactive-engine/terminal-mode-controller.js.map +1 -1
  992. package/dist/modes/json-event.d.ts +28 -0
  993. package/dist/modes/json-event.d.ts.map +1 -0
  994. package/dist/modes/json-event.js +12 -0
  995. package/dist/modes/json-event.js.map +1 -0
  996. package/dist/modes/print-mode.d.ts.map +1 -1
  997. package/dist/modes/print-mode.js +2 -1
  998. package/dist/modes/print-mode.js.map +1 -1
  999. package/dist/modes/rpc/rpc-client-process.d.ts +1 -0
  1000. package/dist/modes/rpc/rpc-client-process.d.ts.map +1 -1
  1001. package/dist/modes/rpc/rpc-client-process.js +5 -1
  1002. package/dist/modes/rpc/rpc-client-process.js.map +1 -1
  1003. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  1004. package/dist/modes/rpc/rpc-client.js +7 -2
  1005. package/dist/modes/rpc/rpc-client.js.map +1 -1
  1006. package/dist/modes/rpc/rpc-command-handler.js +1 -1
  1007. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  1008. package/dist/modes/rpc/rpc-event-buffer.d.ts +9 -0
  1009. package/dist/modes/rpc/rpc-event-buffer.d.ts.map +1 -1
  1010. package/dist/modes/rpc/rpc-event-buffer.js +10 -5
  1011. package/dist/modes/rpc/rpc-event-buffer.js.map +1 -1
  1012. package/dist/modes/rpc/rpc-extension-ui.d.ts.map +1 -1
  1013. package/dist/modes/rpc/rpc-extension-ui.js +3 -0
  1014. package/dist/modes/rpc/rpc-extension-ui.js.map +1 -1
  1015. package/dist/modes/rpc/rpc-input.js +1 -1
  1016. package/dist/modes/rpc/rpc-input.js.map +1 -1
  1017. package/dist/modes/rpc/rpc-output-buffer.d.ts +9 -0
  1018. package/dist/modes/rpc/rpc-output-buffer.d.ts.map +1 -1
  1019. package/dist/modes/rpc/rpc-output-buffer.js +10 -5
  1020. package/dist/modes/rpc/rpc-output-buffer.js.map +1 -1
  1021. package/dist/modes/rpc/rpc-provider-auth.d.ts.map +1 -1
  1022. package/dist/modes/rpc/rpc-provider-auth.js +3 -0
  1023. package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
  1024. package/dist/modes/rpc/rpc-responses.d.ts +1 -1
  1025. package/dist/modes/rpc/rpc-responses.d.ts.map +1 -1
  1026. package/dist/modes/rpc/rpc-responses.js +13 -1
  1027. package/dist/modes/rpc/rpc-responses.js.map +1 -1
  1028. package/dist/modes/rpc/rpc-session-binding.d.ts.map +1 -1
  1029. package/dist/modes/rpc/rpc-session-binding.js +2 -1
  1030. package/dist/modes/rpc/rpc-session-binding.js.map +1 -1
  1031. package/dist/modes/rpc/rpc-types.d.ts +9 -2
  1032. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  1033. package/dist/modes/rpc/rpc-types.js.map +1 -1
  1034. package/dist/rpc-entry.js +2 -0
  1035. package/dist/rpc-entry.js.map +1 -1
  1036. package/dist/self-update-plan.d.ts.map +1 -1
  1037. package/dist/self-update-plan.js +5 -4
  1038. package/dist/self-update-plan.js.map +1 -1
  1039. package/dist/server/create-harness.d.ts +53 -0
  1040. package/dist/server/create-harness.d.ts.map +1 -0
  1041. package/dist/server/create-harness.js +349 -0
  1042. package/dist/server/create-harness.js.map +1 -0
  1043. package/dist/utils/agent-attribution.d.ts +2 -0
  1044. package/dist/utils/agent-attribution.d.ts.map +1 -0
  1045. package/dist/utils/agent-attribution.js +2 -0
  1046. package/dist/utils/agent-attribution.js.map +1 -0
  1047. package/dist/utils/child-process.d.ts +3 -1
  1048. package/dist/utils/child-process.d.ts.map +1 -1
  1049. package/dist/utils/child-process.js +24 -4
  1050. package/dist/utils/child-process.js.map +1 -1
  1051. package/dist/utils/clipboard-image.d.ts.map +1 -1
  1052. package/dist/utils/clipboard-image.js +2 -1
  1053. package/dist/utils/clipboard-image.js.map +1 -1
  1054. package/dist/utils/clipboard.d.ts.map +1 -1
  1055. package/dist/utils/clipboard.js +12 -3
  1056. package/dist/utils/clipboard.js.map +1 -1
  1057. package/dist/utils/management-http.d.ts +23 -0
  1058. package/dist/utils/management-http.d.ts.map +1 -0
  1059. package/dist/utils/management-http.js +50 -0
  1060. package/dist/utils/management-http.js.map +1 -0
  1061. package/dist/utils/open-browser.d.ts.map +1 -1
  1062. package/dist/utils/open-browser.js +2 -1
  1063. package/dist/utils/open-browser.js.map +1 -1
  1064. package/dist/utils/paths.d.ts +2 -0
  1065. package/dist/utils/paths.d.ts.map +1 -1
  1066. package/dist/utils/paths.js +13 -0
  1067. package/dist/utils/paths.js.map +1 -1
  1068. package/dist/utils/shell.d.ts.map +1 -1
  1069. package/dist/utils/shell.js +17 -4
  1070. package/dist/utils/shell.js.map +1 -1
  1071. package/dist/utils/tool-result-images.d.ts +17 -0
  1072. package/dist/utils/tool-result-images.d.ts.map +1 -0
  1073. package/dist/utils/tool-result-images.js +41 -0
  1074. package/dist/utils/tool-result-images.js.map +1 -0
  1075. package/dist/utils/tools-manager.d.ts.map +1 -1
  1076. package/dist/utils/tools-manager.js +7 -8
  1077. package/dist/utils/tools-manager.js.map +1 -1
  1078. package/dist/utils/version-check.d.ts +4 -0
  1079. package/dist/utils/version-check.d.ts.map +1 -1
  1080. package/dist/utils/version-check.js +20 -2
  1081. package/dist/utils/version-check.js.map +1 -1
  1082. package/docs/compaction.md +2 -1
  1083. package/docs/custom-provider.md +15 -7
  1084. package/docs/development.md +1 -0
  1085. package/docs/docs.json +1 -0
  1086. package/docs/environment-variables.md +4 -0
  1087. package/docs/extensions.md +102 -18
  1088. package/docs/i-have-adhd.md +36 -0
  1089. package/docs/intercom.md +31 -16
  1090. package/docs/json.md +2 -2
  1091. package/docs/keybindings.md +55 -12
  1092. package/docs/models/model-selection.md +34 -8
  1093. package/docs/models.md +28 -3
  1094. package/docs/providers.md +20 -2
  1095. package/docs/quickstart.md +5 -5
  1096. package/docs/rpc.md +18 -12
  1097. package/docs/sdk.md +43 -7
  1098. package/docs/security.md +10 -10
  1099. package/docs/sessions.md +2 -0
  1100. package/docs/settings.md +32 -6
  1101. package/docs/subagents.md +30 -45
  1102. package/docs/themes.md +5 -3
  1103. package/docs/tools.md +21 -1
  1104. package/docs/tui.md +41 -24
  1105. package/docs/usage.md +40 -14
  1106. package/docs/windows.md +2 -0
  1107. package/docs/workflows.md +237 -25
  1108. package/examples/extensions/custom-provider-anthropic/index.ts +9 -2
  1109. package/examples/extensions/custom-provider-gitlab-duo/index.ts +9 -2
  1110. package/examples/extensions/gondolin/package-lock.json +3 -3
  1111. package/examples/extensions/modal-editor.ts +8 -10
  1112. package/examples/extensions/rainbow-editor.ts +3 -2
  1113. package/examples/extensions/subagent/README.md +16 -45
  1114. package/examples/extensions/subagent/index.ts +6 -96
  1115. package/examples/extensions/subagent/render.ts +0 -78
  1116. package/examples/extensions/subagent/runner.ts +0 -3
  1117. package/examples/extensions/subagent/schemas.ts +0 -13
  1118. package/examples/extensions/subagent/types.ts +1 -2
  1119. package/examples/sdk/09-api-keys-and-oauth.ts +6 -2
  1120. package/examples/sdk/12-full-control.ts +8 -2
  1121. package/examples/sdk/README.md +4 -1
  1122. package/npm-shrinkwrap.json +191 -634
  1123. package/package.json +14 -7
  1124. package/dist/builtin/subagents/src/agents/chain-serializer.ts +0 -257
  1125. package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +0 -112
  1126. package/dist/builtin/subagents/src/runs/background/async-execution-chain.ts +0 -543
  1127. package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +0 -140
  1128. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +0 -279
  1129. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +0 -99
  1130. package/dist/builtin/subagents/src/runs/background/async-execution.ts +0 -17
  1131. package/dist/builtin/subagents/src/runs/background/async-resume.ts +0 -402
  1132. package/dist/builtin/subagents/src/runs/background/async-status.ts +0 -411
  1133. package/dist/builtin/subagents/src/runs/background/completion-claims.ts +0 -196
  1134. package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +0 -102
  1135. package/dist/builtin/subagents/src/runs/background/parallel-groups.ts +0 -59
  1136. package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +0 -300
  1137. package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +0 -166
  1138. package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +0 -77
  1139. package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +0 -48
  1140. package/dist/builtin/subagents/src/runs/background/result-status.ts +0 -87
  1141. package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +0 -72
  1142. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +0 -320
  1143. package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +0 -105
  1144. package/dist/builtin/subagents/src/runs/background/run-status.ts +0 -358
  1145. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +0 -457
  1146. package/dist/builtin/subagents/src/runs/background/subagent-runner-dynamic.ts +0 -376
  1147. package/dist/builtin/subagents/src/runs/background/subagent-runner-finalize.ts +0 -150
  1148. package/dist/builtin/subagents/src/runs/background/subagent-runner-output.ts +0 -109
  1149. package/dist/builtin/subagents/src/runs/background/subagent-runner-parallel-helpers.ts +0 -128
  1150. package/dist/builtin/subagents/src/runs/background/subagent-runner-parallel.ts +0 -309
  1151. package/dist/builtin/subagents/src/runs/background/subagent-runner-sequential.ts +0 -173
  1152. package/dist/builtin/subagents/src/runs/background/subagent-runner-state.ts +0 -578
  1153. package/dist/builtin/subagents/src/runs/background/subagent-runner-step.ts +0 -330
  1154. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +0 -330
  1155. package/dist/builtin/subagents/src/runs/background/subagent-runner-types.ts +0 -210
  1156. package/dist/builtin/subagents/src/runs/background/subagent-runner-utils.ts +0 -69
  1157. package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +0 -90
  1158. package/dist/builtin/subagents/src/runs/background/top-level-async.ts +0 -12
  1159. package/dist/builtin/subagents/src/runs/foreground/chain-execution-details.ts +0 -38
  1160. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +0 -280
  1161. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +0 -217
  1162. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +0 -271
  1163. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +0 -271
  1164. package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +0 -200
  1165. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +0 -184
  1166. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-control.ts +0 -140
  1167. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +0 -108
  1168. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-types.ts +0 -17
  1169. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +0 -558
  1170. package/dist/builtin/subagents/src/runs/foreground/execution-structured-retries.ts +0 -83
  1171. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +0 -109
  1172. package/dist/builtin/subagents/src/runs/shared/attempt-watchdog.ts +0 -126
  1173. package/dist/builtin/subagents/src/runs/shared/chain-outputs.ts +0 -126
  1174. package/dist/builtin/subagents/src/runs/shared/dynamic-fanout.ts +0 -387
  1175. package/dist/builtin/subagents/src/runs/shared/final-drain.ts +0 -39
  1176. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +0 -339
  1177. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +0 -165
  1178. package/dist/builtin/subagents/src/runs/shared/spawn-env.ts +0 -21
  1179. package/dist/builtin/subagents/src/runs/shared/structured-output.ts +0 -150
  1180. package/dist/builtin/subagents/src/runs/shared/workflow-graph.ts +0 -232
  1181. package/dist/builtin/subagents/src/shared/post-exit-stdio-guard.ts +0 -86
  1182. package/dist/builtin/subagents/src/slash/saved-chain-mapping.ts +0 -60
  1183. package/dist/builtin/subagents/src/tui/render-chain-graph.ts +0 -335
  1184. package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
  1185. package/examples/extensions/subagent/prompts/implement.md +0 -10
  1186. package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
  1187. /package/dist/builtin/subagents/src/runs/{shared/nested-path.ts → inprocess/runtime-support/nested-paths.ts} +0 -0
@@ -1,12 +1,12 @@
1
1
  import { randomBytes } from "node:crypto";
2
- import { createWriteStream } from "node:fs";
3
- import { tmpdir } from "node:os";
4
2
  import { join } from "node:path";
5
3
  import { APP_NAME } from "../../config.js";
4
+ import { PersistedOutputFile } from "./persisted-output-file.js";
5
+ import { ensureSessionTempDir } from "./session-temp-dir.js";
6
6
  import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail } from "./truncate.js";
7
- function defaultTempFilePath(prefix) {
7
+ function defaultTempFilePath(prefix, tempDir) {
8
8
  const id = randomBytes(8).toString("hex");
9
- return join(tmpdir(), `${prefix}-${id}.log`);
9
+ return join(ensureSessionTempDir(tempDir), `${prefix}-${id}.log`);
10
10
  }
11
11
  function byteLength(text) {
12
12
  return Buffer.byteLength(text, "utf-8");
@@ -32,10 +32,12 @@ export class OutputAccumulator {
32
32
  this.currentLineBytes = 0;
33
33
  this.hasOpenLine = false;
34
34
  this.finished = false;
35
+ this.tempFileUnavailable = false;
35
36
  this.maxLines = options.maxLines ?? DEFAULT_MAX_LINES;
36
37
  this.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
37
38
  this.maxRollingBytes = Math.max(this.maxBytes * 2, 1);
38
39
  this.tempFilePrefix = options.tempFilePrefix ?? `${APP_NAME}-output`;
40
+ this.tempDir = options.tempDir;
39
41
  }
40
42
  append(data) {
41
43
  if (this.finished) {
@@ -43,9 +45,9 @@ export class OutputAccumulator {
43
45
  }
44
46
  this.totalRawBytes += data.length;
45
47
  this.appendDecodedText(this.decoder.decode(data, { stream: true }));
46
- if (this.tempFileStream || this.shouldUseTempFile()) {
48
+ if (this.tempFile || this.shouldUseTempFile()) {
47
49
  this.ensureTempFile();
48
- this.tempFileStream?.write(data);
50
+ this.tempFile?.write(data);
49
51
  }
50
52
  else if (data.length > 0) {
51
53
  this.rawChunks.push(data);
@@ -89,24 +91,21 @@ export class OutputAccumulator {
89
91
  };
90
92
  }
91
93
  async closeTempFile() {
92
- if (!this.tempFileStream) {
94
+ const file = this.tempFile;
95
+ if (!file) {
93
96
  return;
94
97
  }
95
- const stream = this.tempFileStream;
96
- this.tempFileStream = undefined;
97
- await new Promise((resolve, reject) => {
98
- const onError = (error) => {
99
- stream.off("finish", onFinish);
100
- reject(error);
101
- };
102
- const onFinish = () => {
103
- stream.off("error", onError);
104
- resolve();
105
- };
106
- stream.once("error", onError);
107
- stream.once("finish", onFinish);
108
- stream.end();
109
- });
98
+ this.tempFile = undefined;
99
+ try {
100
+ await file.close();
101
+ }
102
+ catch (error) {
103
+ // A spill file that failed to flush must not be advertised: a later
104
+ // snapshot reports no path rather than one pointing at a broken file.
105
+ this.tempFilePath = undefined;
106
+ this.tempFileUnavailable = true;
107
+ throw error;
108
+ }
110
109
  }
111
110
  getLastLineBytes() {
112
111
  return this.currentLineBytes;
@@ -165,15 +164,38 @@ export class OutputAccumulator {
165
164
  return (this.totalRawBytes > this.maxBytes || this.totalDecodedBytes > this.maxBytes || this.totalLines > this.maxLines);
166
165
  }
167
166
  ensureTempFile() {
168
- if (this.tempFilePath) {
167
+ if (this.tempFilePath || this.tempFileUnavailable) {
169
168
  return;
170
169
  }
171
- this.tempFilePath = defaultTempFilePath(this.tempFilePrefix);
172
- this.tempFileStream = createWriteStream(this.tempFilePath);
173
- for (const chunk of this.rawChunks) {
174
- this.tempFileStream.write(chunk);
170
+ let file;
171
+ try {
172
+ const path = defaultTempFilePath(this.tempFilePrefix, this.tempDir);
173
+ file = new PersistedOutputFile(path);
174
+ for (const chunk of this.rawChunks) {
175
+ file.write(chunk);
176
+ }
177
+ // Publish the pair only after creation and replay both succeed. Callers
178
+ // must never observe a path for a writer that did not open or could not
179
+ // accept the output buffered before the spill threshold.
180
+ this.tempFile = file;
181
+ this.tempFilePath = path;
182
+ this.rawChunks = [];
183
+ }
184
+ catch {
185
+ // Persistence is a convenience. Refusal by the directory helper, EMFILE,
186
+ // ENOSPC, EACCES, or a replay failure must leave bounded output available
187
+ // without a dangling path, retained raw chunks, or retries on later appends.
188
+ this.tempFileUnavailable = true;
189
+ this.tempFilePath = undefined;
190
+ this.tempFile = undefined;
191
+ this.rawChunks = [];
192
+ try {
193
+ file?.end();
194
+ }
195
+ catch {
196
+ // Best effort: there is no path to advertise and no writer to reuse.
197
+ }
175
198
  }
176
- this.rawChunks = [];
177
199
  }
178
200
  }
179
201
  //# sourceMappingURL=output-accumulator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"output-accumulator.js","sourceRoot":"","sources":["../../../src/core/tools/output-accumulator.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { createWriteStream, type WriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { APP_NAME } from \"../../config.ts\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, type TruncationResult, truncateTail } from \"./truncate.ts\";\n\nexport interface OutputAccumulatorOptions {\n\tmaxLines?: number;\n\tmaxBytes?: number;\n\ttempFilePrefix?: string;\n}\n\nexport interface OutputSnapshot {\n\tcontent: string;\n\ttruncation: TruncationResult;\n\tfullOutputPath?: string;\n}\n\nfunction defaultTempFilePath(prefix: string): string {\n\tconst id = randomBytes(8).toString(\"hex\");\n\treturn join(tmpdir(), `${prefix}-${id}.log`);\n}\n\nfunction byteLength(text: string): number {\n\treturn Buffer.byteLength(text, \"utf-8\");\n}\n\n/**\n * Incrementally tracks streaming output with bounded memory.\n *\n * Appends decode chunks with a streaming UTF-8 decoder, keeps only a decoded\n * tail for display snapshots, and opens a temp file when the full output needs\n * to be preserved.\n */\nexport class OutputAccumulator {\n\tprivate readonly maxLines: number;\n\tprivate readonly maxBytes: number;\n\tprivate readonly maxRollingBytes: number;\n\tprivate readonly tempFilePrefix: string;\n\tprivate readonly decoder = new TextDecoder();\n\n\tprivate rawChunks: Buffer[] = [];\n\tprivate tailText = \"\";\n\tprivate tailBytes = 0;\n\tprivate tailStartsAtLineBoundary = true;\n\tprivate totalRawBytes = 0;\n\tprivate totalDecodedBytes = 0;\n\tprivate completedLines = 0;\n\tprivate totalLines = 0;\n\tprivate currentLineBytes = 0;\n\tprivate hasOpenLine = false;\n\tprivate finished = false;\n\n\tprivate tempFilePath: string | undefined;\n\tprivate tempFileStream: WriteStream | undefined;\n\n\tconstructor(options: OutputAccumulatorOptions = {}) {\n\t\tthis.maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n\t\tthis.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n\t\tthis.maxRollingBytes = Math.max(this.maxBytes * 2, 1);\n\t\tthis.tempFilePrefix = options.tempFilePrefix ?? `${APP_NAME}-output`;\n\t}\n\n\tappend(data: Buffer): void {\n\t\tif (this.finished) {\n\t\t\tthrow new Error(\"Cannot append to a finished output accumulator\");\n\t\t}\n\n\t\tthis.totalRawBytes += data.length;\n\t\tthis.appendDecodedText(this.decoder.decode(data, { stream: true }));\n\n\t\tif (this.tempFileStream || this.shouldUseTempFile()) {\n\t\t\tthis.ensureTempFile();\n\t\t\tthis.tempFileStream?.write(data);\n\t\t} else if (data.length > 0) {\n\t\t\tthis.rawChunks.push(data);\n\t\t}\n\t}\n\n\tfinish(): void {\n\t\tif (this.finished) {\n\t\t\treturn;\n\t\t}\n\t\tthis.finished = true;\n\t\tthis.appendDecodedText(this.decoder.decode());\n\t\tif (this.shouldUseTempFile()) {\n\t\t\tthis.ensureTempFile();\n\t\t}\n\t}\n\n\tsnapshot(options: { persistIfTruncated?: boolean } = {}): OutputSnapshot {\n\t\tconst tailTruncation = truncateTail(this.getSnapshotText(), {\n\t\t\tmaxLines: this.maxLines,\n\t\t\tmaxBytes: this.maxBytes,\n\t\t});\n\t\tconst truncated = this.totalLines > this.maxLines || this.totalDecodedBytes > this.maxBytes;\n\t\tconst truncatedBy = truncated\n\t\t\t? (tailTruncation.truncatedBy ?? (this.totalDecodedBytes > this.maxBytes ? \"bytes\" : \"lines\"))\n\t\t\t: null;\n\t\tconst truncation: TruncationResult = {\n\t\t\t...tailTruncation,\n\t\t\ttruncated,\n\t\t\ttruncatedBy,\n\t\t\ttotalLines: this.totalLines,\n\t\t\ttotalBytes: this.totalDecodedBytes,\n\t\t\tmaxLines: this.maxLines,\n\t\t\tmaxBytes: this.maxBytes,\n\t\t};\n\n\t\tif (options.persistIfTruncated && truncation.truncated) {\n\t\t\tthis.ensureTempFile();\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: truncation.content,\n\t\t\ttruncation,\n\t\t\tfullOutputPath: this.tempFilePath,\n\t\t};\n\t}\n\n\tasync closeTempFile(): Promise<void> {\n\t\tif (!this.tempFileStream) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst stream = this.tempFileStream;\n\t\tthis.tempFileStream = undefined;\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst onError = (error: Error) => {\n\t\t\t\tstream.off(\"finish\", onFinish);\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\tconst onFinish = () => {\n\t\t\t\tstream.off(\"error\", onError);\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tstream.once(\"error\", onError);\n\t\t\tstream.once(\"finish\", onFinish);\n\t\t\tstream.end();\n\t\t});\n\t}\n\n\tgetLastLineBytes(): number {\n\t\treturn this.currentLineBytes;\n\t}\n\n\tprivate appendDecodedText(text: string): void {\n\t\tif (text.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst bytes = byteLength(text);\n\t\tthis.totalDecodedBytes += bytes;\n\t\tthis.tailText += text;\n\t\tthis.tailBytes += bytes;\n\t\tif (this.tailBytes > this.maxRollingBytes * 2) {\n\t\t\tthis.trimTail();\n\t\t}\n\n\t\tlet newlines = 0;\n\t\tlet lastNewline = -1;\n\t\tfor (let i = text.indexOf(\"\\n\"); i !== -1; i = text.indexOf(\"\\n\", i + 1)) {\n\t\t\tnewlines++;\n\t\t\tlastNewline = i;\n\t\t}\n\t\tif (newlines === 0) {\n\t\t\tthis.currentLineBytes += bytes;\n\t\t\tthis.hasOpenLine = true;\n\t\t} else {\n\t\t\tthis.completedLines += newlines;\n\t\t\tconst tail = text.slice(lastNewline + 1);\n\t\t\tthis.currentLineBytes = byteLength(tail);\n\t\t\tthis.hasOpenLine = tail.length > 0;\n\t\t}\n\t\tthis.totalLines = this.completedLines + (this.hasOpenLine ? 1 : 0);\n\t}\n\n\tprivate trimTail(): void {\n\t\tconst buffer = Buffer.from(this.tailText, \"utf-8\");\n\t\tif (buffer.length <= this.maxRollingBytes) {\n\t\t\tthis.tailBytes = buffer.length;\n\t\t\treturn;\n\t\t}\n\n\t\tlet start = buffer.length - this.maxRollingBytes;\n\t\twhile (start < buffer.length && (buffer[start] & 0xc0) === 0x80) {\n\t\t\tstart++;\n\t\t}\n\n\t\tthis.tailStartsAtLineBoundary = start === 0 ? this.tailStartsAtLineBoundary : buffer[start - 1] === 0x0a;\n\t\tthis.tailText = buffer.subarray(start).toString(\"utf-8\");\n\t\tthis.tailBytes = byteLength(this.tailText);\n\t}\n\n\tprivate getSnapshotText(): string {\n\t\tif (this.tailStartsAtLineBoundary) {\n\t\t\treturn this.tailText;\n\t\t}\n\n\t\tconst firstNewline = this.tailText.indexOf(\"\\n\");\n\t\treturn firstNewline === -1 ? this.tailText : this.tailText.slice(firstNewline + 1);\n\t}\n\n\tprivate shouldUseTempFile(): boolean {\n\t\treturn (\n\t\t\tthis.totalRawBytes > this.maxBytes || this.totalDecodedBytes > this.maxBytes || this.totalLines > this.maxLines\n\t\t);\n\t}\n\n\tprivate ensureTempFile(): void {\n\t\tif (this.tempFilePath) {\n\t\t\treturn;\n\t\t}\n\t\tthis.tempFilePath = defaultTempFilePath(this.tempFilePrefix);\n\t\tthis.tempFileStream = createWriteStream(this.tempFilePath);\n\t\tfor (const chunk of this.rawChunks) {\n\t\t\tthis.tempFileStream.write(chunk);\n\t\t}\n\t\tthis.rawChunks = [];\n\t}\n}\n"]}
1
+ {"version":3,"file":"output-accumulator.js","sourceRoot":"","sources":["../../../src/core/tools/output-accumulator.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport { APP_NAME } from \"../../config.ts\";\nimport { PersistedOutputFile } from \"./persisted-output-file.ts\";\nimport { ensureSessionTempDir } from \"./session-temp-dir.ts\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, type TruncationResult, truncateTail } from \"./truncate.ts\";\n\nexport interface OutputAccumulatorOptions {\n\tmaxLines?: number;\n\tmaxBytes?: number;\n\ttempFilePrefix?: string;\n\t/**\n\t * Session-scoped directory for the spill file. Defaults to the active\n\t * session's temp directory so spill files are reapable per session.\n\t */\n\ttempDir?: string;\n}\n\nexport interface OutputSnapshot {\n\tcontent: string;\n\ttruncation: TruncationResult;\n\tfullOutputPath?: string;\n}\n\nfunction defaultTempFilePath(prefix: string, tempDir: string | undefined): string {\n\tconst id = randomBytes(8).toString(\"hex\");\n\treturn join(ensureSessionTempDir(tempDir), `${prefix}-${id}.log`);\n}\n\nfunction byteLength(text: string): number {\n\treturn Buffer.byteLength(text, \"utf-8\");\n}\n\n/**\n * Incrementally tracks streaming output with bounded memory.\n *\n * Appends decode chunks with a streaming UTF-8 decoder, keeps only a decoded\n * tail for display snapshots, and opens a temp file when the full output needs\n * to be preserved.\n */\nexport class OutputAccumulator {\n\tprivate readonly maxLines: number;\n\tprivate readonly maxBytes: number;\n\tprivate readonly maxRollingBytes: number;\n\tprivate readonly tempFilePrefix: string;\n\tprivate readonly tempDir: string | undefined;\n\tprivate readonly decoder = new TextDecoder();\n\n\tprivate rawChunks: Buffer[] = [];\n\tprivate tailText = \"\";\n\tprivate tailBytes = 0;\n\tprivate tailStartsAtLineBoundary = true;\n\tprivate totalRawBytes = 0;\n\tprivate totalDecodedBytes = 0;\n\tprivate completedLines = 0;\n\tprivate totalLines = 0;\n\tprivate currentLineBytes = 0;\n\tprivate hasOpenLine = false;\n\tprivate finished = false;\n\n\tprivate tempFilePath: string | undefined;\n\tprivate tempFile: PersistedOutputFile | undefined;\n\tprivate tempFileUnavailable = false;\n\n\tconstructor(options: OutputAccumulatorOptions = {}) {\n\t\tthis.maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n\t\tthis.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n\t\tthis.maxRollingBytes = Math.max(this.maxBytes * 2, 1);\n\t\tthis.tempFilePrefix = options.tempFilePrefix ?? `${APP_NAME}-output`;\n\t\tthis.tempDir = options.tempDir;\n\t}\n\n\tappend(data: Buffer): void {\n\t\tif (this.finished) {\n\t\t\tthrow new Error(\"Cannot append to a finished output accumulator\");\n\t\t}\n\n\t\tthis.totalRawBytes += data.length;\n\t\tthis.appendDecodedText(this.decoder.decode(data, { stream: true }));\n\n\t\tif (this.tempFile || this.shouldUseTempFile()) {\n\t\t\tthis.ensureTempFile();\n\t\t\tthis.tempFile?.write(data);\n\t\t} else if (data.length > 0) {\n\t\t\tthis.rawChunks.push(data);\n\t\t}\n\t}\n\n\tfinish(): void {\n\t\tif (this.finished) {\n\t\t\treturn;\n\t\t}\n\t\tthis.finished = true;\n\t\tthis.appendDecodedText(this.decoder.decode());\n\t\tif (this.shouldUseTempFile()) {\n\t\t\tthis.ensureTempFile();\n\t\t}\n\t}\n\n\tsnapshot(options: { persistIfTruncated?: boolean } = {}): OutputSnapshot {\n\t\tconst tailTruncation = truncateTail(this.getSnapshotText(), {\n\t\t\tmaxLines: this.maxLines,\n\t\t\tmaxBytes: this.maxBytes,\n\t\t});\n\t\tconst truncated = this.totalLines > this.maxLines || this.totalDecodedBytes > this.maxBytes;\n\t\tconst truncatedBy = truncated\n\t\t\t? (tailTruncation.truncatedBy ?? (this.totalDecodedBytes > this.maxBytes ? \"bytes\" : \"lines\"))\n\t\t\t: null;\n\t\tconst truncation: TruncationResult = {\n\t\t\t...tailTruncation,\n\t\t\ttruncated,\n\t\t\ttruncatedBy,\n\t\t\ttotalLines: this.totalLines,\n\t\t\ttotalBytes: this.totalDecodedBytes,\n\t\t\tmaxLines: this.maxLines,\n\t\t\tmaxBytes: this.maxBytes,\n\t\t};\n\n\t\tif (options.persistIfTruncated && truncation.truncated) {\n\t\t\tthis.ensureTempFile();\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: truncation.content,\n\t\t\ttruncation,\n\t\t\tfullOutputPath: this.tempFilePath,\n\t\t};\n\t}\n\n\tasync closeTempFile(): Promise<void> {\n\t\tconst file = this.tempFile;\n\t\tif (!file) {\n\t\t\treturn;\n\t\t}\n\t\tthis.tempFile = undefined;\n\t\ttry {\n\t\t\tawait file.close();\n\t\t} catch (error) {\n\t\t\t// A spill file that failed to flush must not be advertised: a later\n\t\t\t// snapshot reports no path rather than one pointing at a broken file.\n\t\t\tthis.tempFilePath = undefined;\n\t\t\tthis.tempFileUnavailable = true;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tgetLastLineBytes(): number {\n\t\treturn this.currentLineBytes;\n\t}\n\n\tprivate appendDecodedText(text: string): void {\n\t\tif (text.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst bytes = byteLength(text);\n\t\tthis.totalDecodedBytes += bytes;\n\t\tthis.tailText += text;\n\t\tthis.tailBytes += bytes;\n\t\tif (this.tailBytes > this.maxRollingBytes * 2) {\n\t\t\tthis.trimTail();\n\t\t}\n\n\t\tlet newlines = 0;\n\t\tlet lastNewline = -1;\n\t\tfor (let i = text.indexOf(\"\\n\"); i !== -1; i = text.indexOf(\"\\n\", i + 1)) {\n\t\t\tnewlines++;\n\t\t\tlastNewline = i;\n\t\t}\n\t\tif (newlines === 0) {\n\t\t\tthis.currentLineBytes += bytes;\n\t\t\tthis.hasOpenLine = true;\n\t\t} else {\n\t\t\tthis.completedLines += newlines;\n\t\t\tconst tail = text.slice(lastNewline + 1);\n\t\t\tthis.currentLineBytes = byteLength(tail);\n\t\t\tthis.hasOpenLine = tail.length > 0;\n\t\t}\n\t\tthis.totalLines = this.completedLines + (this.hasOpenLine ? 1 : 0);\n\t}\n\n\tprivate trimTail(): void {\n\t\tconst buffer = Buffer.from(this.tailText, \"utf-8\");\n\t\tif (buffer.length <= this.maxRollingBytes) {\n\t\t\tthis.tailBytes = buffer.length;\n\t\t\treturn;\n\t\t}\n\n\t\tlet start = buffer.length - this.maxRollingBytes;\n\t\twhile (start < buffer.length && (buffer[start] & 0xc0) === 0x80) {\n\t\t\tstart++;\n\t\t}\n\n\t\tthis.tailStartsAtLineBoundary = start === 0 ? this.tailStartsAtLineBoundary : buffer[start - 1] === 0x0a;\n\t\tthis.tailText = buffer.subarray(start).toString(\"utf-8\");\n\t\tthis.tailBytes = byteLength(this.tailText);\n\t}\n\n\tprivate getSnapshotText(): string {\n\t\tif (this.tailStartsAtLineBoundary) {\n\t\t\treturn this.tailText;\n\t\t}\n\n\t\tconst firstNewline = this.tailText.indexOf(\"\\n\");\n\t\treturn firstNewline === -1 ? this.tailText : this.tailText.slice(firstNewline + 1);\n\t}\n\n\tprivate shouldUseTempFile(): boolean {\n\t\treturn (\n\t\t\tthis.totalRawBytes > this.maxBytes || this.totalDecodedBytes > this.maxBytes || this.totalLines > this.maxLines\n\t\t);\n\t}\n\n\tprivate ensureTempFile(): void {\n\t\tif (this.tempFilePath || this.tempFileUnavailable) {\n\t\t\treturn;\n\t\t}\n\t\tlet file: PersistedOutputFile | undefined;\n\t\ttry {\n\t\t\tconst path = defaultTempFilePath(this.tempFilePrefix, this.tempDir);\n\t\t\tfile = new PersistedOutputFile(path);\n\t\t\tfor (const chunk of this.rawChunks) {\n\t\t\t\tfile.write(chunk);\n\t\t\t}\n\t\t\t// Publish the pair only after creation and replay both succeed. Callers\n\t\t\t// must never observe a path for a writer that did not open or could not\n\t\t\t// accept the output buffered before the spill threshold.\n\t\t\tthis.tempFile = file;\n\t\t\tthis.tempFilePath = path;\n\t\t\tthis.rawChunks = [];\n\t\t} catch {\n\t\t\t// Persistence is a convenience. Refusal by the directory helper, EMFILE,\n\t\t\t// ENOSPC, EACCES, or a replay failure must leave bounded output available\n\t\t\t// without a dangling path, retained raw chunks, or retries on later appends.\n\t\t\tthis.tempFileUnavailable = true;\n\t\t\tthis.tempFilePath = undefined;\n\t\t\tthis.tempFile = undefined;\n\t\t\tthis.rawChunks = [];\n\t\t\ttry {\n\t\t\t\tfile?.end();\n\t\t\t} catch {\n\t\t\t\t// Best effort: there is no path to advertise and no writer to reuse.\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"oversized-tool-result.d.ts","sourceRoot":"","sources":["../../../src/core/tools/oversized-tool-result.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAU9E;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,0BAA0B,CAAC,EAAE,MAAM,GAAG,MAAM,CAQnF;AAED,MAAM,WAAW,gCAAgC,CAAC,QAAQ,GAAG,OAAO;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;IAC/D,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yFAAyF;IACzF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,8BAA8B;IAC9C,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAc1D;AAcD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA4BxG;AA4FD;;;;;;;;;;;GAWG;AACH,wBAAsB,2BAA2B,CAAC,QAAQ,GAAG,OAAO,EACnE,KAAK,EAAE,gCAAgC,CAAC,QAAQ,CAAC,GAC/C,OAAO,CAAC,8BAA8B,GAAG,SAAS,CAAC,CAwCrD"}
1
+ {"version":3,"file":"oversized-tool-result.d.ts","sourceRoot":"","sources":["../../../src/core/tools/oversized-tool-result.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAiB9E;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,0BAA0B,CAAC,EAAE,MAAM,GAAG,MAAM,CAQnF;AAED,MAAM,WAAW,gCAAgC,CAAC,QAAQ,GAAG,OAAO;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;IAC/D,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yFAAyF;IACzF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,8BAA8B;IAC9C,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAc1D;AAcD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA4BxG;AAyMD;;;;;;;;;;;GAWG;AACH,wBAAsB,2BAA2B,CAAC,QAAQ,GAAG,OAAO,EACnE,KAAK,EAAE,gCAAgC,CAAC,QAAQ,CAAC,GAC/C,OAAO,CAAC,8BAA8B,GAAG,SAAS,CAAC,CAwCrD"}
@@ -1,8 +1,10 @@
1
1
  import { Buffer } from "node:buffer";
2
- import { mkdir, writeFile } from "node:fs/promises";
3
- import { tmpdir } from "node:os";
2
+ import { constants } from "node:fs";
3
+ import { chmod, lstat, mkdir, open } from "node:fs/promises";
4
4
  import { join } from "node:path";
5
- import { APP_NAME } from "../../config.js";
5
+ import { getErrnoCode } from "./errno.js";
6
+ import { capPersistedText } from "./persisted-output-file.js";
7
+ import { ensureTempDir, resolveSessionTempDirPath, SESSION_TEMP_DIR_MODE, SESSION_TEMP_FILE_MODE, } from "./session-temp-dir.js";
6
8
  import { DEFAULT_MAX_RESULT_SIZE_CHARS, PERSISTED_OUTPUT_CLOSING_TAG, PERSISTED_OUTPUT_TAG, PREVIEW_SIZE_BYTES, TOOL_RESULTS_SUBDIR, } from "./tool-limits.js";
7
9
  /**
8
10
  * Resolve the effective persistence threshold (in characters) for a tool.
@@ -112,22 +114,113 @@ function sanitizePathComponent(value, fallback) {
112
114
  const sanitized = trimUnderscores(value.replace(/[^a-zA-Z0-9._-]+/g, "_")).slice(0, 64);
113
115
  return sanitized.length > 0 ? sanitized : fallback;
114
116
  }
115
- /** Session-scoped directory for persisted tool results: `<sessionDir>/tool-results`. */
116
- function getToolResultsDir(input) {
117
+ /**
118
+ * Session-scoped directory for persisted tool results.
119
+ *
120
+ * A disk-backed session owns `<sessionDir>/tool-results`. It is created here and
121
+ * then chmodded, because `mode` on mkdir is only a request the process umask
122
+ * narrows — a umask of 0o777 otherwise leaves a directory at 000 that nothing,
123
+ * this process included, can write into.
124
+ *
125
+ * An in-memory session falls back to the owner- and session-scoped temp tree, so
126
+ * the sweeper can reap it once the session is gone — and that path goes through
127
+ * {@link ensureTempDir}, which validates every component below the system temp
128
+ * directory instead of letting `mkdir -p` follow a planted link.
129
+ */
130
+ async function ensureToolResultsDir(input) {
117
131
  if (input.sessionDir?.trim()) {
118
- return join(input.sessionDir, TOOL_RESULTS_SUBDIR);
132
+ const dir = join(input.sessionDir, TOOL_RESULTS_SUBDIR);
133
+ await mkdir(dir, { recursive: true, mode: SESSION_TEMP_DIR_MODE });
134
+ if (process.platform !== "win32") {
135
+ await chmod(dir, SESSION_TEMP_DIR_MODE);
136
+ }
137
+ return dir;
138
+ }
139
+ return ensureTempDir(join(resolveSessionTempDirPath(input.sessionId), TOOL_RESULTS_SUBDIR));
140
+ }
141
+ function isOwnedByCurrentUser(uid) {
142
+ const currentUid = typeof process.getuid === "function" ? process.getuid() : undefined;
143
+ if (typeof currentUid !== "number") {
144
+ return true;
145
+ }
146
+ return typeof uid === "bigint" ? uid === BigInt(currentUid) : uid === currentUid;
147
+ }
148
+ function sameFileIdentity(left, right) {
149
+ return left.dev === right.dev && left.ino === right.ino;
150
+ }
151
+ /**
152
+ * Force an open persisted file to owner-only and prove it.
153
+ *
154
+ * `mode` on open is a request the process umask narrows, so a hostile or merely
155
+ * odd umask can leave the file at 000 — advertised but unreadable. Throws when
156
+ * the mode cannot be reached or the file belongs to another account.
157
+ */
158
+ async function enforceOwnerOnlyMode(handle, filepath) {
159
+ if (process.platform === "win32") {
160
+ return;
161
+ }
162
+ const before = await handle.stat();
163
+ if (!isOwnedByCurrentUser(before.uid)) {
164
+ throw new Error(`persisted tool result ${filepath} is owned by another account`);
165
+ }
166
+ await handle.chmod(SESSION_TEMP_FILE_MODE);
167
+ const after = await handle.stat();
168
+ if ((after.mode & 0o777) !== SESSION_TEMP_FILE_MODE) {
169
+ throw new Error(`persisted tool result ${filepath} could not be restricted to 0600`);
170
+ }
171
+ if (!isOwnedByCurrentUser(after.uid)) {
172
+ throw new Error(`persisted tool result ${filepath} is owned by another account`);
119
173
  }
120
- // Fall back to a stable session-scoped temp directory for in-memory sessions.
121
- const safeApp = sanitizePathComponent(APP_NAME || "atomic", "atomic");
122
- const safeSessionId = sanitizePathComponent(input.sessionId || "session", "session");
123
- return join(tmpdir(), `${safeApp}-${TOOL_RESULTS_SUBDIR}`, safeSessionId);
124
174
  }
125
- function getErrnoCode(error) {
126
- if (error && typeof error === "object" && "code" in error) {
127
- const code = error.code;
128
- return typeof code === "string" ? code : undefined;
175
+ /**
176
+ * Validate a file left by a previous turn before advertising it again.
177
+ *
178
+ * The replay path is what makes repeated calls idempotent, but a file that is no
179
+ * longer ours, or is no longer owner-only, must not be handed back. It is never
180
+ * deleted either: refusing costs a preview, deleting could destroy someone
181
+ * else's data.
182
+ */
183
+ async function adoptExistingResultFile(filepath) {
184
+ try {
185
+ const initialPathStat = await lstat(filepath, { bigint: true });
186
+ if (initialPathStat.isSymbolicLink() || !initialPathStat.isFile() || !isOwnedByCurrentUser(initialPathStat.uid)) {
187
+ return false;
188
+ }
189
+ const noFollow = process.platform !== "win32" && typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0;
190
+ const handle = await open(filepath, constants.O_RDONLY | noFollow);
191
+ try {
192
+ const handleStat = await handle.stat({ bigint: true });
193
+ if (!handleStat.isFile() || !sameFileIdentity(initialPathStat, handleStat)) {
194
+ return false;
195
+ }
196
+ const pathBeforeChmod = await lstat(filepath, { bigint: true });
197
+ if (pathBeforeChmod.isSymbolicLink() ||
198
+ !pathBeforeChmod.isFile() ||
199
+ !sameFileIdentity(initialPathStat, pathBeforeChmod) ||
200
+ !sameFileIdentity(handleStat, pathBeforeChmod) ||
201
+ !isOwnedByCurrentUser(pathBeforeChmod.uid)) {
202
+ return false;
203
+ }
204
+ await enforceOwnerOnlyMode(handle, filepath);
205
+ // Do not advertise a path replaced while the descriptor was open.
206
+ const [finalPathStat, finalHandleStat] = await Promise.all([
207
+ lstat(filepath, { bigint: true }),
208
+ handle.stat({ bigint: true }),
209
+ ]);
210
+ return (!finalPathStat.isSymbolicLink() &&
211
+ finalPathStat.isFile() &&
212
+ finalHandleStat.isFile() &&
213
+ sameFileIdentity(finalPathStat, finalHandleStat) &&
214
+ isOwnedByCurrentUser(finalPathStat.uid) &&
215
+ isOwnedByCurrentUser(finalHandleStat.uid));
216
+ }
217
+ finally {
218
+ await handle.close();
219
+ }
220
+ }
221
+ catch {
222
+ return false;
129
223
  }
130
- return undefined;
131
224
  }
132
225
  /**
133
226
  * Persist the full tool output to a session-scoped file and return its path.
@@ -139,17 +232,31 @@ function getErrnoCode(error) {
139
232
  * returning the original result unchanged.
140
233
  */
141
234
  async function persistToolOutput(input) {
142
- const dir = getToolResultsDir({ sessionDir: input.sessionDir, sessionId: input.sessionId });
143
- const fileName = `${sanitizePathComponent(input.toolCallId, "tool-result")}.txt`;
144
- const filepath = join(dir, fileName);
235
+ let dir;
145
236
  try {
146
- await mkdir(dir, { recursive: true, mode: 0o700 });
147
- await writeFile(filepath, input.text, { encoding: "utf8", mode: 0o600, flag: "wx" });
237
+ dir = await ensureToolResultsDir({ sessionDir: input.sessionDir, sessionId: input.sessionId });
238
+ }
239
+ catch {
240
+ // Refused (see TempDirRefusedError) or unwritable: leave the result unchanged
241
+ // rather than pointing the model at a directory we do not own.
242
+ return undefined;
243
+ }
244
+ const filepath = join(dir, `${sanitizePathComponent(input.toolCallId, "tool-result")}.txt`);
245
+ try {
246
+ const handle = await open(filepath, "wx", SESSION_TEMP_FILE_MODE);
247
+ try {
248
+ await handle.writeFile(capPersistedText(input.text), "utf8");
249
+ await enforceOwnerOnlyMode(handle, filepath);
250
+ }
251
+ finally {
252
+ await handle.close();
253
+ }
148
254
  }
149
255
  catch (error) {
150
256
  if (getErrnoCode(error) === "EEXIST") {
151
- // Already persisted on a prior turn — reuse the existing file.
152
- return filepath;
257
+ // Already persisted on a prior turn — reuse the existing file, but only
258
+ // after confirming it is still ours and still owner-only.
259
+ return (await adoptExistingResultFile(filepath)) ? filepath : undefined;
153
260
  }
154
261
  return undefined;
155
262
  }
@@ -1 +1 @@
1
- {"version":3,"file":"oversized-tool-result.js","sourceRoot":"","sources":["../../../src/core/tools/oversized-tool-result.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from \"node:buffer\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { ImageContent, TextContent } from \"@earendil-works/pi-ai/compat\";\nimport { APP_NAME } from \"../../config.ts\";\nimport {\n\tDEFAULT_MAX_RESULT_SIZE_CHARS,\n\tPERSISTED_OUTPUT_CLOSING_TAG,\n\tPERSISTED_OUTPUT_TAG,\n\tPREVIEW_SIZE_BYTES,\n\tTOOL_RESULTS_SUBDIR,\n} from \"./tool-limits.js\";\n\n/**\n * Resolve the effective persistence threshold (in characters) for a tool.\n *\n * Mirrors the upstream `getPersistenceThreshold` convention: a tool may declare a\n * lower per-tool cap, but the global {@link DEFAULT_MAX_RESULT_SIZE_CHARS} acts as\n * a system-wide ceiling. `Infinity` is a hard opt-out for self-bounded tools whose\n * output is already a file the model reads back, where persisting would be circular.\n */\nexport function getPersistenceThreshold(declaredMaxResultSizeChars?: number): number {\n\tif (declaredMaxResultSizeChars === undefined) {\n\t\treturn DEFAULT_MAX_RESULT_SIZE_CHARS;\n\t}\n\tif (!Number.isFinite(declaredMaxResultSizeChars)) {\n\t\treturn declaredMaxResultSizeChars;\n\t}\n\treturn Math.min(declaredMaxResultSizeChars, DEFAULT_MAX_RESULT_SIZE_CHARS);\n}\n\nexport interface RedirectOversizedToolResultInput<TDetails = unknown> {\n\ttoolName: string;\n\ttoolCallId: string;\n\tresult: Pick<AgentToolResult<TDetails>, \"content\" | \"details\">;\n\tisError: boolean;\n\tsessionId: string;\n\tsessionDir?: string;\n\t/** Optional per-tool character cap; clamped by {@link DEFAULT_MAX_RESULT_SIZE_CHARS}. */\n\tmaxResultSizeChars?: number;\n}\n\nexport interface OversizedToolResultReplacement {\n\tcontent: TextContent[];\n\tdetails: unknown;\n\tisError: boolean;\n}\n\n/**\n * Human-readable byte size, e.g. `1536` → \"1.5KB\". Intentionally mirrors\n * upstream Claude Code `formatFileSize` wording instead of using tools/truncate.ts.\n */\nexport function formatFileSize(sizeInBytes: number): string {\n\tconst kb = sizeInBytes / 1024;\n\tif (kb < 1) {\n\t\treturn `${sizeInBytes} bytes`;\n\t}\n\tif (kb < 1024) {\n\t\treturn `${kb.toFixed(1).replace(/\\.0$/, \"\")}KB`;\n\t}\n\tconst mb = kb / 1024;\n\tif (mb < 1024) {\n\t\treturn `${mb.toFixed(1).replace(/\\.0$/, \"\")}MB`;\n\t}\n\tconst gb = mb / 1024;\n\treturn `${gb.toFixed(1).replace(/\\.0$/, \"\")}GB`;\n}\n\nfunction hasImageBlock(content: readonly (TextContent | ImageContent)[]): boolean {\n\treturn content.some((block) => block.type === \"image\");\n}\n\n/** Concatenate the text blocks of a tool result into a single string. */\nfunction collectText(content: readonly (TextContent | ImageContent)[]): string {\n\treturn content\n\t\t.filter((block): block is TextContent => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\");\n}\n\n/**\n * Generate a preview of content, truncating at a newline boundary when possible.\n * Ported from the reference `generatePreview`.\n */\nexport function generatePreview(content: string, maxBytes: number): { preview: string; hasMore: boolean } {\n\tif (Buffer.byteLength(content, \"utf8\") <= maxBytes) {\n\t\treturn { preview: content, hasMore: false };\n\t}\n\n\tlet bytes = 0;\n\tlet hardCutIndex = 0;\n\tlet lastNewlineIndex = -1;\n\tlet lastNewlineBytes = 0;\n\n\tfor (const character of content) {\n\t\tconst characterBytes = Buffer.byteLength(character, \"utf8\");\n\t\tif (bytes + characterBytes > maxBytes) {\n\t\t\tbreak;\n\t\t}\n\t\tconst characterStartIndex = hardCutIndex;\n\t\tbytes += characterBytes;\n\t\thardCutIndex += character.length;\n\t\tif (character === \"\\n\") {\n\t\t\tlastNewlineIndex = characterStartIndex;\n\t\t\tlastNewlineBytes = bytes - characterBytes;\n\t\t}\n\t}\n\n\t// Find the last newline within the byte limit to avoid cutting mid-line;\n\t// fall back to the hard byte limit when the newline is too close to the start.\n\tconst cutPoint = lastNewlineBytes > maxBytes * 0.5 ? lastNewlineIndex : hardCutIndex;\n\treturn { preview: content.slice(0, cutPoint), hasMore: true };\n}\n\n/**\n * Build the `<persisted-output>` preview message shown to the model in place of\n * the oversized content. Ported from the reference `buildLargeToolResultMessage`.\n */\nfunction buildPersistedOutputMessage(input: {\n\toriginalSizeBytes: number;\n\tfilepath: string;\n\tpreview: string;\n\thasMore: boolean;\n}): string {\n\tlet message = `${PERSISTED_OUTPUT_TAG}\\n`;\n\tmessage += `Output too large (${formatFileSize(input.originalSizeBytes)}). Full output saved to: ${input.filepath}\\n\\n`;\n\tmessage += `Preview (first ${formatFileSize(PREVIEW_SIZE_BYTES)}):\\n`;\n\tmessage += input.preview;\n\tmessage += input.hasMore ? \"\\n...\\n\" : \"\\n\";\n\tmessage += PERSISTED_OUTPUT_CLOSING_TAG;\n\treturn message;\n}\n\n/** Strip leading/trailing underscores with a linear scan (no backtracking regex). */\nfunction trimUnderscores(value: string): string {\n\tlet start = 0;\n\tlet end = value.length;\n\twhile (start < end && value[start] === \"_\") {\n\t\tstart++;\n\t}\n\twhile (end > start && value[end - 1] === \"_\") {\n\t\tend--;\n\t}\n\treturn value.slice(start, end);\n}\n\nfunction sanitizePathComponent(value: string, fallback: string): string {\n\t// Collapse disallowed characters to \"_\", then strip leading/trailing \"_\". The trim uses\n\t// a manual linear scan instead of a /^_+|_+$/ regex to avoid a polynomial-time ReDoS on\n\t// tool-call ids containing long runs of underscores (CodeQL js/polynomial-redos).\n\tconst sanitized = trimUnderscores(value.replace(/[^a-zA-Z0-9._-]+/g, \"_\")).slice(0, 64);\n\treturn sanitized.length > 0 ? sanitized : fallback;\n}\n\n/** Session-scoped directory for persisted tool results: `<sessionDir>/tool-results`. */\nfunction getToolResultsDir(input: { sessionDir?: string; sessionId: string }): string {\n\tif (input.sessionDir?.trim()) {\n\t\treturn join(input.sessionDir, TOOL_RESULTS_SUBDIR);\n\t}\n\t// Fall back to a stable session-scoped temp directory for in-memory sessions.\n\tconst safeApp = sanitizePathComponent(APP_NAME || \"atomic\", \"atomic\");\n\tconst safeSessionId = sanitizePathComponent(input.sessionId || \"session\", \"session\");\n\treturn join(tmpdir(), `${safeApp}-${TOOL_RESULTS_SUBDIR}`, safeSessionId);\n}\n\nfunction getErrnoCode(error: unknown): string | undefined {\n\tif (error && typeof error === \"object\" && \"code\" in error) {\n\t\tconst code = (error as { code?: unknown }).code;\n\t\treturn typeof code === \"string\" ? code : undefined;\n\t}\n\treturn undefined;\n}\n\n/**\n * Persist the full tool output to a session-scoped file and return its path.\n *\n * The tool_use_id is unique per invocation and the content is deterministic for a\n * given id, so we write with the `wx` flag and treat `EEXIST` as success — this\n * makes repeated calls (e.g. replay/compaction) idempotent without rewriting.\n * Returns `undefined` on any other write failure so the caller can fall back to\n * returning the original result unchanged.\n */\nasync function persistToolOutput(input: {\n\ttext: string;\n\tsessionDir?: string;\n\tsessionId: string;\n\ttoolCallId: string;\n}): Promise<string | undefined> {\n\tconst dir = getToolResultsDir({ sessionDir: input.sessionDir, sessionId: input.sessionId });\n\tconst fileName = `${sanitizePathComponent(input.toolCallId, \"tool-result\")}.txt`;\n\tconst filepath = join(dir, fileName);\n\ttry {\n\t\tawait mkdir(dir, { recursive: true, mode: 0o700 });\n\t\tawait writeFile(filepath, input.text, { encoding: \"utf8\", mode: 0o600, flag: \"wx\" });\n\t} catch (error) {\n\t\tif (getErrnoCode(error) === \"EEXIST\") {\n\t\t\t// Already persisted on a prior turn — reuse the existing file.\n\t\t\treturn filepath;\n\t\t}\n\t\treturn undefined;\n\t}\n\treturn filepath;\n}\n\n/**\n * When a tool result's text content exceeds the persistence threshold (default\n * 50,000 chars — {@link DEFAULT_MAX_RESULT_SIZE_CHARS}), persist the full output\n * to a session-scoped file and replace the model-visible content with a\n * `<persisted-output>` preview that references the saved file.\n *\n * Returns `undefined` (leave the result untouched) when the result is within the\n * threshold, contains image blocks, or cannot be persisted to disk.\n *\n * Convention ported from the upstream `maybePersistLargeToolResult`\n * (mehmoodosman/claude-code, `src/utils/toolResultStorage.ts`).\n */\nexport async function redirectOversizedToolResult<TDetails = unknown>(\n\tinput: RedirectOversizedToolResultInput<TDetails>,\n): Promise<OversizedToolResultReplacement | undefined> {\n\tconst content = input.result.content;\n\n\t// Image content must be sent to the model as-is; never persist.\n\tif (hasImageBlock(content)) {\n\t\treturn undefined;\n\t}\n\n\tconst text = collectText(content);\n\tconst threshold = getPersistenceThreshold(input.maxResultSizeChars);\n\tif (text.length <= threshold) {\n\t\treturn undefined;\n\t}\n\n\tconst filepath = await persistToolOutput({\n\t\ttext,\n\t\tsessionDir: input.sessionDir,\n\t\tsessionId: input.sessionId,\n\t\ttoolCallId: input.toolCallId,\n\t});\n\t// Graceful degradation: if persistence failed, leave the original result unchanged.\n\tif (filepath === undefined) {\n\t\treturn undefined;\n\t}\n\n\tconst { preview, hasMore } = generatePreview(text, PREVIEW_SIZE_BYTES);\n\tconst message = buildPersistedOutputMessage({\n\t\toriginalSizeBytes: Buffer.byteLength(text, \"utf8\"),\n\t\tfilepath,\n\t\tpreview,\n\t\thasMore,\n\t});\n\n\treturn {\n\t\tcontent: [{ type: \"text\", text: message }],\n\t\t// Details (tool metadata) are passed through untouched, matching the reference\n\t\t// convention which only replaces the model-visible content block.\n\t\tdetails: input.result.details,\n\t\tisError: input.isError,\n\t};\n}\n"]}
1
+ {"version":3,"file":"oversized-tool-result.js","sourceRoot":"","sources":["../../../src/core/tools/oversized-tool-result.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from \"node:buffer\";\nimport { constants } from \"node:fs\";\nimport type { FileHandle } from \"node:fs/promises\";\nimport { chmod, lstat, mkdir, open } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { ImageContent, TextContent } from \"@earendil-works/pi-ai/compat\";\nimport { getErrnoCode } from \"./errno.ts\";\nimport { capPersistedText } from \"./persisted-output-file.ts\";\nimport {\n\tensureTempDir,\n\tresolveSessionTempDirPath,\n\tSESSION_TEMP_DIR_MODE,\n\tSESSION_TEMP_FILE_MODE,\n} from \"./session-temp-dir.ts\";\nimport {\n\tDEFAULT_MAX_RESULT_SIZE_CHARS,\n\tPERSISTED_OUTPUT_CLOSING_TAG,\n\tPERSISTED_OUTPUT_TAG,\n\tPREVIEW_SIZE_BYTES,\n\tTOOL_RESULTS_SUBDIR,\n} from \"./tool-limits.js\";\n\n/**\n * Resolve the effective persistence threshold (in characters) for a tool.\n *\n * Mirrors the upstream `getPersistenceThreshold` convention: a tool may declare a\n * lower per-tool cap, but the global {@link DEFAULT_MAX_RESULT_SIZE_CHARS} acts as\n * a system-wide ceiling. `Infinity` is a hard opt-out for self-bounded tools whose\n * output is already a file the model reads back, where persisting would be circular.\n */\nexport function getPersistenceThreshold(declaredMaxResultSizeChars?: number): number {\n\tif (declaredMaxResultSizeChars === undefined) {\n\t\treturn DEFAULT_MAX_RESULT_SIZE_CHARS;\n\t}\n\tif (!Number.isFinite(declaredMaxResultSizeChars)) {\n\t\treturn declaredMaxResultSizeChars;\n\t}\n\treturn Math.min(declaredMaxResultSizeChars, DEFAULT_MAX_RESULT_SIZE_CHARS);\n}\n\nexport interface RedirectOversizedToolResultInput<TDetails = unknown> {\n\ttoolName: string;\n\ttoolCallId: string;\n\tresult: Pick<AgentToolResult<TDetails>, \"content\" | \"details\">;\n\tisError: boolean;\n\tsessionId: string;\n\tsessionDir?: string;\n\t/** Optional per-tool character cap; clamped by {@link DEFAULT_MAX_RESULT_SIZE_CHARS}. */\n\tmaxResultSizeChars?: number;\n}\n\nexport interface OversizedToolResultReplacement {\n\tcontent: TextContent[];\n\tdetails: unknown;\n\tisError: boolean;\n}\n\n/**\n * Human-readable byte size, e.g. `1536` → \"1.5KB\". Intentionally mirrors\n * upstream Claude Code `formatFileSize` wording instead of using tools/truncate.ts.\n */\nexport function formatFileSize(sizeInBytes: number): string {\n\tconst kb = sizeInBytes / 1024;\n\tif (kb < 1) {\n\t\treturn `${sizeInBytes} bytes`;\n\t}\n\tif (kb < 1024) {\n\t\treturn `${kb.toFixed(1).replace(/\\.0$/, \"\")}KB`;\n\t}\n\tconst mb = kb / 1024;\n\tif (mb < 1024) {\n\t\treturn `${mb.toFixed(1).replace(/\\.0$/, \"\")}MB`;\n\t}\n\tconst gb = mb / 1024;\n\treturn `${gb.toFixed(1).replace(/\\.0$/, \"\")}GB`;\n}\n\nfunction hasImageBlock(content: readonly (TextContent | ImageContent)[]): boolean {\n\treturn content.some((block) => block.type === \"image\");\n}\n\n/** Concatenate the text blocks of a tool result into a single string. */\nfunction collectText(content: readonly (TextContent | ImageContent)[]): string {\n\treturn content\n\t\t.filter((block): block is TextContent => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\");\n}\n\n/**\n * Generate a preview of content, truncating at a newline boundary when possible.\n * Ported from the reference `generatePreview`.\n */\nexport function generatePreview(content: string, maxBytes: number): { preview: string; hasMore: boolean } {\n\tif (Buffer.byteLength(content, \"utf8\") <= maxBytes) {\n\t\treturn { preview: content, hasMore: false };\n\t}\n\n\tlet bytes = 0;\n\tlet hardCutIndex = 0;\n\tlet lastNewlineIndex = -1;\n\tlet lastNewlineBytes = 0;\n\n\tfor (const character of content) {\n\t\tconst characterBytes = Buffer.byteLength(character, \"utf8\");\n\t\tif (bytes + characterBytes > maxBytes) {\n\t\t\tbreak;\n\t\t}\n\t\tconst characterStartIndex = hardCutIndex;\n\t\tbytes += characterBytes;\n\t\thardCutIndex += character.length;\n\t\tif (character === \"\\n\") {\n\t\t\tlastNewlineIndex = characterStartIndex;\n\t\t\tlastNewlineBytes = bytes - characterBytes;\n\t\t}\n\t}\n\n\t// Find the last newline within the byte limit to avoid cutting mid-line;\n\t// fall back to the hard byte limit when the newline is too close to the start.\n\tconst cutPoint = lastNewlineBytes > maxBytes * 0.5 ? lastNewlineIndex : hardCutIndex;\n\treturn { preview: content.slice(0, cutPoint), hasMore: true };\n}\n\n/**\n * Build the `<persisted-output>` preview message shown to the model in place of\n * the oversized content. Ported from the reference `buildLargeToolResultMessage`.\n */\nfunction buildPersistedOutputMessage(input: {\n\toriginalSizeBytes: number;\n\tfilepath: string;\n\tpreview: string;\n\thasMore: boolean;\n}): string {\n\tlet message = `${PERSISTED_OUTPUT_TAG}\\n`;\n\tmessage += `Output too large (${formatFileSize(input.originalSizeBytes)}). Full output saved to: ${input.filepath}\\n\\n`;\n\tmessage += `Preview (first ${formatFileSize(PREVIEW_SIZE_BYTES)}):\\n`;\n\tmessage += input.preview;\n\tmessage += input.hasMore ? \"\\n...\\n\" : \"\\n\";\n\tmessage += PERSISTED_OUTPUT_CLOSING_TAG;\n\treturn message;\n}\n\n/** Strip leading/trailing underscores with a linear scan (no backtracking regex). */\nfunction trimUnderscores(value: string): string {\n\tlet start = 0;\n\tlet end = value.length;\n\twhile (start < end && value[start] === \"_\") {\n\t\tstart++;\n\t}\n\twhile (end > start && value[end - 1] === \"_\") {\n\t\tend--;\n\t}\n\treturn value.slice(start, end);\n}\n\nfunction sanitizePathComponent(value: string, fallback: string): string {\n\t// Collapse disallowed characters to \"_\", then strip leading/trailing \"_\". The trim uses\n\t// a manual linear scan instead of a /^_+|_+$/ regex to avoid a polynomial-time ReDoS on\n\t// tool-call ids containing long runs of underscores (CodeQL js/polynomial-redos).\n\tconst sanitized = trimUnderscores(value.replace(/[^a-zA-Z0-9._-]+/g, \"_\")).slice(0, 64);\n\treturn sanitized.length > 0 ? sanitized : fallback;\n}\n\n/**\n * Session-scoped directory for persisted tool results.\n *\n * A disk-backed session owns `<sessionDir>/tool-results`. It is created here and\n * then chmodded, because `mode` on mkdir is only a request the process umask\n * narrows — a umask of 0o777 otherwise leaves a directory at 000 that nothing,\n * this process included, can write into.\n *\n * An in-memory session falls back to the owner- and session-scoped temp tree, so\n * the sweeper can reap it once the session is gone — and that path goes through\n * {@link ensureTempDir}, which validates every component below the system temp\n * directory instead of letting `mkdir -p` follow a planted link.\n */\nasync function ensureToolResultsDir(input: { sessionDir?: string; sessionId: string }): Promise<string> {\n\tif (input.sessionDir?.trim()) {\n\t\tconst dir = join(input.sessionDir, TOOL_RESULTS_SUBDIR);\n\t\tawait mkdir(dir, { recursive: true, mode: SESSION_TEMP_DIR_MODE });\n\t\tif (process.platform !== \"win32\") {\n\t\t\tawait chmod(dir, SESSION_TEMP_DIR_MODE);\n\t\t}\n\t\treturn dir;\n\t}\n\treturn ensureTempDir(join(resolveSessionTempDirPath(input.sessionId), TOOL_RESULTS_SUBDIR));\n}\n\nfunction isOwnedByCurrentUser(uid: number | bigint): boolean {\n\tconst currentUid = typeof process.getuid === \"function\" ? process.getuid() : undefined;\n\tif (typeof currentUid !== \"number\") {\n\t\treturn true;\n\t}\n\treturn typeof uid === \"bigint\" ? uid === BigInt(currentUid) : uid === currentUid;\n}\n\nfunction sameFileIdentity(left: { dev: bigint; ino: bigint }, right: { dev: bigint; ino: bigint }): boolean {\n\treturn left.dev === right.dev && left.ino === right.ino;\n}\n\n/**\n * Force an open persisted file to owner-only and prove it.\n *\n * `mode` on open is a request the process umask narrows, so a hostile or merely\n * odd umask can leave the file at 000 — advertised but unreadable. Throws when\n * the mode cannot be reached or the file belongs to another account.\n */\nasync function enforceOwnerOnlyMode(handle: FileHandle, filepath: string): Promise<void> {\n\tif (process.platform === \"win32\") {\n\t\treturn;\n\t}\n\tconst before = await handle.stat();\n\tif (!isOwnedByCurrentUser(before.uid)) {\n\t\tthrow new Error(`persisted tool result ${filepath} is owned by another account`);\n\t}\n\tawait handle.chmod(SESSION_TEMP_FILE_MODE);\n\tconst after = await handle.stat();\n\tif ((after.mode & 0o777) !== SESSION_TEMP_FILE_MODE) {\n\t\tthrow new Error(`persisted tool result ${filepath} could not be restricted to 0600`);\n\t}\n\tif (!isOwnedByCurrentUser(after.uid)) {\n\t\tthrow new Error(`persisted tool result ${filepath} is owned by another account`);\n\t}\n}\n\n/**\n * Validate a file left by a previous turn before advertising it again.\n *\n * The replay path is what makes repeated calls idempotent, but a file that is no\n * longer ours, or is no longer owner-only, must not be handed back. It is never\n * deleted either: refusing costs a preview, deleting could destroy someone\n * else's data.\n */\nasync function adoptExistingResultFile(filepath: string): Promise<boolean> {\n\ttry {\n\t\tconst initialPathStat = await lstat(filepath, { bigint: true });\n\t\tif (initialPathStat.isSymbolicLink() || !initialPathStat.isFile() || !isOwnedByCurrentUser(initialPathStat.uid)) {\n\t\t\treturn false;\n\t\t}\n\t\tconst noFollow =\n\t\t\tprocess.platform !== \"win32\" && typeof constants.O_NOFOLLOW === \"number\" ? constants.O_NOFOLLOW : 0;\n\t\tconst handle = await open(filepath, constants.O_RDONLY | noFollow);\n\t\ttry {\n\t\t\tconst handleStat = await handle.stat({ bigint: true });\n\t\t\tif (!handleStat.isFile() || !sameFileIdentity(initialPathStat, handleStat)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst pathBeforeChmod = await lstat(filepath, { bigint: true });\n\t\t\tif (\n\t\t\t\tpathBeforeChmod.isSymbolicLink() ||\n\t\t\t\t!pathBeforeChmod.isFile() ||\n\t\t\t\t!sameFileIdentity(initialPathStat, pathBeforeChmod) ||\n\t\t\t\t!sameFileIdentity(handleStat, pathBeforeChmod) ||\n\t\t\t\t!isOwnedByCurrentUser(pathBeforeChmod.uid)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tawait enforceOwnerOnlyMode(handle, filepath);\n\n\t\t\t// Do not advertise a path replaced while the descriptor was open.\n\t\t\tconst [finalPathStat, finalHandleStat] = await Promise.all([\n\t\t\t\tlstat(filepath, { bigint: true }),\n\t\t\t\thandle.stat({ bigint: true }),\n\t\t\t]);\n\t\t\treturn (\n\t\t\t\t!finalPathStat.isSymbolicLink() &&\n\t\t\t\tfinalPathStat.isFile() &&\n\t\t\t\tfinalHandleStat.isFile() &&\n\t\t\t\tsameFileIdentity(finalPathStat, finalHandleStat) &&\n\t\t\t\tisOwnedByCurrentUser(finalPathStat.uid) &&\n\t\t\t\tisOwnedByCurrentUser(finalHandleStat.uid)\n\t\t\t);\n\t\t} finally {\n\t\t\tawait handle.close();\n\t\t}\n\t} catch {\n\t\treturn false;\n\t}\n}\n/**\n * Persist the full tool output to a session-scoped file and return its path.\n *\n * The tool_use_id is unique per invocation and the content is deterministic for a\n * given id, so we write with the `wx` flag and treat `EEXIST` as success — this\n * makes repeated calls (e.g. replay/compaction) idempotent without rewriting.\n * Returns `undefined` on any other write failure so the caller can fall back to\n * returning the original result unchanged.\n */\nasync function persistToolOutput(input: {\n\ttext: string;\n\tsessionDir?: string;\n\tsessionId: string;\n\ttoolCallId: string;\n}): Promise<string | undefined> {\n\tlet dir: string;\n\ttry {\n\t\tdir = await ensureToolResultsDir({ sessionDir: input.sessionDir, sessionId: input.sessionId });\n\t} catch {\n\t\t// Refused (see TempDirRefusedError) or unwritable: leave the result unchanged\n\t\t// rather than pointing the model at a directory we do not own.\n\t\treturn undefined;\n\t}\n\tconst filepath = join(dir, `${sanitizePathComponent(input.toolCallId, \"tool-result\")}.txt`);\n\ttry {\n\t\tconst handle = await open(filepath, \"wx\", SESSION_TEMP_FILE_MODE);\n\t\ttry {\n\t\t\tawait handle.writeFile(capPersistedText(input.text), \"utf8\");\n\t\t\tawait enforceOwnerOnlyMode(handle, filepath);\n\t\t} finally {\n\t\t\tawait handle.close();\n\t\t}\n\t} catch (error) {\n\t\tif (getErrnoCode(error) === \"EEXIST\") {\n\t\t\t// Already persisted on a prior turn — reuse the existing file, but only\n\t\t\t// after confirming it is still ours and still owner-only.\n\t\t\treturn (await adoptExistingResultFile(filepath)) ? filepath : undefined;\n\t\t}\n\t\treturn undefined;\n\t}\n\treturn filepath;\n}\n\n/**\n * When a tool result's text content exceeds the persistence threshold (default\n * 50,000 chars — {@link DEFAULT_MAX_RESULT_SIZE_CHARS}), persist the full output\n * to a session-scoped file and replace the model-visible content with a\n * `<persisted-output>` preview that references the saved file.\n *\n * Returns `undefined` (leave the result untouched) when the result is within the\n * threshold, contains image blocks, or cannot be persisted to disk.\n *\n * Convention ported from the upstream `maybePersistLargeToolResult`\n * (mehmoodosman/claude-code, `src/utils/toolResultStorage.ts`).\n */\nexport async function redirectOversizedToolResult<TDetails = unknown>(\n\tinput: RedirectOversizedToolResultInput<TDetails>,\n): Promise<OversizedToolResultReplacement | undefined> {\n\tconst content = input.result.content;\n\n\t// Image content must be sent to the model as-is; never persist.\n\tif (hasImageBlock(content)) {\n\t\treturn undefined;\n\t}\n\n\tconst text = collectText(content);\n\tconst threshold = getPersistenceThreshold(input.maxResultSizeChars);\n\tif (text.length <= threshold) {\n\t\treturn undefined;\n\t}\n\n\tconst filepath = await persistToolOutput({\n\t\ttext,\n\t\tsessionDir: input.sessionDir,\n\t\tsessionId: input.sessionId,\n\t\ttoolCallId: input.toolCallId,\n\t});\n\t// Graceful degradation: if persistence failed, leave the original result unchanged.\n\tif (filepath === undefined) {\n\t\treturn undefined;\n\t}\n\n\tconst { preview, hasMore } = generatePreview(text, PREVIEW_SIZE_BYTES);\n\tconst message = buildPersistedOutputMessage({\n\t\toriginalSizeBytes: Buffer.byteLength(text, \"utf8\"),\n\t\tfilepath,\n\t\tpreview,\n\t\thasMore,\n\t});\n\n\treturn {\n\t\tcontent: [{ type: \"text\", text: message }],\n\t\t// Details (tool metadata) are passed through untouched, matching the reference\n\t\t// convention which only replaces the model-visible content block.\n\t\tdetails: input.result.details,\n\t\tisError: input.isError,\n\t};\n}\n"]}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Bounded writer for persisted tool-output files.
3
+ *
4
+ * Every temp file a tool spills to disk goes through here so no single file can
5
+ * exceed {@link MAX_PERSISTED_OUTPUT_BYTES}. Once the cap is reached the writer
6
+ * stops consuming input and appends {@link PERSISTED_OUTPUT_TRUNCATION_MARKER},
7
+ * so the file stays readable and its size stays bounded even when the producing
8
+ * command never stops.
9
+ */
10
+ import { Buffer } from "node:buffer";
11
+ /** Trim a buffer to at most `maxBytes` without splitting a valid UTF-8 sequence. */
12
+ export declare function truncateBufferAtUtf8Boundary(buffer: Buffer, maxBytes: number): Buffer;
13
+ /**
14
+ * Length of the longest prefix of `buffer` that does not end mid-character.
15
+ * Invalid UTF-8 remains complete raw binary; only a valid partial tail waits.
16
+ */
17
+ export declare function completeUtf8PrefixLength(buffer: Buffer): number;
18
+ /**
19
+ * Cap an in-memory string destined for a persisted-output file.
20
+ *
21
+ * Returns the input unchanged when it already fits; otherwise the returned text
22
+ * is the leading portion plus {@link PERSISTED_OUTPUT_TRUNCATION_MARKER}, and the
23
+ * whole result stays within `maxBytes`.
24
+ */
25
+ export declare function capPersistedText(text: string, maxBytes?: number): string;
26
+ export interface PersistedOutputFileOptions {
27
+ /** Byte cap for this file. Defaults to {@link MAX_PERSISTED_OUTPUT_BYTES}. */
28
+ maxBytes?: number;
29
+ }
30
+ /**
31
+ * A write stream that refuses to grow past its byte cap.
32
+ *
33
+ * Marker space cannot simply be subtracted up front: input that lands *exactly*
34
+ * on the cap is not truncated and must be preserved whole. So the writer keeps a
35
+ * short trailing buffer — everything past `maxBytes - markerBytes` — unwritten
36
+ * until it knows which case it is in. Input that stays within the cap has that
37
+ * tail flushed on close; input that exceeds it gets the UTF-8-safe prefix plus
38
+ * the marker, and the file lands at the cap. Flushes are cut at character
39
+ * boundaries, so the file never ends mid-character.
40
+ *
41
+ * Mirrors the subset of `WriteStream` the spill-file call sites use: `write`, a
42
+ * fire-and-forget `end`, and an awaitable `close`. A stream error is captured by
43
+ * a listener installed at construction, so a spill file that fails to write can
44
+ * never surface as an uncaught exception on the fire-and-forget path.
45
+ */
46
+ export declare class PersistedOutputFile {
47
+ readonly path: string;
48
+ private stream;
49
+ private readonly maxBytes;
50
+ /** Bytes that may be written before the marker's reserved space is needed. */
51
+ private readonly safeLimit;
52
+ private writtenBytes;
53
+ private pending;
54
+ private capReached;
55
+ private failure;
56
+ constructor(path: string, options?: PersistedOutputFileOptions);
57
+ /** Whether the cap was reached and the marker written. */
58
+ get truncated(): boolean;
59
+ /** The write error this file failed with, if any. */
60
+ get error(): Error | undefined;
61
+ /** Total input bytes accepted so far, including the unflushed tail. */
62
+ private get acceptedBytes();
63
+ write(chunk: Buffer | string): void;
64
+ /**
65
+ * Write at most `room` pending bytes, never ending mid-character.
66
+ *
67
+ * Both cuts matter. Cutting at `room` uses the boundary walk; flushing the
68
+ * whole buffer still holds back an incomplete trailing sequence, because its
69
+ * continuation bytes arrive in the *next* chunk — and if the cap intervenes
70
+ * first, a lead byte already on disk would sit orphaned before the marker.
71
+ */
72
+ private flushUpTo;
73
+ /** Release the trailing buffer once the input is known to fit within the cap. */
74
+ private flushRemainder;
75
+ /** Close without waiting for the flush to complete. */
76
+ end(): void;
77
+ /** Close and wait for the flush, rejecting on a write error. */
78
+ close(): Promise<void>;
79
+ }
80
+ //# sourceMappingURL=persisted-output-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persisted-output-file.d.ts","sourceRoot":"","sources":["../../../src/core/tools/persisted-output-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAgGrC,oFAAoF;AACpF,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGrF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAmC,GAAG,MAAM,CAQpG;AAED,MAAM,WAAW,0BAA0B;IAC1C,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,mBAAmB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAoB;IAEnC,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,EAgBjE;IAED,0DAA0D;IAC1D,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,qDAAqD;IACrD,IAAI,KAAK,IAAI,KAAK,GAAG,SAAS,CAE7B;IAED,uEAAuE;IACvE,OAAO,KAAK,aAAa,GAExB;IAED,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuBlC;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,SAAS;IAgBjB,iFAAiF;IACjF,OAAO,CAAC,cAAc;IAUtB,uDAAuD;IACvD,GAAG,IAAI,IAAI,CAQV;IAED,gEAAgE;IAC1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA4B3B;CACD"}