@desplega.ai/agent-swarm 2.7.5 → 2.7.7

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 (319) hide show
  1. package/dist/{acp-adapter-g3ads55s.js → acp-adapter-7b4vk3h5.js} +5 -4
  2. package/dist/{actions-zwfykqqk.js → actions-3tt153af.js} +18 -17
  3. package/dist/{amp-adapter-z3s0ssdt.js → amp-adapter-njpts0yr.js} +1 -1
  4. package/dist/{anthropic-messages-x4q6rfq5.js → anthropic-messages-xey2skwx.js} +7 -7
  5. package/dist/{app-vmp4fgep.js → app-nky4378f.js} +3 -3
  6. package/dist/{assistant-vwde653f.js → assistant-jnb669pa.js} +24 -22
  7. package/dist/{azure-openai-responses-s1w5n70z.js → azure-openai-responses-26t7j9ra.js} +5 -5
  8. package/dist/{boot-reembed-375t7tbk.js → boot-reembed-9mgvaztt.js} +1 -1
  9. package/dist/{boot-reembed-gq9rcpnj.js → boot-reembed-qs2djdej.js} +1 -1
  10. package/dist/{boot-scrub-sweep-nd938kyf.js → boot-scrub-sweep-yjpdj7s1.js} +3 -3
  11. package/dist/{boot-seeds-aykx51v3.js → boot-seeds-5cm6ambd.js} +4 -4
  12. package/dist/{boxd-k1j26g3h.js → boxd-nv507va8.js} +5 -5
  13. package/dist/{claude-adapter-8j4hm099.js → claude-adapter-fn287zmm.js} +5 -4
  14. package/dist/{claude-managed-setup-0wyynpn1.js → claude-managed-setup-wtdz2mj2.js} +1 -1
  15. package/dist/{claude-sdk-session-q6wj5hmy.js → claude-sdk-session-x91kqyhm.js} +9677 -9514
  16. package/dist/{cli-j3jvnpe8.js → cli-08bmz9z9.js} +1 -1
  17. package/dist/{cli-gjr2y2xk.js → cli-0agcv1v5.js} +4 -1
  18. package/dist/{cli-y24sc29k.js → cli-1c6tzt8g.js} +30 -8
  19. package/dist/{cli-mjzynrse.js → cli-35rsp8ye.js} +1 -1
  20. package/dist/{cli-rpm2sgv0.js → cli-3fg0bdcv.js} +19 -2
  21. package/dist/{cli-nn4d8dne.js → cli-5b456bpf.js} +2 -2
  22. package/dist/{cli-bhjt02p8.js → cli-5jnhv72d.js} +1 -1
  23. package/dist/{cli-fqzx7gwa.js → cli-5zx699j9.js} +2 -2
  24. package/dist/{cli-hf6zt5m6.js → cli-69szn7w7.js} +17 -1
  25. package/dist/{cli-vqypxzh4.js → cli-6g0hb4cp.js} +8 -8
  26. package/dist/{cli-tqgg40ek.js → cli-6pfd54vx.js} +9 -8
  27. package/dist/{cli-bsn8nhrq.js → cli-6vcp76qk.js} +3 -3
  28. package/dist/{cli-zppwg9p9.js → cli-72v799xn.js} +1 -1
  29. package/dist/cli-82j36f2m.js +45 -0
  30. package/dist/{cli-hn9hxmz9.js → cli-8305gbq0.js} +29 -16
  31. package/dist/{cli-z8eh3ex8.js → cli-8sckt74b.js} +8 -8
  32. package/dist/{cli-bnz7a7qf.js → cli-95jzxcp3.js} +1 -1
  33. package/dist/{cli-0bxqnvq9.js → cli-adeegh7d.js} +29 -7
  34. package/dist/{cli-g61qxmge.js → cli-afkqkrtw.js} +3 -3
  35. package/dist/{cli-7a42nfy0.js → cli-ayayvfg4.js} +24 -4
  36. package/dist/{cli-bqt1mptt.js → cli-az48n0nr.js} +4 -4
  37. package/dist/{cli-z6jkx23q.js → cli-bfv7vdg6.js} +9 -9
  38. package/dist/{cli-pywf3eh5.js → cli-caj33vcq.js} +5 -5
  39. package/dist/{cli-5pag6rmn.js → cli-cb2a8pna.js} +1 -1
  40. package/dist/{cli-wvaawacd.js → cli-cppkf404.js} +5236 -72
  41. package/dist/{cli-mry0qzym.js → cli-ddaanqkd.js} +123 -10
  42. package/dist/{cli-0gey5fzy.js → cli-e0kmphd6.js} +2 -2
  43. package/dist/{cli-zh3fp8v2.js → cli-e46hg0xw.js} +1 -1
  44. package/dist/{cli-jm2vfpfd.js → cli-e5bzrn01.js} +1 -1
  45. package/dist/{cli-qxnf8z2z.js → cli-excnnjg2.js} +165 -153
  46. package/dist/{cli-71ptav7x.js → cli-ferkkrg9.js} +1 -1
  47. package/dist/{cli-vpf89f34.js → cli-fmjd0t1y.js} +3 -3
  48. package/dist/{cli-rm6hqj3z.js → cli-fyt2g4wd.js} +33 -139
  49. package/dist/cli-g08zdaec.js +55 -0
  50. package/dist/{cli-ehq736cn.js → cli-g7s47cc5.js} +4 -4
  51. package/dist/{cli-82ae98pz.js → cli-gz6q4eve.js} +3 -3
  52. package/dist/{cli-82jg7fp9.js → cli-he5nxaa8.js} +1 -1
  53. package/dist/{cli-rqkxrmgw.js → cli-je518txm.js} +39 -14
  54. package/dist/{cli-8hs41zy2.js → cli-jtjtabxe.js} +1 -1
  55. package/dist/{cli-611a1294.js → cli-k0wwfqbg.js} +18 -1
  56. package/dist/{cli-nzxr556s.js → cli-k1nje3v3.js} +38 -43
  57. package/dist/{cli-3h4nhjn8.js → cli-k8196sh2.js} +9 -7
  58. package/dist/{cli-afrrppsw.js → cli-k899ehvh.js} +2 -2
  59. package/dist/{cli-0731hvbw.js → cli-m0da8j35.js} +23 -9
  60. package/dist/cli-m2z8jagn.js +12078 -0
  61. package/dist/{cli-8veytvbh.js → cli-mkk9rnzz.js} +5 -5
  62. package/dist/{cli-7wspm5gm.js → cli-n6bv12jn.js} +528 -6
  63. package/dist/{cli-spknvxbq.js → cli-nmzhp1b5.js} +14 -12
  64. package/dist/{cli-p599f1qm.js → cli-p82cnnjq.js} +1 -1
  65. package/dist/{cli-xtjhfmpc.js → cli-pc6n7fre.js} +1 -1
  66. package/dist/{cli-vbyfwh92.js → cli-pjctyea3.js} +2 -2
  67. package/dist/{cli-nmbmy64z.js → cli-pq73h5mz.js} +3 -3
  68. package/dist/{cli-aa6yxc7m.js → cli-pz4rk021.js} +1 -1
  69. package/dist/{cli-7wcyk2s5.js → cli-q3tkegby.js} +1 -1
  70. package/dist/cli-qghe0h66.js +67 -0
  71. package/dist/{cli-6s7vdcta.js → cli-qh4d4tvk.js} +4 -4
  72. package/dist/{cli-mmwm7zbf.js → cli-rtt8g4v9.js} +1 -1
  73. package/dist/{cli-kg8hchyg.js → cli-sa02jsqt.js} +1 -1
  74. package/dist/{cli-1h3wcpbw.js → cli-snpj5zbj.js} +2 -2
  75. package/dist/{cli-a7v854rf.js → cli-tgrv9cjx.js} +263 -12
  76. package/dist/{cli-a47xy8eq.js → cli-vz22fyqv.js} +186 -54
  77. package/dist/{cli-1ayk1eas.js → cli-wk5yrfwd.js} +285 -42
  78. package/dist/{cli-1338796d.js → cli-ws19768n.js} +1755 -119
  79. package/dist/{cli-70r77n04.js → cli-xae4g51r.js} +1 -1
  80. package/dist/{cli-gf5hbmdr.js → cli-yjdgea32.js} +3 -3
  81. package/dist/{cli-xbkdm710.js → cli-yndmfxb3.js} +3 -3
  82. package/dist/{cli-rhw40jgb.js → cli-yyj3j5m4.js} +2 -2
  83. package/dist/cli.js +26 -25
  84. package/dist/{cloudflare-workers-ai-system-one-bm60fjm0.js → cloudflare-workers-ai-system-one-ef2a980q.js} +2 -2
  85. package/dist/{codex-adapter-q6k3gnyg.js → codex-adapter-cf2yxe9m.js} +3 -2
  86. package/dist/{codex-hook-9efm2x1m.js → codex-hook-a0c6g6t6.js} +1 -1
  87. package/dist/{codex-session-runner-3mwmk3d9.js → codex-session-runner-6vfzdgbd.js} +3 -2
  88. package/dist/{commands-evrenjn9.js → commands-t3mfy7vn.js} +9 -3
  89. package/dist/{controller-xjp8vswh.js → controller-q7xrbaz0.js} +8 -3
  90. package/dist/{controllers-connect-pp5jnxvc.js → controllers-connect-c6nm70kg.js} +20 -19
  91. package/dist/{cursor-adapter-yf47w4t0.js → cursor-adapter-ftd81ga8.js} +1 -1
  92. package/dist/{db-zxpw6aht.js → db-dk572x25.js} +3 -3
  93. package/dist/{db-rgfsh91f.js → db-vemtpmcc.js} +14 -4
  94. package/dist/{devtools-82fzqra8.js → devtools-qxfgbsqz.js} +1 -1
  95. package/dist/{dispatcher-smasgws7.js → dispatcher-kh7ecxh9.js} +17 -16
  96. package/dist/{docker-rrjhaqt9.js → docker-c1a3gqmf.js} +89 -22
  97. package/dist/{dsh-adapter-ftyy8dnp.js → dsh-adapter-v8628r89.js} +1 -1
  98. package/dist/{e2b-w1p0bnpm.js → e2b-fr12yccx.js} +5 -5
  99. package/dist/{e2b-qcaj675y.js → e2b-x6ywzak3.js} +3 -3
  100. package/dist/{easter-egg-3d-yyts7p16.js → easter-egg-3d-nenw4x63.js} +1 -1
  101. package/dist/{embedding-space-1z0mbg95.js → embedding-space-0jepb239.js} +6 -6
  102. package/dist/{embeddings-ygeg7tm7.js → embeddings-xxt49yxg.js} +1 -1
  103. package/dist/{execute-14qhqp4d.js → execute-1mhw6e4x.js} +1 -1
  104. package/dist/{external-channel-ttgrs3sx.js → external-channel-55v12e60.js} +2 -2
  105. package/dist/{fx-adapter-gt6pncj2.js → fx-adapter-bs8wqrk5.js} +6 -5
  106. package/dist/{google-generative-ai-yvmdxyxa.js → google-generative-ai-v94hr7h0.js} +5 -5
  107. package/dist/{google-vertex-jrtdh9gs.js → google-vertex-g7vr6cf8.js} +5 -5
  108. package/dist/{grok-adapter-sm4m5k4g.js → grok-adapter-gpjqmkcq.js} +6 -5
  109. package/dist/handlers-zxmp1ta4.js +32 -0
  110. package/dist/{heartbeat-qahz4p62.js → heartbeat-k42svnr0.js} +20 -19
  111. package/dist/{hook-4fd5wq5w.js → hook-114m7hap.js} +4 -3
  112. package/dist/{hook-kj3d398m.js → hook-6nphweh0.js} +24 -9
  113. package/dist/{http-1ted0j1k.js → http-r8cc4wz7.js} +1196 -211
  114. package/dist/index-a8phxqnk.js +37 -0
  115. package/dist/{index-q4b917zs.js → index-e3s8wmxy.js} +1 -1
  116. package/dist/{index-6rq3r5zb.js → index-fpk4bcd9.js} +1 -1
  117. package/dist/{index-5rk6rfzr.js → index-fvzke5kx.js} +1 -1
  118. package/dist/index-k6h00t4c.js +30 -0
  119. package/dist/{index-7v51awbn.js → index-nh3wyqdt.js} +1027 -577
  120. package/dist/{index-yqhz88yy.js → index-pxn30mse.js} +8 -8
  121. package/dist/index-xrz7te8h.js +33 -0
  122. package/dist/{keepalive-6cf311t5.js → keepalive-x060nt9p.js} +3 -3
  123. package/dist/lead-956sd2yc.js +71 -0
  124. package/dist/{maintenance-a4bm1bmt.js → maintenance-2xxfexhf.js} +1 -1
  125. package/dist/{mistral-conversations-4pmwj1c0.js → mistral-conversations-3gjpdb4b.js} +4 -4
  126. package/dist/{oauth-refresh-sweep-3h0dfw1k.js → oauth-refresh-sweep-fckc4ar5.js} +2 -2
  127. package/dist/{onboard-myn5hraa.js → onboard-zc48j237.js} +5 -5
  128. package/dist/{openai-codex-responses-44j573nm.js → openai-codex-responses-8pbxq9h5.js} +5 -5
  129. package/dist/{openai-completions-a4gee2a8.js → openai-completions-rm00s912.js} +4 -4
  130. package/dist/{openai-decisions-w4qkrcar.js → openai-decisions-8v957r2r.js} +1 -1
  131. package/dist/{openai-responses-rbp6h5kr.js → openai-responses-agxpf96k.js} +5 -5
  132. package/dist/{opencode-adapter-p2nkb5am.js → opencode-adapter-r690h1cr.js} +4 -3
  133. package/dist/{otel-impl-a1a0ef6b.js → otel-impl-r5xbh81q.js} +4 -4
  134. package/dist/{pi-mono-adapter-rzmpb72a.js → pi-mono-adapter-c7v8sdec.js} +7 -6
  135. package/dist/{pricing-refresh-83drrnxj.js → pricing-refresh-3pmre11v.js} +3 -3
  136. package/dist/{rbac-roles-s8y6ecb5.js → rbac-roles-3vbshwsb.js} +1 -1
  137. package/dist/{rbac-roles-0fb6e7pj.js → rbac-roles-910mmkgz.js} +2 -2
  138. package/dist/{render-v2-twmbgrz4.js → render-v2-pxykkbab.js} +3 -3
  139. package/dist/{resume-zfqc36xj.js → resume-adda0bwy.js} +6 -6
  140. package/dist/{runtime-qwggdpqr.js → runtime-fnbm7stk.js} +1 -1
  141. package/dist/{session-access-sc9pn9da.js → session-access-2fvamrdc.js} +4 -4
  142. package/dist/{session-source-backfill-qh07xr8g.js → session-source-backfill-08xvv0sm.js} +2 -2
  143. package/dist/{setup-4fr0m7a1.js → setup-1aqmvmh1.js} +3 -3
  144. package/dist/{typesafe-system-one-5mavm259.js → typesafe-system-one-0bmqcxfg.js} +2 -2
  145. package/dist/{virtual-modules-fh4ha15b.js → virtual-modules-d2pjk9j1.js} +5 -5
  146. package/dist/{work-objects-0wr8zxct.js → work-objects-9s0yrm5j.js} +20 -19
  147. package/dist/{worker-follow-up-ktyyazyp.js → worker-follow-up-3q78fqmr.js} +17 -16
  148. package/dist/worker-y15hy08h.js +71 -0
  149. package/openapi.json +289 -4
  150. package/package.json +9 -8
  151. package/src/apps/definition.ts +6 -5
  152. package/src/be/db/page-theme-tokens.ts +12 -0
  153. package/src/be/db/script-runs.ts +23 -0
  154. package/src/be/db/tasks/read.ts +131 -4
  155. package/src/be/db/tasks/write.ts +19 -0
  156. package/src/be/db-client.ts +114 -11
  157. package/src/be/db.ts +49 -6
  158. package/src/be/memory/providers/sqlite-store.ts +49 -12
  159. package/src/be/migrations/260_runtime_pool_cache.sql +20 -0
  160. package/src/be/migrations/262_session_visibility_indexes.sql +18 -0
  161. package/src/be/migrations/263_task_list_filter_index.sql +11 -0
  162. package/src/be/migrations/264_slack_thread_cover_index.sql +9 -0
  163. package/src/be/migrations/266_script_runs_source_task.sql +11 -0
  164. package/src/be/migrations/269_pages_design_system.sql +23 -0
  165. package/src/be/runtime-pools/cache-cleanup.ts +109 -0
  166. package/src/be/runtime-pools/db.ts +65 -6
  167. package/src/be/runtime-pools/remote-controller.ts +5 -0
  168. package/src/be/runtime-pools/supervisor.ts +33 -2
  169. package/src/be/scripts/typecheck.ts +22 -0
  170. package/src/be/seed/schedules-seeder.ts +0 -10
  171. package/src/be/seed-scripts/catalog/catalog-report.inline.ts +2 -0
  172. package/src/be/seed-scripts/catalog/catalog-report.ts +2 -0
  173. package/src/be/seed-scripts/catalog/memory-eval.ts +2 -0
  174. package/src/be/seed-scripts/catalog/swarm-update-check.ts +150 -0
  175. package/src/be/seed-scripts/catalog/task-failure-audit.ts +5 -1
  176. package/src/be/seed-scripts/index.ts +9 -0
  177. package/src/be/seed-skills/bundled-files.generated.json +3 -3
  178. package/src/be/swarm-config-guard.ts +32 -0
  179. package/src/be/task-auto-title-listener.ts +127 -0
  180. package/src/commands/controller.ts +4 -0
  181. package/src/commands/entrypoint-api-readiness.ts +74 -0
  182. package/src/commands/onboard/agent-fs-version.ts +1 -1
  183. package/src/commands/profile-sync.ts +151 -16
  184. package/src/commands/runner.ts +15 -7
  185. package/src/hooks/hook.ts +20 -9
  186. package/src/http/index.ts +4 -1
  187. package/src/http/list-total-cache.ts +14 -7
  188. package/src/http/memory.ts +38 -9
  189. package/src/http/pages-public.ts +93 -129
  190. package/src/http/pages.ts +94 -21
  191. package/src/http/script-runs.ts +174 -5
  192. package/src/http/status.ts +10 -2
  193. package/src/http/tasks.ts +4 -2
  194. package/src/pages/browser-sdk.ts +48 -21
  195. package/src/pages/color-literals.ts +115 -0
  196. package/src/pages/page-head.ts +766 -0
  197. package/src/pages/version.ts +3 -0
  198. package/src/providers/amp-adapter.ts +1 -1
  199. package/src/providers/codex-adapter.ts +1 -0
  200. package/src/providers/codex-app-server.ts +27 -1
  201. package/src/providers/fx-adapter.ts +1 -1
  202. package/src/providers/pi-mono-extension.ts +30 -15
  203. package/src/runtime-providers/controller-protocol.ts +14 -1
  204. package/src/runtime-providers/controller.ts +5 -0
  205. package/src/runtime-providers/docker.ts +108 -23
  206. package/src/runtime-providers/types.ts +16 -0
  207. package/src/script-workflows/workflow-ctx.ts +8 -0
  208. package/src/scripts-runtime/types/stdlib.d.ts +22 -0
  209. package/src/scripts-runtime/types/swarm-sdk.d.ts +22 -0
  210. package/src/server-user.ts +1 -0
  211. package/src/slack/commands.ts +5 -1
  212. package/src/slack/handlers.ts +37 -2
  213. package/src/slack/left-threads.ts +27 -4
  214. package/src/tasks/follow-up-gate.ts +318 -0
  215. package/src/tasks/follow-up-redelegation-guard.ts +155 -0
  216. package/src/tasks/worker-follow-up.ts +21 -1
  217. package/src/tests/claude-artifacts-read-script.test.ts +209 -0
  218. package/src/tests/codex-app-server.test.ts +59 -0
  219. package/src/tests/codex-gateway-route.test.ts +50 -1
  220. package/src/tests/create-page-tool.test.ts +501 -0
  221. package/src/tests/db-client-busy-retry.test.ts +81 -0
  222. package/src/tests/db-client.test.ts +21 -0
  223. package/src/tests/db-task-read-contract.test.ts +9 -2
  224. package/src/tests/db-task-write-contract.test.ts +7 -1
  225. package/src/tests/db-tasks-read.test.ts +21 -0
  226. package/src/tests/entrypoint-api-readiness.test.ts +416 -210
  227. package/src/tests/explicit-model-validation.test.ts +14 -8
  228. package/src/tests/fixtures/pages/head-v1.html +56 -0
  229. package/src/tests/follow-up-gate-shadow.test.ts +513 -0
  230. package/src/tests/follow-up-redelivery-guard.test.ts +432 -202
  231. package/src/tests/identity-field-budget.test.ts +1 -1
  232. package/src/tests/internal-ai/credentials.test.ts +62 -0
  233. package/src/tests/internal-ai/task-title.test.ts +283 -0
  234. package/src/tests/list-total-cache.test.ts +27 -2
  235. package/src/tests/memory-fts-populate.test.ts +11 -9
  236. package/src/tests/memory-retrieval-purge.test.ts +80 -0
  237. package/src/tests/merge-gate-detect-changes.test.ts +145 -0
  238. package/src/tests/migration-260-runtime-pool-cache.test.ts +118 -0
  239. package/src/tests/page-proxy.test.ts +1 -1
  240. package/src/tests/page-session-dev-cookie.test.ts +188 -0
  241. package/src/tests/pages-frame-ancestors.test.ts +28 -1
  242. package/src/tests/pages-head-v2.test.ts +534 -0
  243. package/src/tests/pages-http.test.ts +330 -0
  244. package/src/tests/pages-public-html.test.ts +43 -0
  245. package/src/tests/pages-storage.test.ts +182 -0
  246. package/src/tests/pages-versioning.test.ts +72 -0
  247. package/src/tests/profile-sync-stale-writeback.test.ts +334 -0
  248. package/src/tests/profile-sync.test.ts +11 -15
  249. package/src/tests/query-audit-plans.test.ts +27 -0
  250. package/src/tests/runtime-cache-cleanup.test.ts +367 -0
  251. package/src/tests/runtime-e2b-pools.test.ts +41 -0
  252. package/src/tests/runtime-pools-db.test.ts +98 -0
  253. package/src/tests/runtime-pools-http.test.ts +29 -0
  254. package/src/tests/runtime-providers-docker.test.ts +253 -0
  255. package/src/tests/runtime-remote-controller.test.ts +66 -2
  256. package/src/tests/runtime-supervisor.test.ts +66 -2
  257. package/src/tests/scheduled-task-required-params-migration.test.ts +3 -1
  258. package/src/tests/script-connections.test.ts +13 -0
  259. package/src/tests/script-runs-http.test.ts +684 -2
  260. package/src/tests/seed-registry.test.ts +28 -6
  261. package/src/tests/seed-schedules.test.ts +61 -8
  262. package/src/tests/seed-scripts.test.ts +168 -2
  263. package/src/tests/slack-leave-thread.test.ts +145 -5
  264. package/src/tests/slack-render-v2-query-plans.test.ts +24 -2
  265. package/src/tests/status.test.ts +11 -0
  266. package/src/tests/swarm-diff.test.ts +121 -2
  267. package/src/tests/task-auto-title-config-guard.test.ts +37 -0
  268. package/src/tests/task-auto-title-listener.test.ts +165 -0
  269. package/src/tests/tasks-readable-row.test.ts +155 -0
  270. package/src/tests/theme-import.test.ts +758 -0
  271. package/src/tests/themes-page-theme.test.ts +155 -0
  272. package/src/tests/themes-presets.test.ts +172 -0
  273. package/src/tests/workflow-script-principal.test.ts +2 -1
  274. package/src/themes/classics.ts +949 -0
  275. package/src/themes/import.ts +420 -0
  276. package/src/themes/page-fields.ts +40 -0
  277. package/src/themes/page-theme.ts +102 -0
  278. package/src/themes/presets.ts +561 -0
  279. package/src/themes/tokens.ts +218 -0
  280. package/src/tools/app-upsert.ts +1 -1
  281. package/src/tools/create-page.ts +118 -12
  282. package/src/tools/send-task.ts +35 -47
  283. package/src/tools/slack-leave-thread.ts +1 -1
  284. package/src/tools/task-dedup.ts +45 -21
  285. package/src/tools/utils.ts +33 -0
  286. package/src/types.ts +83 -3
  287. package/src/utils/constants.ts +19 -0
  288. package/src/utils/follow-up-gate-schedule-ids.ts +13 -0
  289. package/src/utils/internal-ai/credentials.ts +146 -93
  290. package/src/utils/internal-ai/index.ts +10 -0
  291. package/src/utils/internal-ai/models.ts +18 -0
  292. package/src/utils/internal-ai/task-title.ts +282 -0
  293. package/src/utils/page-session.ts +37 -0
  294. package/templates/schedules/daily-status-report/content.md +88 -2
  295. package/templates/schedules/daily-swarm-update-check/content.md +16 -40
  296. package/templates/skills/apps/SKILL.md +1 -1
  297. package/templates/skills/apps/content.md +1 -1
  298. package/templates/skills/composio-google-docs/content.md +10 -0
  299. package/templates/skills/heartbeat-runbook/content.md +1 -1
  300. package/templates/skills/pages/config.json +1 -1
  301. package/templates/skills/pages/content.md +539 -86
  302. package/templates/skills/pages/files/examples/annotated-pr.html +21 -12
  303. package/templates/skills/pages/files/examples/multiplayer-board.html +41 -41
  304. package/templates/skills/pages/files/examples/report-page.html +125 -124
  305. package/templates/skills/script-workflows/content.md +19 -1
  306. package/templates/skills/swarm-docs/content.md +1 -0
  307. package/templates/skills/swarm-scripts/SKILL.md +2 -0
  308. package/templates/skills/swarm-scripts/content.md +2 -0
  309. package/dist/cli-2pnswgh8.js +0 -189
  310. package/dist/cli-dznrgaep.js +0 -30
  311. package/dist/cli-w3hcrxht.js +0 -6985
  312. package/dist/handlers-vwmba1m2.js +0 -31
  313. package/dist/index-5r71rf98.js +0 -32
  314. package/dist/index-anmwxs87.js +0 -29
  315. package/dist/index-spp0ra5c.js +0 -36
  316. package/dist/lead-fjy418cw.js +0 -69
  317. package/dist/worker-0c5tyzqe.js +0 -69
  318. package/templates/schedules/daily-workflow-health-audit/config.json +0 -19
  319. package/templates/schedules/daily-workflow-health-audit/content.md +0 -191
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  bedrockProviderModule
3
- } from "./cli-ehq736cn.js";
3
+ } from "./cli-g7s47cc5.js";
4
4
  import {
5
5
  chatThreadOfContextKey,
6
6
  agentContextKey,
@@ -248,6 +248,7 @@ import {
248
248
  updateTaskClaudeSessionId2,
249
249
  recordTaskProviderIfUnset2,
250
250
  updateTaskTitle2,
251
+ setTaskTitleIfUnset2,
251
252
  completeTask2,
252
253
  failTask2,
253
254
  cancelTask2,
@@ -259,6 +260,7 @@ import {
259
260
  getPausedTasksForAgent2,
260
261
  resetOrphanedInProgressTasksForAgent2,
261
262
  updateTaskProgress2,
263
+ init_write,
262
264
  IdempotencyKeyTakenError,
263
265
  workflowRequestFingerprint,
264
266
  assertWorkflowIdempotencyKeyUnused,
@@ -269,6 +271,8 @@ import {
269
271
  retirePoolKeyStatus,
270
272
  init_api_keys,
271
273
  getScriptRunExecutionArgs2,
274
+ getScriptRunFollowUpGuard2,
275
+ setScriptRunFollowUpGuard2,
272
276
  updateTaskVcs2,
273
277
  upsertAssetKeyMapping2,
274
278
  listAssetSummaries2,
@@ -475,7 +479,7 @@ import {
475
479
  countScriptRunJournalSteps2,
476
480
  countScriptRunJournalAgentTaskSteps2,
477
481
  init_db4
478
- } from "./cli-1ayk1eas.js";
482
+ } from "./cli-wk5yrfwd.js";
479
483
  import {
480
484
  PRIMARY_ROLE_NAMES2,
481
485
  getUserGrant2,
@@ -486,8 +490,8 @@ import {
486
490
  assertNotLastAdmin2,
487
491
  setUserRoles2,
488
492
  init_rbac_roles
489
- } from "./cli-8hs41zy2.js";
490
- import"./cli-6s7vdcta.js";
493
+ } from "./cli-jtjtabxe.js";
494
+ import"./cli-qh4d4tvk.js";
491
495
  import {
492
496
  upsertModelCatalogOverlay,
493
497
  deleteModelCatalogOverlay,
@@ -495,13 +499,14 @@ import {
495
499
  init_model_catalog_store,
496
500
  requestModelCatalogRefresh2,
497
501
  init_pricing_refresh
498
- } from "./cli-nn4d8dne.js";
502
+ } from "./cli-5b456bpf.js";
499
503
  import {
500
504
  workflowEventBus2,
501
505
  init_event_bus
502
506
  } from "./cli-wx3rhnm0.js";
503
- import"./cli-mmwm7zbf.js";
507
+ import"./cli-rtt8g4v9.js";
504
508
  import {
509
+ require_dist4,
505
510
  getSlackConnectionState,
506
511
  init_connection_state,
507
512
  getSlackInboundDiagnostics,
@@ -530,12 +535,12 @@ import {
530
535
  startSlackApp2,
531
536
  stopSlackApp2,
532
537
  init_app3
533
- } from "./cli-wvaawacd.js";
538
+ } from "./cli-cppkf404.js";
534
539
  import {
535
540
  retryFailedRun2,
536
541
  cancelWorkflowRun2,
537
542
  init_resume
538
- } from "./cli-g61qxmge.js";
543
+ } from "./cli-afkqkrtw.js";
539
544
  import {
540
545
  DEFAULT_NEGOTIATED_PROTOCOL_VERSION,
541
546
  SUPPORTED_PROTOCOL_VERSIONS,
@@ -623,6 +628,9 @@ import {
623
628
  hasKvViewArgs,
624
629
  resolveKvView,
625
630
  init_kv_view,
631
+ COLOR_LITERAL_THRESHOLD,
632
+ countColorLiterals,
633
+ init_color_literals,
626
634
  toolErr,
627
635
  createToolRegistrar,
628
636
  init_utils,
@@ -767,6 +775,7 @@ import {
767
775
  extractPageSession,
768
776
  extractLegacyPageSession,
769
777
  extractAndVerifyCookie,
778
+ isLocalDevPageRequest,
770
779
  pageSessionSetCookies,
771
780
  init_page_session,
772
781
  resolveHttpRequestAuth,
@@ -814,6 +823,12 @@ import {
814
823
  init_page_versions,
815
824
  snapshotPage,
816
825
  init_version3,
826
+ DEFAULT_THEME_ID,
827
+ THEME_PRESET_IDS,
828
+ getThemePreset,
829
+ init_presets,
830
+ readThemeFields,
831
+ init_page_fields,
817
832
  assertOAuthAppUrlsSafe,
818
833
  assertOAuthEgressUrlSafe,
819
834
  init_app_validation,
@@ -821,7 +836,7 @@ import {
821
836
  listOAuthPresetIds,
822
837
  getOAuthPreset,
823
838
  hydrateOAuthAppFromPreset,
824
- init_presets,
839
+ init_presets2,
825
840
  scopedResourceScopeIdSchema,
826
841
  resolveScopedResourceId,
827
842
  init_scoped_resource,
@@ -914,6 +929,9 @@ import {
914
929
  mergeScheduleTiming,
915
930
  validateRecurringTiming,
916
931
  init_validate,
932
+ followUpThreadForSourceTask,
933
+ evaluateFollowUpRedelegation,
934
+ init_follow_up_redelegation_guard,
917
935
  checkOutputSchemaShape,
918
936
  sendTaskOutputSchema,
919
937
  sendTaskHandler,
@@ -941,7 +959,7 @@ import {
941
959
  getEnabledCapabilities,
942
960
  createServer,
943
961
  init_server
944
- } from "./cli-1338796d.js";
962
+ } from "./cli-ws19768n.js";
945
963
  import {
946
964
  FilesError,
947
965
  normalizeFilesError,
@@ -973,7 +991,7 @@ import {
973
991
  resolvePoolDelivery2,
974
992
  createPoolAgent2,
975
993
  init_db2
976
- } from "./cli-mry0qzym.js";
994
+ } from "./cli-ddaanqkd.js";
977
995
  import {
978
996
  duplicateGuardedQueryKey,
979
997
  warnIfCorsAllowsAnyOrigin,
@@ -1027,7 +1045,7 @@ import {
1027
1045
  describeRequestRoute,
1028
1046
  route,
1029
1047
  init_route_def
1030
- } from "./cli-z8eh3ex8.js";
1048
+ } from "./cli-8sckt74b.js";
1031
1049
  import {
1032
1050
  startPoolRouting,
1033
1051
  stopPoolRouting,
@@ -1040,13 +1058,17 @@ import {
1040
1058
  checkHeartbeatChecklist2,
1041
1059
  runHeartbeatSweep2,
1042
1060
  stopHeartbeat2
1043
- } from "./cli-z6jkx23q.js";
1044
- import"./cli-rpm2sgv0.js";
1061
+ } from "./cli-bfv7vdg6.js";
1062
+ import"./cli-3fg0bdcv.js";
1045
1063
  import {
1046
1064
  runtimeSupervisorStatus,
1047
1065
  startRuntimeSupervisor,
1048
1066
  stopRuntimeSupervisor
1049
- } from "./cli-rqkxrmgw.js";
1067
+ } from "./cli-je518txm.js";
1068
+ import {
1069
+ TASK_TITLE_TIMEOUT_MS,
1070
+ generateTaskTitle
1071
+ } from "./cli-vz22fyqv.js";
1050
1072
  import"./cli-ns59dc6r.js";
1051
1073
  import {
1052
1074
  ACP_TARGET_IDS
@@ -1067,11 +1089,11 @@ import {
1067
1089
  isUnknownModelError,
1068
1090
  checkProviderPoolKey,
1069
1091
  writeSkillsToFilesystem
1070
- } from "./cli-rhw40jgb.js";
1092
+ } from "./cli-yyj3j5m4.js";
1071
1093
  import {
1072
1094
  inviteEmailToSharedOrg,
1073
1095
  ensureAgentFsCredentialsForAgent
1074
- } from "./cli-vbyfwh92.js";
1096
+ } from "./cli-pjctyea3.js";
1075
1097
  import {
1076
1098
  Anthropic
1077
1099
  } from "./cli-318r69gq.js";
@@ -1087,7 +1109,7 @@ import {
1087
1109
  ampBillsCacheWrites,
1088
1110
  resolveAmpModel,
1089
1111
  init_amp_models
1090
- } from "./cli-mjzynrse.js";
1112
+ } from "./cli-35rsp8ye.js";
1091
1113
  import {
1092
1114
  RATING_MODEL_MAX_LENGTH,
1093
1115
  REFERENCES_SOURCE_MAX_LENGTH,
@@ -1097,7 +1119,7 @@ import {
1097
1119
  import {
1098
1120
  normalizeModelKey,
1099
1121
  init_pricing_normalize
1100
- } from "./cli-xtjhfmpc.js";
1122
+ } from "./cli-pc6n7fre.js";
1101
1123
  import {
1102
1124
  require_dist2,
1103
1125
  getMcpOAuthToken,
@@ -1186,7 +1208,7 @@ import {
1186
1208
  init_typecheck,
1187
1209
  parseSkillContent,
1188
1210
  init_skill_parser
1189
- } from "./cli-0bxqnvq9.js";
1211
+ } from "./cli-adeegh7d.js";
1190
1212
  import {
1191
1213
  signalProcessGroup,
1192
1214
  detachedProcessGroup,
@@ -1203,7 +1225,7 @@ import {
1203
1225
  forceRefreshAuthorizationOrThrow,
1204
1226
  forceRefreshTokenOrThrow,
1205
1227
  init_ensure_token
1206
- } from "./cli-7wcyk2s5.js";
1228
+ } from "./cli-q3tkegby.js";
1207
1229
  import {
1208
1230
  automationIntegrationFixUrl,
1209
1231
  preflightAutomation,
@@ -1247,7 +1269,7 @@ import {
1247
1269
  definitionNodeIds,
1248
1270
  validateDefinition,
1249
1271
  init_definition2
1250
- } from "./cli-spknvxbq.js";
1272
+ } from "./cli-nmzhp1b5.js";
1251
1273
  import {
1252
1274
  _fetchHolder,
1253
1275
  CLIENT_ID,
@@ -1270,10 +1292,8 @@ import {
1270
1292
  } from "./cli-mdb054w3.js";
1271
1293
  import {
1272
1294
  require_content_type
1273
- } from "./cli-gf5hbmdr.js";
1274
- import {
1275
- require_dist9
1276
- } from "./cli-w3hcrxht.js";
1295
+ } from "./cli-yjdgea32.js";
1296
+ import"./cli-g08zdaec.js";
1277
1297
  import {
1278
1298
  isInvalidClientError,
1279
1299
  publicEndpointSsrfOptions,
@@ -1291,11 +1311,11 @@ import {
1291
1311
  revokeMcpToken,
1292
1312
  computeExpiresAt,
1293
1313
  init_mcp_wrapper
1294
- } from "./cli-pywf3eh5.js";
1314
+ } from "./cli-caj33vcq.js";
1295
1315
  import {
1296
1316
  createRuntimeProvider,
1297
1317
  init_runtime_providers
1298
- } from "./cli-xbkdm710.js";
1318
+ } from "./cli-yndmfxb3.js";
1299
1319
  import {
1300
1320
  registerSessionTokenConnection,
1301
1321
  init_session_token_connections,
@@ -1322,17 +1342,17 @@ import {
1322
1342
  revokeAgentTokens,
1323
1343
  fingerprintApiKey,
1324
1344
  init_users
1325
- } from "./cli-bhjt02p8.js";
1345
+ } from "./cli-5jnhv72d.js";
1326
1346
  import"./cli-v41kn3cd.js";
1327
1347
  import {
1328
1348
  setBedrockProviderModule,
1329
1349
  init_bedrock_converse_stream_lazy
1330
- } from "./cli-aa6yxc7m.js";
1350
+ } from "./cli-pz4rk021.js";
1331
1351
  import {
1332
1352
  import_websocket,
1333
1353
  import_websocket_server,
1334
1354
  init_wrapper2
1335
- } from "./cli-dznrgaep.js";
1355
+ } from "./cli-69szn7w7.js";
1336
1356
  import {
1337
1357
  isRbacEnabled,
1338
1358
  decideToolAdmission,
@@ -1350,6 +1370,10 @@ import {
1350
1370
  init_key,
1351
1371
  isSafeBundlePath,
1352
1372
  init_bundle_path,
1373
+ PAGE_THEME_SHARED_TOKENS,
1374
+ PAGE_THEME_TOKENS,
1375
+ HIVE_PAGE_TOKENS,
1376
+ init_tokens2,
1353
1377
  init_zod_openapi,
1354
1378
  AssetKeySchema,
1355
1379
  AssetEntityTypeSchema,
@@ -1440,6 +1464,7 @@ import {
1440
1464
  WorkflowVersionSchema,
1441
1465
  PageContentTypeSchema,
1442
1466
  PageAuthModeSchema,
1467
+ PageThemeTokensInputSchema,
1443
1468
  PageSchema,
1444
1469
  PageVersionSchema,
1445
1470
  MetricWidgetSchema,
@@ -1494,7 +1519,7 @@ import {
1494
1519
  KvKeySchema,
1495
1520
  KvEntrySchema,
1496
1521
  init_types4
1497
- } from "./cli-7wspm5gm.js";
1522
+ } from "./cli-n6bv12jn.js";
1498
1523
  import {
1499
1524
  CODEX_AUTH_FAILURE_BENCH_THRESHOLD,
1500
1525
  CODEX_AUTH_WATCH_NAMESPACE,
@@ -1505,7 +1530,7 @@ import {
1505
1530
  IDENTITY_FIELD_BUDGETS,
1506
1531
  IdentityFieldBudgetError,
1507
1532
  init_identity_field_budget
1508
- } from "./cli-a7v854rf.js";
1533
+ } from "./cli-tgrv9cjx.js";
1509
1534
  import {
1510
1535
  getSlackConfiguration,
1511
1536
  init_config4
@@ -1571,14 +1596,10 @@ import {
1571
1596
  ZodIssueCode,
1572
1597
  exports_coerce
1573
1598
  } from "./cli-agfm16v9.js";
1574
- import {
1575
- getNodeEnv,
1576
- init_node_env
1577
- } from "./cli-rgeadyvq.js";
1578
1599
  import {
1579
1600
  init_package,
1580
1601
  package_default
1581
- } from "./cli-tqgg40ek.js";
1602
+ } from "./cli-6pfd54vx.js";
1582
1603
  import {
1583
1604
  realtimeBus,
1584
1605
  init_bus
@@ -1588,13 +1609,14 @@ import {
1588
1609
  DEFAULT_APP_URL,
1589
1610
  getConfiguredAppUrls,
1590
1611
  getAppUrl,
1612
+ getLocalDevAppOrigins,
1591
1613
  getMcpBaseUrl,
1592
1614
  getPublicMcpBaseUrl,
1593
1615
  agentFsFileRoute,
1594
1616
  isCombEnabled,
1595
1617
  isAgentFsProxyEnabled,
1596
1618
  init_constants3
1597
- } from "./cli-611a1294.js";
1619
+ } from "./cli-k0wwfqbg.js";
1598
1620
  import {
1599
1621
  parseEnvFlag,
1600
1622
  isEnvFlagEnabled,
@@ -2528,6 +2550,88 @@ async function seedLegacyCapabilitiesConfig() {
2528
2550
  return { seeded: true, added: [...added] };
2529
2551
  }
2530
2552
 
2553
+ // src/be/task-auto-title-listener.ts
2554
+ init_api_key();
2555
+ init_constants3();
2556
+ init_env_flag();
2557
+ init_secret_scrubber();
2558
+ init_event_bus();
2559
+ init_read();
2560
+ init_write();
2561
+ var TASK_AUTO_TITLE_CONCURRENCY = 3;
2562
+ function isTaskAutoTitleEnabled(env = process.env) {
2563
+ return parseEnvFlag(env.TASK_AUTO_TITLE_ENABLED, true);
2564
+ }
2565
+ function startTaskAutoTitleListener(options = {}) {
2566
+ const env = options.env ?? process.env;
2567
+ const generate = options.generate ?? generateTaskTitle;
2568
+ const queue = [];
2569
+ let active = 0;
2570
+ let idleWaiters = [];
2571
+ const settleIdle = () => {
2572
+ if (active > 0 || queue.length > 0)
2573
+ return;
2574
+ const waiters = idleWaiters;
2575
+ idleWaiters = [];
2576
+ for (const resolve of waiters)
2577
+ resolve();
2578
+ };
2579
+ const pump = () => {
2580
+ while (active < TASK_AUTO_TITLE_CONCURRENCY) {
2581
+ const taskId = queue.shift();
2582
+ if (!taskId)
2583
+ break;
2584
+ active++;
2585
+ titleTask(taskId, env, generate).catch((error) => console.error("[task-title] Failed:", scrubSecrets(String(error)))).finally(() => {
2586
+ active--;
2587
+ pump();
2588
+ settleIdle();
2589
+ });
2590
+ }
2591
+ };
2592
+ const onTaskCreated = (data) => {
2593
+ if (!isTaskAutoTitleEnabled(env))
2594
+ return;
2595
+ const taskId = data.taskId;
2596
+ if (typeof taskId !== "string" || !taskId)
2597
+ return;
2598
+ queue.push(taskId);
2599
+ pump();
2600
+ };
2601
+ workflowEventBus2.on("task.created", onTaskCreated);
2602
+ return {
2603
+ stop: () => workflowEventBus2.off("task.created", onTaskCreated),
2604
+ idle: () => new Promise((resolve) => {
2605
+ idleWaiters.push(resolve);
2606
+ settleIdle();
2607
+ })
2608
+ };
2609
+ }
2610
+ async function titleTask(taskId, env, generate) {
2611
+ const task = await getTaskById2(taskId);
2612
+ if (!task || task.title)
2613
+ return;
2614
+ const shortId = taskId.slice(0, 8);
2615
+ const startedAt = Date.now();
2616
+ const result = await generate({
2617
+ task: task.task,
2618
+ env,
2619
+ apiUrl: getMcpBaseUrl(),
2620
+ apiKey: getApiKey(),
2621
+ callerTag: `task-title:${task.source}`,
2622
+ signal: AbortSignal.timeout(TASK_TITLE_TIMEOUT_MS)
2623
+ });
2624
+ if (!result.ok) {
2625
+ if (result.reason !== "short-task") {
2626
+ console.log(`[task-title] ${shortId}: no title (${result.reason})`);
2627
+ }
2628
+ return;
2629
+ }
2630
+ const updated = await setTaskTitleIfUnset2(taskId, result.title);
2631
+ const elapsed = Date.now() - startedAt;
2632
+ console.log(scrubSecrets(`[task-title] ${shortId}: "${result.title}" via ${result.model} in ${elapsed}ms${updated ? "" : " (kept the existing title)"}`));
2633
+ }
2634
+
2531
2635
  // src/http/index.ts
2532
2636
  init_telemetry_enable();
2533
2637
 
@@ -15880,7 +15984,7 @@ async function registerTelegramWebhook() {
15880
15984
 
15881
15985
  // src/slack/app-icon.ts
15882
15986
  init_app3();
15883
- var import_web_api = __toESM(require_dist9(), 1);
15987
+ var import_web_api = __toESM(require_dist4(), 1);
15884
15988
  var TTL_MS = 60 * 60 * 1000;
15885
15989
  var REQUEST_TIMEOUT_MS = 2500;
15886
15990
  var cached = null;
@@ -19766,6 +19870,7 @@ function createUserServer(user) {
19766
19870
  offerMode: false,
19767
19871
  leadOnly: false,
19768
19872
  allowDuplicate: false,
19873
+ allowRedelegation: false,
19769
19874
  overrideSlackContext: false
19770
19875
  });
19771
19876
  });
@@ -21375,11 +21480,20 @@ async function handleMemory(req, res, pathSegments, callerAgentId) {
21375
21480
  var MEMORY_GC_INTERVAL_MS = 60 * 60 * 1000;
21376
21481
  var memoryGcTimer = null;
21377
21482
  var SEARCH_RETRIEVAL_TTL_DAYS = 90;
21378
- async function purgeStaleSearchRetrievals() {
21483
+ var SEARCH_RETRIEVAL_PURGE_BATCH = 2000;
21484
+ async function purgeStaleSearchRetrievals(batchSize = SEARCH_RETRIEVAL_PURGE_BATCH) {
21379
21485
  try {
21380
21486
  const cutoff = new Date(Date.now() - SEARCH_RETRIEVAL_TTL_DAYS * 24 * 60 * 60 * 1000).toISOString();
21381
- const result = await getDbClient2().run("DELETE FROM memory_retrieval WHERE eventType = 'search' AND retrievedAt < ?", [cutoff]);
21382
- return result.changes;
21487
+ let purged = 0;
21488
+ for (;; ) {
21489
+ const result = await getDbClient2().run(`DELETE FROM memory_retrieval WHERE rowid IN (
21490
+ SELECT rowid FROM memory_retrieval
21491
+ WHERE +eventType = 'search' AND retrievedAt < ? LIMIT ?)`, [cutoff, batchSize]);
21492
+ purged += result.changes;
21493
+ if (result.changes < batchSize)
21494
+ return purged;
21495
+ await new Promise((resolve) => setImmediate(resolve));
21496
+ }
21383
21497
  } catch (err) {
21384
21498
  console.error("[memory-gc] Search retrieval purge failed:", err.message);
21385
21499
  return 0;
@@ -21399,10 +21513,17 @@ async function runMemoryGcTick(label) {
21399
21513
  console.error(`[memory-gc] ${label} purge failed:`, err);
21400
21514
  }
21401
21515
  }
21402
- async function startMemoryGc(intervalMs = MEMORY_GC_INTERVAL_MS) {
21516
+ var MEMORY_GC_INITIAL_DELAY_MS = 2 * 60 * 1000;
21517
+ var memoryGcInitialTimer = null;
21518
+ async function startMemoryGc(intervalMs = MEMORY_GC_INTERVAL_MS, initialDelayMs = MEMORY_GC_INITIAL_DELAY_MS) {
21403
21519
  if (memoryGcTimer)
21404
21520
  return;
21405
- await runMemoryGcTick("Initial");
21521
+ memoryGcInitialTimer = setTimeout(() => {
21522
+ memoryGcInitialTimer = null;
21523
+ runMemoryGcTick("Initial");
21524
+ }, initialDelayMs);
21525
+ if (typeof memoryGcInitialTimer?.unref === "function")
21526
+ memoryGcInitialTimer.unref();
21406
21527
  memoryGcTimer = setInterval(() => {
21407
21528
  runMemoryGcTick("Periodic");
21408
21529
  }, intervalMs);
@@ -21410,6 +21531,10 @@ async function startMemoryGc(intervalMs = MEMORY_GC_INTERVAL_MS) {
21410
21531
  memoryGcTimer.unref();
21411
21532
  }
21412
21533
  function stopMemoryGc() {
21534
+ if (memoryGcInitialTimer) {
21535
+ clearTimeout(memoryGcInitialTimer);
21536
+ memoryGcInitialTimer = null;
21537
+ }
21413
21538
  if (memoryGcTimer) {
21414
21539
  clearInterval(memoryGcTimer);
21415
21540
  memoryGcTimer = null;
@@ -23056,7 +23181,8 @@ var StatusIdentitySchema = object2({
23056
23181
  is_cloud: boolean(),
23057
23182
  marketing_url: string2().nullable(),
23058
23183
  hide_cloud_promo: boolean(),
23059
- org_id: string2().nullable()
23184
+ org_id: string2().nullable(),
23185
+ dashboard_url: string2().nullable().optional()
23060
23186
  });
23061
23187
  var StatusActivitySchema = object2({
23062
23188
  agents_online: number2().int().nonnegative(),
@@ -23162,7 +23288,7 @@ async function rollupCredStatusForProvider(provider) {
23162
23288
  oldestReportAgeMs
23163
23289
  };
23164
23290
  }
23165
- function buildIdentity() {
23291
+ function buildIdentity(dashboardUrl) {
23166
23292
  const cloudRaw = process.env.SWARM_CLOUD;
23167
23293
  const hideRaw = process.env.SWARM_HIDE_CLOUD_PROMO;
23168
23294
  return {
@@ -23172,7 +23298,8 @@ function buildIdentity() {
23172
23298
  is_cloud: cloudRaw === "true" || cloudRaw === "1",
23173
23299
  marketing_url: process.env.SWARM_MARKETING_URL?.trim() || null,
23174
23300
  hide_cloud_promo: hideRaw === "true" || hideRaw === "1",
23175
- org_id: process.env.SWARM_ORG_ID?.trim() || null
23301
+ org_id: process.env.SWARM_ORG_ID?.trim() || null,
23302
+ dashboard_url: dashboardUrl
23176
23303
  };
23177
23304
  }
23178
23305
  function describeRoll(roll) {
@@ -23474,7 +23601,7 @@ async function buildStatusPayload() {
23474
23601
  const instance = await getInstanceFeedbackSignals();
23475
23602
  return {
23476
23603
  runtime_pools: { enabled: isRuntimePoolsEnabled(), supervisor: runtimeSupervisorStatus() },
23477
- identity: buildIdentity(),
23604
+ identity: buildIdentity(await resolveAppUrl()),
23478
23605
  setup,
23479
23606
  activity: { ...activity, leads_ready: readyLeads },
23480
23607
  agent_fs: {
@@ -24139,9 +24266,10 @@ init_version3();
24139
24266
  init_resolver();
24140
24267
  init_session_templates();
24141
24268
  init_sibling_awareness();
24269
+ init_page_fields();
24270
+ init_presets();
24142
24271
  init_types4();
24143
24272
  init_constants3();
24144
- init_node_env();
24145
24273
  init_page_session();
24146
24274
  init_request_auth_context();
24147
24275
  init_favorite_owner();
@@ -24177,19 +24305,20 @@ var MAX_ENTRIES2 = 500;
24177
24305
  function filterKey(value) {
24178
24306
  return JSON.stringify(value, (_key, v) => v && typeof v === "object" && !Array.isArray(v) ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => a.localeCompare(b))) : v);
24179
24307
  }
24180
- function createListTotalCache(ttlMs = LIST_TOTAL_TTL_MS) {
24308
+ function createListTotalCache(ttlMs = LIST_TOTAL_TTL_MS, firstPageTtlMs = 0) {
24181
24309
  const entries = new Map;
24182
24310
  return {
24183
24311
  get(filters, offset, compute) {
24184
24312
  const key = filterKey(filters);
24185
24313
  const now = Date.now();
24186
24314
  const hit = entries.get(key);
24187
- if (hit && hit.expiresAt > now && (offset ?? 0) > 0)
24315
+ const maxAge = (offset ?? 0) > 0 ? ttlMs : Math.min(ttlMs, firstPageTtlMs);
24316
+ if (hit && hit.countedAt + maxAge > now)
24188
24317
  return hit.total;
24189
24318
  if (hit)
24190
24319
  entries.delete(key);
24191
24320
  const total = compute();
24192
- entries.set(key, { expiresAt: now + ttlMs, total });
24321
+ entries.set(key, { countedAt: now, total });
24193
24322
  total.catch(() => {
24194
24323
  if (entries.get(key)?.total === total)
24195
24324
  entries.delete(key);
@@ -24335,7 +24464,7 @@ var SupersedeTaskResponseSchema = object2({
24335
24464
  resumeTaskId: string2().nullable(),
24336
24465
  resumeTaskStatus: AgentTaskStatusSchema.optional()
24337
24466
  });
24338
- var taskTotals = createListTotalCache();
24467
+ var taskTotals = createListTotalCache(LIST_TOTAL_TTL_MS, 15000);
24339
24468
  var listTasks = route({
24340
24469
  method: "get",
24341
24470
  path: "/api/tasks",
@@ -25859,11 +25988,22 @@ var PageWithShareUrlsSchema = PageSchema.extend({
25859
25988
  api_url: string2(),
25860
25989
  app_url: string2()
25861
25990
  });
25862
- var PageListItemSchema = PageSchema.partial({ body: true, passwordHash: true }).extend({
25991
+ var PageListItemSchema = PageSchema.partial({
25992
+ body: true,
25993
+ passwordHash: true,
25994
+ theme: true,
25995
+ themeTokens: true,
25996
+ designVersion: true
25997
+ }).extend({
25863
25998
  favorite: boolean(),
25864
25999
  api_url: string2(),
25865
26000
  app_url: string2()
25866
26001
  });
26002
+ var pageDesignBodyFields = {
26003
+ theme: string2().nullable().optional().describe(`Theme preset id that restyles the whole page. One of: ${THEME_PRESET_IDS.join(", ")}. Omit to follow the viewer's theme. Pass null on update to clear it.`),
26004
+ themeTokens: PageThemeTokensInputSchema.nullable().optional().describe('Per-page token overrides, applied on top of the preset. Send { light, dark } maps of token name to CSS value, or { format: "css", css } with a CSS variable block (:root, .dark, @theme). Stored normalized. Names outside the token contract, and values that reference a variable outside it, are ignored and listed in ignoredTokens. Replaces the stored overrides. Pass null on update to clear them.'),
26005
+ designVersion: number2().int().min(1).max(2).optional().describe("Design system version. 2 is the swarm design system and the default for new pages. 1 is the original look that older pages keep. Omit on update to keep the stored value.")
26006
+ };
25867
26007
  var createPageRoute = route({
25868
26008
  method: "post",
25869
26009
  path: "/api/pages",
@@ -25879,7 +26019,8 @@ var createPageRoute = route({
25879
26019
  authMode: PageAuthModeSchema.default("authed"),
25880
26020
  password: string2().min(1).optional(),
25881
26021
  body: string2(),
25882
- needsCredentials: array2(string2()).optional()
26022
+ needsCredentials: array2(string2()).optional(),
26023
+ ...pageDesignBodyFields
25883
26024
  }),
25884
26025
  responses: {
25885
26026
  201: {
@@ -25889,10 +26030,12 @@ var createPageRoute = route({
25889
26030
  key: AssetKeySchema,
25890
26031
  version: literal2(1),
25891
26032
  api_url: string2(),
25892
- app_url: string2()
26033
+ app_url: string2(),
26034
+ ignoredTokens: array2(string2()).optional().describe("Theme tokens the importer ignored. A bare name is outside the token contract. Other entries give the reason, for example --font-sans (references --font-geist-sans) or --ring (in .card). Absent when none were ignored."),
26035
+ designVersion: number2().int().min(1).describe("The design version of the new page: 2 unless the body set designVersion: 1.")
25893
26036
  })
25894
26037
  },
25895
- 400: { description: "Invalid body" },
26038
+ 400: { description: "Invalid body, unknown theme, or invalid themeTokens" },
25896
26039
  409: { description: "Slug already exists for this agent" }
25897
26040
  }
25898
26041
  });
@@ -25951,13 +26094,21 @@ var updatePageRoute = route({
25951
26094
  authMode: PageAuthModeSchema.optional(),
25952
26095
  password: string2().min(1).nullable().optional(),
25953
26096
  body: string2().optional(),
25954
- needsCredentials: array2(string2()).nullable().optional()
26097
+ needsCredentials: array2(string2()).nullable().optional(),
26098
+ ...pageDesignBodyFields
25955
26099
  }),
25956
26100
  responses: {
25957
26101
  200: {
25958
26102
  description: "Page updated",
25959
- schema: object2({ id: string2(), key: AssetKeySchema, version: number2().int().min(1) })
26103
+ schema: object2({
26104
+ id: string2(),
26105
+ key: AssetKeySchema,
26106
+ version: number2().int().min(1),
26107
+ ignoredTokens: array2(string2()).optional().describe("Theme tokens the importer ignored. A bare name is outside the token contract. Other entries give the reason, for example --font-sans (references --font-geist-sans) or --ring (in .card). Absent when none were ignored."),
26108
+ designVersion: number2().int().min(1).describe("The design version the page has after the update. An omitted designVersion keeps the stored one, so an older page stays on 1.")
26109
+ })
25960
26110
  },
26111
+ 400: { description: "Unknown theme or invalid themeTokens" },
25961
26112
  404: { description: "Page not found" },
25962
26113
  413: { description: "Payload too large" }
25963
26114
  }
@@ -26168,12 +26319,6 @@ function formatFeedbackComments(comments) {
26168
26319
 
26169
26320
  `);
26170
26321
  }
26171
- function isDevRequest(req) {
26172
- if (getNodeEnv() === "production")
26173
- return false;
26174
- const origin = req.headers.origin ?? "";
26175
- return origin === "" || origin.startsWith("http://localhost") || origin.startsWith("http://127.0.0.1");
26176
- }
26177
26322
  async function handlePages(req, res, pathSegments, queryParams, myAgentId) {
26178
26323
  if (createPageRoute.match(req.method, pathSegments)) {
26179
26324
  if (enforceContentLengthCap(req, res, MAX_PAGE_BODY_BYTES) === BODY_TOO_LARGE)
@@ -26185,6 +26330,11 @@ async function handlePages(req, res, pathSegments, queryParams, myAgentId) {
26185
26330
  jsonError(res, "X-Agent-ID header required", 400);
26186
26331
  return true;
26187
26332
  }
26333
+ const themeFields = readThemeFields(parsed.body);
26334
+ if ("error" in themeFields) {
26335
+ jsonError(res, themeFields.error, 400);
26336
+ return true;
26337
+ }
26188
26338
  const slug = parsed.body.slug ?? slugify2(parsed.body.title);
26189
26339
  let passwordHash;
26190
26340
  if (parsed.body.password) {
@@ -26202,14 +26352,19 @@ async function handlePages(req, res, pathSegments, queryParams, myAgentId) {
26202
26352
  authMode: parsed.body.authMode,
26203
26353
  passwordHash,
26204
26354
  body: parsed.body.body,
26205
- needsCredentials: parsed.body.needsCredentials
26355
+ needsCredentials: parsed.body.needsCredentials,
26356
+ theme: themeFields.theme,
26357
+ themeTokens: themeFields.themeTokens,
26358
+ designVersion: parsed.body.designVersion
26206
26359
  });
26207
26360
  createPageRoute.respond(res, 201, {
26208
26361
  id: page.id,
26209
26362
  key: page.key,
26210
26363
  version: 1,
26211
26364
  api_url: `${getApiBaseUrl()}/p/${page.id}`,
26212
- app_url: `${getAppBaseUrl()}/pages/${page.slug}`
26365
+ app_url: `${getAppBaseUrl()}/pages/${page.slug}`,
26366
+ ...themeFields.ignored.length > 0 ? { ignoredTokens: themeFields.ignored } : {},
26367
+ designVersion: page.designVersion
26213
26368
  });
26214
26369
  } catch (err) {
26215
26370
  if (err instanceof AssetKeyAuthorizationError) {
@@ -26373,6 +26528,11 @@ async function handlePages(req, res, pathSegments, queryParams, myAgentId) {
26373
26528
  jsonError(res, "Page belongs to another agent", 403);
26374
26529
  return true;
26375
26530
  }
26531
+ const themeFields = readThemeFields(parsed.body);
26532
+ if ("error" in themeFields) {
26533
+ jsonError(res, themeFields.error, 400);
26534
+ return true;
26535
+ }
26376
26536
  let passwordHashUpdate;
26377
26537
  if (parsed.body.password === null) {
26378
26538
  passwordHashUpdate = null;
@@ -26402,7 +26562,10 @@ async function handlePages(req, res, pathSegments, queryParams, myAgentId) {
26402
26562
  authMode: parsed.body.authMode,
26403
26563
  passwordHash: passwordHashUpdate,
26404
26564
  body: parsed.body.body,
26405
- needsCredentials: parsed.body.needsCredentials ?? undefined
26565
+ needsCredentials: parsed.body.needsCredentials ?? undefined,
26566
+ theme: themeFields.theme,
26567
+ themeTokens: themeFields.themeTokens,
26568
+ designVersion: parsed.body.designVersion
26406
26569
  });
26407
26570
  if (!updated) {
26408
26571
  res.writeHead(404);
@@ -26412,7 +26575,9 @@ async function handlePages(req, res, pathSegments, queryParams, myAgentId) {
26412
26575
  updatePageRoute.respond(res, 200, {
26413
26576
  id: updated.id,
26414
26577
  key: updated.key,
26415
- version: await getPageEditCounter(updated.id)
26578
+ version: await getPageEditCounter(updated.id),
26579
+ ...themeFields.ignored.length > 0 ? { ignoredTokens: themeFields.ignored } : {},
26580
+ designVersion: updated.designVersion
26416
26581
  });
26417
26582
  return true;
26418
26583
  }
@@ -26521,7 +26686,7 @@ ${defuseFeedbackTags(note)}
26521
26686
  const user = authUser(auth);
26522
26687
  const identity = user ? { uid: user.id, name: user.name } : isOperatorAuth(auth) ? { name: `guest-${randomUUID4().slice(0, 8)}`, op: true } : undefined;
26523
26688
  const cookies = await pageSessionSetCookies(req, page.id, {
26524
- dev: isDevRequest(req),
26689
+ dev: isLocalDevPageRequest(req),
26525
26690
  ...identity
26526
26691
  });
26527
26692
  applyLaunchCors(req, res);
@@ -26869,11 +27034,23 @@ var SWARM_UI_JS = `
26869
27034
  closeCursorRoomIfUnused(record);
26870
27035
  }
26871
27036
 
27037
+ // Colors and fonts read the page theme tokens (designVersion 2). Each
27038
+ // fallback is the original literal, so a designVersion 1 page, which has no
27039
+ // tokens, renders exactly as before.
26872
27040
  var SEV_COLOR = {
26873
- error: '#ef4444',
26874
- warn: '#f59e0b',
26875
- info: '#3b82f6',
27041
+ error: 'var(--color-status-error-strong, #ef4444)',
27042
+ warn: 'var(--color-status-warning-strong, #f59e0b)',
27043
+ info: 'var(--color-status-info-strong, #3b82f6)',
26876
27044
  };
27045
+ var MUTED = 'var(--color-muted-foreground, #7c8aa6)';
27046
+ var MONO = "var(--font-mono, 'Space Mono', ui-monospace, monospace)";
27047
+
27048
+ // A color at a lower alpha. Mixing with transparent keeps the color and
27049
+ // scales its alpha, so tint('#ef4444', '13.33%') equals #ef444422 and
27050
+ // tint('rgb(34,197,94)', '10%') equals rgba(34,197,94,0.10).
27051
+ function tint(color, percent) {
27052
+ return 'color-mix(in srgb, ' + color + ' ' + percent + ', transparent)';
27053
+ }
26877
27054
 
26878
27055
  function esc(s) {
26879
27056
  return String(s == null ? '' : s)
@@ -26908,7 +27085,7 @@ var SWARM_UI_JS = `
26908
27085
  '<span class="swarm-diff-annot no-print" '
26909
27086
  + 'style="display:inline-block;margin-left:8px;padding:1px 6px;'
26910
27087
  + 'border-radius:4px;font-size:11px;font-weight:600;'
26911
- + 'background:' + color + '22;color:' + color + ';border:1px solid ' + color + '55;">'
27088
+ + 'background:' + tint(color, '13.33%') + ';color:' + color + ';border:1px solid ' + tint(color, '33.33%') + ';">'
26912
27089
  + esc((ann && ann.severity ? ann.severity.toUpperCase() : 'INFO')) + ' · ' + esc(ann && ann.text || '')
26913
27090
  + '</span>'
26914
27091
  );
@@ -26940,12 +27117,12 @@ var SWARM_UI_JS = `
26940
27117
  var text = line.text == null ? '' : line.text;
26941
27118
  var bg, oldCell, newCell, sign;
26942
27119
  if (type === 'add') {
26943
- bg = 'rgba(34,197,94,0.10)';
27120
+ bg = tint('var(--color-status-success, rgb(34,197,94))', '10%');
26944
27121
  oldCell = '';
26945
27122
  newCell = String(newN++);
26946
27123
  sign = '+';
26947
27124
  } else if (type === 'del') {
26948
- bg = 'rgba(239,68,68,0.10)';
27125
+ bg = tint('var(--color-status-error, rgb(239,68,68))', '10%');
26949
27126
  oldCell = String(oldN++);
26950
27127
  newCell = '';
26951
27128
  sign = '-';
@@ -26957,15 +27134,17 @@ var SWARM_UI_JS = `
26957
27134
  }
26958
27135
 
26959
27136
  var annHtml = '';
26960
- var anns = annByLine[Number(newCell)] || annByLine[Number(oldCell)] || [];
27137
+ // Annotations name new-side lines. A deleted row has no new-side
27138
+ // number, so only a deleted row matches on its old-side number.
27139
+ var anns = annByLine[Number(type === 'del' ? oldCell : newCell)] || [];
26961
27140
  for (var k = 0; k < anns.length; k++) annHtml += renderAnnotation(anns[k]);
26962
27141
 
26963
27142
  rowsHtml += (
26964
27143
  '<tr style="background:' + bg + ';">'
26965
- + '<td class="swarm-diff-gutter" style="user-select:none;text-align:right;padding:0 8px;color:#7c8aa6;font-size:12px;width:48px;">' + esc(oldCell) + '</td>'
26966
- + '<td class="swarm-diff-gutter" style="user-select:none;text-align:right;padding:0 8px;color:#7c8aa6;font-size:12px;width:48px;">' + esc(newCell) + '</td>'
26967
- + '<td class="swarm-diff-sign" style="user-select:none;text-align:center;padding:0 4px;color:#7c8aa6;font-size:12px;width:18px;">' + esc(sign) + '</td>'
26968
- + '<td class="swarm-diff-code" style="padding:0 8px;white-space:pre-wrap;word-break:break-word;font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:12px;">' + esc(text) + annHtml + '</td>'
27144
+ + '<td class="swarm-diff-gutter" style="user-select:none;text-align:right;padding:0 8px;color:' + MUTED + ';font-size:12px;width:48px;">' + esc(oldCell) + '</td>'
27145
+ + '<td class="swarm-diff-gutter" style="user-select:none;text-align:right;padding:0 8px;color:' + MUTED + ';font-size:12px;width:48px;">' + esc(newCell) + '</td>'
27146
+ + '<td class="swarm-diff-sign" style="user-select:none;text-align:center;padding:0 4px;color:' + MUTED + ';font-size:12px;width:18px;">' + esc(sign) + '</td>'
27147
+ + '<td class="swarm-diff-code" style="padding:0 8px;white-space:pre-wrap;word-break:break-word;font-family:' + MONO + ';font-size:12px;">' + esc(text) + annHtml + '</td>'
26969
27148
  + '</tr>'
26970
27149
  );
26971
27150
  }
@@ -26977,8 +27156,8 @@ var SWARM_UI_JS = `
26977
27156
  );
26978
27157
 
26979
27158
  return (
26980
- '<a id="' + esc(anchorId) + '" class="swarm-diff-anchor" data-hunk="' + esc(anchorSlug) + '"></a>'
26981
- + '<div class="swarm-diff-hunk-header" style="padding:6px 12px;background:rgba(124,138,166,0.10);color:#7c8aa6;font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:11px;border-top:1px solid var(--swarm-border,#22304a);">'
27159
+ '<a id="' + esc(anchorId) + '" class="swarm-diff-anchor" data-hunk="' + esc(anchorSlug) + '" data-new-start="' + esc(newStart) + '"></a>'
27160
+ + '<div class="swarm-diff-hunk-header" style="padding:6px 12px;background:' + tint('var(--color-muted-foreground, rgb(124,138,166))', '10%') + ';color:' + MUTED + ';font-family:' + MONO + ';font-size:11px;border-top:1px solid var(--swarm-border,#22304a);">'
26982
27161
  + esc(header)
26983
27162
  + '</div>'
26984
27163
  + '<table class="swarm-diff-table" style="width:100%;border-collapse:collapse;table-layout:fixed;">'
@@ -26995,7 +27174,7 @@ var SWARM_UI_JS = `
26995
27174
 
26996
27175
  var shaLine = '';
26997
27176
  if (baseSha || headSha) {
26998
- shaLine = '<span class="swarm-diff-sha" style="font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:11px;color:#7c8aa6;">'
27177
+ shaLine = '<span class="swarm-diff-sha" style="font-family:' + MONO + ';font-size:11px;color:' + MUTED + ';">'
26999
27178
  + esc(baseSha) + ' → ' + esc(headSha)
27000
27179
  + '</span>';
27001
27180
  }
@@ -27007,8 +27186,8 @@ var SWARM_UI_JS = `
27007
27186
 
27008
27187
  rootEl.innerHTML = (
27009
27188
  '<div class="swarm-diff-root" style="border:1px solid var(--swarm-border,#22304a);border-radius:8px;background:var(--swarm-card,#121826);overflow:hidden;margin:12px 0;break-inside:avoid;">'
27010
- + '<div class="swarm-diff-header" style="display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:rgba(59,130,246,0.10);border-bottom:1px solid var(--swarm-border,#22304a);">'
27011
- + '<span class="swarm-diff-file" style="font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:13px;font-weight:700;color:var(--swarm-text,#e6eaf2);">' + esc(file || '(untitled)') + '</span>'
27189
+ + '<div class="swarm-diff-header" style="display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:var(--color-surface, rgba(59,130,246,0.10));border-bottom:1px solid var(--swarm-border,#22304a);">'
27190
+ + '<span class="swarm-diff-file" style="font-family:' + MONO + ';font-size:13px;font-weight:700;color:var(--swarm-text,#e6eaf2);">' + esc(file || '(untitled)') + '</span>'
27012
27191
  + shaLine
27013
27192
  + '</div>'
27014
27193
  + hunksHtml
@@ -27072,21 +27251,34 @@ var SWARM_UI_JS = `
27072
27251
  var renderJumps = function() {
27073
27252
  var anchors = document.querySelectorAll('.swarm-diff-anchor[data-hunk]');
27074
27253
  if (!anchors.length) {
27075
- self.innerHTML = '<span class="no-print" style="color:#7c8aa6;font-size:12px;">No hunks yet.</span>';
27254
+ self.innerHTML = '<span class="no-print" style="color:' + MUTED + ';font-size:12px;">No hunks yet.</span>';
27076
27255
  return;
27077
27256
  }
27078
- var items = '';
27257
+ var labels = [];
27258
+ var fileCounts = new Map();
27079
27259
  for (var i = 0; i < anchors.length; i++) {
27080
27260
  var a = anchors[i];
27081
27261
  var slug = a.getAttribute('data-hunk') || ('hunk-' + i);
27082
27262
  // Hunk title = nearest preceding diff's file attribute if available.
27083
27263
  var diff = a.closest && a.closest('swarm-diff');
27084
27264
  var file = (diff && diff.getAttribute('file')) || slug;
27085
- items += '<li style="margin:0;padding:2px 0;"><a href="#' + esc(a.id) + '" style="color:#3b82f6;text-decoration:none;font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:12px;">' + esc(file) + '</a></li>';
27265
+ labels.push(file);
27266
+ fileCounts.set(file, (fileCounts.get(file) || 0) + 1);
27267
+ }
27268
+ var items = '';
27269
+ for (var n = 0; n < anchors.length; n++) {
27270
+ // A file with more than one hunk gets each hunk's new-side start
27271
+ // line (src/x.ts:58), so its links differ.
27272
+ var label = labels[n];
27273
+ var newStart = anchors[n].getAttribute('data-new-start');
27274
+ if (fileCounts.get(label) > 1 && newStart) label += ':' + newStart;
27275
+ // target=_self: the page head sets <base target="_blank">, which would
27276
+ // open these in-page anchors in a new tab.
27277
+ items += '<li style="margin:0;padding:2px 0;"><a href="#' + esc(anchors[n].id) + '" target="_self" style="color:var(--color-primary, #3b82f6);text-decoration:none;font-family:' + MONO + ';font-size:12px;">' + esc(label) + '</a></li>';
27086
27278
  }
27087
27279
  self.innerHTML = (
27088
- '<nav class="swarm-diff-jumps no-print" style="padding:8px 12px;border:1px dashed var(--swarm-border,#22304a);border-radius:8px;background:rgba(124,138,166,0.05);">'
27089
- + '<div style="font-size:10px;text-transform:uppercase;letter-spacing:0.08em;color:#7c8aa6;margin-bottom:4px;">Jump to</div>'
27280
+ '<nav class="swarm-diff-jumps no-print" style="padding:8px 12px;border:1px dashed var(--swarm-border,#22304a);border-radius:8px;background:' + tint('var(--color-muted-foreground, rgb(124,138,166))', '5%') + ';">'
27281
+ + '<div style="font-size:10px;text-transform:uppercase;letter-spacing:0.08em;color:' + MUTED + ';margin-bottom:4px;">Jump to</div>'
27090
27282
  + '<ul style="list-style:none;padding:0;margin:0;">' + items + '</ul>'
27091
27283
  + '</nav>'
27092
27284
  );
@@ -27352,6 +27544,9 @@ var SWARM_UI_JS = `
27352
27544
  })();
27353
27545
  `;
27354
27546
 
27547
+ // src/http/pages-public.ts
27548
+ init_color_literals();
27549
+
27355
27550
  // src/pages/feedback-overlay.ts
27356
27551
  var PAGE_FEEDBACK_PARAM = "__swarm-feedback";
27357
27552
  function isPageFeedbackRequested(queryParams) {
@@ -27900,58 +28095,82 @@ function feedbackKeyGuardScript() {
27900
28095
  return `<script>${FEEDBACK_KEY_GUARD_JS}</script>`;
27901
28096
  }
27902
28097
 
27903
- // src/http/pages-public.ts
27904
- init_types4();
27905
- init_constants3();
27906
- init_node_env();
27907
- init_page_session();
27908
- init_secret_scrubber();
27909
- init_route_def();
27910
- var PublicPageJsonSchema = PageSchema.pick({
27911
- id: true,
27912
- title: true,
27913
- description: true,
27914
- contentType: true,
27915
- authMode: true,
27916
- body: true
27917
- }).extend({
27918
- version: literal2(1)
27919
- });
27920
- var publicPageRoute = route({
27921
- method: "get",
27922
- path: "/p/{id}",
27923
- pattern: ["p", null],
27924
- summary: "Render a page (HTML/SVG inline; JSON redirects to SPA)",
27925
- tags: ["Pages"],
27926
- params: object2({ id: string2() }),
27927
- responses: {
27928
- 200: {
27929
- description: "Rendered HTML page or raw SVG image",
27930
- unstructured: "Serves raw image/svg+xml bytes, the page's agent-authored HTML body (SDK-injected) or, for ?print=1 on a JSON-content page, a standalone printable HTML document — not a JSON shape"
27931
- },
27932
- 302: { description: "Redirect to SPA for JSON content" },
27933
- 401: { description: "Page requires an authenticated session" },
27934
- 403: { description: "Cookie does not match this page id" },
27935
- 404: { description: "Page not found" }
27936
- },
27937
- auth: { apiKey: false }
27938
- });
27939
- var publicPageJsonRoute = route({
27940
- method: "get",
27941
- path: "/p/{id}.json",
27942
- pattern: ["p", null],
27943
- summary: "Page metadata + body as JSON (used by SPA renderer)",
27944
- tags: ["Pages"],
27945
- params: object2({ id: string2() }),
27946
- responses: {
27947
- 200: { description: "Page JSON", schema: PublicPageJsonSchema },
27948
- 401: { description: "Page requires an authenticated session" },
27949
- 403: { description: "Cookie does not match this page id" },
27950
- 404: { description: "Page not found" }
27951
- },
27952
- auth: { apiKey: false }
27953
- });
27954
- var PAGE_HEAD_DEFAULTS = `<base target="_blank">
28098
+ // src/themes/page-theme.ts
28099
+ init_presets();
28100
+ init_tokens2();
28101
+ var SWARM_ALIASES = [
28102
+ ["--swarm-bg", "--color-background"],
28103
+ ["--swarm-card", "--color-card"],
28104
+ ["--swarm-border", "--color-border"],
28105
+ ["--swarm-text", "--color-foreground"],
28106
+ ["--swarm-muted", "--color-muted-foreground"],
28107
+ ["--swarm-primary", "--color-primary"]
28108
+ ];
28109
+ function contractValues(vars) {
28110
+ const values = {};
28111
+ if (!vars)
28112
+ return values;
28113
+ for (const token of PAGE_THEME_TOKENS) {
28114
+ const value = vars[token];
28115
+ if (value !== undefined)
28116
+ values[token] = value;
28117
+ }
28118
+ return values;
28119
+ }
28120
+ function resolvePageTheme({
28121
+ pageTheme,
28122
+ viewerTheme,
28123
+ overrides
28124
+ }) {
28125
+ const preset = getThemePreset(pageTheme) ?? getThemePreset(viewerTheme) ?? getThemePreset(DEFAULT_THEME_ID);
28126
+ const lightOverrides = contractValues(overrides?.light);
28127
+ const darkOverrides = contractValues(overrides?.dark);
28128
+ const light = {
28129
+ ...HIVE_PAGE_TOKENS.light,
28130
+ ...contractValues(preset?.vars.light),
28131
+ ...lightOverrides
28132
+ };
28133
+ const dark = { ...HIVE_PAGE_TOKENS.dark, ...contractValues(preset?.vars.dark), ...darkOverrides };
28134
+ for (const token of PAGE_THEME_SHARED_TOKENS) {
28135
+ const value = lightOverrides[token];
28136
+ if (value !== undefined && darkOverrides[token] === undefined)
28137
+ dark[token] = value;
28138
+ }
28139
+ return { presetId: preset?.id ?? DEFAULT_THEME_ID, light, dark };
28140
+ }
28141
+ function declarationLines(values, indent) {
28142
+ return PAGE_THEME_TOKENS.map((token) => `${indent}${token}: ${values[token]};`).join(`
28143
+ `);
28144
+ }
28145
+ function renderPageThemeCss(theme) {
28146
+ const aliases = SWARM_ALIASES.map(([alias, token]) => ` ${alias}: var(${token});`).join(`
28147
+ `);
28148
+ return [
28149
+ `:root {
28150
+ color-scheme: light;
28151
+ ${declarationLines(theme.light, " ")}
28152
+ ${aliases}
28153
+ }`,
28154
+ `:root.dark {
28155
+ color-scheme: dark;
28156
+ ${declarationLines(theme.dark, " ")}
28157
+ }`,
28158
+ `@media print {
28159
+ :root.dark {
28160
+ color-scheme: light;
28161
+ ${declarationLines(theme.light, " ")}
28162
+ }
28163
+ }`
28164
+ ].join(`
28165
+
28166
+ `);
28167
+ }
28168
+
28169
+ // src/pages/page-head.ts
28170
+ init_tokens2();
28171
+ var PAGE_THEME_PARAM = "__swarm-theme";
28172
+ var PAGE_MODE_PARAM = "__swarm-mode";
28173
+ var PAGE_HEAD_V1 = `<base target="_blank">
27955
28174
  <link rel="preconnect" href="https://fonts.googleapis.com">
27956
28175
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
27957
28176
  <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">
@@ -28007,14 +28226,689 @@ var PAGE_HEAD_DEFAULTS = `<base target="_blank">
28007
28226
  .swarm-card, swarm-diff { break-inside: avoid; }
28008
28227
  }
28009
28228
  </style>`;
28010
- function injectBrowserSdk(html, headFirst = "") {
28011
- const injection = `${headFirst}${PAGE_HEAD_DEFAULTS}<script>${BROWSER_SDK_JS}</script><script>${SWARM_UI_JS}</script>`;
28012
- const headOpenMatch = html.match(/<head\b[^>]*>/i);
28013
- if (headOpenMatch) {
28014
- const idx = headOpenMatch.index + headOpenMatch[0].length;
28015
- return html.slice(0, idx) + injection + html.slice(idx);
28229
+ var TAILWIND_BROWSER_SRC = "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3/dist/index.global.js";
28230
+ var TAILWIND_BROWSER_INTEGRITY = "sha384-2ql948lIdLcGEE0/qxNiudyTjgauA3RDJERu5xW75kFCvSl5a9odyQYCb6tEjnmB";
28231
+ var IN_PAGE_LINK_SCRIPT = `<script>document.addEventListener("click", function (event) {
28232
+ var link = event.target && event.target.closest && event.target.closest('a[href^="#"]:not([target])');
28233
+ if (link) link.setAttribute("target", "_self");
28234
+ }, true);</script>`;
28235
+ var FONT_LINKS = `<link rel="preconnect" href="https://fonts.googleapis.com">
28236
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
28237
+ <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">`;
28238
+ var TAILWIND_SOURCE = [
28239
+ '@import "tailwindcss/theme" layer(theme);',
28240
+ '@import "tailwindcss/utilities" layer(utilities);',
28241
+ "@custom-variant dark (&:where(.dark, .dark *));",
28242
+ "@theme inline reference {",
28243
+ ...PAGE_THEME_TOKENS.map((token) => ` ${token}: var(${token});`),
28244
+ "}"
28245
+ ].join(`
28246
+ `);
28247
+ var TAILWIND_SOURCE_SCRIPT = `<script>(function () {
28248
+ var style = document.createElement("style");
28249
+ style.type = "text/tailwindcss";
28250
+ style.textContent = ${JSON.stringify(TAILWIND_SOURCE).replace(/</g, "\\u003c")};
28251
+ document.head.appendChild(style);
28252
+ })();</script>`;
28253
+ var CONTROL_LOOK = `min-width: 0;
28254
+ padding: 7px 12px;
28255
+ font-size: 14px;
28256
+ line-height: 20px;
28257
+ color: var(--color-foreground);
28258
+ background-color: var(--color-card);
28259
+ border: 1px solid var(--color-input);
28260
+ border-radius: var(--radius-md);
28261
+ transition: border-color 150ms, box-shadow 150ms;`;
28262
+ var BUTTON_LOOK = `display: inline-flex;
28263
+ align-items: center;
28264
+ justify-content: center;
28265
+ gap: 8px;
28266
+ padding: 7px 14px;
28267
+ font-size: 14px;
28268
+ font-weight: 500;
28269
+ line-height: 20px;
28270
+ color: var(--color-foreground);
28271
+ background-color: var(--color-card);
28272
+ border: 1px solid var(--color-input);
28273
+ border-radius: var(--radius-md);
28274
+ text-decoration: none;
28275
+ white-space: nowrap;
28276
+ cursor: pointer;
28277
+ transition: color 150ms, background-color 150ms, border-color 150ms, box-shadow 150ms;`;
28278
+ var FOCUS_RING = `outline: none;
28279
+ border-color: var(--color-ring);
28280
+ box-shadow: 0 0 0 2px color-mix(in oklab, var(--color-ring) 60%, transparent);`;
28281
+ var TEXT_CONTROLS = `:where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"], [type="button"], [type="submit"], [type="reset"], [type="image"], [type="hidden"]), select, textarea)`;
28282
+ var BUTTON_CONTROLS = `:where(button, input[type="button"], input[type="submit"], input[type="reset"])`;
28283
+ var EDGE_SHADOW = "color-mix(in oklab, var(--color-foreground) 14%, transparent)";
28284
+ var TONES = [
28285
+ ["neutral", "--color-status-neutral", "--color-status-neutral-strong"],
28286
+ ["primary", "--color-primary", "--color-primary"],
28287
+ ...["success", "warning", "error", "info", "pending", "paused", "active"].map((tone) => [tone, `--color-status-${tone}`, `--color-status-${tone}-strong`])
28288
+ ];
28289
+ var TONE_RULES = TONES.map(([tone, soft, strong]) => ` :is(.swarm-badge, .swarm-callout, .swarm-metric)[data-tone="${tone}"] {
28290
+ --swarm-tone: var(${soft});
28291
+ --swarm-tone-strong: var(${strong});
28292
+ }`).join(`
28293
+ `);
28294
+ var PAGE_DESIGN_CSS = `@layer base {
28295
+ *, ::before, ::after, ::backdrop, ::file-selector-button {
28296
+ box-sizing: border-box;
28297
+ border: 0 solid var(--color-border);
28016
28298
  }
28017
- return injection + html;
28299
+ html {
28300
+ color: var(--color-foreground);
28301
+ -webkit-text-size-adjust: 100%;
28302
+ text-size-adjust: 100%;
28303
+ tab-size: 4;
28304
+ }
28305
+ body {
28306
+ margin: 0;
28307
+ padding: 24px;
28308
+ background-color: var(--color-background);
28309
+ color: var(--color-foreground);
28310
+ font-family: var(--font-sans), ui-sans-serif, system-ui, sans-serif;
28311
+ font-size: 15px;
28312
+ line-height: 1.55;
28313
+ -webkit-font-smoothing: antialiased;
28314
+ -moz-osx-font-smoothing: grayscale;
28315
+ }
28316
+ @media (max-width: 640px) {
28317
+ body { padding: 16px; }
28318
+ }
28319
+ :focus-visible {
28320
+ outline: 2px solid var(--color-ring);
28321
+ outline-offset: 2px;
28322
+ }
28323
+ h1, h2, h3, h4, h5, h6 {
28324
+ margin: 0;
28325
+ font-weight: 600;
28326
+ text-wrap: balance;
28327
+ }
28328
+ h1 { margin: 0 0 12px; font-size: 30px; line-height: 1.2; letter-spacing: -0.02em; }
28329
+ h2 { margin: 40px 0 12px; font-size: 20px; line-height: 1.3; letter-spacing: -0.015em; }
28330
+ h3 { margin: 28px 0 8px; font-size: 16px; line-height: 1.4; letter-spacing: -0.01em; }
28331
+ h4 { margin: 24px 0 6px; font-size: 15px; line-height: 1.45; }
28332
+ h5, h6 { margin: 20px 0 6px; font-size: 13px; line-height: 1.45; }
28333
+ p { margin: 0 0 12px; text-wrap: pretty; }
28334
+ ul, ol { margin: 0 0 12px; padding-left: 1.5em; }
28335
+ li { margin: 4px 0; }
28336
+ li > ul, li > ol { margin: 4px 0 0; }
28337
+ li::marker { color: var(--color-muted-foreground); }
28338
+ dl, figure, blockquote, pre, table, details, fieldset, form { margin: 0 0 16px; }
28339
+ dt { font-weight: 500; }
28340
+ dd { margin: 0 0 8px; }
28341
+ :where(h1, h2, h3, h4, h5, h6):first-child { margin-top: 0; }
28342
+ :where(p, ul, ol, dl, dd, figure, blockquote, pre, table, details, fieldset, form):last-child { margin-bottom: 0; }
28343
+ a {
28344
+ color: var(--color-primary);
28345
+ text-decoration-line: underline;
28346
+ text-decoration-thickness: 1px;
28347
+ text-decoration-color: color-mix(in oklab, currentColor 35%, transparent);
28348
+ text-underline-offset: 3px;
28349
+ }
28350
+ a:hover { text-decoration-color: currentColor; }
28351
+ hr {
28352
+ height: 0;
28353
+ margin: 32px 0;
28354
+ color: inherit;
28355
+ border-top: 1px solid var(--color-border-subtle);
28356
+ }
28357
+ b, strong { font-weight: 600; }
28358
+ mark {
28359
+ padding: 0 2px;
28360
+ color: inherit;
28361
+ background-color: color-mix(in oklab, var(--color-status-pending) 35%, transparent);
28362
+ border-radius: 2px;
28363
+ }
28364
+ code, kbd, samp, pre {
28365
+ font-family: var(--font-mono), ui-monospace, SFMono-Regular, Menlo, monospace;
28366
+ font-size: 0.85em;
28367
+ }
28368
+ code {
28369
+ padding: 0.1em 0.35em;
28370
+ background-color: var(--color-muted);
28371
+ border-radius: var(--radius-sm);
28372
+ -webkit-box-decoration-break: clone;
28373
+ box-decoration-break: clone;
28374
+ }
28375
+ kbd {
28376
+ padding: 0.05em 0.4em;
28377
+ background-color: var(--color-card);
28378
+ border: 1px solid var(--color-border);
28379
+ border-bottom-width: 2px;
28380
+ border-radius: var(--radius-sm);
28381
+ }
28382
+ pre {
28383
+ padding: 12px 14px;
28384
+ overflow: auto;
28385
+ line-height: 1.6;
28386
+ background-color: var(--color-surface);
28387
+ border: 1px solid var(--color-border);
28388
+ border-radius: var(--radius-lg);
28389
+ }
28390
+ pre code {
28391
+ padding: 0;
28392
+ font-size: inherit;
28393
+ background-color: transparent;
28394
+ border-radius: 0;
28395
+ }
28396
+ blockquote {
28397
+ padding: 2px 0 2px 16px;
28398
+ color: var(--color-muted-foreground);
28399
+ border-left: 2px solid var(--color-border);
28400
+ }
28401
+ summary {
28402
+ cursor: pointer;
28403
+ font-weight: 500;
28404
+ }
28405
+ summary::marker { color: var(--color-muted-foreground); }
28406
+ details[open] > summary { margin-bottom: 8px; }
28407
+ img, video {
28408
+ display: block;
28409
+ max-width: 100%;
28410
+ height: auto;
28411
+ }
28412
+ figcaption {
28413
+ margin-top: 8px;
28414
+ font-size: 13px;
28415
+ color: var(--color-muted-foreground);
28416
+ }
28417
+ table {
28418
+ width: 100%;
28419
+ border-collapse: collapse;
28420
+ font-size: 14px;
28421
+ font-variant-numeric: tabular-nums;
28422
+ }
28423
+ caption {
28424
+ padding-bottom: 8px;
28425
+ font-size: 13px;
28426
+ text-align: left;
28427
+ color: var(--color-muted-foreground);
28428
+ }
28429
+ th, td {
28430
+ padding: 8px 12px;
28431
+ text-align: left;
28432
+ vertical-align: middle;
28433
+ border-bottom: 1px solid var(--color-border-subtle);
28434
+ }
28435
+ th {
28436
+ font-size: 11px;
28437
+ font-weight: 500;
28438
+ line-height: 1.45;
28439
+ letter-spacing: 0.05em;
28440
+ text-transform: uppercase;
28441
+ vertical-align: bottom;
28442
+ color: var(--color-muted-foreground);
28443
+ border-bottom-color: var(--color-border);
28444
+ }
28445
+ th[scope="row"] {
28446
+ font-size: inherit;
28447
+ letter-spacing: normal;
28448
+ text-transform: none;
28449
+ vertical-align: middle;
28450
+ color: inherit;
28451
+ border-bottom-color: var(--color-border-subtle);
28452
+ }
28453
+ tfoot :is(td, th) {
28454
+ font-weight: 600;
28455
+ border-top: 1px solid var(--color-border);
28456
+ }
28457
+ tbody:has(+ tfoot) > tr:last-child > :is(td, th) { border-bottom-color: var(--color-border); }
28458
+ :where(button, input, optgroup, select, textarea), ::file-selector-button {
28459
+ font: inherit;
28460
+ font-feature-settings: inherit;
28461
+ font-variation-settings: inherit;
28462
+ letter-spacing: inherit;
28463
+ color: inherit;
28464
+ }
28465
+ ${TEXT_CONTROLS} {
28466
+ ${CONTROL_LOOK}
28467
+ }
28468
+ ${TEXT_CONTROLS}:focus-visible {
28469
+ ${FOCUS_RING}
28470
+ }
28471
+ :where(input, select, textarea)::placeholder {
28472
+ color: var(--color-muted-foreground);
28473
+ opacity: 1;
28474
+ }
28475
+ :where(input, select, textarea, button):disabled {
28476
+ cursor: not-allowed;
28477
+ opacity: 0.5;
28478
+ }
28479
+ :where(input, select, textarea)[aria-invalid="true"] { border-color: var(--color-destructive); }
28480
+ textarea {
28481
+ min-height: 80px;
28482
+ line-height: 1.5;
28483
+ resize: vertical;
28484
+ }
28485
+ select:not([multiple], [size]) {
28486
+ appearance: none;
28487
+ padding-right: 32px;
28488
+ background-image:
28489
+ linear-gradient(45deg, transparent 50%, var(--color-muted-foreground) 50%),
28490
+ linear-gradient(135deg, var(--color-muted-foreground) 50%, transparent 50%);
28491
+ background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
28492
+ background-size: 5px 5px;
28493
+ background-repeat: no-repeat;
28494
+ }
28495
+ ${BUTTON_CONTROLS} {
28496
+ ${BUTTON_LOOK}
28497
+ }
28498
+ ${BUTTON_CONTROLS}:hover:not(:disabled) {
28499
+ color: var(--color-accent-foreground);
28500
+ background-color: var(--color-accent);
28501
+ }
28502
+ ${BUTTON_CONTROLS}:focus-visible {
28503
+ ${FOCUS_RING}
28504
+ }
28505
+ ::file-selector-button {
28506
+ margin-right: 12px;
28507
+ padding: 4px 10px;
28508
+ font-size: 13px;
28509
+ font-weight: 500;
28510
+ color: var(--color-foreground);
28511
+ background-color: var(--color-card);
28512
+ border: 1px solid var(--color-input);
28513
+ border-radius: var(--radius-sm);
28514
+ cursor: pointer;
28515
+ }
28516
+ input[type="checkbox"], input[type="radio"], input[type="range"], progress {
28517
+ accent-color: var(--color-primary);
28518
+ }
28519
+ fieldset {
28520
+ min-width: 0;
28521
+ padding: 12px 16px 16px;
28522
+ border: 1px solid var(--color-border);
28523
+ border-radius: var(--radius-lg);
28524
+ }
28525
+ legend {
28526
+ padding: 0 6px;
28527
+ font-size: 13px;
28528
+ font-weight: 500;
28529
+ color: var(--color-muted-foreground);
28530
+ }
28531
+ label:has(input, select, textarea), label[for] { cursor: pointer; }
28532
+ ::selection {
28533
+ color: var(--color-primary-foreground);
28534
+ background-color: var(--color-primary);
28535
+ }
28536
+ }
28537
+
28538
+ @layer components {
28539
+ .swarm-page {
28540
+ max-width: 1120px;
28541
+ margin-inline: auto;
28542
+ padding-block: 8px 24px;
28543
+ }
28544
+ .swarm-eyebrow {
28545
+ margin: 0 0 8px;
28546
+ font-size: 11px;
28547
+ font-weight: 500;
28548
+ line-height: 1.45;
28549
+ letter-spacing: 0.08em;
28550
+ text-transform: uppercase;
28551
+ color: var(--color-muted-foreground);
28552
+ }
28553
+ .swarm-lede {
28554
+ max-width: 68ch;
28555
+ margin: 0 0 16px;
28556
+ font-size: 17px;
28557
+ line-height: 1.55;
28558
+ color: var(--color-muted-foreground);
28559
+ text-wrap: pretty;
28560
+ }
28561
+ .swarm-section { margin-block: 40px; }
28562
+ .swarm-section:last-child { margin-bottom: 0; }
28563
+ .swarm-section > :first-child { margin-top: 0; }
28564
+
28565
+ .swarm-metrics {
28566
+ display: grid;
28567
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 148px), 1fr));
28568
+ gap: 12px;
28569
+ margin: 24px 0;
28570
+ }
28571
+ .swarm-metric {
28572
+ display: flex;
28573
+ flex-direction: column;
28574
+ gap: 4px;
28575
+ min-width: 0;
28576
+ padding: 14px 16px;
28577
+ color: var(--color-card-foreground);
28578
+ background-color: var(--color-card);
28579
+ border: 1px solid var(--color-border);
28580
+ border-radius: var(--radius-xl);
28581
+ }
28582
+ .swarm-metric-value {
28583
+ font-size: 26px;
28584
+ font-weight: 600;
28585
+ line-height: 1.15;
28586
+ letter-spacing: -0.02em;
28587
+ font-variant-numeric: tabular-nums;
28588
+ overflow-wrap: anywhere;
28589
+ }
28590
+ .swarm-metric[data-tone] .swarm-metric-value { color: var(--swarm-tone-strong); }
28591
+ .swarm-metric-label {
28592
+ font-size: 12px;
28593
+ line-height: 1.45;
28594
+ color: var(--color-muted-foreground);
28595
+ }
28596
+
28597
+ .swarm-panel, .swarm-card {
28598
+ padding: 20px;
28599
+ color: var(--color-card-foreground);
28600
+ background-color: var(--color-card);
28601
+ border: 1px solid var(--color-border);
28602
+ border-radius: var(--radius-xl);
28603
+ }
28604
+ :is(.swarm-panel, .swarm-card) > :first-child { margin-top: 0; }
28605
+ :is(.swarm-panel, .swarm-card) > :last-child { margin-bottom: 0; }
28606
+
28607
+ .swarm-badge {
28608
+ --swarm-tone: var(--color-status-neutral);
28609
+ --swarm-tone-strong: var(--color-status-neutral-strong);
28610
+ display: inline-flex;
28611
+ align-items: center;
28612
+ gap: 6px;
28613
+ height: 22px;
28614
+ padding: 0 8px;
28615
+ font-size: 12px;
28616
+ font-weight: 500;
28617
+ line-height: 1;
28618
+ white-space: nowrap;
28619
+ vertical-align: middle;
28620
+ color: var(--swarm-tone-strong);
28621
+ background-color: color-mix(in oklab, var(--swarm-tone) 16%, transparent);
28622
+ border: 1px solid color-mix(in oklab, var(--swarm-tone) 28%, transparent);
28623
+ border-radius: 999px;
28624
+ }
28625
+ .swarm-badge[data-dot]::before {
28626
+ content: "";
28627
+ flex: none;
28628
+ width: 6px;
28629
+ height: 6px;
28630
+ background: var(--swarm-dot, currentColor);
28631
+ border-radius: 999px;
28632
+ }
28633
+
28634
+ .swarm-table-wrap {
28635
+ max-height: min(70vh, 720px);
28636
+ margin: 0 0 16px;
28637
+ overflow: auto;
28638
+ background:
28639
+ linear-gradient(to right, var(--color-card) 30%, transparent) left / 40px 100% no-repeat local,
28640
+ linear-gradient(to left, var(--color-card) 30%, transparent) right / 40px 100% no-repeat local,
28641
+ linear-gradient(to right, ${EDGE_SHADOW}, transparent) left / 14px 100% no-repeat scroll,
28642
+ linear-gradient(to left, ${EDGE_SHADOW}, transparent) right / 14px 100% no-repeat scroll,
28643
+ var(--color-card);
28644
+ border: 1px solid var(--color-border);
28645
+ border-radius: var(--radius-xl);
28646
+ }
28647
+ .swarm-table-wrap:last-child { margin-bottom: 0; }
28648
+ .swarm-table-wrap > table { margin: 0; }
28649
+ .swarm-table {
28650
+ width: 100%;
28651
+ border-collapse: separate;
28652
+ border-spacing: 0;
28653
+ font-size: 13px;
28654
+ line-height: 1.45;
28655
+ font-variant-numeric: tabular-nums;
28656
+ }
28657
+ .swarm-table :is(th, td) { padding: 8px 12px; }
28658
+ .swarm-table thead th {
28659
+ position: sticky;
28660
+ top: 0;
28661
+ z-index: 1;
28662
+ padding-block: 10px 8px;
28663
+ white-space: nowrap;
28664
+ background-color: var(--color-card);
28665
+ }
28666
+ .swarm-table tbody tr:hover > :is(td, th) { background-color: color-mix(in oklab, var(--color-accent) 70%, transparent); }
28667
+ .swarm-table-wrap > .swarm-table > :last-child > tr:last-child > :is(td, th) { border-bottom: 0; }
28668
+ :is(td, th).num {
28669
+ text-align: right;
28670
+ white-space: nowrap;
28671
+ font-variant-numeric: tabular-nums;
28672
+ }
28673
+ :is(td, th).nowrap { white-space: nowrap; }
28674
+ .swarm-diff-root :is(table, th, td) { margin: 0; border: 0; }
28675
+
28676
+ .swarm-button {
28677
+ ${BUTTON_LOOK}
28678
+ }
28679
+ .swarm-button:hover {
28680
+ color: var(--color-accent-foreground);
28681
+ background-color: var(--color-accent);
28682
+ }
28683
+ .swarm-button[data-variant="primary"] {
28684
+ color: var(--color-primary-foreground);
28685
+ background-color: var(--color-primary);
28686
+ border-color: transparent;
28687
+ }
28688
+ .swarm-button[data-variant="primary"]:hover {
28689
+ color: var(--color-primary-foreground);
28690
+ background-color: color-mix(in oklab, var(--color-primary) 90%, transparent);
28691
+ }
28692
+ .swarm-button[data-variant="ghost"] {
28693
+ background-color: transparent;
28694
+ border-color: transparent;
28695
+ }
28696
+ .swarm-button[data-variant="ghost"]:hover { background-color: var(--color-accent); }
28697
+ .swarm-button:focus-visible {
28698
+ ${FOCUS_RING}
28699
+ }
28700
+ .swarm-button:is(:disabled, [aria-disabled="true"]) {
28701
+ opacity: 0.5;
28702
+ pointer-events: none;
28703
+ }
28704
+
28705
+ .swarm-input {
28706
+ ${CONTROL_LOOK}
28707
+ }
28708
+ .swarm-input:focus-visible {
28709
+ ${FOCUS_RING}
28710
+ }
28711
+ select.swarm-input:not([multiple], [size]) { padding-right: 32px; }
28712
+
28713
+ .swarm-toolbar {
28714
+ display: flex;
28715
+ flex-wrap: wrap;
28716
+ align-items: center;
28717
+ gap: 8px;
28718
+ margin: 0 0 12px;
28719
+ }
28720
+ .swarm-toolbar > :is(input[type="search"], input[type="text"], input:not([type])) { flex: 1 1 260px; }
28721
+
28722
+ .swarm-segmented {
28723
+ display: inline-flex;
28724
+ align-items: center;
28725
+ gap: 2px;
28726
+ height: 36px;
28727
+ padding: 2px;
28728
+ vertical-align: middle;
28729
+ background-color: color-mix(in oklab, var(--color-muted) 40%, transparent);
28730
+ border: 1px solid var(--color-border);
28731
+ border-radius: var(--radius-md);
28732
+ }
28733
+ .swarm-segmented > :is(button, a) {
28734
+ display: inline-flex;
28735
+ align-items: center;
28736
+ justify-content: center;
28737
+ gap: 6px;
28738
+ height: 100%;
28739
+ padding: 0 12px;
28740
+ font-size: 12px;
28741
+ font-weight: 500;
28742
+ line-height: 1;
28743
+ white-space: nowrap;
28744
+ text-decoration: none;
28745
+ color: var(--color-muted-foreground);
28746
+ background-color: transparent;
28747
+ border: 0;
28748
+ border-radius: calc(var(--radius-md) - 3px);
28749
+ box-shadow: none;
28750
+ cursor: pointer;
28751
+ transition: color 150ms, background-color 150ms;
28752
+ }
28753
+ .swarm-segmented > :is(button, a):hover {
28754
+ color: var(--color-foreground);
28755
+ background-color: transparent;
28756
+ }
28757
+ .swarm-segmented > :is([aria-pressed="true"], [data-active]:not([data-active="false"])) {
28758
+ color: var(--color-primary-foreground);
28759
+ background-color: var(--color-primary);
28760
+ }
28761
+ .swarm-segmented > :is(button, a):focus-visible {
28762
+ outline: none;
28763
+ box-shadow: 0 0 0 2px color-mix(in oklab, var(--color-ring) 60%, transparent);
28764
+ }
28765
+
28766
+ .swarm-callout {
28767
+ --swarm-tone: var(--color-status-info);
28768
+ --swarm-tone-strong: var(--color-status-info-strong);
28769
+ margin: 0 0 12px;
28770
+ padding: 12px 16px;
28771
+ color: var(--color-foreground);
28772
+ background-color: color-mix(in oklab, var(--swarm-tone) 12%, transparent);
28773
+ border: 1px solid color-mix(in oklab, var(--swarm-tone) 40%, transparent);
28774
+ border-radius: var(--radius-lg);
28775
+ }
28776
+ .swarm-callout:last-child { margin-bottom: 0; }
28777
+ .swarm-callout > :first-child { margin-top: 0; }
28778
+ .swarm-callout > :last-child { margin-bottom: 0; }
28779
+
28780
+ .swarm-kv {
28781
+ display: grid;
28782
+ grid-template-columns: minmax(96px, max-content) minmax(0, 1fr);
28783
+ gap: 8px 20px;
28784
+ margin: 0 0 16px;
28785
+ font-size: 14px;
28786
+ }
28787
+ .swarm-kv:last-child { margin-bottom: 0; }
28788
+ .swarm-kv > dt {
28789
+ font-weight: 400;
28790
+ color: var(--color-muted-foreground);
28791
+ }
28792
+ .swarm-kv > dd {
28793
+ min-width: 0;
28794
+ margin: 0;
28795
+ overflow-wrap: anywhere;
28796
+ }
28797
+
28798
+ ${TONE_RULES}
28799
+ }
28800
+
28801
+ @media print {
28802
+ html, body { background: white !important; color: black !important; }
28803
+ a:not(.swarm-button) { color: black !important; text-decoration: underline; }
28804
+ .no-print { display: none !important; }
28805
+ .swarm-panel, .swarm-card, swarm-diff, .swarm-metric { break-inside: avoid; }
28806
+ .swarm-table-wrap { max-height: none; overflow: visible; }
28807
+ .swarm-table { font-size: 12px; }
28808
+ .swarm-table :is(th, td):not(.num) { white-space: normal; }
28809
+ .swarm-table thead th { position: static; }
28810
+ tfoot { display: table-row-group; }
28811
+ }`;
28812
+ function buildPageHeadV2({
28813
+ theme,
28814
+ mode
28815
+ }) {
28816
+ return [
28817
+ '<base target="_blank">',
28818
+ IN_PAGE_LINK_SCRIPT,
28819
+ "<style>@layer properties, theme, base, components, utilities;</style>",
28820
+ FONT_LINKS,
28821
+ `<style id="swarm-theme">
28822
+ ${renderPageThemeCss(theme)}
28823
+ </style>`,
28824
+ `<style id="swarm-design">
28825
+ ${PAGE_DESIGN_CSS}
28826
+ </style>`,
28827
+ TAILWIND_SOURCE_SCRIPT,
28828
+ `<script src="${TAILWIND_BROWSER_SRC}" integrity="${TAILWIND_BROWSER_INTEGRITY}" crossorigin="anonymous"></script>`,
28829
+ ...mode === "dark" ? ['<script>document.documentElement.classList.add("dark")</script>'] : []
28830
+ ].join(`
28831
+ `);
28832
+ }
28833
+
28834
+ // src/http/pages-public.ts
28835
+ init_types4();
28836
+ init_constants3();
28837
+ init_page_session();
28838
+ init_secret_scrubber();
28839
+ init_route_def();
28840
+ var PublicPageJsonSchema = PageSchema.pick({
28841
+ id: true,
28842
+ title: true,
28843
+ description: true,
28844
+ contentType: true,
28845
+ authMode: true,
28846
+ body: true
28847
+ }).extend({
28848
+ version: literal2(1)
28849
+ });
28850
+ var publicPageRoute = route({
28851
+ method: "get",
28852
+ path: "/p/{id}",
28853
+ pattern: ["p", null],
28854
+ summary: "Render a page (HTML/SVG inline; JSON redirects to SPA)",
28855
+ tags: ["Pages"],
28856
+ params: object2({ id: string2() }),
28857
+ responses: {
28858
+ 200: {
28859
+ description: "Rendered HTML page or raw SVG image",
28860
+ unstructured: "Serves raw image/svg+xml bytes, the page's agent-authored HTML body (SDK-injected) or, for ?print=1 on a JSON-content page, a standalone printable HTML document — not a JSON shape"
28861
+ },
28862
+ 302: { description: "Redirect to SPA for JSON content" },
28863
+ 401: { description: "Page requires an authenticated session" },
28864
+ 403: { description: "Cookie does not match this page id" },
28865
+ 404: { description: "Page not found" }
28866
+ },
28867
+ auth: { apiKey: false }
28868
+ });
28869
+ var publicPageJsonRoute = route({
28870
+ method: "get",
28871
+ path: "/p/{id}.json",
28872
+ pattern: ["p", null],
28873
+ summary: "Page metadata + body as JSON (used by SPA renderer)",
28874
+ tags: ["Pages"],
28875
+ params: object2({ id: string2() }),
28876
+ responses: {
28877
+ 200: { description: "Page JSON", schema: PublicPageJsonSchema },
28878
+ 401: { description: "Page requires an authenticated session" },
28879
+ 403: { description: "Cookie does not match this page id" },
28880
+ 404: { description: "Page not found" }
28881
+ },
28882
+ auth: { apiKey: false }
28883
+ });
28884
+ function pageHead(page, queryParams, wantsPrint) {
28885
+ if (page.designVersion === 1)
28886
+ return PAGE_HEAD_V1;
28887
+ const theme = resolvePageTheme({
28888
+ pageTheme: page.theme,
28889
+ viewerTheme: queryParams.get(PAGE_THEME_PARAM),
28890
+ overrides: page.themeTokens
28891
+ });
28892
+ const dark = !wantsPrint && queryParams.get(PAGE_MODE_PARAM) === "dark" && countColorLiterals(page.body) < COLOR_LITERAL_THRESHOLD;
28893
+ return buildPageHeadV2({ theme, mode: dark ? "dark" : "light" });
28894
+ }
28895
+ var LEADING_DOCTYPE_RE = /^\s*<!doctype\b[^>]*>/i;
28896
+ var LEADING_HTML_TAG_RE = /^\s*<!doctype\b[^>]*>\s*<html\b[^>]*>/i;
28897
+ function injectBrowserSdk(html, { head, headFirst, standardsMode }) {
28898
+ const injection = `${headFirst}${head}<script>${BROWSER_SDK_JS}</script><script>${SWARM_UI_JS}</script>`;
28899
+ const doc = standardsMode && !LEADING_DOCTYPE_RE.test(html) ? `<!doctype html>${html}` : html;
28900
+ const leading = standardsMode ? LEADING_HTML_TAG_RE.exec(doc) ?? LEADING_DOCTYPE_RE.exec(doc) : null;
28901
+ const idx = headTagEnd(doc) ?? (leading ? leading.index + leading[0].length : null);
28902
+ if (idx === null)
28903
+ return injection + doc;
28904
+ return doc.slice(0, idx) + injection + doc.slice(idx);
28905
+ }
28906
+ function headTagEnd(doc) {
28907
+ const start = doc.search(/<head\b/i);
28908
+ if (start === -1)
28909
+ return null;
28910
+ const close = doc.indexOf(">", start);
28911
+ return close === -1 ? null : close + 1;
28018
28912
  }
28019
28913
  var PRINT_AUTOTRIGGER_SCRIPT = `<script>
28020
28914
  (function () {
@@ -28124,14 +29018,7 @@ function getPageFrameAncestors() {
28124
29018
  }
28125
29019
  function buildCsp(page) {
28126
29020
  const configured = getConfiguredAppUrls();
28127
- const devFallbacks = getNodeEnv() === "production" ? [] : [
28128
- "http://localhost:5274",
28129
- "http://localhost:5175",
28130
- "http://127.0.0.1:5274",
28131
- "http://127.0.0.1:5175",
28132
- "https://*.localhost",
28133
- "http://*.localhost"
28134
- ];
29021
+ const devFallbacks = getLocalDevAppOrigins();
28135
29022
  const embedders = page.authMode === "public" ? getPageFrameAncestors() : [];
28136
29023
  const ancestors = Array.from(new Set([...configured, ...devFallbacks, ...embedders]));
28137
29024
  return [
@@ -28186,19 +29073,6 @@ function extractPasswordCandidate(req, queryParams) {
28186
29073
  return null;
28187
29074
  return decoded.slice(colonIdx + 1);
28188
29075
  }
28189
- function isLocalhostRequest(req) {
28190
- if (getNodeEnv() === "production")
28191
- return false;
28192
- const origin = req.headers.origin ?? "";
28193
- if (origin === "") {
28194
- const rawHost = req.headers.host;
28195
- const host = Array.isArray(rawHost) ? rawHost[0] : rawHost;
28196
- if (!host)
28197
- return true;
28198
- return host.startsWith("localhost") || host.startsWith("127.0.0.1");
28199
- }
28200
- return origin.startsWith("http://localhost") || origin.startsWith("http://127.0.0.1");
28201
- }
28202
29076
  async function handlePagesPublic(req, res, pathSegments, queryParams) {
28203
29077
  if (pathSegments.length !== 2 || pathSegments[0] !== "p")
28204
29078
  return false;
@@ -28239,7 +29113,7 @@ async function handlePagesPublic(req, res, pathSegments, queryParams) {
28239
29113
  }
28240
29114
  if (matched) {
28241
29115
  inlineSetCookie = await pageSessionSetCookies(req, page.id, {
28242
- dev: isLocalhostRequest(req)
29116
+ dev: isLocalDevPageRequest(req)
28243
29117
  });
28244
29118
  } else {
28245
29119
  res.writeHead(401, {
@@ -28319,7 +29193,11 @@ async function handlePagesPublic(req, res, pathSegments, queryParams) {
28319
29193
  return true;
28320
29194
  }
28321
29195
  const feedback = isPageFeedbackRequested(queryParams);
28322
- const html = injectBrowserSdk(page.body, feedback ? feedbackKeyGuardScript() : "") + (wantsPrint ? PRINT_AUTOTRIGGER_SCRIPT : "") + (feedback ? feedbackOverlayScripts(page.id) : "");
29196
+ const html = injectBrowserSdk(page.body, {
29197
+ head: pageHead(page, queryParams, wantsPrint),
29198
+ headFirst: feedback ? feedbackKeyGuardScript() : "",
29199
+ standardsMode: page.designVersion !== 1
29200
+ }) + (wantsPrint ? PRINT_AUTOTRIGGER_SCRIPT : "") + (feedback ? feedbackOverlayScripts(page.id) : "");
28323
29201
  const headers = {
28324
29202
  "Content-Type": "text/html; charset=utf-8",
28325
29203
  "Cache-Control": "no-store",
@@ -31591,7 +32469,7 @@ init_vendored_openapi();
31591
32469
  init_app_validation();
31592
32470
  init_ensure_token();
31593
32471
  init_mcp_wrapper();
31594
- init_presets();
32472
+ init_presets2();
31595
32473
  init_wrapper();
31596
32474
  init_credential_broker();
31597
32475
  init_telemetry();
@@ -33498,6 +34376,9 @@ function refuseSourceWithSecrets(source) {
33498
34376
  };
33499
34377
  }
33500
34378
 
34379
+ // src/http/script-runs.ts
34380
+ init_rbac();
34381
+
33501
34382
  // src/script-workflows/label-lint.ts
33502
34383
  var import_typescript = __toESM(require_typescript2(), 1);
33503
34384
  var ITERATION_CALLBACK_METHODS = new Set([
@@ -33567,6 +34448,7 @@ function lintWorkflowLabels(source) {
33567
34448
  }
33568
34449
 
33569
34450
  // src/http/script-runs.ts
34451
+ init_follow_up_redelegation_guard();
33570
34452
  init_types4();
33571
34453
  init_constants3();
33572
34454
  init_secret_scrubber();
@@ -33626,7 +34508,8 @@ var agentTaskBodySchema = object2({
33626
34508
  allowCustomModel: boolean().optional(),
33627
34509
  parentTaskId: string2().uuid().optional(),
33628
34510
  requestedByUserId: string2().optional(),
33629
- outputSchema: record2(string2(), unknown()).optional()
34511
+ outputSchema: record2(string2(), unknown()).optional(),
34512
+ allowRedelegation: boolean().optional()
33630
34513
  });
33631
34514
  var scriptRunCreatedSchema = object2({
33632
34515
  id: string2().uuid(),
@@ -33792,9 +34675,41 @@ var agentTaskRoute = route({
33792
34675
  description: "Agent task created or still running",
33793
34676
  schema: object2({ taskId: string2(), status: AgentTaskStatusSchema })
33794
34677
  },
33795
- 404: { description: "Script run not found" }
34678
+ 403: {
34679
+ description: "Script run belongs to another agent, or the run's agent may not create a child task under parentTaskId"
34680
+ },
34681
+ 404: { description: "Script run not found" },
34682
+ 409: { description: "Agent task failed, was cancelled, or was superseded" },
34683
+ 422: { description: "Blocked by the follow-up re-delegation guard" }
33796
34684
  }
33797
34685
  });
34686
+ async function stepParentRefusal(runAgentId, parentTaskId) {
34687
+ const parentTask = await getTaskById2(parentTaskId);
34688
+ if (!parentTask)
34689
+ return null;
34690
+ const runAgent = await getAgentById2(runAgentId);
34691
+ const decision = can({
34692
+ principal: { kind: "agent", agentId: runAgentId, isLead: runAgent?.isLead ?? false },
34693
+ verb: "task.parent.attach",
34694
+ resource: {
34695
+ kind: "task",
34696
+ taskId: parentTask.id,
34697
+ requestedByUserId: parentTask.requestedByUserId,
34698
+ creatorAgentId: parentTask.creatorAgentId,
34699
+ agentId: parentTask.agentId
34700
+ },
34701
+ source: "http"
34702
+ });
34703
+ return decision.allow ? null : `You don't have context for parent task ${parentTaskId}. Only its assignee, its creator, or a lead can create a child task under it.`;
34704
+ }
34705
+ async function resolveRunSourceTaskId(req, agentId) {
34706
+ const raw = req.headers["x-source-task-id"];
34707
+ const sourceTaskId = Array.isArray(raw) ? raw[0] : raw;
34708
+ if (!sourceTaskId)
34709
+ return;
34710
+ const task = await getTaskById2(sourceTaskId);
34711
+ return task?.agentId === agentId ? task.id : undefined;
34712
+ }
33798
34713
  async function requireAgent(res, agentId) {
33799
34714
  if (!agentId) {
33800
34715
  jsonError(res, "X-Agent-ID required for script runs API", 400);
@@ -33872,6 +34787,7 @@ async function handleScriptRuns(req, res, pathSegments, queryParams, agentId) {
33872
34787
  }
33873
34788
  }
33874
34789
  const cap = scriptRunConcurrencyCap();
34790
+ const sourceTaskId = await resolveRunSourceTaskId(req, agent.id);
33875
34791
  const creation = await getDbClient2().transaction(async () => {
33876
34792
  if (await countActiveScriptRuns2() >= cap)
33877
34793
  return null;
@@ -33883,6 +34799,7 @@ async function handleScriptRuns(req, res, pathSegments, queryParams, agentId) {
33883
34799
  scriptName: parsed.body.scriptName,
33884
34800
  idempotencyKey: parsed.body.idempotencyKey,
33885
34801
  requestedByUserId: parsed.body.requestedByUserId,
34802
+ sourceTaskId,
33886
34803
  createdBy: parsed.body.requestedByUserId
33887
34804
  });
33888
34805
  });
@@ -34079,9 +34996,22 @@ async function handleScriptRuns(req, res, pathSegments, queryParams, agentId) {
34079
34996
  jsonError(res, "Script run not found", 404);
34080
34997
  return true;
34081
34998
  }
34999
+ if (agentId !== run.agentId) {
35000
+ jsonError(res, "Script run belongs to another agent", 403);
35001
+ return true;
35002
+ }
35003
+ if (parsed.body.parentTaskId) {
35004
+ const refusal = await stepParentRefusal(run.agentId, parsed.body.parentTaskId);
35005
+ if (refusal) {
35006
+ jsonError(res, refusal, 403);
35007
+ return true;
35008
+ }
35009
+ }
34082
35010
  const contextKey = `script-run:${run.id}:${parsed.body.stepKey}`;
34083
35011
  let task = await getLatestScriptRunStepTaskByContextKey2(contextKey);
35012
+ let dispatchedHere = false;
34084
35013
  if (!task) {
35014
+ const taskDescription = parsed.body.template ?? parsed.body.task ?? parsed.body.stepKey;
34085
35015
  const modelError = await explicitModelErrorForAgent({
34086
35016
  model: parsed.body.model,
34087
35017
  allowCustomModel: parsed.body.allowCustomModel,
@@ -34091,25 +35021,62 @@ async function handleScriptRuns(req, res, pathSegments, queryParams, agentId) {
34091
35021
  jsonError(res, modelError, 400);
34092
35022
  return true;
34093
35023
  }
35024
+ const followUpThread = await followUpThreadForSourceTask(run.sourceTaskId);
35025
+ let dispatched;
34094
35026
  try {
34095
- task = await createTaskExtended2(parsed.body.template ?? parsed.body.task ?? parsed.body.stepKey, {
34096
- agentId: parsed.body.agentId,
34097
- routingReason: parsed.body.routingReason ?? (parsed.body.agentId ? "human_pinned" : undefined),
34098
- routingNote: parsed.body.routingNote,
34099
- routingSource: parsed.body.routingReason ? "declared" : parsed.body.agentId ? "engine_default" : undefined,
34100
- tags: parsed.body.tags,
34101
- priority: parsed.body.priority,
34102
- dependsOn: parsed.body.dependsOn,
34103
- offeredTo: parsed.body.offerMode ? parsed.body.agentId : undefined,
34104
- taskType: "script-run-step",
34105
- source: "mcp",
34106
- dir: parsed.body.dir,
34107
- vcsRepo: parsed.body.vcsRepo,
34108
- model: parsed.body.model,
34109
- parentTaskId: parsed.body.parentTaskId,
34110
- requestedByUserId: parsed.body.requestedByUserId ?? run.requestedByUserId,
34111
- outputSchema: parsed.body.outputSchema,
34112
- contextKey
35027
+ dispatched = await getDbClient2().transaction(async () => {
35028
+ const replayed = await getLatestScriptRunStepTaskByContextKey2(contextKey);
35029
+ if (replayed)
35030
+ return { task: replayed };
35031
+ let override;
35032
+ if (followUpThread) {
35033
+ const decision = await getScriptRunFollowUpGuard2(run.id);
35034
+ if (decision !== "passed") {
35035
+ const blocked = decision === null ? await evaluateFollowUpRedelegation({
35036
+ ...followUpThread,
35037
+ creatorAgentId: run.agentId,
35038
+ taskDescription,
35039
+ targetAgentId: parsed.body.agentId
35040
+ }) : {
35041
+ rule: decision,
35042
+ message: `Blocked by the follow-up re-delegation guard (${decision} rule): an earlier step of this script run was blocked, and a run counts as one dispatch. If it must run, pass allowRedelegation: true.`
35043
+ };
35044
+ if (blocked && !parsed.body.allowRedelegation) {
35045
+ if (decision === null)
35046
+ await setScriptRunFollowUpGuard2(run.id, blocked.rule);
35047
+ return { blocked };
35048
+ }
35049
+ override = blocked?.rule;
35050
+ await setScriptRunFollowUpGuard2(run.id, "passed");
35051
+ }
35052
+ }
35053
+ const created = await createTaskExtended2(taskDescription, {
35054
+ agentId: parsed.body.agentId,
35055
+ routingReason: parsed.body.routingReason ?? (parsed.body.agentId ? "human_pinned" : undefined),
35056
+ routingNote: parsed.body.routingNote,
35057
+ routingSource: parsed.body.routingReason ? "declared" : parsed.body.agentId ? "engine_default" : undefined,
35058
+ tags: parsed.body.tags,
35059
+ priority: parsed.body.priority,
35060
+ dependsOn: parsed.body.dependsOn,
35061
+ offeredTo: parsed.body.offerMode ? parsed.body.agentId : undefined,
35062
+ taskType: "script-run-step",
35063
+ source: "mcp",
35064
+ creatorAgentId: run.agentId,
35065
+ sourceTaskId: run.sourceTaskId,
35066
+ ...followUpThread ? {
35067
+ slackChannelId: followUpThread.channelId,
35068
+ slackThreadTs: followUpThread.threadTs,
35069
+ slackUserId: followUpThread.userId
35070
+ } : {},
35071
+ dir: parsed.body.dir,
35072
+ vcsRepo: parsed.body.vcsRepo,
35073
+ model: parsed.body.model,
35074
+ parentTaskId: parsed.body.parentTaskId,
35075
+ requestedByUserId: parsed.body.requestedByUserId ?? run.requestedByUserId,
35076
+ outputSchema: parsed.body.outputSchema,
35077
+ contextKey
35078
+ });
35079
+ return { task: created, created: true, override };
34113
35080
  });
34114
35081
  } catch (error) {
34115
35082
  if (error instanceof ExtensionAgentAssignmentError2) {
@@ -34118,6 +35085,22 @@ async function handleScriptRuns(req, res, pathSegments, queryParams, agentId) {
34118
35085
  }
34119
35086
  throw error;
34120
35087
  }
35088
+ if (dispatched.override) {
35089
+ console.log(`[script-runs] follow-up re-delegation override: rule=${dispatched.override} runId=${run.id} creatorAgentId=${run.agentId} sourceTaskId=${run.sourceTaskId} thread=${followUpThread?.channelId}/${followUpThread?.threadTs}`);
35090
+ }
35091
+ if (!dispatched.task) {
35092
+ json(res, { error: dispatched.blocked.message, rule: dispatched.blocked.rule }, 422);
35093
+ return true;
35094
+ }
35095
+ task = dispatched.task;
35096
+ dispatchedHere = dispatched.created === true;
35097
+ }
35098
+ if (!dispatchedHere && task.parentTaskId) {
35099
+ const refusal = await stepParentRefusal(run.agentId, task.parentTaskId);
35100
+ if (refusal) {
35101
+ jsonError(res, refusal, 403);
35102
+ return true;
35103
+ }
34121
35104
  }
34122
35105
  const deadline = Date.now() + 30000;
34123
35106
  while (Date.now() < deadline) {
@@ -42912,9 +43895,10 @@ var httpServer = createHttpServer(async (req, res) => {
42912
43895
  });
42913
43896
  });
42914
43897
  var detachRealtime = attachRealtimeTransport(httpServer);
42915
- var { attachControllerTransport } = await import("./controllers-connect-pp5jnxvc.js");
43898
+ var { attachControllerTransport } = await import("./controllers-connect-c6nm70kg.js");
42916
43899
  var detachControllers = attachControllerTransport(httpServer);
42917
43900
  var stopWorkerNudges = startWorkerNudgeListener();
43901
+ var taskAutoTitles = startTaskAutoTitleListener();
42918
43902
  var stopRoomDeletion = realtimeBus.subscribe("room:namespace-deleted", (namespace) => {
42919
43903
  Promise.resolve(removeNamespaceRooms(String(namespace))).catch((error) => console.error("[rooms] Deletion failed:", scrubSecrets(String(error))));
42920
43904
  });
@@ -42922,6 +43906,7 @@ globalState.__closeRealtime = () => {
42922
43906
  detachRealtime();
42923
43907
  detachControllers();
42924
43908
  stopWorkerNudges();
43909
+ taskAutoTitles.stop();
42925
43910
  stopRoomDeletion();
42926
43911
  };
42927
43912
  globalState.__httpServer = httpServer;
@@ -42941,7 +43926,7 @@ async function shutdown() {
42941
43926
  sessionsProcessed: getServerSessionsProcessed()
42942
43927
  });
42943
43928
  if (hasCapability("scheduling")) {
42944
- const { stopScheduler } = await import("./index-5r71rf98.js");
43929
+ const { stopScheduler } = await import("./index-xrz7te8h.js");
42945
43930
  stopScheduler();
42946
43931
  }
42947
43932
  stopHeartbeat2();
@@ -42953,7 +43938,7 @@ async function shutdown() {
42953
43938
  await stopSlackApp2();
42954
43939
  await stopChatSdk();
42955
43940
  if (!isEnvFlagEnabled("OAUTH_KEEPALIVE_DISABLE", false)) {
42956
- const { stopOAuthKeepalive } = await import("./keepalive-6cf311t5.js");
43941
+ const { stopOAuthKeepalive } = await import("./keepalive-x060nt9p.js");
42957
43942
  await stopOAuthKeepalive();
42958
43943
  }
42959
43944
  stopOAuthPendingGc();
@@ -43035,21 +44020,21 @@ try {
43035
44020
  console.warn("[startup] CAPABILITIES upgrade seed failed (non-fatal):", err);
43036
44021
  }
43037
44022
  try {
43038
- const { ensurePricingSeeded } = await import("./boot-seeds-aykx51v3.js");
44023
+ const { ensurePricingSeeded } = await import("./boot-seeds-5cm6ambd.js");
43039
44024
  ensurePricingSeeded();
43040
- const { startPricingRefreshLoop } = await import("./pricing-refresh-83drrnxj.js");
44025
+ const { startPricingRefreshLoop } = await import("./pricing-refresh-3pmre11v.js");
43041
44026
  startPricingRefreshLoop();
43042
44027
  } catch (err) {
43043
44028
  console.error("[startup] Failed to seed pricing rows:", err);
43044
44029
  }
43045
44030
  try {
43046
- const { ensureModelProfilesSeeded } = await import("./boot-seeds-aykx51v3.js");
44031
+ const { ensureModelProfilesSeeded } = await import("./boot-seeds-5cm6ambd.js");
43047
44032
  await ensureModelProfilesSeeded();
43048
44033
  } catch (err) {
43049
44034
  console.error("[startup] Failed to seed model profiles:", err);
43050
44035
  }
43051
44036
  try {
43052
- const { ensureRbacSeeded } = await import("./boot-seeds-aykx51v3.js");
44037
+ const { ensureRbacSeeded } = await import("./boot-seeds-5cm6ambd.js");
43053
44038
  ensureRbacSeeded();
43054
44039
  } catch (err) {
43055
44040
  console.error("[startup] Failed to sync RBAC seed rows:", err);
@@ -43057,7 +44042,7 @@ try {
43057
44042
  throw err;
43058
44043
  }
43059
44044
  try {
43060
- const { runAllSeeders } = await import("./index-7v51awbn.js");
44045
+ const { runAllSeeders } = await import("./index-nh3wyqdt.js");
43061
44046
  await runAllSeeders({ scriptEmbeddingMode: "skip" });
43062
44047
  } catch (err) {
43063
44048
  console.error("[startup] Failed to seed built-in entities:", err);
@@ -43120,26 +44105,26 @@ httpServer.listen(port, async () => {
43120
44105
  await initWorkflows2();
43121
44106
  await startScriptRunSupervisor(getMcpBaseUrl());
43122
44107
  if (hasCapability("scheduling")) {
43123
- const { startScheduler } = await import("./index-5r71rf98.js");
43124
- const { getExecutorRegistry } = await import("./index-spp0ra5c.js");
44108
+ const { startScheduler } = await import("./index-xrz7te8h.js");
44109
+ const { getExecutorRegistry } = await import("./index-a8phxqnk.js");
43125
44110
  const intervalMs = Number(process.env.SCHEDULER_INTERVAL_MS) || 1e4;
43126
44111
  startScheduler(getExecutorRegistry(), intervalMs, {
43127
44112
  runId: globalState.__runId
43128
44113
  });
43129
44114
  }
43130
44115
  if (!isEnvFlagEnabled("HEARTBEAT_DISABLE", false)) {
43131
- const { startHeartbeat } = await import("./index-anmwxs87.js");
44116
+ const { startHeartbeat } = await import("./index-k6h00t4c.js");
43132
44117
  const heartbeatMs = Number(process.env.HEARTBEAT_INTERVAL_MS) || 90000;
43133
44118
  startHeartbeat(heartbeatMs);
43134
44119
  }
43135
44120
  startPoolRouting();
43136
44121
  startRuntimeSupervisor();
43137
44122
  if (!isEnvFlagEnabled("OAUTH_KEEPALIVE_DISABLE", false)) {
43138
- const { startOAuthKeepalive } = await import("./keepalive-6cf311t5.js");
44123
+ const { startOAuthKeepalive } = await import("./keepalive-x060nt9p.js");
43139
44124
  startOAuthKeepalive();
43140
44125
  }
43141
44126
  if (!isEnvFlagEnabled("OAUTH_REFRESH_SWEEP_DISABLE", false)) {
43142
- const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-3h0dfw1k.js");
44127
+ const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-fckc4ar5.js");
43143
44128
  startOAuthRefreshSweep();
43144
44129
  }
43145
44130
  startOAuthPendingGc();
@@ -43148,16 +44133,16 @@ httpServer.listen(port, async () => {
43148
44133
  await startDbRetention();
43149
44134
  startHumanFreeDrain();
43150
44135
  startTaskSearchBackfill();
43151
- import("./embedding-space-1z0mbg95.js").then(({ runEmbeddingMaintenance, setDeploymentEnvReader }) => {
44136
+ import("./embedding-space-0jepb239.js").then(({ runEmbeddingMaintenance, setDeploymentEnvReader }) => {
43152
44137
  setDeploymentEnvReader(getDeploymentEnvValue);
43153
44138
  return runEmbeddingMaintenance({ backfill: true });
43154
44139
  }).catch((err) => {
43155
44140
  console.error("[embedding-space] startup maintenance failed (non-fatal):", err);
43156
44141
  });
43157
- import("./boot-scrub-sweep-nd938kyf.js").then(({ runBootScrubSweep }) => runBootScrubSweep()).catch((err) => {
44142
+ import("./boot-scrub-sweep-yjpdj7s1.js").then(({ runBootScrubSweep }) => runBootScrubSweep()).catch((err) => {
43158
44143
  console.error("[boot-scrub-sweep] startup scrub failed (non-fatal):", err);
43159
44144
  });
43160
- import("./session-source-backfill-qh07xr8g.js").then(({ runSessionSourceBackfill }) => runSessionSourceBackfill()).catch((err) => {
44145
+ import("./session-source-backfill-08xvv0sm.js").then(({ runSessionSourceBackfill }) => runSessionSourceBackfill()).catch((err) => {
43161
44146
  console.error("[session-source-backfill] startup run failed (non-fatal):", err);
43162
44147
  });
43163
44148
  }).on("error", (err) => {