@desplega.ai/agent-swarm 1.122.0 → 1.123.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/README.md +2 -0
  2. package/dist/{actions-k3bwtmgy.js → actions-e4c9f0xy.js} +6 -6
  3. package/dist/{app-knevny0f.js → app-vmvmj2v3.js} +4 -4
  4. package/dist/{assistant-as8087ft.js → assistant-yn7a792a.js} +14 -11
  5. package/dist/{boot-reembed-j305cpdr.js → boot-reembed-chxty50a.js} +4 -4
  6. package/dist/{boot-reembed-1dcc1yyk.js → boot-reembed-xg1r86h2.js} +3 -3
  7. package/dist/{boot-scrub-logs-w9qkjzkm.js → boot-scrub-logs-exwddvp5.js} +2 -2
  8. package/dist/{claude-adapter-vxvcym3r.js → claude-adapter-zvzp4x76.js} +1 -1
  9. package/dist/{claude-managed-adapter-g807894s.js → claude-managed-adapter-g92bcm1a.js} +1 -1
  10. package/dist/{cli-3ptjc655.js → cli-1592nfd6.js} +1 -1
  11. package/dist/{cli-x4apc9t3.js → cli-36dctyg8.js} +139 -23
  12. package/dist/{cli-fc1gvt9c.js → cli-3tv9z4wx.js} +6 -3
  13. package/dist/{cli-wmx631p8.js → cli-4509mwm5.js} +159 -21
  14. package/dist/{cli-ma04faw5.js → cli-5arfywtm.js} +2 -0
  15. package/dist/{cli-m7dmk462.js → cli-822d4bjk.js} +18 -14
  16. package/dist/{cli-mjxnr12j.js → cli-8cq4z4x7.js} +510 -30
  17. package/dist/{cli-zpa6gjwq.js → cli-8ef5ky75.js} +1 -1
  18. package/dist/{cli-hjq6c6vz.js → cli-9eka6jwv.js} +2 -2
  19. package/dist/{cli-z3hcrghs.js → cli-9hj1adgp.js} +1 -1
  20. package/dist/{cli-60q15ncp.js → cli-byv3720g.js} +2 -2
  21. package/dist/{cli-tc8xk5zh.js → cli-c9m59f83.js} +1 -1
  22. package/dist/{cli-zweca3q3.js → cli-exfs8aym.js} +1 -1
  23. package/dist/{cli-9fhxk91h.js → cli-fjf04hpa.js} +11 -6
  24. package/dist/{cli-w48hgc2y.js → cli-h2say6xk.js} +3 -3
  25. package/dist/{cli-586x669g.js → cli-hbbxmhec.js} +4 -4
  26. package/dist/{cli-5c4327dx.js → cli-jj1arm18.js} +15 -1
  27. package/dist/{cli-00yr0kxv.js → cli-kmm1rwmp.js} +1 -1
  28. package/dist/{cli-7jb8mk4n.js → cli-mepk1j0t.js} +1 -1
  29. package/dist/{cli-y3an9mk7.js → cli-mkpf4ndf.js} +1052 -254
  30. package/dist/{cli-haeq79yf.js → cli-mngsj9fx.js} +8 -3
  31. package/dist/{cli-bxdb36d2.js → cli-n8mf7x4b.js} +2 -2
  32. package/dist/{cli-wwsaj97q.js → cli-ngbsk4yx.js} +16 -1
  33. package/dist/{cli-8sv69q06.js → cli-np0yhmmk.js} +60 -22
  34. package/dist/{cli-8x745f40.js → cli-p11rf59d.js} +7 -4
  35. package/dist/{cli-16dv125e.js → cli-peaqed7c.js} +20 -3
  36. package/dist/{cli-qnmj37m5.js → cli-vz9drmce.js} +3 -2
  37. package/dist/{cli-tyfxrrdd.js → cli-w5r4wfm5.js} +11 -1
  38. package/dist/{cli-kpfsabp2.js → cli-we91ywvy.js} +85 -7
  39. package/dist/{cli-qf0qxzw5.js → cli-zdp11t8m.js} +22 -17
  40. package/dist/{cli-j89ph4c4.js → cli-zkj6f2sk.js} +2 -2
  41. package/dist/cli.js +12 -12
  42. package/dist/{codex-adapter-0kv2meed.js → codex-adapter-vcseqpwf.js} +1 -1
  43. package/dist/{codex-session-runner-m1e1v4r0.js → codex-session-runner-jec9e9t1.js} +1 -1
  44. package/dist/{commands-6j54dz62.js → commands-sjk3zfyr.js} +7 -4
  45. package/dist/{db-gcnz2tqx.js → db-2je5agjb.js} +24 -2
  46. package/dist/{devin-adapter-pe1cgpd4.js → devin-adapter-8nmsgff3.js} +1 -1
  47. package/dist/{handlers-c43sm2h1.js → handlers-yzv369hf.js} +41 -12
  48. package/dist/{hook-y1p25vm5.js → hook-rfsj2r8x.js} +1 -1
  49. package/dist/{http-bsz1rze1.js → http-v9rr144m.js} +484 -640
  50. package/dist/{index-03zn2rz7.js → index-3xtk777g.js} +9 -9
  51. package/dist/{index-qyzfh62q.js → index-c3tan44f.js} +10 -10
  52. package/dist/{index-8m5gd1vs.js → index-nr2199m6.js} +11 -11
  53. package/dist/{index-7swcv6rv.js → index-smjdc3h9.js} +7 -7
  54. package/dist/{keepalive-69v93p45.js → keepalive-5ds53bjd.js} +5 -5
  55. package/dist/{lead-xn8kfchy.js → lead-5xhez25b.js} +26 -26
  56. package/dist/{maintenance-g2x7q13q.js → maintenance-b43d24q6.js} +4 -4
  57. package/dist/{oauth-refresh-sweep-j80szsyr.js → oauth-refresh-sweep-qe286vn2.js} +4 -4
  58. package/dist/{onboard-e3xcjt8b.js → onboard-c4r3ds3z.js} +2 -2
  59. package/dist/{opencode-adapter-s3nhtp9m.js → opencode-adapter-44z93505.js} +1 -1
  60. package/dist/{otel-impl-24egvjaa.js → otel-impl-nv3rjw61.js} +1 -1
  61. package/dist/{pi-mono-adapter-k3z6e5fn.js → pi-mono-adapter-2syx1x4d.js} +21 -1
  62. package/dist/{pricing-refresh-01kg9gky.js → pricing-refresh-5ct2wp4k.js} +4 -4
  63. package/dist/{rbac-roles-jqfp0zza.js → rbac-roles-b82cxpxn.js} +4 -4
  64. package/dist/{rbac-roles-f9bdj93y.js → rbac-roles-m502w0qv.js} +3 -3
  65. package/dist/{seed-pricing-z2t7rank.js → seed-pricing-jhjphbf0.js} +3 -3
  66. package/dist/{setup-kw2ps002.js → setup-zbaspydq.js} +2 -2
  67. package/dist/{worker-336w8930.js → worker-snvhpax5.js} +26 -26
  68. package/openapi.json +311 -16
  69. package/package.json +3 -3
  70. package/src/be/budget-admission.ts +2 -1
  71. package/src/be/db.ts +288 -2
  72. package/src/be/memory/constants.ts +29 -25
  73. package/src/be/memory/providers/sqlite-store.ts +3 -3
  74. package/src/be/memory/reranker.ts +4 -5
  75. package/src/be/migrations/121_task_steering_messages.sql +24 -0
  76. package/src/be/migrations/122_steering_handled_note.sql +4 -0
  77. package/src/be/rbac-audit.ts +2 -1
  78. package/src/be/scripts/typecheck.ts +1 -0
  79. package/src/be/steering.ts +251 -0
  80. package/src/be/swarm-config-guard.ts +117 -1
  81. package/src/commands/context-preamble.ts +68 -8
  82. package/src/commands/provider-credentials.ts +2 -2
  83. package/src/commands/runner.ts +168 -1
  84. package/src/gitlab/auth.ts +3 -1
  85. package/src/heartbeat/heartbeat.ts +79 -20
  86. package/src/http/active-sessions.ts +1 -1
  87. package/src/http/core.ts +69 -1
  88. package/src/http/index.ts +6 -2
  89. package/src/http/mcp-oauth.ts +2 -1
  90. package/src/http/memory.ts +2 -2
  91. package/src/http/schedules.ts +2 -2
  92. package/src/http/script-runs.ts +1 -1
  93. package/src/http/sessions.ts +5 -1
  94. package/src/http/stats.ts +5 -1
  95. package/src/http/tasks.ts +407 -13
  96. package/src/oauth/mcp-wrapper.ts +2 -1
  97. package/src/otel.ts +23 -10
  98. package/src/prompts/base-prompt.ts +15 -0
  99. package/src/prompts/session-templates.ts +31 -0
  100. package/src/providers/claude-adapter.ts +208 -26
  101. package/src/providers/claude-managed-adapter.ts +20 -1
  102. package/src/providers/codex-adapter.ts +2 -1
  103. package/src/providers/devin-adapter.ts +18 -1
  104. package/src/providers/opencode-adapter.ts +32 -0
  105. package/src/providers/pi-mono-adapter.ts +33 -1
  106. package/src/providers/types.ts +11 -1
  107. package/src/rbac/admission.ts +2 -1
  108. package/src/rbac/legacy-policy.ts +2 -0
  109. package/src/rbac/permissions.ts +8 -0
  110. package/src/scripts-runtime/sdk-allowlist.ts +1 -0
  111. package/src/scripts-runtime/types/stdlib.d.ts +6 -0
  112. package/src/scripts-runtime/types/swarm-sdk.d.ts +6 -0
  113. package/src/server-user.ts +22 -0
  114. package/src/server.ts +11 -0
  115. package/src/slack/HEURISTICS.md +7 -0
  116. package/src/slack/assistant.ts +3 -2
  117. package/src/slack/blocks.ts +2 -0
  118. package/src/slack/commands.ts +2 -1
  119. package/src/slack/handlers.ts +39 -4
  120. package/src/slack/router.ts +5 -2
  121. package/src/slack/steering.ts +67 -0
  122. package/src/slack/thread-buffer.ts +39 -0
  123. package/src/slack/watcher.ts +5 -0
  124. package/src/tasks/worker-follow-up.ts +9 -2
  125. package/src/telemetry.ts +2 -1
  126. package/src/tests/claude-adapter-binary.test.ts +5 -0
  127. package/src/tests/claude-managed-adapter.test.ts +61 -0
  128. package/src/tests/devin-adapter.test.ts +41 -0
  129. package/src/tests/env-flag.test.ts +93 -0
  130. package/src/tests/heartbeat-reroute-decision.test.ts +10 -10
  131. package/src/tests/heartbeat-supersede-resume.test.ts +2 -2
  132. package/src/tests/mcp-user-route.test.ts +14 -2
  133. package/src/tests/opencode-adapter.test.ts +176 -1
  134. package/src/tests/pi-mono-adapter.test.ts +80 -0
  135. package/src/tests/prompt-template-session.test.ts +5 -4
  136. package/src/tests/provider-steering-capabilities.test.ts +44 -0
  137. package/src/tests/rbac-engine.test.ts +2 -1
  138. package/src/tests/reload-config.test.ts +81 -6
  139. package/src/tests/sdk-allowlist.test.ts +7 -0
  140. package/src/tests/slack-steering.test.ts +227 -0
  141. package/src/tests/status.test.ts +20 -0
  142. package/src/tests/steer-task-tool.test.ts +200 -0
  143. package/src/tests/steering-core.test.ts +601 -0
  144. package/src/tests/steering-enabled.test.ts +343 -0
  145. package/src/tests/steering-promotion.test.ts +205 -0
  146. package/src/tests/steering-transport.test.ts +338 -0
  147. package/src/tests/tool-output-agent-id.test.ts +182 -0
  148. package/src/tests/user-token-rest-auth.test.ts +31 -30
  149. package/src/tools/accept-steer.ts +148 -0
  150. package/src/tools/cancel-task.ts +1 -1
  151. package/src/tools/context-diff.ts +1 -1
  152. package/src/tools/context-history.ts +2 -3
  153. package/src/tools/create-channel.ts +2 -2
  154. package/src/tools/credential-bindings/tool.ts +1 -1
  155. package/src/tools/delete-channel.ts +1 -1
  156. package/src/tools/get-swarm.ts +1 -1
  157. package/src/tools/get-task-details.ts +4 -1
  158. package/src/tools/get-tasks.ts +4 -1
  159. package/src/tools/inject-learning.ts +1 -1
  160. package/src/tools/join-swarm.ts +1 -1
  161. package/src/tools/kv/kv-delete.ts +1 -1
  162. package/src/tools/kv/kv-get.ts +1 -1
  163. package/src/tools/kv/kv-incr.ts +1 -1
  164. package/src/tools/kv/kv-list.ts +1 -1
  165. package/src/tools/kv/kv-set.ts +1 -1
  166. package/src/tools/list-channels.ts +1 -1
  167. package/src/tools/list-services.ts +2 -2
  168. package/src/tools/mcp-servers/mcp-server-create.ts +1 -1
  169. package/src/tools/mcp-servers/mcp-server-delete.ts +1 -1
  170. package/src/tools/mcp-servers/mcp-server-get.ts +1 -1
  171. package/src/tools/mcp-servers/mcp-server-install.ts +1 -1
  172. package/src/tools/mcp-servers/mcp-server-list.ts +1 -1
  173. package/src/tools/mcp-servers/mcp-server-uninstall.ts +1 -1
  174. package/src/tools/mcp-servers/mcp-server-update.ts +1 -1
  175. package/src/tools/memory-delete.ts +1 -1
  176. package/src/tools/memory-edit.ts +1 -1
  177. package/src/tools/memory-get.ts +1 -1
  178. package/src/tools/memory-search.ts +27 -22
  179. package/src/tools/my-agent-info.ts +1 -1
  180. package/src/tools/poll-task.ts +1 -1
  181. package/src/tools/post-message.ts +2 -2
  182. package/src/tools/prompt-templates/delete.ts +1 -1
  183. package/src/tools/prompt-templates/get.ts +1 -1
  184. package/src/tools/prompt-templates/list.ts +1 -1
  185. package/src/tools/prompt-templates/preview.ts +1 -1
  186. package/src/tools/prompt-templates/set.ts +1 -1
  187. package/src/tools/read-messages.ts +1 -1
  188. package/src/tools/register-agentmail-inbox.ts +1 -1
  189. package/src/tools/register-kapso-number.ts +2 -3
  190. package/src/tools/register-service.ts +1 -1
  191. package/src/tools/request-human-input.ts +1 -1
  192. package/src/tools/schedules/create-schedule.ts +2 -6
  193. package/src/tools/schedules/delete-schedule.ts +1 -1
  194. package/src/tools/schedules/list-schedules.ts +1 -1
  195. package/src/tools/schedules/patch-schedule.ts +2 -2
  196. package/src/tools/schedules/run-schedule-now.ts +1 -1
  197. package/src/tools/schedules/update-schedule.ts +2 -2
  198. package/src/tools/script-connections/tool.ts +1 -1
  199. package/src/tools/send-task.ts +4 -2
  200. package/src/tools/skills/skill-create.ts +1 -1
  201. package/src/tools/skills/skill-delete.ts +1 -1
  202. package/src/tools/skills/skill-get-file.ts +1 -1
  203. package/src/tools/skills/skill-get.ts +1 -1
  204. package/src/tools/skills/skill-install-remote.ts +1 -1
  205. package/src/tools/skills/skill-install.ts +1 -1
  206. package/src/tools/skills/skill-list.ts +1 -1
  207. package/src/tools/skills/skill-publish.ts +1 -1
  208. package/src/tools/skills/skill-search.ts +1 -1
  209. package/src/tools/skills/skill-sync-remote.ts +1 -1
  210. package/src/tools/skills/skill-uninstall.ts +1 -1
  211. package/src/tools/skills/skill-update.ts +1 -1
  212. package/src/tools/steer-task.ts +149 -0
  213. package/src/tools/store-progress.ts +17 -12
  214. package/src/tools/swarm-config/delete-config.ts +1 -1
  215. package/src/tools/swarm-config/get-config.ts +1 -2
  216. package/src/tools/swarm-config/list-config.ts +2 -2
  217. package/src/tools/swarm-config/set-config.ts +1 -2
  218. package/src/tools/task-action.ts +1 -1
  219. package/src/tools/tool-config.ts +3 -1
  220. package/src/tools/unregister-service.ts +1 -1
  221. package/src/tools/update-profile.ts +1 -2
  222. package/src/tools/update-service-status.ts +1 -1
  223. package/src/tools/whatsapp-message.ts +1 -1
  224. package/src/types.ts +106 -22
  225. package/src/utils/env-flag.ts +55 -0
  226. package/src/utils/scripts-only-mode.ts +12 -2
  227. package/src/utils/steering-enabled.ts +12 -0
  228. package/src/workflows/engine.ts +14 -6
  229. package/src/workflows/executors/agent-task.ts +3 -1
package/README.md CHANGED
@@ -127,6 +127,8 @@ Check [our templates](https://templates.agent-swarm.dev) for a quick start.
127
127
  - **Multi-channel inputs** — Slack, GitHub, GitLab, email, WhatsApp, Linear, Jira, and the HTTP API all create tasks. [Integrations](#integrations)
128
128
  - **Workflow engine with Human-in-the-Loop** — DAG-based automation with approval gates, retries, and structured I/O. [Workflows →](https://docs.agent-swarm.dev/docs/concepts/workflows)
129
129
  - **Scheduled & recurring tasks** — cron-based automation for standing work, with schedules that can target agent tasks, workflows, or catalog scripts. [Scheduling →](https://docs.agent-swarm.dev/docs/concepts/scheduling)
130
+ - **Mid-run task steering** — add context at the next turn boundary, request an immediate interrupt where the harness supports it, or degrade safely to a follow-up task. [Task steering →](https://docs.agent-swarm.dev/docs/guides/task-steering)
131
+ - **Operator configuration UI** — tune non-secret feature flags, limits, integration toggles, and runtime defaults from Settings → Configuration, with source and restart-required indicators. [Configuration →](https://docs.agent-swarm.dev/docs/ui/configuration)
130
132
  - **Asset namespaces** — group tasks, workflows, schedules, pages, and mapped files under canonical shared or personal keys, with inheritance, subtree filtering, audited moves, and cross-entity discovery. [Asset namespaces →](https://docs.agent-swarm.dev/docs/guides/asset-namespaces)
131
133
  - **Persistent shared files via agent-fs** — co-deploy agent-fs for shared task attachments, previews, and search; late provisioning or config reloads activate the provider without an API restart, and tenant-authenticated control planes can invite shared-org members without receiving the bootstrap key. [Co-deployment guide →](https://docs.agent-swarm.dev/docs/guides/agent-fs-co-deployment)
132
134
  - **Durable script workflows** — launch background script runs, inspect their journals, and track them from the dashboard when a one-shot `script-run` is too small. [Guide →](https://docs.agent-swarm.dev/docs/guides/script-workflow-runs)
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  resolveSlackUserId
3
- } from "./cli-bxdb36d2.js";
4
- import"./cli-3ptjc655.js";
3
+ } from "./cli-n8mf7x4b.js";
4
+ import"./cli-1592nfd6.js";
5
5
  import {
6
6
  createTaskWithSiblingAwareness
7
- } from "./cli-00yr0kxv.js";
7
+ } from "./cli-kmm1rwmp.js";
8
8
  import {
9
9
  buildCancelledBlocks,
10
10
  getTaskLink
11
- } from "./cli-ma04faw5.js";
11
+ } from "./cli-5arfywtm.js";
12
12
  import"./cli-wspgs9bt.js";
13
13
  import"./cli-dh55d5fg.js";
14
14
  import {
@@ -19,9 +19,9 @@ import {
19
19
  init_context_key,
20
20
  init_db,
21
21
  slackContextKey
22
- } from "./cli-mjxnr12j.js";
22
+ } from "./cli-8cq4z4x7.js";
23
23
  import"./cli-z2zcxes1.js";
24
- import"./cli-w48hgc2y.js";
24
+ import"./cli-h2say6xk.js";
25
25
  import"./cli-4j2mrzag.js";
26
26
  import"./cli-bw80ck94.js";
27
27
  import"./cli-xz9aq0rf.js";
@@ -3,15 +3,15 @@ import {
3
3
  initSlackApp,
4
4
  startSlackApp,
5
5
  stopSlackApp
6
- } from "./cli-9fhxk91h.js";
6
+ } from "./cli-fjf04hpa.js";
7
7
  import"./cli-rkndnn90.js";
8
8
  import"./cli-b0p7rfnd.js";
9
- import"./cli-ma04faw5.js";
9
+ import"./cli-5arfywtm.js";
10
10
  import"./cli-wspgs9bt.js";
11
11
  import"./cli-dh55d5fg.js";
12
- import"./cli-mjxnr12j.js";
12
+ import"./cli-8cq4z4x7.js";
13
13
  import"./cli-z2zcxes1.js";
14
- import"./cli-w48hgc2y.js";
14
+ import"./cli-h2say6xk.js";
15
15
  import"./cli-4j2mrzag.js";
16
16
  import"./cli-bw80ck94.js";
17
17
  import"./cli-xz9aq0rf.js";
@@ -1,24 +1,24 @@
1
1
  import {
2
2
  bufferThreadMessage,
3
3
  wasEventSeen
4
- } from "./cli-kpfsabp2.js";
4
+ } from "./cli-we91ywvy.js";
5
5
  import {
6
6
  hasOtherUserMention
7
- } from "./cli-fc1gvt9c.js";
7
+ } from "./cli-3tv9z4wx.js";
8
8
  import {
9
9
  resolveSlackUserId,
10
10
  rewriteSlackMentions
11
- } from "./cli-bxdb36d2.js";
12
- import"./cli-3ptjc655.js";
11
+ } from "./cli-n8mf7x4b.js";
12
+ import"./cli-1592nfd6.js";
13
13
  import {
14
14
  createTaskWithSiblingAwareness
15
- } from "./cli-00yr0kxv.js";
15
+ } from "./cli-kmm1rwmp.js";
16
16
  import {
17
17
  require_dist
18
- } from "./cli-9fhxk91h.js";
18
+ } from "./cli-fjf04hpa.js";
19
19
  import"./cli-rkndnn90.js";
20
20
  import"./cli-b0p7rfnd.js";
21
- import"./cli-ma04faw5.js";
21
+ import"./cli-5arfywtm.js";
22
22
  import"./cli-wspgs9bt.js";
23
23
  import"./cli-dh55d5fg.js";
24
24
  import {
@@ -27,12 +27,14 @@ import {
27
27
  getMostRecentTaskInThread,
28
28
  init_context_key,
29
29
  init_db,
30
+ init_env_flag,
30
31
  init_resolver,
32
+ isEnvFlagEnabled,
31
33
  resolveTemplate,
32
34
  slackContextKey
33
- } from "./cli-mjxnr12j.js";
35
+ } from "./cli-8cq4z4x7.js";
34
36
  import"./cli-z2zcxes1.js";
35
- import"./cli-w48hgc2y.js";
37
+ import"./cli-h2say6xk.js";
36
38
  import"./cli-4j2mrzag.js";
37
39
  import"./cli-bw80ck94.js";
38
40
  import"./cli-xz9aq0rf.js";
@@ -47,7 +49,8 @@ init_db();
47
49
  init_resolver();
48
50
  init_context_key();
49
51
  var import_bolt = __toESM(require_dist(), 1);
50
- var additiveSlack = process.env.ADDITIVE_SLACK === "true";
52
+ init_env_flag();
53
+ var isAdditiveSlack = () => isEnvFlagEnabled("ADDITIVE_SLACK", false);
51
54
  var cachedBotUserId = null;
52
55
  function createAssistant() {
53
56
  return new import_bolt.Assistant({
@@ -119,7 +122,7 @@ function createAssistant() {
119
122
  }) : undefined;
120
123
  const workingAgent = getAgentWorkingOnThread(channelId, threadTs);
121
124
  if (workingAgent && workingAgent.status !== "offline") {
122
- if (additiveSlack) {
125
+ if (isAdditiveSlack()) {
123
126
  bufferThreadMessage(channelId, threadTs, messageText, userId, message.ts);
124
127
  await safeSetStatus("Queuing follow-up...");
125
128
  return;
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  embedScript,
3
3
  embeddingProvider
4
- } from "./cli-60q15ncp.js";
5
- import"./cli-qf0qxzw5.js";
4
+ } from "./cli-byv3720g.js";
5
+ import"./cli-zdp11t8m.js";
6
6
  import"./cli-q25ejbyn.js";
7
7
  import {
8
8
  getDb,
9
9
  init_db
10
- } from "./cli-mjxnr12j.js";
10
+ } from "./cli-8cq4z4x7.js";
11
11
  import"./cli-z2zcxes1.js";
12
- import"./cli-w48hgc2y.js";
12
+ import"./cli-h2say6xk.js";
13
13
  import"./cli-4j2mrzag.js";
14
14
  import"./cli-bw80ck94.js";
15
15
  import"./cli-xz9aq0rf.js";
@@ -3,14 +3,14 @@ import {
3
3
  getEmbeddingProvider,
4
4
  getMemoryStore,
5
5
  init_constants
6
- } from "./cli-qf0qxzw5.js";
6
+ } from "./cli-zdp11t8m.js";
7
7
  import"./cli-q25ejbyn.js";
8
8
  import {
9
9
  getDb,
10
10
  init_db
11
- } from "./cli-mjxnr12j.js";
11
+ } from "./cli-8cq4z4x7.js";
12
12
  import"./cli-z2zcxes1.js";
13
- import"./cli-w48hgc2y.js";
13
+ import"./cli-h2say6xk.js";
14
14
  import"./cli-4j2mrzag.js";
15
15
  import"./cli-bw80ck94.js";
16
16
  import"./cli-xz9aq0rf.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  getDb,
3
3
  init_db
4
- } from "./cli-mjxnr12j.js";
4
+ } from "./cli-8cq4z4x7.js";
5
5
  import"./cli-z2zcxes1.js";
6
- import"./cli-w48hgc2y.js";
6
+ import"./cli-h2say6xk.js";
7
7
  import {
8
8
  init_secret_scrubber,
9
9
  scrubSecrets
@@ -12,7 +12,7 @@ import {
12
12
  resolveClaudeBinary,
13
13
  resolveClaudeBinaryArgv,
14
14
  resolveClaudeBridgeEnabled
15
- } from "./cli-x4apc9t3.js";
15
+ } from "./cli-36dctyg8.js";
16
16
  import"./cli-psrqtw2m.js";
17
17
  import"./cli-tng3131n.js";
18
18
  import"./cli-zm7njwzd.js";
@@ -3,7 +3,7 @@ import {
3
3
  checkClaudeManagedCredentials,
4
4
  composeManagedUserMessage,
5
5
  normalizeRepoUrl
6
- } from "./cli-5c4327dx.js";
6
+ } from "./cli-jj1arm18.js";
7
7
  import"./cli-07er7wrs.js";
8
8
  import"./cli-yv9dttkh.js";
9
9
  import"./cli-d6n0thxw.js";
@@ -4,7 +4,7 @@ import {
4
4
  incrKv,
5
5
  init_db,
6
6
  upsertKv
7
- } from "./cli-mjxnr12j.js";
7
+ } from "./cli-8cq4z4x7.js";
8
8
 
9
9
  // src/be/users.ts
10
10
  init_db();
@@ -71,6 +71,38 @@ function parseClaudeBinary(raw) {
71
71
  return ["claude"];
72
72
  return trimmed.split(/\s+/);
73
73
  }
74
+ var MIN_CLAUDE_QUEUE_STEERING_VERSION = [2, 1, 205];
75
+ function resolveClaudeQueueSteeringOverride(env) {
76
+ const raw = env.CLAUDE_QUEUE_STEERING?.trim().toLowerCase();
77
+ if (!raw)
78
+ return;
79
+ if (["0", "false", "off", "no"].includes(raw))
80
+ return false;
81
+ if (["1", "true", "on", "yes"].includes(raw))
82
+ return true;
83
+ return;
84
+ }
85
+ function supportsClaudeQueueSteering(versionOutput) {
86
+ const match = versionOutput?.match(/claude(?: code)? version:\s*(\d+)\.(\d+)\.(\d+)/i) ?? versionOutput?.match(/(\d+)\.(\d+)\.(\d+)\s*\(Claude Code\)/i);
87
+ if (!match)
88
+ return false;
89
+ const detected = match.slice(1, 4).map(Number);
90
+ for (let index = 0;index < MIN_CLAUDE_QUEUE_STEERING_VERSION.length; index++) {
91
+ const actual = detected[index] ?? 0;
92
+ const minimum = MIN_CLAUDE_QUEUE_STEERING_VERSION[index] ?? 0;
93
+ if (actual !== minimum)
94
+ return actual > minimum;
95
+ }
96
+ return true;
97
+ }
98
+ function claudeUserMessage(text) {
99
+ return `${JSON.stringify({
100
+ type: "user",
101
+ message: { role: "user", content: text },
102
+ parent_tool_use_id: null
103
+ })}
104
+ `;
105
+ }
74
106
  function resolveClaudeBinary(resolvedEnv, fallbackEnv = process.env) {
75
107
  const candidate = resolvedEnv.CLAUDE_BINARY?.trim() || fallbackEnv.CLAUDE_BINARY?.trim();
76
108
  return candidate || "claude";
@@ -247,7 +279,9 @@ class ClaudeSession {
247
279
  claudeBinaryArgv;
248
280
  harnessVariant;
249
281
  harnessVariantMeta;
282
+ queueSteeringSupported;
250
283
  proc;
284
+ stdinWriter;
251
285
  listeners = [];
252
286
  eventQueue = [];
253
287
  _sessionId;
@@ -257,13 +291,15 @@ class ClaudeSession {
257
291
  contextWindowSize;
258
292
  systemPromptFile;
259
293
  appliedReasoningEffort;
260
- constructor(config, model, taskFilePath, taskFilePid, sessionMcpConfig = null, claudeBinaryArgv = ["claude"], systemPromptFile = null, harnessVariant, harnessVariantMeta) {
294
+ deliverSteering;
295
+ constructor(config, model, taskFilePath, taskFilePid, sessionMcpConfig = null, claudeBinaryArgv = ["claude"], systemPromptFile = null, harnessVariant, harnessVariantMeta, queueSteeringSupported = false) {
261
296
  this.config = config;
262
297
  this.model = model;
263
298
  this.sessionMcpConfig = sessionMcpConfig;
264
299
  this.claudeBinaryArgv = claudeBinaryArgv;
265
300
  this.harnessVariant = harnessVariant;
266
301
  this.harnessVariantMeta = harnessVariantMeta;
302
+ this.queueSteeringSupported = queueSteeringSupported;
267
303
  this.taskFilePid = taskFilePid;
268
304
  this.contextWindowSize = getContextWindowSize(model);
269
305
  this.systemPromptFile = systemPromptFile;
@@ -289,11 +325,60 @@ class ClaudeSession {
289
325
  ...sourceEnv.CLAUDE_CODE_OAUTH_TOKEN ? { AGENT_SWARM_CLAUDE_OAUTH_TOKEN: sourceEnv.CLAUDE_CODE_OAUTH_TOKEN } : {},
290
326
  CONTEXT_MODE_EXTERNAL_MCP_NUDGE_EVERY: CTX_MODE_NUDGE_EVERY
291
327
  },
328
+ ...this.queueSteeringSupported ? { stdin: "pipe" } : {},
292
329
  stdout: "pipe",
293
330
  stderr: "pipe"
294
331
  });
332
+ if (this.queueSteeringSupported) {
333
+ const stdin = this.proc.stdin;
334
+ if (stdin && typeof stdin !== "number") {
335
+ this.stdinWriter = stdin;
336
+ this.writeUserMessage(this.config.prompt).catch((err) => {
337
+ console.warn(`\x1B[33m[claude]\x1B[0m Failed to write initial prompt to Claude stdin: ${scrubSecrets(String(err))}`);
338
+ this.closeStdin();
339
+ try {
340
+ this.proc.kill("SIGTERM");
341
+ } catch {}
342
+ });
343
+ } else {
344
+ console.warn("\x1B[33m[claude]\x1B[0m Claude stdin was not piped; terminating the session to avoid waiting without a prompt.");
345
+ try {
346
+ this.proc.kill("SIGTERM");
347
+ } catch {}
348
+ }
349
+ }
350
+ if (this.queueSteeringSupported && this.stdinWriter) {
351
+ this.deliverSteering = async ({
352
+ mode,
353
+ text
354
+ }) => {
355
+ if (mode === "steer") {
356
+ console.warn("[claude-adapter] Interrupt requested; raw Claude CLI supports queued steering only, so the message will run at the next turn boundary.");
357
+ }
358
+ if (!this.stdinWriter) {
359
+ return { delivered: false, reason: "Claude stdin is closed" };
360
+ }
361
+ try {
362
+ await this.writeUserMessage(text);
363
+ return { delivered: true, mode: "queue" };
364
+ } catch (err) {
365
+ this.closeStdin();
366
+ return {
367
+ delivered: false,
368
+ reason: `Claude stdin write failed: ${String(err)}`
369
+ };
370
+ }
371
+ };
372
+ }
295
373
  this.completionPromise = this.processStreams();
296
374
  }
375
+ async writeUserMessage(text) {
376
+ const writer = this.stdinWriter;
377
+ if (!writer)
378
+ throw new Error("Claude stdin is closed");
379
+ await writer.write(claudeUserMessage(text));
380
+ await writer.flush?.();
381
+ }
297
382
  buildCommand() {
298
383
  const cmd = [
299
384
  ...this.claudeBinaryArgv,
@@ -305,10 +390,13 @@ class ClaudeSession {
305
390
  "--dangerously-skip-permissions",
306
391
  "--allow-dangerously-skip-permissions",
307
392
  "--permission-mode",
308
- "bypassPermissions",
309
- "-p",
310
- this.config.prompt
393
+ "bypassPermissions"
311
394
  ];
395
+ if (this.queueSteeringSupported) {
396
+ cmd.push("--input-format", "stream-json");
397
+ } else {
398
+ cmd.push("-p", this.config.prompt);
399
+ }
312
400
  if (this.config.additionalArgs?.length) {
313
401
  cmd.push(...this.config.additionalArgs);
314
402
  }
@@ -331,6 +419,16 @@ class ClaudeSession {
331
419
  this.eventQueue.push(event);
332
420
  }
333
421
  }
422
+ closeStdin() {
423
+ const writer = this.stdinWriter;
424
+ this.stdinWriter = undefined;
425
+ if (!writer)
426
+ return;
427
+ try {
428
+ const result = writer.end();
429
+ Promise.resolve(result).catch(() => {});
430
+ } catch {}
431
+ }
334
432
  async processStreams() {
335
433
  const logFileHandle = Bun.file(this.config.logFile).writer();
336
434
  let stderrOutput = "";
@@ -383,7 +481,11 @@ class ClaudeSession {
383
481
  this.emit({ type: "raw_stderr", content: scrubbedText });
384
482
  }
385
483
  })();
386
- await Promise.all([stdoutPromise, stderrPromise]);
484
+ try {
485
+ await Promise.all([stdoutPromise, stderrPromise]);
486
+ } finally {
487
+ this.closeStdin();
488
+ }
387
489
  await logFileHandle.end();
388
490
  const exitCode = await this.proc.exited;
389
491
  await cleanupTaskFile(this.taskFilePid);
@@ -422,6 +524,9 @@ ${scrubSecrets(stderrOutput)}`);
422
524
  processJsonLine(trimmed, setCost) {
423
525
  try {
424
526
  const json = JSON.parse(trimmed);
527
+ if (json.type === "result") {
528
+ this.closeStdin();
529
+ }
425
530
  if (json.type === "system" && json.subtype === "init" && json.session_id) {
426
531
  this._sessionId = json.session_id;
427
532
  this.emit({
@@ -527,13 +632,20 @@ ${scrubSecrets(stderrOutput)}`);
527
632
  return this.completionPromise;
528
633
  }
529
634
  async abort() {
530
- this.proc.kill("SIGTERM");
635
+ this.closeStdin();
636
+ try {
637
+ this.proc.kill("SIGTERM");
638
+ } catch {}
531
639
  }
532
640
  }
533
641
 
534
642
  class ClaudeAdapter {
535
643
  name = "claude";
536
- traits = { hasMcp: true, hasLocalEnvironment: true };
644
+ traits = {
645
+ hasMcp: true,
646
+ hasLocalEnvironment: true,
647
+ steerModes: ["queue"]
648
+ };
537
649
  async createSession(config) {
538
650
  if (config.resumeSessionId) {
539
651
  console.warn("[claude-adapter] resumeSessionId ignored — native resume is disabled by deprecation plan");
@@ -594,24 +706,28 @@ class ClaudeAdapter {
594
706
  }
595
707
  const harnessVariant = useClaudeBridge ? "bridge" : "stock";
596
708
  let harnessVariantMeta;
597
- if (useClaudeBridge) {
598
- try {
599
- const bin = effectiveClaudeBinaryArgv[0] ?? "claude-bridge";
600
- const result = await Bun.$`${bin} --version`.quiet();
601
- const trimmed = result.text().trim();
602
- if (trimmed)
603
- harnessVariantMeta = { version: trimmed };
604
- } catch {}
605
- } else {
606
- try {
607
- const bin = effectiveClaudeBinaryArgv[0] ?? "claude";
608
- const result = await Bun.$`${bin} --version`.quiet();
609
- const trimmed = result.text().trim();
610
- if (trimmed)
709
+ const queueSteeringOverride = resolveClaudeQueueSteeringOverride(sourceEnv);
710
+ let harnessVersion;
711
+ try {
712
+ const result = Bun.spawnSync([...effectiveClaudeBinaryArgv, "--version"], {
713
+ env: sourceEnv,
714
+ stdout: "pipe",
715
+ stderr: "pipe"
716
+ });
717
+ if (result.success) {
718
+ const trimmed = `${result.stdout?.toString() ?? ""}
719
+ ${result.stderr?.toString() ?? ""}`.trim();
720
+ if (trimmed) {
721
+ harnessVersion = trimmed;
611
722
  harnessVariantMeta = { version: trimmed };
612
- } catch {}
723
+ }
724
+ }
725
+ } catch {}
726
+ const queueSteeringSupported = queueSteeringOverride ?? (!isInteractiveTmuxClaude && supportsClaudeQueueSteering(harnessVersion));
727
+ if (!queueSteeringSupported && queueSteeringOverride === undefined) {
728
+ console.warn(`\x1B[33m[claude]\x1B[0m Queued steering requires Claude Code >= ${MIN_CLAUDE_QUEUE_STEERING_VERSION.join(".")}; detected ${harnessVersion ?? "an unknown version"}. Steering messages will be promoted to follow-up tasks.`);
613
729
  }
614
- return new ClaudeSession(config, model, taskFilePath, taskFilePid, sessionMcpConfig, effectiveClaudeBinaryArgv, systemPromptFile, harnessVariant, harnessVariantMeta);
730
+ return new ClaudeSession(config, model, taskFilePath, taskFilePid, sessionMcpConfig, effectiveClaudeBinaryArgv, systemPromptFile, harnessVariant, harnessVariantMeta, queueSteeringSupported);
615
731
  }
616
732
  async canResume(_sessionId) {
617
733
  return true;
@@ -2,18 +2,21 @@ import {
2
2
  getAgentById,
3
3
  getAgentWorkingOnThread,
4
4
  getAllAgents,
5
- init_db
6
- } from "./cli-mjxnr12j.js";
5
+ init_db,
6
+ init_env_flag,
7
+ isEnvFlagEnabled
8
+ } from "./cli-8cq4z4x7.js";
7
9
 
8
10
  // src/slack/router.ts
9
11
  init_db();
12
+ init_env_flag();
10
13
  function hasOtherUserMention(text, botUserId) {
11
14
  const mentions = text.match(/<@([A-Z0-9]+)>/g) ?? [];
12
15
  return mentions.some((m) => m !== `<@${botUserId}>`);
13
16
  }
14
17
  function routeMessage(text, botUserId, botMentioned, threadContext) {
15
18
  const matches = [];
16
- const requireMentionForThreadFollowup = process.env.SLACK_THREAD_FOLLOWUP_REQUIRE_MENTION === "true";
19
+ const requireMentionForThreadFollowup = isEnvFlagEnabled("SLACK_THREAD_FOLLOWUP_REQUIRE_MENTION", false);
17
20
  const agents = getAllAgents().filter((a) => a.status !== "offline");
18
21
  const idMatches = text.matchAll(/swarm#([a-f0-9-]{36})/gi);
19
22
  for (const match of idMatches) {