@bastani/atomic 0.9.13-alpha.2 → 0.9.13-alpha.4

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 (317) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +1 -1
  3. package/dist/builtin/i-have-adhd/package.json +1 -1
  4. package/dist/builtin/intercom/CHANGELOG.md +14 -0
  5. package/dist/builtin/intercom/README.md +12 -12
  6. package/dist/builtin/intercom/incoming-message-delivery.ts +1 -1
  7. package/dist/builtin/intercom/index.ts +1 -1
  8. package/dist/builtin/intercom/intercom-tool.ts +1 -1
  9. package/dist/builtin/intercom/intercom-utils.ts +3 -6
  10. package/dist/builtin/intercom/package.json +1 -1
  11. package/dist/builtin/intercom/result-renderers.ts +1 -1
  12. package/dist/builtin/intercom/session-target.ts +1 -15
  13. package/dist/builtin/intercom/skills/intercom/SKILL.md +6 -6
  14. package/dist/builtin/intercom/terminal-ordering-barrier.ts +2 -2
  15. package/dist/builtin/intercom/ui/inline-message.ts +7 -5
  16. package/dist/builtin/intercom/ui/session-list.ts +23 -10
  17. package/dist/builtin/mcp/package.json +1 -1
  18. package/dist/builtin/subagents/CHANGELOG.md +19 -0
  19. package/dist/builtin/subagents/README.md +29 -73
  20. package/dist/builtin/subagents/package.json +2 -2
  21. package/dist/builtin/subagents/prompts/parallel-cleanup.md +1 -1
  22. package/dist/builtin/subagents/prompts/parallel-review.md +1 -1
  23. package/dist/builtin/subagents/prompts/review-loop.md +2 -2
  24. package/dist/builtin/subagents/skills/subagent/SKILL.md +23 -59
  25. package/dist/builtin/subagents/skills/tmux/SKILL.md +1 -1
  26. package/dist/builtin/subagents/src/extension/control-notices.ts +2 -3
  27. package/dist/builtin/subagents/src/extension/doctor.ts +2 -14
  28. package/dist/builtin/subagents/src/extension/fanout-child.ts +1 -17
  29. package/dist/builtin/subagents/src/extension/index.ts +9 -70
  30. package/dist/builtin/subagents/src/extension/notification-content.ts +1 -1
  31. package/dist/builtin/subagents/src/extension/prompt-guidance.ts +2 -2
  32. package/dist/builtin/subagents/src/extension/schemas.ts +2 -8
  33. package/dist/builtin/subagents/src/extension/tool-description.ts +2 -3
  34. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +1 -1
  35. package/dist/builtin/subagents/src/intercom/result-intercom.ts +5 -46
  36. package/dist/builtin/subagents/src/runs/{background → foreground}/completion-notification.ts +2 -2
  37. package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +25 -88
  38. package/dist/builtin/subagents/src/runs/{background → foreground}/notify.ts +5 -5
  39. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +11 -28
  40. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +3 -0
  41. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +2 -0
  42. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-runtime.ts +0 -5
  43. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +30 -20
  44. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +4 -4
  45. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +0 -13
  46. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +104 -48
  47. package/dist/builtin/subagents/src/runs/inprocess/index.ts +1 -1
  48. package/dist/builtin/subagents/src/runs/inprocess/runner.ts +5 -5
  49. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-api.ts +0 -7
  50. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-core.ts +0 -10
  51. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-projection.ts +3 -108
  52. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-sanitize.ts +0 -4
  53. package/dist/builtin/subagents/src/runs/shared/subagent-control.ts +1 -1
  54. package/dist/builtin/subagents/src/shared/formatters.ts +3 -5
  55. package/dist/builtin/subagents/src/shared/model-resolution.ts +78 -0
  56. package/dist/builtin/subagents/src/shared/status-format.ts +4 -11
  57. package/dist/builtin/subagents/src/shared/types-config.ts +10 -9
  58. package/dist/builtin/subagents/src/shared/types-nested.ts +127 -0
  59. package/dist/builtin/subagents/src/shared/types-results.ts +2 -8
  60. package/dist/builtin/subagents/src/shared/types-runtime.ts +0 -9
  61. package/dist/builtin/subagents/src/shared/types.ts +1 -1
  62. package/dist/builtin/subagents/src/shared/utils.ts +1 -109
  63. package/dist/builtin/subagents/src/slash/slash-commands.ts +7 -17
  64. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -252
  65. package/dist/builtin/subagents/src/tui/render-layout.ts +4 -4
  66. package/dist/builtin/subagents/src/tui/render-result.ts +0 -9
  67. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -34
  68. package/dist/builtin/subagents/src/tui/render.ts +0 -2
  69. package/dist/builtin/web-access/package.json +1 -1
  70. package/dist/builtin/workflows/CHANGELOG.md +23 -0
  71. package/dist/builtin/workflows/README.md +3 -3
  72. package/dist/builtin/workflows/package.json +1 -1
  73. package/dist/builtin/workflows/src/durable/backend.ts +11 -0
  74. package/dist/builtin/workflows/src/durable/completed-catalog-stage-groups.ts +63 -25
  75. package/dist/builtin/workflows/src/durable/completed-catalog.ts +166 -25
  76. package/dist/builtin/workflows/src/durable/dbos-backend.ts +42 -24
  77. package/dist/builtin/workflows/src/durable/dbos-envelope.ts +2 -1
  78. package/dist/builtin/workflows/src/durable/run-timing.ts +28 -7
  79. package/dist/builtin/workflows/src/durable/scoped-backend.ts +4 -0
  80. package/dist/builtin/workflows/src/durable/targeted-inspection.ts +110 -0
  81. package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +2 -2
  82. package/dist/builtin/workflows/src/engine/runtime.ts +19 -2
  83. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +3 -0
  84. package/dist/builtin/workflows/src/extension/index.bundle.mjs +750 -168
  85. package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +6 -0
  86. package/dist/builtin/workflows/src/extension/ui-surface.ts +4 -0
  87. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +6 -1
  88. package/dist/builtin/workflows/src/extension/workflow-targets.ts +18 -10
  89. package/dist/builtin/workflows/src/extension/workflow-tool-inspection.ts +31 -16
  90. package/dist/builtin/workflows/src/extension/workflow-tool-send.ts +75 -3
  91. package/dist/builtin/workflows/src/extension/workflow-tool.ts +53 -6
  92. package/dist/builtin/workflows/src/runs/background/run-inspect.ts +5 -1
  93. package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +94 -60
  94. package/dist/builtin/workflows/src/runs/foreground/executor-stage-context.ts +1 -1
  95. package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +7 -7
  96. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +25 -4
  97. package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +4 -1
  98. package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +2 -0
  99. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +142 -4
  100. package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +2 -0
  101. package/dist/builtin/workflows/src/runs/foreground/stage-session-heartbeat.ts +88 -0
  102. package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +1 -0
  103. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +1 -0
  104. package/dist/builtin/workflows/src/tui/run-detail.ts +25 -12
  105. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +27 -8
  106. package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +17 -1
  107. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +20 -3
  108. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +10 -1
  109. package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +1 -0
  110. package/dist/core/agent-session-events.d.ts.map +1 -1
  111. package/dist/core/agent-session-events.js +22 -5
  112. package/dist/core/agent-session-events.js.map +1 -1
  113. package/dist/core/agent-session-export.d.ts.map +1 -1
  114. package/dist/core/agent-session-export.js +2 -1
  115. package/dist/core/agent-session-export.js.map +1 -1
  116. package/dist/core/agent-session-methods.d.ts +10 -4
  117. package/dist/core/agent-session-methods.d.ts.map +1 -1
  118. package/dist/core/agent-session-methods.js.map +1 -1
  119. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  120. package/dist/core/agent-session-prompt.js +68 -0
  121. package/dist/core/agent-session-prompt.js.map +1 -1
  122. package/dist/core/agent-session-queue-pause.d.ts.map +1 -1
  123. package/dist/core/agent-session-queue-pause.js +6 -0
  124. package/dist/core/agent-session-queue-pause.js.map +1 -1
  125. package/dist/core/agent-session-summary.d.ts +21 -0
  126. package/dist/core/agent-session-summary.d.ts.map +1 -0
  127. package/dist/core/agent-session-summary.js +156 -0
  128. package/dist/core/agent-session-summary.js.map +1 -0
  129. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  130. package/dist/core/agent-session-tool-registry.js +0 -4
  131. package/dist/core/agent-session-tool-registry.js.map +1 -1
  132. package/dist/core/agent-session-transfer.d.ts.map +1 -1
  133. package/dist/core/agent-session-transfer.js +0 -2
  134. package/dist/core/agent-session-transfer.js.map +1 -1
  135. package/dist/core/agent-session-tree.d.ts.map +1 -1
  136. package/dist/core/agent-session-tree.js +6 -0
  137. package/dist/core/agent-session-tree.js.map +1 -1
  138. package/dist/core/agent-session.d.ts +21 -3
  139. package/dist/core/agent-session.d.ts.map +1 -1
  140. package/dist/core/agent-session.js +22 -5
  141. package/dist/core/agent-session.js.map +1 -1
  142. package/dist/core/atomic-guide-command.js +2 -2
  143. package/dist/core/atomic-guide-command.js.map +1 -1
  144. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  145. package/dist/core/compaction/branch-summarization.js +1 -0
  146. package/dist/core/compaction/branch-summarization.js.map +1 -1
  147. package/dist/core/compaction/index.d.ts +1 -0
  148. package/dist/core/compaction/index.d.ts.map +1 -1
  149. package/dist/core/compaction/index.js +1 -0
  150. package/dist/core/compaction/index.js.map +1 -1
  151. package/dist/core/compaction/session-summarization.d.ts +41 -0
  152. package/dist/core/compaction/session-summarization.d.ts.map +1 -0
  153. package/dist/core/compaction/session-summarization.js +97 -0
  154. package/dist/core/compaction/session-summarization.js.map +1 -0
  155. package/dist/core/extensions/ui-types.d.ts +4 -0
  156. package/dist/core/extensions/ui-types.d.ts.map +1 -1
  157. package/dist/core/extensions/ui-types.js.map +1 -1
  158. package/dist/core/keybindings.d.ts +0 -5
  159. package/dist/core/keybindings.d.ts.map +1 -1
  160. package/dist/core/keybindings.js +0 -2
  161. package/dist/core/keybindings.js.map +1 -1
  162. package/dist/core/session-manager-core.d.ts +3 -1
  163. package/dist/core/session-manager-core.d.ts.map +1 -1
  164. package/dist/core/session-manager-core.js +9 -1
  165. package/dist/core/session-manager-core.js.map +1 -1
  166. package/dist/core/session-manager-entries.d.ts +24 -1
  167. package/dist/core/session-manager-entries.d.ts.map +1 -1
  168. package/dist/core/session-manager-entries.js +48 -0
  169. package/dist/core/session-manager-entries.js.map +1 -1
  170. package/dist/core/session-manager-list.d.ts.map +1 -1
  171. package/dist/core/session-manager-list.js +10 -0
  172. package/dist/core/session-manager-list.js.map +1 -1
  173. package/dist/core/session-manager-types.d.ts +10 -1
  174. package/dist/core/session-manager-types.d.ts.map +1 -1
  175. package/dist/core/session-manager-types.js.map +1 -1
  176. package/dist/core/settings-manager-basic-accessors.d.ts +3 -0
  177. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  178. package/dist/core/settings-manager-basic-accessors.js +5 -0
  179. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  180. package/dist/core/settings-manager.d.ts +1 -1
  181. package/dist/core/settings-manager.d.ts.map +1 -1
  182. package/dist/core/settings-manager.js.map +1 -1
  183. package/dist/core/settings-types.d.ts +4 -0
  184. package/dist/core/settings-types.d.ts.map +1 -1
  185. package/dist/core/settings-types.js.map +1 -1
  186. package/dist/core/slash-commands.js +2 -2
  187. package/dist/core/slash-commands.js.map +1 -1
  188. package/dist/core/tools/bash.d.ts +0 -15
  189. package/dist/core/tools/bash.d.ts.map +1 -1
  190. package/dist/core/tools/bash.js +3 -81
  191. package/dist/core/tools/bash.js.map +1 -1
  192. package/dist/core/tools/fetch-url.d.ts +12 -0
  193. package/dist/core/tools/fetch-url.d.ts.map +1 -1
  194. package/dist/core/tools/fetch-url.js +76 -10
  195. package/dist/core/tools/fetch-url.js.map +1 -1
  196. package/dist/core/tools/index.js +4 -4
  197. package/dist/core/tools/index.js.map +1 -1
  198. package/dist/core/tools/session-temp-dir.d.ts +2 -2
  199. package/dist/core/tools/session-temp-dir.d.ts.map +1 -1
  200. package/dist/core/tools/session-temp-dir.js +6 -7
  201. package/dist/core/tools/session-temp-dir.js.map +1 -1
  202. package/dist/core/usage-totals.js +1 -1
  203. package/dist/core/usage-totals.js.map +1 -1
  204. package/dist/index.d.ts +1 -1
  205. package/dist/index.d.ts.map +1 -1
  206. package/dist/index.js +1 -1
  207. package/dist/index.js.map +1 -1
  208. package/dist/modes/interactive/components/footer.js +1 -1
  209. package/dist/modes/interactive/components/footer.js.map +1 -1
  210. package/dist/modes/interactive/components/host-session-picker.d.ts.map +1 -1
  211. package/dist/modes/interactive/components/host-session-picker.js +1 -0
  212. package/dist/modes/interactive/components/host-session-picker.js.map +1 -1
  213. package/dist/modes/interactive/components/index.d.ts +1 -0
  214. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  215. package/dist/modes/interactive/components/index.js +1 -0
  216. package/dist/modes/interactive/components/index.js.map +1 -1
  217. package/dist/modes/interactive/components/session-selector-list.d.ts.map +1 -1
  218. package/dist/modes/interactive/components/session-selector-list.js +29 -4
  219. package/dist/modes/interactive/components/session-selector-list.js.map +1 -1
  220. package/dist/modes/interactive/components/session-selector-search.js +1 -1
  221. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  222. package/dist/modes/interactive/components/transcript-follow-indicator.d.ts +14 -0
  223. package/dist/modes/interactive/components/transcript-follow-indicator.d.ts.map +1 -0
  224. package/dist/modes/interactive/components/transcript-follow-indicator.js +36 -0
  225. package/dist/modes/interactive/components/transcript-follow-indicator.js.map +1 -0
  226. package/dist/modes/interactive/components/tree-selector-content.d.ts.map +1 -1
  227. package/dist/modes/interactive/components/tree-selector-content.js +6 -0
  228. package/dist/modes/interactive/components/tree-selector-content.js.map +1 -1
  229. package/dist/modes/interactive/interactive-extension-custom-ui.js +3 -0
  230. package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
  231. package/dist/modes/interactive/interactive-input-handling.js +0 -3
  232. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  233. package/dist/modes/interactive/interactive-mode-base.d.ts +1 -0
  234. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  235. package/dist/modes/interactive/interactive-mode-base.js +7 -1
  236. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  237. package/dist/modes/interactive/interactive-mode-surface.d.ts +3 -3
  238. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  239. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  240. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  241. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  242. package/dist/modes/interactive/interactive-mode.js +1 -0
  243. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  244. package/dist/modes/interactive/interactive-slash-commands.js +2 -5
  245. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  246. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  247. package/dist/modes/interactive/interactive-startup.js +6 -0
  248. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  249. package/dist/modes/interactive/interactive-transcript-follow.d.ts +2 -0
  250. package/dist/modes/interactive/interactive-transcript-follow.d.ts.map +1 -0
  251. package/dist/modes/interactive/interactive-transcript-follow.js +6 -0
  252. package/dist/modes/interactive/interactive-transcript-follow.js.map +1 -0
  253. package/dist/modes/interactive/interactive-tui.d.ts +13 -1
  254. package/dist/modes/interactive/interactive-tui.d.ts.map +1 -1
  255. package/dist/modes/interactive/interactive-tui.js +59 -1
  256. package/dist/modes/interactive/interactive-tui.js.map +1 -1
  257. package/dist/modes/interactive-engine/engine-custom-ui.d.ts +2 -0
  258. package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
  259. package/dist/modes/interactive-engine/engine-custom-ui.js +1 -0
  260. package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
  261. package/dist/modes/interactive-engine/protocol.d.ts +1 -0
  262. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
  263. package/dist/modes/interactive-engine/protocol.js +5 -1
  264. package/dist/modes/interactive-engine/protocol.js.map +1 -1
  265. package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
  266. package/dist/modes/interactive-engine/remote-component.js +21 -9
  267. package/dist/modes/interactive-engine/remote-component.js.map +1 -1
  268. package/docs/environment-variables.md +1 -1
  269. package/docs/intercom.md +20 -21
  270. package/docs/keybindings.md +2 -5
  271. package/docs/quickstart.md +5 -1
  272. package/docs/sdk.md +1 -1
  273. package/docs/session-format.md +15 -0
  274. package/docs/sessions.md +8 -0
  275. package/docs/settings.md +6 -0
  276. package/docs/subagents.md +19 -31
  277. package/docs/tools.md +3 -5
  278. package/docs/usage.md +3 -1
  279. package/docs/windows.md +1 -1
  280. package/docs/workflows.md +60 -32
  281. package/npm-shrinkwrap.json +29 -29
  282. package/package.json +2 -2
  283. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +0 -331
  284. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +0 -161
  285. package/dist/builtin/subagents/src/runs/inprocess/background-single.ts +0 -195
  286. package/dist/builtin/subagents/src/runs/inprocess/background.ts +0 -90
  287. package/dist/builtin/subagents/src/shared/types-async.ts +0 -247
  288. package/dist/builtin/subagents/src/tui/render-widget-graph.ts +0 -217
  289. package/dist/builtin/subagents/src/tui/render-widget.ts +0 -366
  290. package/dist/core/async/format.d.ts +0 -3
  291. package/dist/core/async/format.d.ts.map +0 -1
  292. package/dist/core/async/format.js +0 -52
  293. package/dist/core/async/format.js.map +0 -1
  294. package/dist/core/async/job-manager.d.ts +0 -40
  295. package/dist/core/async/job-manager.d.ts.map +0 -1
  296. package/dist/core/async/job-manager.js +0 -293
  297. package/dist/core/async/job-manager.js.map +0 -1
  298. package/dist/core/async/session-manager.d.ts +0 -16
  299. package/dist/core/async/session-manager.d.ts.map +0 -1
  300. package/dist/core/async/session-manager.js +0 -34
  301. package/dist/core/async/session-manager.js.map +0 -1
  302. package/dist/core/async/types.d.ts +0 -23
  303. package/dist/core/async/types.d.ts.map +0 -1
  304. package/dist/core/async/types.js +0 -2
  305. package/dist/core/async/types.js.map +0 -1
  306. package/dist/core/tools/bash-async-execution.d.ts +0 -27
  307. package/dist/core/tools/bash-async-execution.d.ts.map +0 -1
  308. package/dist/core/tools/bash-async-execution.js +0 -81
  309. package/dist/core/tools/bash-async-execution.js.map +0 -1
  310. package/dist/core/tools/bash-async-jobs.d.ts +0 -30
  311. package/dist/core/tools/bash-async-jobs.d.ts.map +0 -1
  312. package/dist/core/tools/bash-async-jobs.js +0 -87
  313. package/dist/core/tools/bash-async-jobs.js.map +0 -1
  314. package/dist/core/tools/bash-async-output.d.ts +0 -13
  315. package/dist/core/tools/bash-async-output.d.ts.map +0 -1
  316. package/dist/core/tools/bash-async-output.js +0 -122
  317. package/dist/core/tools/bash-async-output.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"job-manager.d.ts","sourceRoot":"","sources":["../../../src/core/async/job-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+C,KAAK,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE/G,OAAO,KAAK,EACX,wBAAwB,EACxB,uBAAuB,EAGvB,MAAM,YAAY,CAAC;AAOpB,UAAU,sBAAsB;IAC/B,aAAa,EAAE,wBAAwB,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAeD,qBAAa,eAAe;;IAG3B,MAAM,CAAC,QAAQ,IAAI,eAAe,GAAG,SAAS,CAE7C;IAED,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAE3D;IAED,MAAM,CAAC,aAAa,IAAI,IAAI,CAE3B;IAkBD,YAAY,OAAO,EAAE,sBAAsB,EAK1C;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,UAAU,IAAI,OAAO,CAIxB;IAED,eAAe,IAAI,MAAM,CAKxB;IAED,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAQtC;IAED,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAUpG;IAED,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE5C;IACD,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,UAAU,CAAC,EAAE,uBAAuB,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAkBnG;IAED,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAMzC;IAED,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAUrD;IAED,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE3C;IAED,aAAa,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAC;QAAC,aAAa,EAAE,MAAM,EAAE,CAAA;KAAE,CAOhF;IAED,cAAc,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAS3G;IAED,OAAO,IAAI,IAAI,CAWd;CAkID"}
@@ -1,293 +0,0 @@
1
- var _a;
2
- import { COMPLETED_JOB_TTL_MS, MAX_MANAGED_BASH_JOBS } from "../tools/bash-async-jobs.js";
3
- import { formatAsyncResultForFollowUp } from "./format.js";
4
- const DEFAULT_MAX_RUNNING_JOBS = 15;
5
- const DELIVERY_RETRY_BASE_MS = 500;
6
- const DELIVERY_RETRY_MAX_MS = 30_000;
7
- const DELIVERY_RETRY_JITTER_MS = 200;
8
- export class AsyncJobManager {
9
- static #instance;
10
- static instance() {
11
- return _a.#instance;
12
- }
13
- static setInstance(value) {
14
- _a.#instance = value;
15
- }
16
- static resetForTests() {
17
- _a.#instance = undefined;
18
- }
19
- #jobs = new Map();
20
- #deliveries = [];
21
- #suppressedDeliveries = new Set();
22
- #inFlightDeliveries = new Map();
23
- #deliveryHandlers = new Map();
24
- #jobSessions = new Map();
25
- #sessions = new Map();
26
- #onJobComplete;
27
- #maxRunningJobs;
28
- #maxRetainedJobs;
29
- #completedJobTtlMs;
30
- #timer;
31
- #disposed = false;
32
- #runningDeliveryLoop = false;
33
- #disposeWhenUnused = false;
34
- constructor(options) {
35
- this.#onJobComplete = options.onJobComplete;
36
- this.#maxRunningJobs = Math.max(1, Math.floor(options.maxRunningJobs ?? DEFAULT_MAX_RUNNING_JOBS));
37
- this.#maxRetainedJobs = Math.max(1, Math.floor(options.maxRetainedJobs ?? MAX_MANAGED_BASH_JOBS));
38
- this.#completedJobTtlMs = Math.max(0, Math.floor(options.completedJobTtlMs ?? COMPLETED_JOB_TTL_MS));
39
- }
40
- get disposed() {
41
- return this.#disposed;
42
- }
43
- get atCapacity() {
44
- let running = 0;
45
- for (const job of this.#jobs.values())
46
- if (job.status === "running")
47
- running += 1;
48
- return running >= this.#maxRunningJobs;
49
- }
50
- registerSession() {
51
- if (this.#disposed)
52
- throw new Error("Async job manager is disposed");
53
- const sessionId = Symbol("async-job-session");
54
- this.#sessions.set(sessionId, { disposed: false, activeJobIds: new Set() });
55
- return sessionId;
56
- }
57
- releaseSession(sessionId) {
58
- const session = this.#sessions.get(sessionId);
59
- if (!session)
60
- return;
61
- session.disposed = true;
62
- this.acknowledgeDeliveries([...session.activeJobIds]);
63
- this.#sessions.delete(sessionId);
64
- if (this.#sessions.size === 0)
65
- this.#disposeWhenUnused = true;
66
- this.#disposeIfUnused();
67
- }
68
- transferSessionDeliveries(sourceId, targetId, handler) {
69
- const source = this.#sessions.get(sourceId);
70
- const target = this.#sessions.get(targetId);
71
- if (!source || !target || target.disposed)
72
- return;
73
- for (const jobId of source.activeJobIds) {
74
- source.activeJobIds.delete(jobId);
75
- target.activeJobIds.add(jobId);
76
- this.#jobSessions.set(jobId, targetId);
77
- this.#deliveryHandlers.set(jobId, handler);
78
- }
79
- }
80
- isSessionDisposed(sessionId) {
81
- return this.#disposed || this.#sessions.get(sessionId)?.disposed !== false;
82
- }
83
- registerBashJob(job, onComplete, sessionId) {
84
- if (this.#disposed)
85
- throw new Error("Async job manager is disposed");
86
- this.#pruneRetention();
87
- if (this.atCapacity)
88
- throw new Error(`Background job limit reached (${this.#maxRunningJobs}). Wait for running jobs to finish or cancel one.`);
89
- if (sessionId !== undefined && this.isSessionDisposed(sessionId))
90
- throw new Error("Async job session is disposed");
91
- this.#suppressedDeliveries.delete(job.jobId);
92
- if (onComplete)
93
- this.#deliveryHandlers.set(job.jobId, onComplete);
94
- else
95
- this.#deliveryHandlers.delete(job.jobId);
96
- if (sessionId !== undefined) {
97
- this.#jobSessions.set(job.jobId, sessionId);
98
- this.#sessions.get(sessionId)?.activeJobIds.add(job.jobId);
99
- }
100
- else
101
- this.#jobSessions.delete(job.jobId);
102
- this.#jobs.set(job.jobId, job);
103
- this.#pruneRetention();
104
- }
105
- completeBashJob(job) {
106
- if (this.#disposed || this.#suppressedDeliveries.has(job.jobId))
107
- return;
108
- if (job.status === "running")
109
- return;
110
- this.#jobs.set(job.jobId, job);
111
- this.#pruneRetention();
112
- if (this.#jobs.has(job.jobId))
113
- this.#enqueueDelivery(job);
114
- }
115
- acknowledgeDeliveries(jobIds) {
116
- for (const jobId of jobIds) {
117
- this.#suppressedDeliveries.add(jobId);
118
- for (let index = this.#deliveries.length - 1; index >= 0; index -= 1) {
119
- if (this.#deliveries[index]?.jobId === jobId)
120
- this.#deliveries.splice(index, 1);
121
- }
122
- this.#deliveryHandlers.delete(jobId);
123
- this.#completeTrackedJob(jobId);
124
- }
125
- this.#pruneRetention();
126
- }
127
- isDeliverySuppressed(jobId) {
128
- return this.#suppressedDeliveries.has(jobId);
129
- }
130
- deliveryState() {
131
- this.#pruneRetention();
132
- return {
133
- queued: this.#deliveries.length,
134
- delivering: this.#runningDeliveryLoop || this.#inFlightDeliveries.size > 0,
135
- pendingJobIds: [...this.#deliveries.map((delivery) => delivery.jobId), ...this.#inFlightDeliveries.keys()],
136
- };
137
- }
138
- retentionState() {
139
- this.#pruneRetention();
140
- return {
141
- jobs: this.#jobs.size,
142
- suppressions: this.#suppressedDeliveries.size,
143
- handlers: this.#deliveryHandlers.size,
144
- queued: this.#deliveries.length + this.#inFlightDeliveries.size,
145
- sessions: this.#sessions.size,
146
- };
147
- }
148
- dispose() {
149
- this.#disposed = true;
150
- if (this.#timer)
151
- clearTimeout(this.#timer);
152
- this.#timer = undefined;
153
- this.#deliveries.length = 0;
154
- this.#inFlightDeliveries.clear();
155
- this.#deliveryHandlers.clear();
156
- this.#jobSessions.clear();
157
- this.#sessions.clear();
158
- this.#jobs.clear();
159
- this.#suppressedDeliveries.clear();
160
- }
161
- #enqueueDelivery(job) {
162
- if (this.#inFlightDeliveries.has(job.jobId))
163
- return;
164
- for (let index = this.#deliveries.length - 1; index >= 0; index -= 1)
165
- if (this.#deliveries[index]?.jobId === job.jobId)
166
- this.#deliveries.splice(index, 1);
167
- this.#deliveries.push({
168
- jobId: job.jobId,
169
- message: formatAsyncResultForFollowUp(job),
170
- attempt: 0,
171
- nextAttemptAt: Date.now(),
172
- });
173
- this.#pruneRetention();
174
- void this.#runDeliveryLoop();
175
- }
176
- #completeTrackedJob(jobId) {
177
- const sessionId = this.#jobSessions.get(jobId);
178
- if (sessionId !== undefined)
179
- this.#sessions.get(sessionId)?.activeJobIds.delete(jobId);
180
- this.#jobSessions.delete(jobId);
181
- }
182
- #disposeIfUnused() {
183
- if (!this.#disposeWhenUnused || this.#sessions.size > 0 || this.#inFlightDeliveries.size > 0)
184
- return;
185
- this.dispose();
186
- if (_a.#instance === this)
187
- _a.#instance = undefined;
188
- }
189
- #pruneRetention(now = Date.now()) {
190
- for (const [jobId, job] of this.#jobs) {
191
- if (job.status !== "running" && job.endedAt !== undefined && now - job.endedAt > this.#completedJobTtlMs) {
192
- this.#jobs.delete(jobId);
193
- this.#completeTrackedJob(jobId);
194
- }
195
- }
196
- for (const jobId of this.#suppressedDeliveries) {
197
- if (!this.#jobs.has(jobId))
198
- this.#suppressedDeliveries.delete(jobId);
199
- }
200
- const oldestTerminalJobs = [...this.#jobs.values()]
201
- .filter((job) => job.status !== "running")
202
- .sort((a, b) => (a.endedAt ?? a.startedAt) - (b.endedAt ?? b.startedAt));
203
- while (this.#jobs.size > this.#maxRetainedJobs && oldestTerminalJobs.length > 0) {
204
- const job = oldestTerminalJobs.shift();
205
- if (job) {
206
- this.#jobs.delete(job.jobId);
207
- this.#completeTrackedJob(job.jobId);
208
- }
209
- }
210
- for (let index = this.#deliveries.length - 1; index >= 0; index -= 1) {
211
- const delivery = this.#deliveries[index];
212
- if (!delivery || !this.#jobs.has(delivery.jobId) || this.#suppressedDeliveries.has(delivery.jobId))
213
- this.#deliveries.splice(index, 1);
214
- }
215
- while (this.#deliveries.length + this.#inFlightDeliveries.size > this.#maxRetainedJobs &&
216
- this.#deliveries.length > 0)
217
- this.#deliveries.shift();
218
- for (const jobId of this.#deliveryHandlers.keys())
219
- if (!this.#jobs.has(jobId) || this.#suppressedDeliveries.has(jobId))
220
- this.#deliveryHandlers.delete(jobId);
221
- for (const session of this.#sessions.values())
222
- for (const jobId of session.activeJobIds)
223
- if (!this.#jobs.has(jobId))
224
- session.activeJobIds.delete(jobId);
225
- }
226
- #scheduleDeliveryLoop(delayMs) {
227
- if (this.#disposed)
228
- return;
229
- if (this.#timer)
230
- clearTimeout(this.#timer);
231
- this.#timer = setTimeout(() => {
232
- this.#timer = undefined;
233
- void this.#runDeliveryLoop();
234
- }, delayMs);
235
- this.#timer.unref?.();
236
- }
237
- async #runDeliveryLoop() {
238
- if (this.#runningDeliveryLoop || this.#disposed)
239
- return;
240
- this.#runningDeliveryLoop = true;
241
- try {
242
- while (!this.#disposed) {
243
- const now = Date.now();
244
- const delivery = this.#deliveries.find((candidate) => candidate.nextAttemptAt <= now);
245
- if (!delivery)
246
- break;
247
- this.#deliveries.splice(this.#deliveries.indexOf(delivery), 1);
248
- this.#startDelivery(delivery);
249
- }
250
- }
251
- finally {
252
- this.#runningDeliveryLoop = false;
253
- }
254
- this.#scheduleNextDelivery();
255
- }
256
- #startDelivery(delivery) {
257
- if (this.#suppressedDeliveries.has(delivery.jobId) ||
258
- !this.#jobs.has(delivery.jobId) ||
259
- this.#inFlightDeliveries.has(delivery.jobId))
260
- return;
261
- const handler = this.#deliveryHandlers.get(delivery.jobId) ?? this.#onJobComplete;
262
- this.#inFlightDeliveries.set(delivery.jobId, delivery);
263
- delivery.promise = (async () => handler(delivery.message))()
264
- .then(() => {
265
- if (!this.#suppressedDeliveries.has(delivery.jobId) && this.#jobs.has(delivery.jobId)) {
266
- this.#deliveryHandlers.delete(delivery.jobId);
267
- this.#completeTrackedJob(delivery.jobId);
268
- }
269
- })
270
- .catch(() => {
271
- if (this.#disposed || this.#suppressedDeliveries.has(delivery.jobId) || !this.#jobs.has(delivery.jobId))
272
- return;
273
- delivery.attempt += 1;
274
- const jitter = Math.floor(Math.random() * DELIVERY_RETRY_JITTER_MS);
275
- delivery.nextAttemptAt =
276
- Date.now() + Math.min(DELIVERY_RETRY_MAX_MS, DELIVERY_RETRY_BASE_MS * 2 ** delivery.attempt) + jitter;
277
- this.#deliveries.push(delivery);
278
- })
279
- .finally(() => {
280
- this.#inFlightDeliveries.delete(delivery.jobId);
281
- this.#pruneRetention();
282
- this.#scheduleNextDelivery();
283
- this.#disposeIfUnused();
284
- });
285
- }
286
- #scheduleNextDelivery() {
287
- const next = this.#deliveries.reduce((soonest, delivery) => soonest === undefined ? delivery.nextAttemptAt : Math.min(soonest, delivery.nextAttemptAt), undefined);
288
- if (next !== undefined)
289
- this.#scheduleDeliveryLoop(Math.max(0, next - Date.now()));
290
- }
291
- }
292
- _a = AsyncJobManager;
293
- //# sourceMappingURL=job-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"job-manager.js","sourceRoot":"","sources":["../../../src/core/async/job-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { COMPLETED_JOB_TTL_MS, MAX_MANAGED_BASH_JOBS, type ManagedBashJob } from \"../tools/bash-async-jobs.js\";\nimport { formatAsyncResultForFollowUp } from \"./format.js\";\nimport type {\n\tAsyncJobDeliveryCallback,\n\tAsyncJobDeliveryHandler,\n\tAsyncJobDeliveryMessage,\n\tManagedAsyncBashJob,\n} from \"./types.js\";\n\nconst DEFAULT_MAX_RUNNING_JOBS = 15;\nconst DELIVERY_RETRY_BASE_MS = 500;\nconst DELIVERY_RETRY_MAX_MS = 30_000;\nconst DELIVERY_RETRY_JITTER_MS = 200;\n\ninterface AsyncJobManagerOptions {\n\tonJobComplete: AsyncJobDeliveryCallback;\n\tmaxRunningJobs?: number;\n\tmaxRetainedJobs?: number;\n\tcompletedJobTtlMs?: number;\n}\n\ninterface Delivery {\n\tjobId: string;\n\tmessage: AsyncJobDeliveryMessage;\n\tattempt: number;\n\tnextAttemptAt: number;\n\tpromise?: Promise<void>;\n}\n\ninterface RegisteredSession {\n\tdisposed: boolean;\n\tactiveJobIds: Set<string>;\n}\n\nexport class AsyncJobManager {\n\tstatic #instance: AsyncJobManager | undefined;\n\n\tstatic instance(): AsyncJobManager | undefined {\n\t\treturn AsyncJobManager.#instance;\n\t}\n\n\tstatic setInstance(value: AsyncJobManager | undefined): void {\n\t\tAsyncJobManager.#instance = value;\n\t}\n\n\tstatic resetForTests(): void {\n\t\tAsyncJobManager.#instance = undefined;\n\t}\n\n\treadonly #jobs = new Map<string, ManagedBashJob>();\n\treadonly #deliveries: Delivery[] = [];\n\treadonly #suppressedDeliveries = new Set<string>();\n\treadonly #inFlightDeliveries = new Map<string, Delivery>();\n\treadonly #deliveryHandlers = new Map<string, AsyncJobDeliveryHandler>();\n\treadonly #jobSessions = new Map<string, symbol>();\n\treadonly #sessions = new Map<symbol, RegisteredSession>();\n\treadonly #onJobComplete: AsyncJobDeliveryCallback;\n\treadonly #maxRunningJobs: number;\n\treadonly #maxRetainedJobs: number;\n\treadonly #completedJobTtlMs: number;\n\t#timer: NodeJS.Timeout | undefined;\n\t#disposed = false;\n\t#runningDeliveryLoop = false;\n\t#disposeWhenUnused = false;\n\n\tconstructor(options: AsyncJobManagerOptions) {\n\t\tthis.#onJobComplete = options.onJobComplete;\n\t\tthis.#maxRunningJobs = Math.max(1, Math.floor(options.maxRunningJobs ?? DEFAULT_MAX_RUNNING_JOBS));\n\t\tthis.#maxRetainedJobs = Math.max(1, Math.floor(options.maxRetainedJobs ?? MAX_MANAGED_BASH_JOBS));\n\t\tthis.#completedJobTtlMs = Math.max(0, Math.floor(options.completedJobTtlMs ?? COMPLETED_JOB_TTL_MS));\n\t}\n\n\tget disposed(): boolean {\n\t\treturn this.#disposed;\n\t}\n\n\tget atCapacity(): boolean {\n\t\tlet running = 0;\n\t\tfor (const job of this.#jobs.values()) if (job.status === \"running\") running += 1;\n\t\treturn running >= this.#maxRunningJobs;\n\t}\n\n\tregisterSession(): symbol {\n\t\tif (this.#disposed) throw new Error(\"Async job manager is disposed\");\n\t\tconst sessionId = Symbol(\"async-job-session\");\n\t\tthis.#sessions.set(sessionId, { disposed: false, activeJobIds: new Set() });\n\t\treturn sessionId;\n\t}\n\n\treleaseSession(sessionId: symbol): void {\n\t\tconst session = this.#sessions.get(sessionId);\n\t\tif (!session) return;\n\t\tsession.disposed = true;\n\t\tthis.acknowledgeDeliveries([...session.activeJobIds]);\n\t\tthis.#sessions.delete(sessionId);\n\t\tif (this.#sessions.size === 0) this.#disposeWhenUnused = true;\n\t\tthis.#disposeIfUnused();\n\t}\n\n\ttransferSessionDeliveries(sourceId: symbol, targetId: symbol, handler: AsyncJobDeliveryHandler): void {\n\t\tconst source = this.#sessions.get(sourceId);\n\t\tconst target = this.#sessions.get(targetId);\n\t\tif (!source || !target || target.disposed) return;\n\t\tfor (const jobId of source.activeJobIds) {\n\t\t\tsource.activeJobIds.delete(jobId);\n\t\t\ttarget.activeJobIds.add(jobId);\n\t\t\tthis.#jobSessions.set(jobId, targetId);\n\t\t\tthis.#deliveryHandlers.set(jobId, handler);\n\t\t}\n\t}\n\n\tisSessionDisposed(sessionId: symbol): boolean {\n\t\treturn this.#disposed || this.#sessions.get(sessionId)?.disposed !== false;\n\t}\n\tregisterBashJob(job: ManagedBashJob, onComplete?: AsyncJobDeliveryHandler, sessionId?: symbol): void {\n\t\tif (this.#disposed) throw new Error(\"Async job manager is disposed\");\n\t\tthis.#pruneRetention();\n\t\tif (this.atCapacity)\n\t\t\tthrow new Error(\n\t\t\t\t`Background job limit reached (${this.#maxRunningJobs}). Wait for running jobs to finish or cancel one.`,\n\t\t\t);\n\t\tif (sessionId !== undefined && this.isSessionDisposed(sessionId))\n\t\t\tthrow new Error(\"Async job session is disposed\");\n\t\tthis.#suppressedDeliveries.delete(job.jobId);\n\t\tif (onComplete) this.#deliveryHandlers.set(job.jobId, onComplete);\n\t\telse this.#deliveryHandlers.delete(job.jobId);\n\t\tif (sessionId !== undefined) {\n\t\t\tthis.#jobSessions.set(job.jobId, sessionId);\n\t\t\tthis.#sessions.get(sessionId)?.activeJobIds.add(job.jobId);\n\t\t} else this.#jobSessions.delete(job.jobId);\n\t\tthis.#jobs.set(job.jobId, job);\n\t\tthis.#pruneRetention();\n\t}\n\n\tcompleteBashJob(job: ManagedBashJob): void {\n\t\tif (this.#disposed || this.#suppressedDeliveries.has(job.jobId)) return;\n\t\tif (job.status === \"running\") return;\n\t\tthis.#jobs.set(job.jobId, job);\n\t\tthis.#pruneRetention();\n\t\tif (this.#jobs.has(job.jobId)) this.#enqueueDelivery(job as ManagedAsyncBashJob);\n\t}\n\n\tacknowledgeDeliveries(jobIds: readonly string[]): void {\n\t\tfor (const jobId of jobIds) {\n\t\t\tthis.#suppressedDeliveries.add(jobId);\n\t\t\tfor (let index = this.#deliveries.length - 1; index >= 0; index -= 1) {\n\t\t\t\tif (this.#deliveries[index]?.jobId === jobId) this.#deliveries.splice(index, 1);\n\t\t\t}\n\t\t\tthis.#deliveryHandlers.delete(jobId);\n\t\t\tthis.#completeTrackedJob(jobId);\n\t\t}\n\t\tthis.#pruneRetention();\n\t}\n\n\tisDeliverySuppressed(jobId: string): boolean {\n\t\treturn this.#suppressedDeliveries.has(jobId);\n\t}\n\n\tdeliveryState(): { queued: number; delivering: boolean; pendingJobIds: string[] } {\n\t\tthis.#pruneRetention();\n\t\treturn {\n\t\t\tqueued: this.#deliveries.length,\n\t\t\tdelivering: this.#runningDeliveryLoop || this.#inFlightDeliveries.size > 0,\n\t\t\tpendingJobIds: [...this.#deliveries.map((delivery) => delivery.jobId), ...this.#inFlightDeliveries.keys()],\n\t\t};\n\t}\n\n\tretentionState(): { jobs: number; suppressions: number; handlers: number; queued: number; sessions: number } {\n\t\tthis.#pruneRetention();\n\t\treturn {\n\t\t\tjobs: this.#jobs.size,\n\t\t\tsuppressions: this.#suppressedDeliveries.size,\n\t\t\thandlers: this.#deliveryHandlers.size,\n\t\t\tqueued: this.#deliveries.length + this.#inFlightDeliveries.size,\n\t\t\tsessions: this.#sessions.size,\n\t\t};\n\t}\n\n\tdispose(): void {\n\t\tthis.#disposed = true;\n\t\tif (this.#timer) clearTimeout(this.#timer);\n\t\tthis.#timer = undefined;\n\t\tthis.#deliveries.length = 0;\n\t\tthis.#inFlightDeliveries.clear();\n\t\tthis.#deliveryHandlers.clear();\n\t\tthis.#jobSessions.clear();\n\t\tthis.#sessions.clear();\n\t\tthis.#jobs.clear();\n\t\tthis.#suppressedDeliveries.clear();\n\t}\n\n\t#enqueueDelivery(job: ManagedAsyncBashJob): void {\n\t\tif (this.#inFlightDeliveries.has(job.jobId)) return;\n\t\tfor (let index = this.#deliveries.length - 1; index >= 0; index -= 1)\n\t\t\tif (this.#deliveries[index]?.jobId === job.jobId) this.#deliveries.splice(index, 1);\n\t\tthis.#deliveries.push({\n\t\t\tjobId: job.jobId,\n\t\t\tmessage: formatAsyncResultForFollowUp(job),\n\t\t\tattempt: 0,\n\t\t\tnextAttemptAt: Date.now(),\n\t\t});\n\t\tthis.#pruneRetention();\n\t\tvoid this.#runDeliveryLoop();\n\t}\n\n\t#completeTrackedJob(jobId: string): void {\n\t\tconst sessionId = this.#jobSessions.get(jobId);\n\t\tif (sessionId !== undefined) this.#sessions.get(sessionId)?.activeJobIds.delete(jobId);\n\t\tthis.#jobSessions.delete(jobId);\n\t}\n\t#disposeIfUnused(): void {\n\t\tif (!this.#disposeWhenUnused || this.#sessions.size > 0 || this.#inFlightDeliveries.size > 0) return;\n\t\tthis.dispose();\n\t\tif (AsyncJobManager.#instance === this) AsyncJobManager.#instance = undefined;\n\t}\n\t#pruneRetention(now = Date.now()): void {\n\t\tfor (const [jobId, job] of this.#jobs) {\n\t\t\tif (job.status !== \"running\" && job.endedAt !== undefined && now - job.endedAt > this.#completedJobTtlMs) {\n\t\t\t\tthis.#jobs.delete(jobId);\n\t\t\t\tthis.#completeTrackedJob(jobId);\n\t\t\t}\n\t\t}\n\t\tfor (const jobId of this.#suppressedDeliveries) {\n\t\t\tif (!this.#jobs.has(jobId)) this.#suppressedDeliveries.delete(jobId);\n\t\t}\n\t\tconst oldestTerminalJobs = [...this.#jobs.values()]\n\t\t\t.filter((job) => job.status !== \"running\")\n\t\t\t.sort((a, b) => (a.endedAt ?? a.startedAt) - (b.endedAt ?? b.startedAt));\n\t\twhile (this.#jobs.size > this.#maxRetainedJobs && oldestTerminalJobs.length > 0) {\n\t\t\tconst job = oldestTerminalJobs.shift();\n\t\t\tif (job) {\n\t\t\t\tthis.#jobs.delete(job.jobId);\n\t\t\t\tthis.#completeTrackedJob(job.jobId);\n\t\t\t}\n\t\t}\n\t\tfor (let index = this.#deliveries.length - 1; index >= 0; index -= 1) {\n\t\t\tconst delivery = this.#deliveries[index];\n\t\t\tif (!delivery || !this.#jobs.has(delivery.jobId) || this.#suppressedDeliveries.has(delivery.jobId))\n\t\t\t\tthis.#deliveries.splice(index, 1);\n\t\t}\n\t\twhile (\n\t\t\tthis.#deliveries.length + this.#inFlightDeliveries.size > this.#maxRetainedJobs &&\n\t\t\tthis.#deliveries.length > 0\n\t\t)\n\t\t\tthis.#deliveries.shift();\n\t\tfor (const jobId of this.#deliveryHandlers.keys())\n\t\t\tif (!this.#jobs.has(jobId) || this.#suppressedDeliveries.has(jobId)) this.#deliveryHandlers.delete(jobId);\n\t\tfor (const session of this.#sessions.values())\n\t\t\tfor (const jobId of session.activeJobIds) if (!this.#jobs.has(jobId)) session.activeJobIds.delete(jobId);\n\t}\n\n\t#scheduleDeliveryLoop(delayMs: number): void {\n\t\tif (this.#disposed) return;\n\t\tif (this.#timer) clearTimeout(this.#timer);\n\t\tthis.#timer = setTimeout(() => {\n\t\t\tthis.#timer = undefined;\n\t\t\tvoid this.#runDeliveryLoop();\n\t\t}, delayMs);\n\t\tthis.#timer.unref?.();\n\t}\n\n\tasync #runDeliveryLoop(): Promise<void> {\n\t\tif (this.#runningDeliveryLoop || this.#disposed) return;\n\t\tthis.#runningDeliveryLoop = true;\n\t\ttry {\n\t\t\twhile (!this.#disposed) {\n\t\t\t\tconst now = Date.now();\n\t\t\t\tconst delivery = this.#deliveries.find((candidate) => candidate.nextAttemptAt <= now);\n\t\t\t\tif (!delivery) break;\n\t\t\t\tthis.#deliveries.splice(this.#deliveries.indexOf(delivery), 1);\n\t\t\t\tthis.#startDelivery(delivery);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#runningDeliveryLoop = false;\n\t\t}\n\t\tthis.#scheduleNextDelivery();\n\t}\n\n\t#startDelivery(delivery: Delivery): void {\n\t\tif (\n\t\t\tthis.#suppressedDeliveries.has(delivery.jobId) ||\n\t\t\t!this.#jobs.has(delivery.jobId) ||\n\t\t\tthis.#inFlightDeliveries.has(delivery.jobId)\n\t\t)\n\t\t\treturn;\n\t\tconst handler = this.#deliveryHandlers.get(delivery.jobId) ?? this.#onJobComplete;\n\t\tthis.#inFlightDeliveries.set(delivery.jobId, delivery);\n\t\tdelivery.promise = (async () => handler(delivery.message))()\n\t\t\t.then(() => {\n\t\t\t\tif (!this.#suppressedDeliveries.has(delivery.jobId) && this.#jobs.has(delivery.jobId)) {\n\t\t\t\t\tthis.#deliveryHandlers.delete(delivery.jobId);\n\t\t\t\t\tthis.#completeTrackedJob(delivery.jobId);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tif (this.#disposed || this.#suppressedDeliveries.has(delivery.jobId) || !this.#jobs.has(delivery.jobId))\n\t\t\t\t\treturn;\n\t\t\t\tdelivery.attempt += 1;\n\t\t\t\tconst jitter = Math.floor(Math.random() * DELIVERY_RETRY_JITTER_MS);\n\t\t\t\tdelivery.nextAttemptAt =\n\t\t\t\t\tDate.now() + Math.min(DELIVERY_RETRY_MAX_MS, DELIVERY_RETRY_BASE_MS * 2 ** delivery.attempt) + jitter;\n\t\t\t\tthis.#deliveries.push(delivery);\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tthis.#inFlightDeliveries.delete(delivery.jobId);\n\t\t\t\tthis.#pruneRetention();\n\t\t\t\tthis.#scheduleNextDelivery();\n\t\t\t\tthis.#disposeIfUnused();\n\t\t\t});\n\t}\n\n\t#scheduleNextDelivery(): void {\n\t\tconst next = this.#deliveries.reduce<number | undefined>(\n\t\t\t(soonest, delivery) =>\n\t\t\t\tsoonest === undefined ? delivery.nextAttemptAt : Math.min(soonest, delivery.nextAttemptAt),\n\t\t\tundefined,\n\t\t);\n\t\tif (next !== undefined) this.#scheduleDeliveryLoop(Math.max(0, next - Date.now()));\n\t}\n}\n"]}
@@ -1,16 +0,0 @@
1
- import type { SendMessageOptions } from "../extensions/index.ts";
2
- import { AsyncJobManager } from "./job-manager.js";
3
- import type { AsyncJobDeliveryHandler, AsyncJobDeliveryMessage } from "./types.js";
4
- export interface SessionAsyncJobManagerHandle {
5
- manager: AsyncJobManager;
6
- owns: boolean;
7
- sessionId: symbol;
8
- }
9
- interface AsyncDeliverySession {
10
- sendCustomMessage(message: AsyncJobDeliveryMessage, options?: SendMessageOptions): Promise<void>;
11
- }
12
- export declare function createSessionAsyncDeliveryHandler(session: AsyncDeliverySession, manager?: AsyncJobManager, sessionId?: symbol): AsyncJobDeliveryHandler;
13
- export declare function createSessionAsyncJobManager(session: AsyncDeliverySession): SessionAsyncJobManagerHandle;
14
- export declare function disposeSessionAsyncJobManager(manager: AsyncJobManager | undefined, sessionId: symbol | undefined): void;
15
- export {};
16
- //# sourceMappingURL=session-manager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../../src/core/async/session-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAEnF,MAAM,WAAW,4BAA4B;IAC5C,OAAO,EAAE,eAAe,CAAC;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CAClB;AACD,UAAU,oBAAoB;IAC7B,iBAAiB,CAAC,OAAO,EAAE,uBAAuB,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjG;AAED,wBAAgB,iCAAiC,CAChD,OAAO,EAAE,oBAAoB,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,SAAS,CAAC,EAAE,MAAM,GAChB,uBAAuB,CAazB;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,CASxG;AAED,wBAAgB,6BAA6B,CAC5C,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,SAAS,EAAE,MAAM,GAAG,SAAS,GAC3B,IAAI,CAIN"}
@@ -1,34 +0,0 @@
1
- import { AsyncJobManager } from "./job-manager.js";
2
- export function createSessionAsyncDeliveryHandler(session, manager, sessionId) {
3
- return async (message) => {
4
- const isStale = () => manager?.disposed === true ||
5
- manager?.isDeliverySuppressed(message.details.jobId) === true ||
6
- (sessionId !== undefined && manager?.isSessionDisposed(sessionId) === true);
7
- if (isStale())
8
- return;
9
- await session.sendCustomMessage(message, {
10
- deliverAs: "followUp",
11
- triggerTurn: true,
12
- stageAdmissionKey: `async-job:${message.details.jobId}`,
13
- });
14
- };
15
- }
16
- export function createSessionAsyncJobManager(session) {
17
- const existing = AsyncJobManager.instance();
18
- if (existing)
19
- return { manager: existing, owns: false, sessionId: existing.registerSession() };
20
- let manager;
21
- manager = new AsyncJobManager({
22
- onJobComplete: (message) => createSessionAsyncDeliveryHandler(session, manager)(message),
23
- });
24
- AsyncJobManager.setInstance(manager);
25
- return { manager, owns: true, sessionId: manager.registerSession() };
26
- }
27
- export function disposeSessionAsyncJobManager(manager, sessionId) {
28
- if (!manager || !sessionId)
29
- return;
30
- manager.releaseSession(sessionId);
31
- if (manager.disposed && AsyncJobManager.instance() === manager)
32
- AsyncJobManager.setInstance(undefined);
33
- }
34
- //# sourceMappingURL=session-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../../src/core/async/session-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAYnD,MAAM,UAAU,iCAAiC,CAChD,OAA6B,EAC7B,OAAyB,EACzB,SAAkB;IAElB,OAAO,KAAK,EAAE,OAAgC,EAAE,EAAE;QACjD,MAAM,OAAO,GAAG,GAAG,EAAE,CACpB,OAAO,EAAE,QAAQ,KAAK,IAAI;YAC1B,OAAO,EAAE,oBAAoB,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI;YAC7D,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,EAAE,iBAAiB,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC,CAAC;QAC7E,IAAI,OAAO,EAAE;YAAE,OAAO;QACtB,MAAM,OAAO,CAAC,iBAAiB,CAAC,OAAO,EAAE;YACxC,SAAS,EAAE,UAAU;YACrB,WAAW,EAAE,IAAI;YACjB,iBAAiB,EAAE,aAAa,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE;SACvD,CAAC,CAAC;IACJ,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,OAA6B;IACzE,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC;IAC5C,IAAI,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC;IAC/F,IAAI,OAAwB,CAAC;IAC7B,OAAO,GAAG,IAAI,eAAe,CAAC;QAC7B,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,iCAAiC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC;KACxF,CAAC,CAAC;IACH,eAAe,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC5C,OAAoC,EACpC,SAA6B;IAE7B,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS;QAAE,OAAO;IACnC,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IAClC,IAAI,OAAO,CAAC,QAAQ,IAAI,eAAe,CAAC,QAAQ,EAAE,KAAK,OAAO;QAAE,eAAe,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;AACxG,CAAC","sourcesContent":["import type { SendMessageOptions } from \"../extensions/index.ts\";\nimport { AsyncJobManager } from \"./job-manager.js\";\nimport type { AsyncJobDeliveryHandler, AsyncJobDeliveryMessage } from \"./types.js\";\n\nexport interface SessionAsyncJobManagerHandle {\n\tmanager: AsyncJobManager;\n\towns: boolean;\n\tsessionId: symbol;\n}\ninterface AsyncDeliverySession {\n\tsendCustomMessage(message: AsyncJobDeliveryMessage, options?: SendMessageOptions): Promise<void>;\n}\n\nexport function createSessionAsyncDeliveryHandler(\n\tsession: AsyncDeliverySession,\n\tmanager?: AsyncJobManager,\n\tsessionId?: symbol,\n): AsyncJobDeliveryHandler {\n\treturn async (message: AsyncJobDeliveryMessage) => {\n\t\tconst isStale = () =>\n\t\t\tmanager?.disposed === true ||\n\t\t\tmanager?.isDeliverySuppressed(message.details.jobId) === true ||\n\t\t\t(sessionId !== undefined && manager?.isSessionDisposed(sessionId) === true);\n\t\tif (isStale()) return;\n\t\tawait session.sendCustomMessage(message, {\n\t\t\tdeliverAs: \"followUp\",\n\t\t\ttriggerTurn: true,\n\t\t\tstageAdmissionKey: `async-job:${message.details.jobId}`,\n\t\t});\n\t};\n}\n\nexport function createSessionAsyncJobManager(session: AsyncDeliverySession): SessionAsyncJobManagerHandle {\n\tconst existing = AsyncJobManager.instance();\n\tif (existing) return { manager: existing, owns: false, sessionId: existing.registerSession() };\n\tlet manager: AsyncJobManager;\n\tmanager = new AsyncJobManager({\n\t\tonJobComplete: (message) => createSessionAsyncDeliveryHandler(session, manager)(message),\n\t});\n\tAsyncJobManager.setInstance(manager);\n\treturn { manager, owns: true, sessionId: manager.registerSession() };\n}\n\nexport function disposeSessionAsyncJobManager(\n\tmanager: AsyncJobManager | undefined,\n\tsessionId: symbol | undefined,\n): void {\n\tif (!manager || !sessionId) return;\n\tmanager.releaseSession(sessionId);\n\tif (manager.disposed && AsyncJobManager.instance() === manager) AsyncJobManager.setInstance(undefined);\n}\n"]}
@@ -1,23 +0,0 @@
1
- import type { ManagedBashJob } from "../tools/bash-async-jobs.js";
2
- export type AsyncJobStatus = "running" | "completed" | "failed";
3
- export interface AsyncJobDeliveryDetails {
4
- jobId: string;
5
- type: "bash";
6
- status: AsyncJobStatus;
7
- command: string;
8
- exitCode?: number | null;
9
- fullOutputPath?: string;
10
- wallTimeMs?: number;
11
- }
12
- export interface AsyncJobDeliveryMessage {
13
- customType: "async-job-result";
14
- content: string;
15
- display: true;
16
- details: AsyncJobDeliveryDetails;
17
- }
18
- export type AsyncJobDeliveryCallback = (message: AsyncJobDeliveryMessage) => void | Promise<void>;
19
- export type AsyncJobDeliveryHandler = (message: AsyncJobDeliveryMessage) => void | Promise<void>;
20
- export interface ManagedAsyncBashJob extends ManagedBashJob {
21
- status: AsyncJobStatus;
22
- }
23
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/async/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEhE,MAAM,WAAW,uBAAuB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,uBAAuB,CAAC;CACjC;AAED,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAElG,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEjG,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IAC1D,MAAM,EAAE,cAAc,CAAC;CACvB"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/async/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ManagedBashJob } from \"../tools/bash-async-jobs.js\";\n\nexport type AsyncJobStatus = \"running\" | \"completed\" | \"failed\";\n\nexport interface AsyncJobDeliveryDetails {\n\tjobId: string;\n\ttype: \"bash\";\n\tstatus: AsyncJobStatus;\n\tcommand: string;\n\texitCode?: number | null;\n\tfullOutputPath?: string;\n\twallTimeMs?: number;\n}\n\nexport interface AsyncJobDeliveryMessage {\n\tcustomType: \"async-job-result\";\n\tcontent: string;\n\tdisplay: true;\n\tdetails: AsyncJobDeliveryDetails;\n}\n\nexport type AsyncJobDeliveryCallback = (message: AsyncJobDeliveryMessage) => void | Promise<void>;\n\nexport type AsyncJobDeliveryHandler = (message: AsyncJobDeliveryMessage) => void | Promise<void>;\n\nexport interface ManagedAsyncBashJob extends ManagedBashJob {\n\tstatus: AsyncJobStatus;\n}\n"]}
@@ -1,27 +0,0 @@
1
- import type { AsyncJobManager } from "../async/job-manager.js";
2
- import type { AsyncJobDeliveryHandler } from "../async/types.js";
3
- import type { BashOperations, BashToolDetails } from "./bash.ts";
4
- interface StartAsyncBashCommandOptions {
5
- command: string;
6
- cwd: string;
7
- env: NodeJS.ProcessEnv;
8
- pty?: boolean;
9
- timeoutSeconds: number;
10
- requestedTimeoutSeconds?: number;
11
- signal?: AbortSignal;
12
- operations: BashOperations;
13
- manager?: AsyncJobManager;
14
- deliveryHandler?: AsyncJobDeliveryHandler;
15
- sessionId?: symbol;
16
- /** Session-scoped directory for the async spill log. */
17
- sessionTempDir?: string;
18
- }
19
- export declare function startAsyncBashCommand(options: StartAsyncBashCommandOptions): Promise<{
20
- content: Array<{
21
- type: "text";
22
- text: string;
23
- }>;
24
- details: BashToolDetails;
25
- }>;
26
- export {};
27
- //# sourceMappingURL=bash-async-execution.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bash-async-execution.d.ts","sourceRoot":"","sources":["../../../src/core/tools/bash-async-execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAKjE,UAAU,4BAA4B;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,cAAc,CAAC;IAC3B,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,eAAe,CAAC,EAAE,uBAAuB,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC;IAC3F,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,eAAe,CAAC;CACzB,CAAC,CA6ED"}
@@ -1,81 +0,0 @@
1
- import { createManagedBashJob, discardManagedBashJob, formatAsyncJobError } from "./bash-async-jobs.js";
2
- import { createAsyncOutputAppender } from "./bash-async-output.js";
3
- import { invalidateNativeSearchCache } from "./search-native.js";
4
- export async function startAsyncBashCommand(options) {
5
- if (options.manager?.atCapacity)
6
- throw new Error("Background job limit reached. Wait for running jobs to finish or cancel one.");
7
- const job = createManagedBashJob(options.command, options.cwd, options.timeoutSeconds, options.requestedTimeoutSeconds);
8
- try {
9
- options.manager?.registerBashJob(job, options.deliveryHandler, options.sessionId);
10
- }
11
- catch (registerError) {
12
- // The job was inserted into the managed map but never started; drop it so
13
- // it cannot linger as a permanently-"running" zombie entry (see
14
- // discardManagedBashJob). Registration failures (disposed manager/session,
15
- // capacity race) still surface to the caller as tool errors.
16
- discardManagedBashJob(job.jobId);
17
- throw registerError;
18
- }
19
- const appendAsyncOutput = createAsyncOutputAppender(job, {
20
- persistAfterBytes: 12_000,
21
- sessionTempDir: options.sessionTempDir,
22
- });
23
- const onParentAbort = () => {
24
- options.manager?.acknowledgeDeliveries([job.jobId]);
25
- job.abortController?.abort();
26
- };
27
- if (options.signal?.aborted)
28
- onParentAbort();
29
- else
30
- options.signal?.addEventListener("abort", onParentAbort, { once: true });
31
- void (async () => {
32
- let error;
33
- let exitCode;
34
- try {
35
- exitCode = (await options.operations.exec(options.command, options.cwd, {
36
- onData: appendAsyncOutput.append,
37
- timeout: options.timeoutSeconds,
38
- env: options.env,
39
- pty: options.pty,
40
- signal: job.abortController?.signal,
41
- })).exitCode;
42
- }
43
- catch (execError) {
44
- error = execError instanceof Error ? execError : String(execError);
45
- }
46
- try {
47
- await appendAsyncOutput.close();
48
- }
49
- catch (closeError) {
50
- error ??= closeError instanceof Error ? closeError : String(closeError);
51
- }
52
- if (error !== undefined) {
53
- job.status = "failed";
54
- job.error = job.abortController?.signal.aborted ? "aborted" : formatAsyncJobError(error);
55
- }
56
- else {
57
- job.exitCode = exitCode;
58
- job.status = exitCode && exitCode !== 0 ? "failed" : "completed";
59
- }
60
- job.endedAt = Date.now();
61
- invalidateNativeSearchCache();
62
- options.manager?.completeBashJob(job);
63
- options.signal?.removeEventListener("abort", onParentAbort);
64
- })();
65
- return {
66
- content: [
67
- {
68
- type: "text",
69
- text: `Started async bash command ${job.jobId}: ${options.command}\nPoll with bash({ command: "__atomic_bash_job ${job.jobId}" }); cancel with bash({ command: "__atomic_bash_job_cancel ${job.jobId}" })`,
70
- },
71
- ],
72
- details: {
73
- async: { jobId: job.jobId, type: "bash", state: "running", command: options.command, status: "running" },
74
- timeoutSeconds: options.timeoutSeconds,
75
- ...(options.requestedTimeoutSeconds !== undefined
76
- ? { requestedTimeoutSeconds: options.requestedTimeoutSeconds }
77
- : {}),
78
- },
79
- };
80
- }
81
- //# sourceMappingURL=bash-async-execution.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bash-async-execution.js","sourceRoot":"","sources":["../../../src/core/tools/bash-async-execution.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAkBjE,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAqC;IAIhF,IAAI,OAAO,CAAC,OAAO,EAAE,UAAU;QAC9B,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;IACjG,MAAM,GAAG,GAAG,oBAAoB,CAC/B,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,GAAG,EACX,OAAO,CAAC,cAAc,EACtB,OAAO,CAAC,uBAAuB,CAC/B,CAAC;IACF,IAAI,CAAC;QACJ,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACnF,CAAC;IAAC,OAAO,aAAa,EAAE,CAAC;QACxB,0EAA0E;QAC1E,gEAAgE;QAChE,2EAA2E;QAC3E,6DAA6D;QAC7D,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,aAAa,CAAC;IACrB,CAAC;IACD,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,GAAG,EAAE;QACxD,iBAAiB,EAAE,MAAM;QACzB,cAAc,EAAE,OAAO,CAAC,cAAc;KACtC,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,GAAG,EAAE;QAC1B,OAAO,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO;QAAE,aAAa,EAAE,CAAC;;QACxC,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,KAAK,IAAI,EAAE;QAChB,IAAI,KAAiC,CAAC;QACtC,IAAI,QAAmC,CAAC;QACxC,IAAI,CAAC;YACJ,QAAQ,GAAG,CACV,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE;gBAC3D,MAAM,EAAE,iBAAiB,CAAC,MAAM;gBAChC,OAAO,EAAE,OAAO,CAAC,cAAc;gBAC/B,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,MAAM,EAAE,GAAG,CAAC,eAAe,EAAE,MAAM;aACnC,CAAC,CACF,CAAC,QAAQ,CAAC;QACZ,CAAC;QAAC,OAAO,SAAS,EAAE,CAAC;YACpB,KAAK,GAAG,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,CAAC;YACJ,MAAM,iBAAiB,CAAC,KAAK,EAAE,CAAC;QACjC,CAAC;QAAC,OAAO,UAAU,EAAE,CAAC;YACrB,KAAK,KAAK,UAAU,YAAY,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,GAAG,CAAC,MAAM,GAAG,QAAQ,CAAC;YACtB,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC1F,CAAC;aAAM,CAAC;YACP,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACxB,GAAG,CAAC,MAAM,GAAG,QAAQ,IAAI,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC;QAClE,CAAC;QACD,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,2BAA2B,EAAE,CAAC;QAC9B,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC;QACtC,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAC7D,CAAC,CAAC,EAAE,CAAC;IACL,OAAO;QACN,OAAO,EAAE;YACR;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,8BAA8B,GAAG,CAAC,KAAK,KAAK,OAAO,CAAC,OAAO,kDAAkD,GAAG,CAAC,KAAK,+DAA+D,GAAG,CAAC,KAAK,MAAM;aAC1M;SACD;QACD,OAAO,EAAE;YACR,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE;YACxG,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,GAAG,CAAC,OAAO,CAAC,uBAAuB,KAAK,SAAS;gBAChD,CAAC,CAAC,EAAE,uBAAuB,EAAE,OAAO,CAAC,uBAAuB,EAAE;gBAC9D,CAAC,CAAC,EAAE,CAAC;SACN;KACD,CAAC;AACH,CAAC","sourcesContent":["import type { AsyncJobManager } from \"../async/job-manager.js\";\nimport type { AsyncJobDeliveryHandler } from \"../async/types.js\";\nimport type { BashOperations, BashToolDetails } from \"./bash.ts\";\nimport { createManagedBashJob, discardManagedBashJob, formatAsyncJobError } from \"./bash-async-jobs.js\";\nimport { createAsyncOutputAppender } from \"./bash-async-output.js\";\nimport { invalidateNativeSearchCache } from \"./search-native.ts\";\n\ninterface StartAsyncBashCommandOptions {\n\tcommand: string;\n\tcwd: string;\n\tenv: NodeJS.ProcessEnv;\n\tpty?: boolean;\n\ttimeoutSeconds: number;\n\trequestedTimeoutSeconds?: number;\n\tsignal?: AbortSignal;\n\toperations: BashOperations;\n\tmanager?: AsyncJobManager;\n\tdeliveryHandler?: AsyncJobDeliveryHandler;\n\tsessionId?: symbol;\n\t/** Session-scoped directory for the async spill log. */\n\tsessionTempDir?: string;\n}\n\nexport async function startAsyncBashCommand(options: StartAsyncBashCommandOptions): Promise<{\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tdetails: BashToolDetails;\n}> {\n\tif (options.manager?.atCapacity)\n\t\tthrow new Error(\"Background job limit reached. Wait for running jobs to finish or cancel one.\");\n\tconst job = createManagedBashJob(\n\t\toptions.command,\n\t\toptions.cwd,\n\t\toptions.timeoutSeconds,\n\t\toptions.requestedTimeoutSeconds,\n\t);\n\ttry {\n\t\toptions.manager?.registerBashJob(job, options.deliveryHandler, options.sessionId);\n\t} catch (registerError) {\n\t\t// The job was inserted into the managed map but never started; drop it so\n\t\t// it cannot linger as a permanently-\"running\" zombie entry (see\n\t\t// discardManagedBashJob). Registration failures (disposed manager/session,\n\t\t// capacity race) still surface to the caller as tool errors.\n\t\tdiscardManagedBashJob(job.jobId);\n\t\tthrow registerError;\n\t}\n\tconst appendAsyncOutput = createAsyncOutputAppender(job, {\n\t\tpersistAfterBytes: 12_000,\n\t\tsessionTempDir: options.sessionTempDir,\n\t});\n\tconst onParentAbort = () => {\n\t\toptions.manager?.acknowledgeDeliveries([job.jobId]);\n\t\tjob.abortController?.abort();\n\t};\n\tif (options.signal?.aborted) onParentAbort();\n\telse options.signal?.addEventListener(\"abort\", onParentAbort, { once: true });\n\tvoid (async () => {\n\t\tlet error: Error | string | undefined;\n\t\tlet exitCode: number | null | undefined;\n\t\ttry {\n\t\t\texitCode = (\n\t\t\t\tawait options.operations.exec(options.command, options.cwd, {\n\t\t\t\t\tonData: appendAsyncOutput.append,\n\t\t\t\t\ttimeout: options.timeoutSeconds,\n\t\t\t\t\tenv: options.env,\n\t\t\t\t\tpty: options.pty,\n\t\t\t\t\tsignal: job.abortController?.signal,\n\t\t\t\t})\n\t\t\t).exitCode;\n\t\t} catch (execError) {\n\t\t\terror = execError instanceof Error ? execError : String(execError);\n\t\t}\n\t\ttry {\n\t\t\tawait appendAsyncOutput.close();\n\t\t} catch (closeError) {\n\t\t\terror ??= closeError instanceof Error ? closeError : String(closeError);\n\t\t}\n\t\tif (error !== undefined) {\n\t\t\tjob.status = \"failed\";\n\t\t\tjob.error = job.abortController?.signal.aborted ? \"aborted\" : formatAsyncJobError(error);\n\t\t} else {\n\t\t\tjob.exitCode = exitCode;\n\t\t\tjob.status = exitCode && exitCode !== 0 ? \"failed\" : \"completed\";\n\t\t}\n\t\tjob.endedAt = Date.now();\n\t\tinvalidateNativeSearchCache();\n\t\toptions.manager?.completeBashJob(job);\n\t\toptions.signal?.removeEventListener(\"abort\", onParentAbort);\n\t})();\n\treturn {\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: `Started async bash command ${job.jobId}: ${options.command}\\nPoll with bash({ command: \"__atomic_bash_job ${job.jobId}\" }); cancel with bash({ command: \"__atomic_bash_job_cancel ${job.jobId}\" })`,\n\t\t\t},\n\t\t],\n\t\tdetails: {\n\t\t\tasync: { jobId: job.jobId, type: \"bash\", state: \"running\", command: options.command, status: \"running\" },\n\t\t\ttimeoutSeconds: options.timeoutSeconds,\n\t\t\t...(options.requestedTimeoutSeconds !== undefined\n\t\t\t\t? { requestedTimeoutSeconds: options.requestedTimeoutSeconds }\n\t\t\t\t: {}),\n\t\t},\n\t};\n}\n"]}
@@ -1,30 +0,0 @@
1
- export interface ManagedBashJob {
2
- jobId: string;
3
- command: string;
4
- cwd: string;
5
- status: "running" | "completed" | "failed";
6
- output: string;
7
- fullOutputPath?: string;
8
- exitCode?: number | null;
9
- error?: string;
10
- startedAt: number;
11
- endedAt?: number;
12
- timeoutSeconds?: number;
13
- requestedTimeoutSeconds?: number;
14
- abortController?: AbortController;
15
- }
16
- export declare const MAX_MANAGED_BASH_JOBS = 100;
17
- export declare const COMPLETED_JOB_TTL_MS: number;
18
- export declare function formatAsyncJobError(error: unknown): string;
19
- export declare function createManagedBashJob(command: string, cwd: string, timeoutSeconds?: number, requestedTimeoutSeconds?: number): ManagedBashJob;
20
- /**
21
- * Remove a managed job that never actually started executing (for example when
22
- * async-manager registration fails after the map insert). Without this, the
23
- * entry would stay "running" forever: TTL cleanup only evicts settled jobs, so
24
- * the zombie would linger until the max-jobs overflow forcibly removed it.
25
- */
26
- export declare function discardManagedBashJob(jobId: string): void;
27
- export declare function listManagedBashJobIds(): string[];
28
- export declare function getManagedBashJob(jobId: string): ManagedBashJob | undefined;
29
- export declare function abortManagedBashJob(jobId: string): ManagedBashJob | undefined;
30
- //# sourceMappingURL=bash-async-jobs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bash-async-jobs.d.ts","sourceRoot":"","sources":["../../../src/core/tools/bash-async-jobs.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,eAAe,CAAC,EAAE,eAAe,CAAC;CAClC;AAED,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,oBAAoB,QAAiB,CAAC;AAEnD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAI1D;AA2BD,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,cAAc,CAAC,EAAE,MAAM,EACvB,uBAAuB,CAAC,EAAE,MAAM,GAC9B,cAAc,CAiBhB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAKzD;AAED,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAM3E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAK7E"}