agor-live 0.21.2 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. package/dist/cli/commands/branch/env/restart.js +1 -1
  2. package/dist/cli/commands/branch/env/start.js +1 -1
  3. package/dist/cli/commands/branch/env/stop.js +1 -1
  4. package/dist/core/api/index.cjs +5 -1
  5. package/dist/core/api/index.d.ts +6 -1
  6. package/dist/core/api/index.d.ts.map +1 -1
  7. package/dist/core/api/index.js +5 -1
  8. package/dist/core/claude/index.cjs +162 -14
  9. package/dist/core/claude/index.js +166 -18
  10. package/dist/core/client/index.cjs +43 -3
  11. package/dist/core/client/index.js +37 -3
  12. package/dist/core/config/browser.cjs +2 -2
  13. package/dist/core/config/browser.js +2 -2
  14. package/dist/core/config/config-manager.d.ts.map +1 -1
  15. package/dist/core/config/constants.d.ts +1 -1
  16. package/dist/core/config/index.cjs +174 -20
  17. package/dist/core/config/index.js +178 -24
  18. package/dist/core/config/types.d.ts +8 -0
  19. package/dist/core/config/types.d.ts.map +1 -1
  20. package/dist/core/db/index.cjs +495 -86
  21. package/dist/core/db/index.js +482 -75
  22. package/dist/core/db/repositories/artifacts.d.ts.map +1 -1
  23. package/dist/core/db/repositories/branches.d.ts +13 -1
  24. package/dist/core/db/repositories/branches.d.ts.map +1 -1
  25. package/dist/core/db/repositories/gateway-channels.d.ts.map +1 -1
  26. package/dist/core/db/repositories/index.d.ts +1 -0
  27. package/dist/core/db/repositories/index.d.ts.map +1 -1
  28. package/dist/core/db/repositories/session-relationships.d.ts +30 -0
  29. package/dist/core/db/repositories/session-relationships.d.ts.map +1 -0
  30. package/dist/core/db/repositories/users.d.ts +11 -0
  31. package/dist/core/db/repositories/users.d.ts.map +1 -1
  32. package/dist/core/db/schema.d.ts +421 -4
  33. package/dist/core/db/schema.d.ts.map +1 -1
  34. package/dist/core/db/schema.postgres.d.ts +226 -2
  35. package/dist/core/db/schema.postgres.d.ts.map +1 -1
  36. package/dist/core/db/schema.sqlite.d.ts +228 -2
  37. package/dist/core/db/schema.sqlite.d.ts.map +1 -1
  38. package/dist/core/drizzle/postgres/0050_artifact_source_session.sql +3 -0
  39. package/dist/core/drizzle/postgres/0051_session_relationships.sql +26 -0
  40. package/dist/core/drizzle/postgres/meta/_journal.json +14 -0
  41. package/dist/core/drizzle/sqlite/0059_artifact_source_session.sql +2 -0
  42. package/dist/core/drizzle/sqlite/0060_session_relationships.sql +23 -0
  43. package/dist/core/drizzle/sqlite/meta/_journal.json +14 -0
  44. package/dist/core/gateway/connector-registry.d.ts.map +1 -1
  45. package/dist/core/gateway/connector.d.ts +22 -0
  46. package/dist/core/gateway/connector.d.ts.map +1 -1
  47. package/dist/core/gateway/connectors/slack.d.ts +35 -3
  48. package/dist/core/gateway/connectors/slack.d.ts.map +1 -1
  49. package/dist/core/gateway/connectors/teams.d.ts +107 -0
  50. package/dist/core/gateway/connectors/teams.d.ts.map +1 -0
  51. package/dist/core/gateway/context.d.ts.map +1 -1
  52. package/dist/core/gateway/index.cjs +552 -52
  53. package/dist/core/gateway/index.d.ts +3 -2
  54. package/dist/core/gateway/index.d.ts.map +1 -1
  55. package/dist/core/gateway/index.js +544 -52
  56. package/dist/core/gateway/system-message.d.ts +21 -0
  57. package/dist/core/gateway/system-message.d.ts.map +1 -1
  58. package/dist/core/index.cjs +616 -127
  59. package/dist/core/index.js +597 -116
  60. package/dist/core/mcp/index.cjs +146 -9
  61. package/dist/core/mcp/index.js +146 -9
  62. package/dist/core/mcp/template-resolver.d.ts.map +1 -1
  63. package/dist/core/seed/index.cjs +375 -59
  64. package/dist/core/seed/index.js +378 -62
  65. package/dist/core/sessions/index.cjs +19 -0
  66. package/dist/core/sessions/index.js +19 -0
  67. package/dist/core/templates/agor-system-prompt.md +21 -53
  68. package/dist/core/templates/session-context.cjs +2 -73
  69. package/dist/core/templates/session-context.d.ts +9 -53
  70. package/dist/core/templates/session-context.d.ts.map +1 -1
  71. package/dist/core/templates/session-context.js +2 -72
  72. package/dist/core/tools/mcp/jwt-auth.cjs +2 -20
  73. package/dist/core/tools/mcp/jwt-auth.d.ts.map +1 -1
  74. package/dist/core/tools/mcp/jwt-auth.js +2 -20
  75. package/dist/core/tools/mcp/oauth-mcp-transport.cjs +2 -15
  76. package/dist/core/tools/mcp/oauth-mcp-transport.d.ts.map +1 -1
  77. package/dist/core/tools/mcp/oauth-mcp-transport.js +2 -15
  78. package/dist/core/tools/mcp/oauth-refresh.cjs +167 -19
  79. package/dist/core/tools/mcp/oauth-refresh.js +167 -19
  80. package/dist/core/types/artifact.d.ts +5 -1
  81. package/dist/core/types/artifact.d.ts.map +1 -1
  82. package/dist/core/types/branch.d.ts +14 -0
  83. package/dist/core/types/branch.d.ts.map +1 -1
  84. package/dist/core/types/gateway.d.ts +1 -1
  85. package/dist/core/types/gateway.d.ts.map +1 -1
  86. package/dist/core/types/id.d.ts +1 -0
  87. package/dist/core/types/id.d.ts.map +1 -1
  88. package/dist/core/types/index.cjs +36 -0
  89. package/dist/core/types/index.js +30 -0
  90. package/dist/core/types/session.d.ts +65 -1
  91. package/dist/core/types/session.d.ts.map +1 -1
  92. package/dist/core/types/task.d.ts +9 -0
  93. package/dist/core/types/task.d.ts.map +1 -1
  94. package/dist/core/unix/index.cjs +371 -55
  95. package/dist/core/unix/index.js +374 -58
  96. package/dist/core/unix/unix-integration-service.d.ts +10 -7
  97. package/dist/core/unix/unix-integration-service.d.ts.map +1 -1
  98. package/dist/core/utils/permission-mode-mapper.cjs +19 -0
  99. package/dist/core/utils/permission-mode-mapper.js +19 -0
  100. package/dist/daemon/declarations.d.ts +7 -0
  101. package/dist/daemon/declarations.d.ts.map +1 -1
  102. package/dist/daemon/hooks/gateway-route.d.ts.map +1 -1
  103. package/dist/daemon/hooks/gateway-route.js +53 -1
  104. package/dist/daemon/index.js +3760 -2107
  105. package/dist/daemon/main.js +3760 -2107
  106. package/dist/daemon/mcp/server.js +155 -17
  107. package/dist/daemon/mcp/tools/analytics.js +6 -7
  108. package/dist/daemon/mcp/tools/artifacts.d.ts.map +1 -1
  109. package/dist/daemon/mcp/tools/artifacts.js +7 -7
  110. package/dist/daemon/mcp/tools/boards.js +6 -7
  111. package/dist/daemon/mcp/tools/branches.js +6 -7
  112. package/dist/daemon/mcp/tools/card-types.js +6 -7
  113. package/dist/daemon/mcp/tools/cards.js +6 -7
  114. package/dist/daemon/mcp/tools/environment.d.ts.map +1 -1
  115. package/dist/daemon/mcp/tools/environment.js +19 -12
  116. package/dist/daemon/mcp/tools/knowledge.js +6 -7
  117. package/dist/daemon/mcp/tools/mcp-servers.js +6 -7
  118. package/dist/daemon/mcp/tools/messages.js +6 -7
  119. package/dist/daemon/mcp/tools/proxies.js +6 -7
  120. package/dist/daemon/mcp/tools/repos.js +6 -7
  121. package/dist/daemon/mcp/tools/schedules.js +6 -7
  122. package/dist/daemon/mcp/tools/search.js +6 -7
  123. package/dist/daemon/mcp/tools/sessions.d.ts.map +1 -1
  124. package/dist/daemon/mcp/tools/sessions.js +140 -11
  125. package/dist/daemon/mcp/tools/tasks.js +6 -7
  126. package/dist/daemon/mcp/tools/users.js +6 -7
  127. package/dist/daemon/mcp/tools/widgets.js +7 -8
  128. package/dist/daemon/register-hooks.d.ts +5 -1
  129. package/dist/daemon/register-hooks.d.ts.map +1 -1
  130. package/dist/daemon/register-hooks.js +404 -179
  131. package/dist/daemon/register-routes.d.ts.map +1 -1
  132. package/dist/daemon/register-routes.js +360 -162
  133. package/dist/daemon/register-services.d.ts.map +1 -1
  134. package/dist/daemon/register-services.js +1928 -671
  135. package/dist/daemon/services/artifacts.d.ts +10 -1
  136. package/dist/daemon/services/artifacts.d.ts.map +1 -1
  137. package/dist/daemon/services/artifacts.js +25 -1
  138. package/dist/daemon/services/branches.d.ts +11 -1
  139. package/dist/daemon/services/branches.d.ts.map +1 -1
  140. package/dist/daemon/services/branches.js +470 -184
  141. package/dist/daemon/services/claude-models.js +879 -339
  142. package/dist/daemon/services/gateway.d.ts +58 -2
  143. package/dist/daemon/services/gateway.d.ts.map +1 -1
  144. package/dist/daemon/services/gateway.js +590 -47
  145. package/dist/daemon/services/groups.d.ts +2 -0
  146. package/dist/daemon/services/groups.d.ts.map +1 -1
  147. package/dist/daemon/services/groups.js +56 -0
  148. package/dist/daemon/services/mcp-servers.d.ts.map +1 -1
  149. package/dist/daemon/services/mcp-servers.js +0 -6
  150. package/dist/daemon/services/scheduler.d.ts.map +1 -1
  151. package/dist/daemon/services/scheduler.js +6 -2
  152. package/dist/daemon/services/sessions.d.ts +11 -3
  153. package/dist/daemon/services/sessions.d.ts.map +1 -1
  154. package/dist/daemon/services/sessions.js +68 -7
  155. package/dist/daemon/services/tasks.d.ts +13 -2
  156. package/dist/daemon/services/tasks.d.ts.map +1 -1
  157. package/dist/daemon/services/tasks.js +42 -26
  158. package/dist/daemon/startup.js +6 -2
  159. package/dist/daemon/utils/session-stop.d.ts +43 -0
  160. package/dist/daemon/utils/session-stop.d.ts.map +1 -0
  161. package/dist/daemon/utils/session-stop.js +102 -0
  162. package/dist/daemon/utils/session-task-state.d.ts +7 -2
  163. package/dist/daemon/utils/session-task-state.d.ts.map +1 -1
  164. package/dist/daemon/utils/session-task-state.js +9 -3
  165. package/dist/daemon/utils/session-tasks.d.ts +4 -4
  166. package/dist/daemon/utils/session-tasks.d.ts.map +1 -1
  167. package/dist/daemon/utils/session-tasks.js +4 -8
  168. package/dist/executor/commands/environment.d.ts +13 -0
  169. package/dist/executor/commands/environment.d.ts.map +1 -0
  170. package/dist/executor/commands/environment.js +287 -0
  171. package/dist/executor/commands/index.d.ts.map +1 -1
  172. package/dist/executor/commands/index.js +5 -1
  173. package/dist/executor/commands/unix.d.ts +8 -1
  174. package/dist/executor/commands/unix.d.ts.map +1 -1
  175. package/dist/executor/commands/unix.js +157 -2
  176. package/dist/executor/payload-types.d.ts +201 -5
  177. package/dist/executor/payload-types.d.ts.map +1 -1
  178. package/dist/executor/payload-types.js +98 -0
  179. package/dist/executor/sdk-handlers/base/mcp-scoping.d.ts.map +1 -1
  180. package/dist/executor/sdk-handlers/base/mcp-scoping.js +14 -0
  181. package/dist/executor/sdk-handlers/claude/message-processor.d.ts.map +1 -1
  182. package/dist/executor/sdk-handlers/claude/message-processor.js +0 -1
  183. package/dist/executor/sdk-handlers/claude/query-builder.d.ts +1 -0
  184. package/dist/executor/sdk-handlers/claude/query-builder.d.ts.map +1 -1
  185. package/dist/executor/sdk-handlers/claude/query-builder.js +91 -39
  186. package/dist/executor/sdk-handlers/codex/prompt-service.d.ts +12 -5
  187. package/dist/executor/sdk-handlers/codex/prompt-service.d.ts.map +1 -1
  188. package/dist/executor/sdk-handlers/codex/prompt-service.js +72 -30
  189. package/dist/executor/sdk-handlers/copilot/prompt-service.d.ts +2 -4
  190. package/dist/executor/sdk-handlers/copilot/prompt-service.d.ts.map +1 -1
  191. package/dist/executor/sdk-handlers/copilot/prompt-service.js +4 -13
  192. package/dist/executor/sdk-handlers/gemini/prompt-service.d.ts +2 -4
  193. package/dist/executor/sdk-handlers/gemini/prompt-service.d.ts.map +1 -1
  194. package/dist/executor/sdk-handlers/gemini/prompt-service.js +4 -13
  195. package/dist/ui/assets/App-DcEY8Ota.js +3 -0
  196. package/dist/ui/assets/App-DcEY8Ota.js.gz +0 -0
  197. package/dist/ui/assets/{ArtifactConsentModal-ParNk5kW.js → ArtifactConsentModal-CiCbK9iv.js} +1 -1
  198. package/dist/ui/assets/ArtifactConsentModal-CiCbK9iv.js.gz +0 -0
  199. package/dist/ui/assets/ArtifactFullscreenPage-CfsTEGKd.js +9 -0
  200. package/dist/ui/assets/ArtifactFullscreenPage-CfsTEGKd.js.gz +0 -0
  201. package/dist/ui/assets/AutocompleteTextarea-BAFFH_5e.js +18 -0
  202. package/dist/ui/assets/AutocompleteTextarea-BAFFH_5e.js.gz +0 -0
  203. package/dist/ui/assets/BoardObjectNodes-D-O6bZIG.js +34 -0
  204. package/dist/ui/assets/BoardObjectNodes-D-O6bZIG.js.gz +0 -0
  205. package/dist/ui/assets/{CodeEditor.inner-D51Z_CLQ.js → CodeEditor.inner-DBgsP4tn.js} +2 -2
  206. package/dist/ui/assets/CodeEditor.inner-DBgsP4tn.js.gz +0 -0
  207. package/dist/ui/assets/ConversationView-CUWR0gR6.js +1 -0
  208. package/dist/ui/assets/ConversationView-CUWR0gR6.js.gz +0 -0
  209. package/dist/ui/assets/KnowledgePage-B2bzlXfn.js +24 -0
  210. package/dist/ui/assets/KnowledgePage-B2bzlXfn.js.gz +0 -0
  211. package/dist/ui/assets/MarketingScreenshotPage-9Qd7eZsm.css +1 -0
  212. package/dist/ui/assets/MarketingScreenshotPage-zv5RUCuV.js +143 -0
  213. package/dist/ui/assets/MarketingScreenshotPage-zv5RUCuV.js.gz +0 -0
  214. package/dist/ui/assets/MobileApp-VgVnsnsN.js +1 -0
  215. package/dist/ui/assets/MobileApp-VgVnsnsN.js.gz +0 -0
  216. package/dist/ui/assets/SessionCanvas-f1-1Gbcw.js +20 -0
  217. package/dist/ui/assets/SessionCanvas-f1-1Gbcw.js.gz +0 -0
  218. package/dist/ui/assets/{App-BAdBsEnV.css → SessionCanvas-mEmYGZhC.css} +1 -1
  219. package/dist/ui/assets/SessionCanvas-mEmYGZhC.css.gz +0 -0
  220. package/dist/ui/assets/{StreamdownDemoPage-B9wbgp2s.js → StreamdownDemoPage-wzWaqWwr.js} +1 -1
  221. package/dist/ui/assets/StreamdownDemoPage-wzWaqWwr.js.gz +0 -0
  222. package/dist/ui/assets/{ThemeSwitcher-ubn6IOz9.js → ThemeSwitcher-Dly2y9pi.js} +1 -1
  223. package/dist/ui/assets/ThemeSwitcher-Dly2y9pi.js.gz +0 -0
  224. package/dist/ui/assets/antd-CfbbHJOz.js +401 -0
  225. package/dist/ui/assets/antd-CfbbHJOz.js.gz +0 -0
  226. package/dist/ui/assets/architecture-U656AL7Q-CykGFbQU.js +1 -0
  227. package/dist/ui/assets/{architectureDiagram-VXUJARFQ-ChmZt3zk.js → architectureDiagram-VXUJARFQ-C8HXAenz.js} +1 -1
  228. package/dist/ui/assets/architectureDiagram-VXUJARFQ-C8HXAenz.js.gz +0 -0
  229. package/dist/ui/assets/{blockDiagram-VD42YOAC-CzGHAHao.js → blockDiagram-VD42YOAC-BhZaEN19.js} +1 -1
  230. package/dist/ui/assets/blockDiagram-VD42YOAC-BhZaEN19.js.gz +0 -0
  231. package/dist/ui/assets/{c4Diagram-YG6GDRKO-DscJyaWN.js → c4Diagram-YG6GDRKO-Dk_UH-sY.js} +1 -1
  232. package/dist/ui/assets/c4Diagram-YG6GDRKO-Dk_UH-sY.js.gz +0 -0
  233. package/dist/ui/assets/channel-D6_nUWlW.js +1 -0
  234. package/dist/ui/assets/{chunk-4BX2VUAB-DoWpTvP8.js → chunk-4BX2VUAB-XprbG2TG.js} +1 -1
  235. package/dist/ui/assets/chunk-55IACEB6-ByzqIgSb.js +1 -0
  236. package/dist/ui/assets/{chunk-ABZYJK2D-RzDCrjE6.js → chunk-ABZYJK2D-BJcrryHK.js} +1 -1
  237. package/dist/ui/assets/chunk-ABZYJK2D-BJcrryHK.js.gz +0 -0
  238. package/dist/ui/assets/{chunk-AGHRB4JF-jidCS5Of.js → chunk-AGHRB4JF-DvxmfbM0.js} +1 -1
  239. package/dist/ui/assets/chunk-AGHRB4JF-DvxmfbM0.js.gz +0 -0
  240. package/dist/ui/assets/{chunk-ATLVNIR6-BEIIfJtC.js → chunk-ATLVNIR6-DbeJ0OrR.js} +1 -1
  241. package/dist/ui/assets/chunk-ATLVNIR6-DbeJ0OrR.js.gz +0 -0
  242. package/dist/ui/assets/{chunk-B4BG7PRW-B8b6dQQ2.js → chunk-B4BG7PRW-C53q2ggf.js} +1 -1
  243. package/dist/ui/assets/chunk-B4BG7PRW-C53q2ggf.js.gz +0 -0
  244. package/dist/ui/assets/{chunk-CVBHYZKI-D-mQAfrk.js → chunk-CVBHYZKI-B3EBSlb3.js} +1 -1
  245. package/dist/ui/assets/{chunk-DI55MBZ5-BfATX3V8.js → chunk-DI55MBZ5-vIyNEQN-.js} +1 -1
  246. package/dist/ui/assets/chunk-DI55MBZ5-vIyNEQN-.js.gz +0 -0
  247. package/dist/ui/assets/chunk-EXTU4WIE-B3ObkuOm.js +1 -0
  248. package/dist/ui/assets/{chunk-FMBD7UC4-fqXscNvc.js → chunk-FMBD7UC4-rddmfK-Z.js} +1 -1
  249. package/dist/ui/assets/{chunk-HN2XXSSU-BCHvD80g.js → chunk-HN2XXSSU-Dttqcg3b.js} +1 -1
  250. package/dist/ui/assets/chunk-HN2XXSSU-Dttqcg3b.js.gz +0 -0
  251. package/dist/ui/assets/{chunk-JA3XYJ7Z-Cp6dqHnY.js → chunk-JA3XYJ7Z-DbNDev3D.js} +1 -1
  252. package/dist/ui/assets/chunk-JA3XYJ7Z-DbNDev3D.js.gz +0 -0
  253. package/dist/ui/assets/{chunk-JZLCHNYA-cKMooY3y.js → chunk-JZLCHNYA-EUmx2y4H.js} +1 -1
  254. package/dist/ui/assets/chunk-JZLCHNYA-EUmx2y4H.js.gz +0 -0
  255. package/dist/ui/assets/{chunk-MI3HLSF2-BlzO5wOE.js → chunk-MI3HLSF2-65n9Mkyc.js} +1 -1
  256. package/dist/ui/assets/chunk-MI3HLSF2-65n9Mkyc.js.gz +0 -0
  257. package/dist/ui/assets/chunk-N4CR4FBY-mv5koXqW.js +2 -0
  258. package/dist/ui/assets/chunk-N4CR4FBY-mv5koXqW.js.gz +0 -0
  259. package/dist/ui/assets/{chunk-QN33PNHL-DIHGQ_pd.js → chunk-QN33PNHL-DsRKK6NR.js} +1 -1
  260. package/dist/ui/assets/{chunk-QXUST7PY-C9l0muI0.js → chunk-QXUST7PY-BCYnMiS3.js} +1 -1
  261. package/dist/ui/assets/chunk-QXUST7PY-BCYnMiS3.js.gz +0 -0
  262. package/dist/ui/assets/chunk-QZHKN3VN-HucAw4xW.js +1 -0
  263. package/dist/ui/assets/{chunk-S3R3BYOJ-VJiLzt2o.js → chunk-S3R3BYOJ-CWMEa9Dc.js} +1 -1
  264. package/dist/ui/assets/chunk-S3R3BYOJ-CWMEa9Dc.js.gz +0 -0
  265. package/dist/ui/assets/{chunk-TZMSLE5B-DZwI0C_2.js → chunk-TZMSLE5B-BuQUQcTr.js} +1 -1
  266. package/dist/ui/assets/chunk-TZMSLE5B-BuQUQcTr.js.gz +0 -0
  267. package/dist/ui/assets/classDiagram-2ON5EDUG-CUT3rPTB.js +1 -0
  268. package/dist/ui/assets/classDiagram-v2-WZHVMYZB-CUT3rPTB.js +1 -0
  269. package/dist/ui/assets/{cose-bilkent-S5V4N54A-Ipik-oSD.js → cose-bilkent-S5V4N54A-CnPB3ARO.js} +1 -1
  270. package/dist/ui/assets/cose-bilkent-S5V4N54A-CnPB3ARO.js.gz +0 -0
  271. package/dist/ui/assets/cursor-QEb7m-rN.png +0 -0
  272. package/dist/ui/assets/{dagre-6UL2VRFP-BDpyWQnh.js → dagre-6UL2VRFP-DhS-k_Se.js} +1 -1
  273. package/dist/ui/assets/dagre-6UL2VRFP-DhS-k_Se.js.gz +0 -0
  274. package/dist/ui/assets/{dagre-CgA4KhUX.js → dagre-KgLoHEuy.js} +1 -1
  275. package/dist/ui/assets/dagre-KgLoHEuy.js.gz +0 -0
  276. package/dist/ui/assets/{diagram-PSM6KHXK-B4GRzxLJ.js → diagram-PSM6KHXK-BZg3MJmb.js} +1 -1
  277. package/dist/ui/assets/diagram-PSM6KHXK-BZg3MJmb.js.gz +0 -0
  278. package/dist/ui/assets/{diagram-QEK2KX5R-BWPW28XI.js → diagram-QEK2KX5R-BPCitvbo.js} +1 -1
  279. package/dist/ui/assets/diagram-QEK2KX5R-BPCitvbo.js.gz +0 -0
  280. package/dist/ui/assets/{diagram-S2PKOQOG-BIHhcGoV.js → diagram-S2PKOQOG-NW4uK6sx.js} +1 -1
  281. package/dist/ui/assets/diagram-S2PKOQOG-NW4uK6sx.js.gz +0 -0
  282. package/dist/ui/assets/{editor-C-HJ7Yw0.js → editor-CzFWIUw2.js} +1 -1
  283. package/dist/ui/assets/editor-CzFWIUw2.js.gz +0 -0
  284. package/dist/ui/assets/{emoji-D8F6B62m.js → emoji-Dkz4Zzv_.js} +1 -1
  285. package/dist/ui/assets/emoji-Dkz4Zzv_.js.gz +0 -0
  286. package/dist/ui/assets/{erDiagram-Q2GNP2WA-ubTaAFcK.js → erDiagram-Q2GNP2WA-me1fboaf.js} +1 -1
  287. package/dist/ui/assets/erDiagram-Q2GNP2WA-me1fboaf.js.gz +0 -0
  288. package/dist/ui/assets/{flowDiagram-NV44I4VS-BHLCTYjI.js → flowDiagram-NV44I4VS-DzE8dGsh.js} +1 -1
  289. package/dist/ui/assets/flowDiagram-NV44I4VS-DzE8dGsh.js.gz +0 -0
  290. package/dist/ui/assets/{ganttDiagram-LVOFAZNH-ClC3pay1.js → ganttDiagram-LVOFAZNH-CFQD09Mi.js} +2 -2
  291. package/dist/ui/assets/ganttDiagram-LVOFAZNH-CFQD09Mi.js.gz +0 -0
  292. package/dist/ui/assets/{gitGraph-F6HP7TQM-DghoobE6.js → gitGraph-F6HP7TQM-CfFE_uAC.js} +1 -1
  293. package/dist/ui/assets/{gitGraphDiagram-NY62KEGX-Clqpiswu.js → gitGraphDiagram-NY62KEGX-CaVoxU4C.js} +1 -1
  294. package/dist/ui/assets/gitGraphDiagram-NY62KEGX-CaVoxU4C.js.gz +0 -0
  295. package/dist/ui/assets/index-BN5_Qq7R.js +324 -0
  296. package/dist/ui/assets/index-BN5_Qq7R.js.gz +0 -0
  297. package/dist/ui/assets/index-DxuPq13l.css +1 -0
  298. package/dist/ui/assets/index-DxuPq13l.css.gz +0 -0
  299. package/dist/ui/assets/{info-NVLQJR56-0ZldEXPQ.js → info-NVLQJR56-i_xHYg3f.js} +1 -1
  300. package/dist/ui/assets/{infoDiagram-ER5ION4S-DMmPX-il.js → infoDiagram-ER5ION4S-2NL93b78.js} +1 -1
  301. package/dist/ui/assets/{journeyDiagram-XKPGCS4Q-CrVickA2.js → journeyDiagram-XKPGCS4Q-CZF-2DHU.js} +1 -1
  302. package/dist/ui/assets/journeyDiagram-XKPGCS4Q-CZF-2DHU.js.gz +0 -0
  303. package/dist/ui/assets/{kanban-definition-3W4ZIXB7-C_BsdHYL.js → kanban-definition-3W4ZIXB7-CfvJIOny.js} +1 -1
  304. package/dist/ui/assets/kanban-definition-3W4ZIXB7-CfvJIOny.js.gz +0 -0
  305. package/dist/ui/assets/{line-CfBP7Yic.js → line-DDv8kOJk.js} +1 -1
  306. package/dist/ui/assets/{linear-BsjageUB.js → linear-Daef-l29.js} +1 -1
  307. package/dist/ui/assets/linear-Daef-l29.js.gz +0 -0
  308. package/dist/ui/assets/{mermaid-parser.core-DZdP-NFq.js → mermaid-parser.core-CdK9QgYV.js} +2 -2
  309. package/dist/ui/assets/mermaid-parser.core-CdK9QgYV.js.gz +0 -0
  310. package/dist/ui/assets/{mermaid.core-TNrI0pHG.js → mermaid.core-D6GS9mU-.js} +3 -3
  311. package/dist/ui/assets/mermaid.core-D6GS9mU-.js.gz +0 -0
  312. package/dist/ui/assets/message-SqLqNYcv.js +36 -0
  313. package/dist/ui/assets/message-SqLqNYcv.js.gz +0 -0
  314. package/dist/ui/assets/{mindmap-definition-VGOIOE7T-BbmaUjMY.js → mindmap-definition-VGOIOE7T-Cb3QMflX.js} +1 -1
  315. package/dist/ui/assets/mindmap-definition-VGOIOE7T-Cb3QMflX.js.gz +0 -0
  316. package/dist/ui/assets/{packet-BFZMPI3H-D_ZhkXuT.js → packet-BFZMPI3H-Bm2uwz4i.js} +1 -1
  317. package/dist/ui/assets/{particles-Dv28pjOd.js → particles-DsJFOarW.js} +1 -1
  318. package/dist/ui/assets/particles-DsJFOarW.js.gz +0 -0
  319. package/dist/ui/assets/{pie-7BOR55EZ-Dn0Q3qNx.js → pie-7BOR55EZ-5i17tVnF.js} +1 -1
  320. package/dist/ui/assets/{pieDiagram-ADFJNKIX-BbyjfYu8.js → pieDiagram-ADFJNKIX-BxIwQWvw.js} +1 -1
  321. package/dist/ui/assets/pieDiagram-ADFJNKIX-BxIwQWvw.js.gz +0 -0
  322. package/dist/ui/assets/{quadrantDiagram-AYHSOK5B-Bc3GqMKz.js → quadrantDiagram-AYHSOK5B-B5HPe4ga.js} +1 -1
  323. package/dist/ui/assets/quadrantDiagram-AYHSOK5B-B5HPe4ga.js.gz +0 -0
  324. package/dist/ui/assets/{radar-NHE76QYJ-BHwoAy1q.js → radar-NHE76QYJ-BTn-tq0k.js} +1 -1
  325. package/dist/ui/assets/{reactflow-BVYPxNhc.js → reactflow-Bf74ngoo.js} +2 -2
  326. package/dist/ui/assets/reactflow-Bf74ngoo.js.gz +0 -0
  327. package/dist/ui/assets/{requirementDiagram-UZGBJVZJ-BQaKKL09.js → requirementDiagram-UZGBJVZJ-YfI6llkX.js} +1 -1
  328. package/dist/ui/assets/requirementDiagram-UZGBJVZJ-YfI6llkX.js.gz +0 -0
  329. package/dist/ui/assets/{sandpack-BQW_FQ7G.js → sandpack-D7koO5op.js} +1 -1
  330. package/dist/ui/assets/sandpack-D7koO5op.js.gz +0 -0
  331. package/dist/ui/assets/{sankeyDiagram-TZEHDZUN-DiJvDvhb.js → sankeyDiagram-TZEHDZUN-DOk_B10B.js} +1 -1
  332. package/dist/ui/assets/sankeyDiagram-TZEHDZUN-DOk_B10B.js.gz +0 -0
  333. package/dist/ui/assets/{sequenceDiagram-WL72ISMW-Dw32824o.js → sequenceDiagram-WL72ISMW-DAe4Um17.js} +1 -1
  334. package/dist/ui/assets/sequenceDiagram-WL72ISMW-DAe4Um17.js.gz +0 -0
  335. package/dist/ui/assets/{stateDiagram-FKZM4ZOC-BCOpNdHV.js → stateDiagram-FKZM4ZOC-CCesDu_C.js} +1 -1
  336. package/dist/ui/assets/stateDiagram-FKZM4ZOC-CCesDu_C.js.gz +0 -0
  337. package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-CMlIrsoO.js +1 -0
  338. package/dist/ui/assets/{syntax-VJrU5BEu.js → syntax-C-M-8jOU.js} +1 -1
  339. package/dist/ui/assets/syntax-C-M-8jOU.js.gz +0 -0
  340. package/dist/ui/assets/{theme-DZtFA8b4.js → theme-BQZdiqwv.js} +1 -1
  341. package/dist/ui/assets/{timeline-definition-IT6M3QCI-Jh_WZzXv.js → timeline-definition-IT6M3QCI-D6P5txjT.js} +1 -1
  342. package/dist/ui/assets/timeline-definition-IT6M3QCI-D6P5txjT.js.gz +0 -0
  343. package/dist/ui/assets/{treemap-KMMF4GRG-CPYIgjxE.js → treemap-KMMF4GRG-Bitm3gy4.js} +1 -1
  344. package/dist/ui/assets/{knowledgeRoutes-CivaUqha.js → useUserLocalStorage-Ckb8HsIw.js} +1 -1
  345. package/dist/ui/assets/useUserLocalStorage-Ckb8HsIw.js.gz +0 -0
  346. package/dist/ui/assets/{xychartDiagram-PRI3JC2R-CERc7Rdb.js → xychartDiagram-PRI3JC2R-CsybjUbd.js} +1 -1
  347. package/dist/ui/assets/xychartDiagram-PRI3JC2R-CsybjUbd.js.gz +0 -0
  348. package/dist/ui/index.html +13 -11
  349. package/dist/ui/index.html.gz +0 -0
  350. package/package.json +10 -9
  351. package/dist/ui/assets/App-9s2WHM6S.js +0 -22
  352. package/dist/ui/assets/App-9s2WHM6S.js.gz +0 -0
  353. package/dist/ui/assets/App-BAdBsEnV.css.gz +0 -0
  354. package/dist/ui/assets/ArtifactConsentModal-ParNk5kW.js.gz +0 -0
  355. package/dist/ui/assets/ArtifactFullscreenPage-VQxLMCiN.js +0 -9
  356. package/dist/ui/assets/ArtifactFullscreenPage-VQxLMCiN.js.gz +0 -0
  357. package/dist/ui/assets/AutocompleteTextarea-3RchrIgk.js +0 -18
  358. package/dist/ui/assets/AutocompleteTextarea-3RchrIgk.js.gz +0 -0
  359. package/dist/ui/assets/CodeEditor.inner-D51Z_CLQ.js.gz +0 -0
  360. package/dist/ui/assets/ConversationView-Dyddw2b1.js +0 -34
  361. package/dist/ui/assets/ConversationView-Dyddw2b1.js.gz +0 -0
  362. package/dist/ui/assets/KnowledgePage-CdftslnF.js +0 -24
  363. package/dist/ui/assets/KnowledgePage-CdftslnF.js.gz +0 -0
  364. package/dist/ui/assets/MobileApp-BdBMpnJ1.js +0 -1
  365. package/dist/ui/assets/MobileApp-BdBMpnJ1.js.gz +0 -0
  366. package/dist/ui/assets/StreamdownDemoPage-B9wbgp2s.js.gz +0 -0
  367. package/dist/ui/assets/ThemeSwitcher-ubn6IOz9.js.gz +0 -0
  368. package/dist/ui/assets/antd-C-HfEC4E.js +0 -400
  369. package/dist/ui/assets/antd-C-HfEC4E.js.gz +0 -0
  370. package/dist/ui/assets/architecture-U656AL7Q-dkBewUpN.js +0 -1
  371. package/dist/ui/assets/architectureDiagram-VXUJARFQ-ChmZt3zk.js.gz +0 -0
  372. package/dist/ui/assets/blockDiagram-VD42YOAC-CzGHAHao.js.gz +0 -0
  373. package/dist/ui/assets/c4Diagram-YG6GDRKO-DscJyaWN.js.gz +0 -0
  374. package/dist/ui/assets/channel-DvRQqEqC.js +0 -1
  375. package/dist/ui/assets/chunk-55IACEB6-DojF2pZN.js +0 -1
  376. package/dist/ui/assets/chunk-ABZYJK2D-RzDCrjE6.js.gz +0 -0
  377. package/dist/ui/assets/chunk-AGHRB4JF-jidCS5Of.js.gz +0 -0
  378. package/dist/ui/assets/chunk-ATLVNIR6-BEIIfJtC.js.gz +0 -0
  379. package/dist/ui/assets/chunk-B4BG7PRW-B8b6dQQ2.js.gz +0 -0
  380. package/dist/ui/assets/chunk-DI55MBZ5-BfATX3V8.js.gz +0 -0
  381. package/dist/ui/assets/chunk-EXTU4WIE-BKt6lPJM.js +0 -1
  382. package/dist/ui/assets/chunk-HN2XXSSU-BCHvD80g.js.gz +0 -0
  383. package/dist/ui/assets/chunk-JA3XYJ7Z-Cp6dqHnY.js.gz +0 -0
  384. package/dist/ui/assets/chunk-JZLCHNYA-cKMooY3y.js.gz +0 -0
  385. package/dist/ui/assets/chunk-MI3HLSF2-BlzO5wOE.js.gz +0 -0
  386. package/dist/ui/assets/chunk-N4CR4FBY-pASDorUx.js +0 -2
  387. package/dist/ui/assets/chunk-N4CR4FBY-pASDorUx.js.gz +0 -0
  388. package/dist/ui/assets/chunk-QXUST7PY-C9l0muI0.js.gz +0 -0
  389. package/dist/ui/assets/chunk-QZHKN3VN-CZskCFCf.js +0 -1
  390. package/dist/ui/assets/chunk-S3R3BYOJ-VJiLzt2o.js.gz +0 -0
  391. package/dist/ui/assets/chunk-TZMSLE5B-DZwI0C_2.js.gz +0 -0
  392. package/dist/ui/assets/classDiagram-2ON5EDUG-BFASUbmZ.js +0 -1
  393. package/dist/ui/assets/classDiagram-v2-WZHVMYZB-BFASUbmZ.js +0 -1
  394. package/dist/ui/assets/cose-bilkent-S5V4N54A-Ipik-oSD.js.gz +0 -0
  395. package/dist/ui/assets/dagre-6UL2VRFP-BDpyWQnh.js.gz +0 -0
  396. package/dist/ui/assets/dagre-CgA4KhUX.js.gz +0 -0
  397. package/dist/ui/assets/diagram-PSM6KHXK-B4GRzxLJ.js.gz +0 -0
  398. package/dist/ui/assets/diagram-QEK2KX5R-BWPW28XI.js.gz +0 -0
  399. package/dist/ui/assets/diagram-S2PKOQOG-BIHhcGoV.js.gz +0 -0
  400. package/dist/ui/assets/editor-C-HJ7Yw0.js.gz +0 -0
  401. package/dist/ui/assets/emoji-D8F6B62m.js.gz +0 -0
  402. package/dist/ui/assets/erDiagram-Q2GNP2WA-ubTaAFcK.js.gz +0 -0
  403. package/dist/ui/assets/flowDiagram-NV44I4VS-BHLCTYjI.js.gz +0 -0
  404. package/dist/ui/assets/ganttDiagram-LVOFAZNH-ClC3pay1.js.gz +0 -0
  405. package/dist/ui/assets/gitGraphDiagram-NY62KEGX-Clqpiswu.js.gz +0 -0
  406. package/dist/ui/assets/index-D9OElx9A.css +0 -1
  407. package/dist/ui/assets/index-D9OElx9A.css.gz +0 -0
  408. package/dist/ui/assets/index-DxPuzG7E.js +0 -350
  409. package/dist/ui/assets/index-DxPuzG7E.js.gz +0 -0
  410. package/dist/ui/assets/journeyDiagram-XKPGCS4Q-CrVickA2.js.gz +0 -0
  411. package/dist/ui/assets/kanban-definition-3W4ZIXB7-C_BsdHYL.js.gz +0 -0
  412. package/dist/ui/assets/knowledgeRoutes-CivaUqha.js.gz +0 -0
  413. package/dist/ui/assets/linear-BsjageUB.js.gz +0 -0
  414. package/dist/ui/assets/mermaid-parser.core-DZdP-NFq.js.gz +0 -0
  415. package/dist/ui/assets/mermaid.core-TNrI0pHG.js.gz +0 -0
  416. package/dist/ui/assets/message-BtWWJ9Af.js +0 -36
  417. package/dist/ui/assets/message-BtWWJ9Af.js.gz +0 -0
  418. package/dist/ui/assets/mindmap-definition-VGOIOE7T-BbmaUjMY.js.gz +0 -0
  419. package/dist/ui/assets/particles-Dv28pjOd.js.gz +0 -0
  420. package/dist/ui/assets/pieDiagram-ADFJNKIX-BbyjfYu8.js.gz +0 -0
  421. package/dist/ui/assets/quadrantDiagram-AYHSOK5B-Bc3GqMKz.js.gz +0 -0
  422. package/dist/ui/assets/reactflow-BVYPxNhc.js.gz +0 -0
  423. package/dist/ui/assets/requirementDiagram-UZGBJVZJ-BQaKKL09.js.gz +0 -0
  424. package/dist/ui/assets/sandpack-BQW_FQ7G.js.gz +0 -0
  425. package/dist/ui/assets/sankeyDiagram-TZEHDZUN-DiJvDvhb.js.gz +0 -0
  426. package/dist/ui/assets/sequenceDiagram-WL72ISMW-Dw32824o.js.gz +0 -0
  427. package/dist/ui/assets/stateDiagram-FKZM4ZOC-BCOpNdHV.js.gz +0 -0
  428. package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-Cuqwvgfg.js +0 -1
  429. package/dist/ui/assets/syntax-VJrU5BEu.js.gz +0 -0
  430. package/dist/ui/assets/timeline-definition-IT6M3QCI-Jh_WZzXv.js.gz +0 -0
  431. package/dist/ui/assets/xychartDiagram-PRI3JC2R-CERc7Rdb.js.gz +0 -0
@@ -315,7 +315,7 @@ var init_mcp_token_authorization = __esm({
315
315
  });
316
316
 
317
317
  // src/utils/session-tasks.ts
318
- import { TaskStatus as TaskStatus2 } from "@agor/core/types";
318
+ import { EXECUTING_TASK_STATUSES, isTaskExecuting } from "@agor/core/types";
319
319
  function recencyKey(t) {
320
320
  return new Date(t.started_at || t.created_at).getTime();
321
321
  }
@@ -335,22 +335,16 @@ async function findTasksForSession(app, sessionId, params) {
335
335
  }
336
336
  async function findActiveTasksForSession(app, sessionId, params) {
337
337
  const all = await findTasksForSession(app, sessionId, params);
338
- return all.filter((t) => ACTIVE_TASK_STATUSES.has(t.status));
338
+ return all.filter((t) => isTaskExecuting(t));
339
339
  }
340
340
  async function findHostTaskForSession(app, sessionId, params) {
341
341
  const all = await findTasksForSession(app, sessionId, params);
342
342
  if (all.length === 0) return void 0;
343
- return all.find((t) => ACTIVE_TASK_STATUSES.has(t.status)) ?? all[0];
343
+ return all.find((t) => isTaskExecuting(t)) ?? all[0];
344
344
  }
345
- var ACTIVE_TASK_STATUSES;
346
345
  var init_session_tasks = __esm({
347
346
  "src/utils/session-tasks.ts"() {
348
347
  "use strict";
349
- ACTIVE_TASK_STATUSES = /* @__PURE__ */ new Set([
350
- TaskStatus2.RUNNING,
351
- TaskStatus2.AWAITING_PERMISSION,
352
- TaskStatus2.STOPPING
353
- ]);
354
348
  }
355
349
  });
356
350
 
@@ -1330,7 +1324,7 @@ __export(tokens_exports, {
1330
1324
  validateSessionToken: () => validateSessionToken
1331
1325
  });
1332
1326
  import { MCP_TOKEN } from "@agor/core/config";
1333
- import { generateId as generateId5, SessionRepository as SessionRepository3, shortId as shortId8 } from "@agor/core/db";
1327
+ import { generateId as generateId5, SessionRepository as SessionRepository3, shortId as shortId9 } from "@agor/core/db";
1334
1328
  import {
1335
1329
  MCP_TOKEN_AUDIENCE,
1336
1330
  MCP_TOKEN_ISSUER
@@ -1384,7 +1378,7 @@ async function generateSessionToken2(app, sessionId, userId) {
1384
1378
  const cached2 = s.tokenCache.get(cacheKey);
1385
1379
  const refreshBufferMs = Math.min(5 * 60 * 1e3, Math.max(30 * 1e3, s.expirationMs * 0.1));
1386
1380
  if (cached2 && cached2.expiresAtMs - nowMs > refreshBufferMs) {
1387
- mcpTokenDebug(`\u{1F3AB} MCP token cache hit: session=${shortId8(sessionId)}`);
1381
+ mcpTokenDebug(`\u{1F3AB} MCP token cache hit: session=${shortId9(sessionId)}`);
1388
1382
  return cached2.token;
1389
1383
  }
1390
1384
  const sessionExists = await s.sessionRepo.exists(sessionId);
@@ -1410,7 +1404,7 @@ async function generateSessionToken2(app, sessionId, userId) {
1410
1404
  const token = jwt4.sign(payload, jwtSecret, { algorithm: "HS256" });
1411
1405
  s.tokenCache.set(cacheKey, { token, expiresAtMs });
1412
1406
  mcpTokenDebug(
1413
- `\u{1F3AB} MCP token issued: session=${shortId8(sessionId)} jti=${jti.substring(0, 8)} exp=+${Math.floor(s.expirationMs / 1e3)}s`
1407
+ `\u{1F3AB} MCP token issued: session=${shortId9(sessionId)} jti=${jti.substring(0, 8)} exp=+${Math.floor(s.expirationMs / 1e3)}s`
1414
1408
  );
1415
1409
  return token;
1416
1410
  }
@@ -1450,7 +1444,7 @@ async function validateSessionToken(app, token) {
1450
1444
  }
1451
1445
  const sessionExists = await s.sessionRepo.exists(sessionId);
1452
1446
  if (!sessionExists) {
1453
- console.warn(`[mcp-tokens] token rejected: session ${shortId8(sessionId)} not found`);
1447
+ console.warn(`[mcp-tokens] token rejected: session ${shortId9(sessionId)} not found`);
1454
1448
  return null;
1455
1449
  }
1456
1450
  return { sessionId, userId, jti: payload.jti };
@@ -1500,11 +1494,11 @@ import {
1500
1494
  import {
1501
1495
  generateId as generateId6,
1502
1496
  SessionRepository as SessionRepository4,
1503
- shortId as shortId9,
1497
+ shortId as shortId10,
1504
1498
  TaskRepository
1505
1499
  } from "@agor/core/db";
1506
1500
  import {
1507
- SessionStatus as SessionStatus3,
1501
+ SessionStatus as SessionStatus4,
1508
1502
  TaskStatus as TaskStatus4
1509
1503
  } from "@agor/core/types";
1510
1504
  import {
@@ -1522,7 +1516,7 @@ async function persistActiveTurnSnapshot(app, sessionId, turn) {
1522
1516
  const repo = new SessionRepository4(db);
1523
1517
  const row = await repo.findById(sessionId);
1524
1518
  if (!row) {
1525
- throw new Error(`persistActiveTurnSnapshot: session not found: ${shortId9(sessionId)}`);
1519
+ throw new Error(`persistActiveTurnSnapshot: session not found: ${shortId10(sessionId)}`);
1526
1520
  }
1527
1521
  const patch = {
1528
1522
  cli_state: {
@@ -1702,7 +1696,7 @@ function buildCliEventSink(app) {
1702
1696
  });
1703
1697
  app.service("tasks").emit("created", task);
1704
1698
  await app.service("sessions").patch(sessionId, {
1705
- status: SessionStatus3.RUNNING,
1699
+ status: SessionStatus4.RUNNING,
1706
1700
  ready_for_prompt: false,
1707
1701
  tasks: [...session.tasks, task.task_id]
1708
1702
  }).catch((err) => {
@@ -1979,7 +1973,7 @@ function buildCliEventSink(app) {
1979
1973
  }
1980
1974
  try {
1981
1975
  const patch = {
1982
- status: SessionStatus3.IDLE,
1976
+ status: SessionStatus4.IDLE,
1983
1977
  ready_for_prompt: true
1984
1978
  };
1985
1979
  if (computedContextWindow !== void 0) {
@@ -2044,7 +2038,7 @@ function buildSpawnConfigForSession(session, branchCwd, opts = {}) {
2044
2038
  return {
2045
2039
  sessionId: transcriptExists ? void 0 : session.session_id,
2046
2040
  resumeSessionId: transcriptExists ? session.session_id : void 0,
2047
- displayName: `cli-${shortId9(session.session_id)}`,
2041
+ displayName: `cli-${shortId10(session.session_id)}`,
2048
2042
  model: session.model_config?.model,
2049
2043
  effort: session.model_config?.effort,
2050
2044
  advisorModel: session.model_config?.advisorModel,
@@ -2161,7 +2155,7 @@ async function writeClaudeCliMcpConfigForSession(app, session, opts = {}) {
2161
2155
  sessionCreatedBy: session.created_by
2162
2156
  })) {
2163
2157
  console.warn(
2164
- `[claude-cli-integration] not writing owner-scoped MCP config for session ${shortId9(session.session_id)}: caller ${opts.actor.user_id ?? "anonymous"} cannot receive session creator token`
2158
+ `[claude-cli-integration] not writing owner-scoped MCP config for session ${shortId10(session.session_id)}: caller ${opts.actor.user_id ?? "anonymous"} cannot receive session creator token`
2165
2159
  );
2166
2160
  return void 0;
2167
2161
  }
@@ -2178,12 +2172,12 @@ async function writeClaudeCliMcpConfigForSession(app, session, opts = {}) {
2178
2172
  });
2179
2173
  return writeClaudeCliMcpConfigFile({
2180
2174
  mcpConfig,
2181
- sessionShortId: shortId9(session.session_id),
2175
+ sessionShortId: shortId10(session.session_id),
2182
2176
  targetUnixUser: resolveClaudeCliMcpConfigTargetUnixUser(config2, session)
2183
2177
  });
2184
2178
  } catch (err) {
2185
2179
  console.warn(
2186
- `[claude-cli-integration] failed to write MCP config for session ${shortId9(session.session_id)}; Agor MCP tools will be unavailable in Claude CLI/RemoteTrigger:`,
2180
+ `[claude-cli-integration] failed to write MCP config for session ${shortId10(session.session_id)}; Agor MCP tools will be unavailable in Claude CLI/RemoteTrigger:`,
2187
2181
  err instanceof Error ? err.message : String(err)
2188
2182
  );
2189
2183
  return void 0;
@@ -2210,7 +2204,7 @@ async function onCliSessionCreated(app, session, branchCwd) {
2210
2204
  const mcpConfigPath = await writeClaudeCliMcpConfigForSession(app, session);
2211
2205
  const spawnCfg = buildSpawnConfigForSession(session, branchCwd, { mcpConfigPath });
2212
2206
  const built = buildClaudeCliSpawn(spawnCfg);
2213
- const tabName = spawnCfg.displayName ?? `cli-${shortId9(session.session_id)}`;
2207
+ const tabName = spawnCfg.displayName ?? `cli-${shortId10(session.session_id)}`;
2214
2208
  const persister = buildCliPersister(app);
2215
2209
  await persister.saveOffset(session.session_id, {
2216
2210
  watcher_offset: 0,
@@ -18113,6 +18107,7 @@ IMPORTANT:
18113
18107
  {
18114
18108
  folderPath,
18115
18109
  branch_id: resolvedBranchId,
18110
+ source_session_id: ctx.sessionId,
18116
18111
  subpath,
18117
18112
  board_id: resolvedBoardId,
18118
18113
  name: coerceString(args.name),
@@ -19045,7 +19040,7 @@ var init_environment_helpers = __esm({
19045
19040
  // src/mcp/tools/branches.ts
19046
19041
  import { existsSync as existsSync3 } from "fs";
19047
19042
  import { isBranchRbacEnabled } from "@agor/core/config";
19048
- import { BranchRepository as BranchRepository3, shortId as shortId10 } from "@agor/core/db";
19043
+ import { BranchRepository as BranchRepository3, shortId as shortId11 } from "@agor/core/db";
19049
19044
  import { BRANCH_PERMISSION_LEVELS as BRANCH_PERMISSION_LEVELS2, getAssistantConfig, isAssistant } from "@agor/core/types";
19050
19045
  import { computeZoneRelativePosition } from "@agor/core/utils/board-placement";
19051
19046
  import { normalizeOptionalHttpUrl } from "@agor/core/utils/url";
@@ -19654,7 +19649,7 @@ function registerBranchTools(server, ctx) {
19654
19649
  }
19655
19650
  const targetSessionId = rawTargetSessionId ? await resolveSessionId(ctx, rawTargetSessionId) : void 0;
19656
19651
  console.log(
19657
- zoneId === null ? `\u{1F4CD} MCP clearing zone pin for branch ${shortId10(branchId)}` : `\u{1F4CD} MCP pinning branch ${shortId10(branchId)} to zone ${zoneId}`
19652
+ zoneId === null ? `\u{1F4CD} MCP clearing zone pin for branch ${shortId11(branchId)}` : `\u{1F4CD} MCP pinning branch ${shortId11(branchId)} to zone ${zoneId}`
19658
19653
  );
19659
19654
  const branch = await ctx.app.service("branches").get(branchId, ctx.baseServiceParams);
19660
19655
  const boardObjectsService = ctx.app.service("board-objects");
@@ -19717,7 +19712,7 @@ function registerBranchTools(server, ctx) {
19717
19712
  const hasZoneTrigger = zone.trigger?.template && zone.trigger.template.trim().length > 0;
19718
19713
  const isAlwaysNew = hasZoneTrigger && zone.trigger.behavior === "always_new";
19719
19714
  if (triggerTemplate && targetSessionId && hasZoneTrigger) {
19720
- console.log(`\u{1F3AF} Triggering zone prompt template for session ${shortId10(targetSessionId)}`);
19715
+ console.log(`\u{1F3AF} Triggering zone prompt template for session ${shortId11(targetSessionId)}`);
19721
19716
  const { renderTemplate: renderTemplate2 } = await import("@agor/core/templates/handlebars-helpers");
19722
19717
  const { buildZoneTriggerContext: buildZoneTriggerContext2 } = await import("@agor/core/templates/zone-trigger-context");
19723
19718
  let targetSession;
@@ -19750,7 +19745,7 @@ function registerBranchTools(server, ctx) {
19750
19745
  note: "Session is busy. Zone trigger prompt has been queued."
19751
19746
  };
19752
19747
  console.log(
19753
- `\u{1F4EC} Zone trigger queued for session ${shortId10(targetSessionId)} at position ${task.queue_position}`
19748
+ `\u{1F4EC} Zone trigger queued for session ${shortId11(targetSessionId)} at position ${task.queue_position}`
19754
19749
  );
19755
19750
  } else {
19756
19751
  promptResult = {
@@ -19758,7 +19753,7 @@ function registerBranchTools(server, ctx) {
19758
19753
  sessionId: targetSessionId,
19759
19754
  note: "Zone trigger prompt sent to target session"
19760
19755
  };
19761
- console.log(`\u2705 Zone trigger executed: task ${shortId10(task.task_id)}`);
19756
+ console.log(`\u2705 Zone trigger executed: task ${shortId11(task.task_id)}`);
19762
19757
  }
19763
19758
  } else {
19764
19759
  promptResult = {
@@ -19768,7 +19763,7 @@ function registerBranchTools(server, ctx) {
19768
19763
  }
19769
19764
  } else if (isAlwaysNew) {
19770
19765
  console.log(
19771
- `\u{1F3AF} Zone has always_new trigger, auto-creating session for branch ${shortId10(branchId)}`
19766
+ `\u{1F3AF} Zone has always_new trigger, auto-creating session for branch ${shortId11(branchId)}`
19772
19767
  );
19773
19768
  try {
19774
19769
  const user = await ctx.app.service("users").get(ctx.userId, ctx.baseServiceParams);
@@ -19783,13 +19778,13 @@ function registerBranchTools(server, ctx) {
19783
19778
  userId: ctx.userId
19784
19779
  });
19785
19780
  const agenticTool = newSession.agentic_tool;
19786
- console.log(`\u2705 Auto-created session ${shortId10(newSession.session_id)} (${agenticTool})`);
19781
+ console.log(`\u2705 Auto-created session ${shortId11(newSession.session_id)} (${agenticTool})`);
19787
19782
  promptResult = {
19788
19783
  taskId: task.task_id,
19789
19784
  sessionId: newSession.session_id,
19790
- note: `always_new trigger: created session ${shortId10(newSession.session_id)} (${agenticTool}) and sent prompt`
19785
+ note: `always_new trigger: created session ${shortId11(newSession.session_id)} (${agenticTool}) and sent prompt`
19791
19786
  };
19792
- console.log(`\u2705 Zone trigger executed: task ${shortId10(task.task_id)}`);
19787
+ console.log(`\u2705 Zone trigger executed: task ${shortId11(task.task_id)}`);
19793
19788
  } catch (error51) {
19794
19789
  const message = error51 instanceof Error ? error51.message : String(error51);
19795
19790
  if (message.includes("rendered to an empty prompt")) {
@@ -20524,7 +20519,11 @@ function registerEnvironmentTools(server, ctx) {
20524
20519
  branchId,
20525
20520
  ctx.baseServiceParams
20526
20521
  );
20527
- return textResult({ success: true, branch });
20522
+ return textResult({
20523
+ success: true,
20524
+ branch,
20525
+ message: "Environment start requested. Poll agor_environment_health and agor_environment_logs for readiness, progress, or failures."
20526
+ });
20528
20527
  } catch (error51) {
20529
20528
  const errorMessage = error51 instanceof Error ? error51.message : "Unknown error";
20530
20529
  const commandOutput = error51 instanceof Error ? error51.commandOutput : void 0;
@@ -20553,7 +20552,11 @@ function registerEnvironmentTools(server, ctx) {
20553
20552
  branchId,
20554
20553
  ctx.baseServiceParams
20555
20554
  );
20556
- return textResult({ success: true, branch });
20555
+ return textResult({
20556
+ success: true,
20557
+ branch,
20558
+ message: "Environment stop requested. Poll agor_environment_health for final status and agor_environment_logs for command output."
20559
+ });
20557
20560
  } catch (error51) {
20558
20561
  return textResult({
20559
20562
  success: false,
@@ -20595,7 +20598,7 @@ function registerEnvironmentTools(server, ctx) {
20595
20598
  server.registerTool(
20596
20599
  "agor_environment_logs",
20597
20600
  {
20598
- description: "Fetch recent logs from a branch environment (non-streaming, last ~100 lines; shell command by default, or HTTP(S) GET webhook when URL-shaped / webhook-only mode)",
20601
+ description: "Fetch recent logs from a branch environment (non-streaming, last ~500 lines; shell command by default, or HTTP(S) GET webhook when URL-shaped / webhook-only mode)",
20599
20602
  annotations: { readOnlyHint: true },
20600
20603
  inputSchema: external_exports.object({
20601
20604
  branchId: mcpRequiredId("branchId", "Branch")
@@ -20684,7 +20687,7 @@ function registerEnvironmentTools(server, ctx) {
20684
20687
  return textResult({
20685
20688
  success: true,
20686
20689
  branch: started,
20687
- message: `Environment variant set to "${updated.environment_variant}" and started.`
20690
+ message: `Environment variant set to "${updated.environment_variant}" and start requested. Poll agor_environment_health and agor_environment_logs for readiness, progress, or failures.`
20688
20691
  });
20689
20692
  } catch (startError) {
20690
20693
  const startMessage = startError instanceof Error ? startError.message : "Unknown error";
@@ -20728,7 +20731,7 @@ function registerEnvironmentTools(server, ctx) {
20728
20731
  return textResult({
20729
20732
  success: true,
20730
20733
  branch,
20731
- message: "Environment nuked successfully - all data and volumes destroyed"
20734
+ message: "Environment nuke requested. Poll agor_environment_health for final status and agor_environment_logs for command output."
20732
20735
  });
20733
20736
  } catch (error51) {
20734
20737
  return textResult({
@@ -20841,7 +20844,7 @@ var init_markdown_outline = __esm({
20841
20844
  import {
20842
20845
  BranchRepository as BranchRepository4,
20843
20846
  KnowledgeNamespaceRepository,
20844
- shortId as shortId11
20847
+ shortId as shortId12
20845
20848
  } from "@agor/core/db";
20846
20849
  import { getAssistantConfig as getAssistantConfig2, isAssistant as isAssistant2 } from "@agor/core/types";
20847
20850
  var ASSISTANT_MEMORY_PATH_TEMPLATE, ASSISTANT_NAMESPACE_MISSING_MESSAGE;
@@ -23713,7 +23716,11 @@ var init_search = __esm({
23713
23716
  });
23714
23717
 
23715
23718
  // src/mcp/tools/sessions.ts
23716
- import { BranchRepository as BranchRepository6, shortId as shortId12 } from "@agor/core/db";
23719
+ import {
23720
+ BranchRepository as BranchRepository6,
23721
+ SessionRelationshipRepository,
23722
+ shortId as shortId13
23723
+ } from "@agor/core/db";
23717
23724
  import {
23718
23725
  AVAILABLE_CLAUDE_MODEL_ALIASES,
23719
23726
  CODEX_MODEL_METADATA,
@@ -24219,10 +24226,70 @@ function registerSessionTools(server, ctx) {
24219
24226
  return textResult({ error: `Unknown mode: ${mode}` });
24220
24227
  }
24221
24228
  );
24229
+ server.registerTool(
24230
+ "agor_session_relationships_list",
24231
+ {
24232
+ description: "List durable non-genealogy relationships for a session, including cross-branch remote-created child/parent links. Defaults to the current session.",
24233
+ annotations: { readOnlyHint: true },
24234
+ inputSchema: external_exports.object({
24235
+ sessionId: mcpOptionalId(
24236
+ "sessionId",
24237
+ "Session",
24238
+ "Session ID to inspect (defaults to current session)"
24239
+ )
24240
+ })
24241
+ },
24242
+ async (args) => {
24243
+ const sessionId = args.sessionId ? await resolveSessionId(ctx, args.sessionId) : ctx.sessionId;
24244
+ if (!sessionId) return sessionContextRequiredResult();
24245
+ await ctx.app.service("sessions").get(sessionId, ctx.baseServiceParams);
24246
+ const relationships = await new SessionRelationshipRepository(ctx.db).findForSession(
24247
+ sessionId
24248
+ );
24249
+ return textResult({ relationships });
24250
+ }
24251
+ );
24252
+ server.registerTool(
24253
+ "agor_session_relationships_set_callback",
24254
+ {
24255
+ description: "Enable or disable callback/report-back delivery for a durable session relationship without deleting the relationship itself.",
24256
+ inputSchema: external_exports.object({
24257
+ relationshipId: mcpRequiredString(
24258
+ "relationshipId",
24259
+ "Session relationship ID returned by agor_session_relationships_list"
24260
+ ),
24261
+ callbackEnabled: external_exports.boolean().describe("Whether the remote child should report back.")
24262
+ })
24263
+ },
24264
+ async (args) => {
24265
+ const repo = new SessionRelationshipRepository(ctx.db);
24266
+ const relationshipId = args.relationshipId;
24267
+ const existingRelationship = await repo.get(relationshipId);
24268
+ await ctx.app.service("sessions").get(existingRelationship.source_session_id, ctx.baseServiceParams);
24269
+ const targetSession = await ctx.app.service("sessions").get(existingRelationship.target_session_id, ctx.baseServiceParams);
24270
+ const relationship = await repo.setCallbackEnabled(relationshipId, args.callbackEnabled);
24271
+ const callbackSessionId = relationship.callback_session_id ?? relationship.source_session_id;
24272
+ await ctx.app.service("sessions").patch(
24273
+ relationship.target_session_id,
24274
+ {
24275
+ callback_config: {
24276
+ ...targetSession.callback_config ?? {},
24277
+ enabled: args.callbackEnabled,
24278
+ callback_session_id: callbackSessionId
24279
+ }
24280
+ },
24281
+ {
24282
+ ...ctx.baseServiceParams,
24283
+ _skipRelationshipCallbackSync: true
24284
+ }
24285
+ );
24286
+ return textResult({ relationship });
24287
+ }
24288
+ );
24222
24289
  server.registerTool(
24223
24290
  "agor_sessions_create",
24224
24291
  {
24225
- description: 'Create a new session in an existing branch. Use for starting fresh work on a new task in the same codebase (e.g., new feature branch, separate investigation). Unlike spawn, this creates an independent session with no parent-child relationship. MCP servers are inherited from the branch (if configured) or user defaults, or can be overridden via `mcpServerIds`. Model selection falls back to user defaults and can be overridden via `modelConfig` (accepts either a model ID string like "claude-opus-4-6" or a full {mode, model, effort, advisorModel, provider} object \u2014 call `agor_models_list` to discover valid model IDs per agenticTool). Supports optional callbacks to notify the creating session when the new session completes.',
24292
+ description: 'Create a new session in an existing branch. When called from an MCP session context in the same target branch (the default for branch-local orchestrator agents), the new session is automatically linked to the calling session as its parent \u2014 pass `parentSessionId: null` to create an unlinked root session instead. Cross-branch sessions are not genealogy-linked automatically; use callbacks for remote completion routing. Use for starting work on a new task in the same codebase (e.g., new feature branch, separate investigation). MCP servers are inherited from the branch (if configured) or user defaults, or can be overridden via `mcpServerIds`. Model selection falls back to user defaults and can be overridden via `modelConfig` (accepts either a model ID string like "claude-opus-4-6" or a full {mode, model, effort, advisorModel, provider} object \u2014 call `agor_models_list` to discover valid model IDs per agenticTool). Supports optional callbacks to notify the creating session when the new session completes.',
24226
24293
  inputSchema: external_exports.object({
24227
24294
  branchId: mcpRequiredId(
24228
24295
  "branchId",
@@ -24252,6 +24319,9 @@ function registerSessionTools(server, ctx) {
24252
24319
  callbackMode: external_exports.enum(["once", "persistent"]).optional().describe(
24253
24320
  'Callback firing mode: "once" (default) fires on first completion then auto-disables, "persistent" fires on every completion'
24254
24321
  ),
24322
+ parentSessionId: external_exports.string().min(1, "parentSessionId cannot be empty when provided.").nullish().describe(
24323
+ "Parent session ID to link this session to in the branch-local genealogy tree. Must be in the target branch. When omitted and called from a session MCP context in the same branch, automatically defaults to the calling session. Pass null to explicitly create a root session with no parent; use callbackSessionId for cross-branch routing."
24324
+ ),
24255
24325
  mcpServerIds: external_exports.array(mcpRequiredId("mcpServerIds[]", "MCP server")).optional().describe(
24256
24326
  "MCP server IDs to attach. Overrides branch and user default inheritance. Omit to use branch config > user defaults."
24257
24327
  ),
@@ -24306,6 +24376,37 @@ function registerSessionTools(server, ctx) {
24306
24376
  if (wantsCallback) {
24307
24377
  callbackConfig.callback_mode = args.callbackMode ?? "once";
24308
24378
  }
24379
+ let resolvedParentSessionId;
24380
+ let parentSessionForPatch;
24381
+ let skippedAutoParentDueToBranchMismatch = false;
24382
+ let remoteRelationshipSourceSessionId;
24383
+ let remoteRelationshipSourceBranchId;
24384
+ if (args.parentSessionId !== void 0) {
24385
+ if (args.parentSessionId !== null) {
24386
+ resolvedParentSessionId = await resolveSessionId(ctx, args.parentSessionId);
24387
+ parentSessionForPatch = await ctx.app.service("sessions").get(resolvedParentSessionId, ctx.baseServiceParams);
24388
+ if (parentSessionForPatch.branch_id !== branch.branch_id) {
24389
+ throw new Error(
24390
+ `parentSessionId must reference a session in the target branch (${shortId13(branch.branch_id)}). For cross-branch completion routing, use enableCallback/callbackSessionId instead of genealogy.`
24391
+ );
24392
+ }
24393
+ }
24394
+ } else if (ctx.sessionId) {
24395
+ const callingSession = await ctx.app.service("sessions").get(ctx.sessionId, ctx.baseServiceParams);
24396
+ if (callingSession.branch_id === branch.branch_id) {
24397
+ resolvedParentSessionId = callingSession.session_id;
24398
+ parentSessionForPatch = callingSession;
24399
+ } else {
24400
+ skippedAutoParentDueToBranchMismatch = true;
24401
+ remoteRelationshipSourceSessionId = callingSession.session_id;
24402
+ remoteRelationshipSourceBranchId = callingSession.branch_id;
24403
+ }
24404
+ }
24405
+ if (remoteRelationshipSourceSessionId && effectiveCallbackSessionId) {
24406
+ callbackConfig.enabled ??= Boolean(wantsCallback);
24407
+ callbackConfig.callback_session_id ??= effectiveCallbackSessionId;
24408
+ callbackConfig.callback_created_by ??= ctx.userId;
24409
+ }
24309
24410
  const sessionData = {
24310
24411
  branch_id: branch.branch_id,
24311
24412
  agentic_tool: agenticTool,
@@ -24323,10 +24424,44 @@ function registerSessionTools(server, ctx) {
24323
24424
  base_sha: currentSha,
24324
24425
  current_sha: currentSha
24325
24426
  },
24326
- genealogy: { children: [] },
24427
+ genealogy: {
24428
+ ...resolvedParentSessionId && { parent_session_id: resolvedParentSessionId },
24429
+ children: []
24430
+ },
24327
24431
  tasks: []
24328
24432
  };
24329
24433
  const session = await ctx.app.service("sessions").create(sessionData, ctx.baseServiceParams);
24434
+ const remoteRelationship = remoteRelationshipSourceSessionId ? await new SessionRelationshipRepository(ctx.db).create({
24435
+ source_session_id: remoteRelationshipSourceSessionId,
24436
+ target_session_id: session.session_id,
24437
+ relationship_type: "remote_create",
24438
+ created_by: ctx.userId,
24439
+ callback_enabled: Boolean(wantsCallback),
24440
+ // Keep the durable relationship target even when callbacks are
24441
+ // muted. callback_enabled/callback_config.enabled are the delivery
24442
+ // switches; callback_session_id is the stable endpoint to re-enable.
24443
+ callback_session_id: effectiveCallbackSessionId ? effectiveCallbackSessionId : null,
24444
+ data: {
24445
+ source_branch_id: remoteRelationshipSourceBranchId,
24446
+ target_branch_id: branch.branch_id
24447
+ }
24448
+ }) : null;
24449
+ if (remoteRelationship && remoteRelationshipSourceSessionId) {
24450
+ const sourceSession = await ctx.app.service("sessions").get(remoteRelationshipSourceSessionId, ctx.baseServiceParams);
24451
+ ctx.app.service("sessions").emit?.("patched", sourceSession, ctx.baseServiceParams);
24452
+ }
24453
+ if (resolvedParentSessionId && parentSessionForPatch) {
24454
+ await ctx.app.service("sessions").patch(
24455
+ resolvedParentSessionId,
24456
+ {
24457
+ genealogy: {
24458
+ ...parentSessionForPatch.genealogy,
24459
+ children: [...parentSessionForPatch.genealogy?.children ?? [], session.session_id]
24460
+ }
24461
+ },
24462
+ ctx.baseServiceParams
24463
+ );
24464
+ }
24330
24465
  const mcpAttachFailures = [];
24331
24466
  if (mcpServerIds && mcpServerIds.length > 0) {
24332
24467
  for (const mcpServerId of mcpServerIds) {
@@ -24354,12 +24489,14 @@ function registerSessionTools(server, ctx) {
24354
24489
  { ...ctx.baseServiceParams, route: { id: session.session_id } }
24355
24490
  );
24356
24491
  }
24357
- const callbackNote = callbackConfig.callback_session_id ? ` Callback will be sent to session ${shortId12(callbackConfig.callback_session_id)} on completion.` : "";
24492
+ const callbackNote = callbackConfig.callback_session_id ? ` Callback will be sent to session ${shortId13(callbackConfig.callback_session_id)} on completion.` : "";
24493
+ const parentNote = resolvedParentSessionId ? ` Linked to parent session ${shortId13(resolvedParentSessionId)}.` : skippedAutoParentDueToBranchMismatch ? " Not genealogy-linked because the target branch differs from the calling session branch." : "";
24358
24494
  const mcpFailureNote = mcpAttachFailures.length > 0 ? ` Warning: ${mcpAttachFailures.length} requested MCP server(s) failed to attach \u2014 see mcpAttachFailures.` : "";
24359
24495
  return textResult({
24360
24496
  session: redactSessionForMcp(session),
24361
24497
  taskId: initialTask?.task_id,
24362
- note: args.initialPrompt ? `Session created and initial prompt execution started.${callbackNote}${mcpFailureNote}` : `Session created successfully.${callbackNote}${mcpFailureNote}`,
24498
+ note: args.initialPrompt ? `Session created and initial prompt execution started.${parentNote}${callbackNote}${mcpFailureNote}` : `Session created successfully.${parentNote}${callbackNote}${mcpFailureNote}`,
24499
+ ...remoteRelationship && { remoteRelationship },
24363
24500
  ...mcpAttachFailures.length > 0 && { mcpAttachFailures }
24364
24501
  });
24365
24502
  }
@@ -24608,7 +24745,7 @@ function registerSessionTools(server, ctx) {
24608
24745
  server.registerTool(
24609
24746
  "agor_sessions_stop",
24610
24747
  {
24611
- description: "Stop a running session. Kills the executor process and sets the session to idle. Use this for emergency stops, timeout-based cancellation, or human-in-the-loop gates. Only works on sessions in active states (running, awaiting_permission, stopping).",
24748
+ description: "Stop a running session. Kills the executor process and sets the session to idle. Use this for emergency stops, timeout-based cancellation, or human-in-the-loop gates. Only works on sessions in active states (running, stopping, awaiting_permission, awaiting_input).",
24612
24749
  annotations: { destructiveHint: true },
24613
24750
  inputSchema: external_exports.object({
24614
24751
  sessionId: mcpRequiredId("sessionId", "Session", "Session ID to stop (UUIDv7 or short ID)"),
@@ -25242,7 +25379,7 @@ __export(server_exports, {
25242
25379
  textResult: () => textResult
25243
25380
  });
25244
25381
  import { randomUUID as randomUUID2 } from "crypto";
25245
- import { shortId as shortId13, UserApiKeysRepository } from "@agor/core/db";
25382
+ import { shortId as shortId14, UserApiKeysRepository } from "@agor/core/db";
25246
25383
  import { getServiceTier as getServiceTier2, SERVICE_GROUP_TO_MCP_DOMAINS, SERVICE_TIER_RANK } from "@agor/core/types";
25247
25384
  import { NotFoundError as NotFoundError3 } from "@agor/core/utils/errors";
25248
25385
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -25553,7 +25690,7 @@ function setupMCPRoutes(app, db, toolSearchEnabled = true, servicesConfig) {
25553
25690
  }
25554
25691
  }
25555
25692
  mcpRequestDebug(
25556
- `\u{1F50C} MCP request authenticated (user: ${shortId13(userId)}, session: ${sessionId ? shortId13(sessionId) : "none"})`
25693
+ `\u{1F50C} MCP request authenticated (user: ${shortId14(userId)}, session: ${sessionId ? shortId14(sessionId) : "none"})`
25557
25694
  );
25558
25695
  const mcpContext = {
25559
25696
  app,
@@ -25794,7 +25931,7 @@ import {
25794
25931
  ScheduleRepository as ScheduleRepository2,
25795
25932
  SessionMCPServerRepository as SessionMCPServerRepository2,
25796
25933
  SessionRepository as SessionRepository6,
25797
- shortId as shortId14,
25934
+ shortId as shortId15,
25798
25935
  TaskRepository as TaskRepository2,
25799
25936
  UsersRepository as UsersRepository3
25800
25937
  } from "@agor/core/db";
@@ -25816,7 +25953,7 @@ import {
25816
25953
  MessageRole as MessageRole4,
25817
25954
  ROLES as ROLES9,
25818
25955
  SERVICE_GROUP_NAMES as SERVICE_GROUP_NAMES2,
25819
- SessionStatus as SessionStatus4,
25956
+ SessionStatus as SessionStatus5,
25820
25957
  TaskStatus as TaskStatus5
25821
25958
  } from "@agor/core/types";
25822
25959
  import { NotFoundError as NotFoundError4 } from "@agor/core/utils/errors";
@@ -26972,24 +27109,97 @@ function ensureScheduleRunsAsCaller(options) {
26972
27109
  };
26973
27110
  }
26974
27111
 
27112
+ // src/utils/session-stop.ts
27113
+ init_session_tasks();
27114
+ import { shortId as shortId6 } from "@agor/core/db";
27115
+ import { isSessionExecuting, SessionStatus as SessionStatus2, TaskStatus } from "@agor/core/types";
27116
+ async function markStoppedSessionPromptableNoDrain(sessionsService, sessionId, params) {
27117
+ await sessionsService.patch(
27118
+ sessionId,
27119
+ {
27120
+ status: SessionStatus2.IDLE,
27121
+ ready_for_prompt: true
27122
+ },
27123
+ {
27124
+ ...params ?? {},
27125
+ suppressTerminalQueueProcessing: true
27126
+ }
27127
+ );
27128
+ }
27129
+ async function stopSessionPreserveQueue(deps, sessionId, params = {}, options = {}) {
27130
+ const session = await deps.sessionsService.get(sessionId, params);
27131
+ if (!isSessionExecuting(session)) {
27132
+ return {
27133
+ success: false,
27134
+ reason: `Session cannot be stopped (status: ${session.status})`
27135
+ };
27136
+ }
27137
+ const targetTasksArray = await findActiveTasksForSession(deps.app, sessionId, params);
27138
+ const queuedTasks = await deps.taskRepo.findQueued(sessionId);
27139
+ if (targetTasksArray.length === 0) {
27140
+ console.warn(
27141
+ `\u26A0\uFE0F [Stop] No active tasks for session ${shortId6(sessionId)}, resetting to IDLE${options.reason ? ` (reason: ${options.reason})` : ""}`
27142
+ );
27143
+ await markStoppedSessionPromptableNoDrain(deps.sessionsService, sessionId, params);
27144
+ return {
27145
+ success: true,
27146
+ status: SessionStatus2.IDLE,
27147
+ reason: "No active tasks found, session reset to idle",
27148
+ queuedTasksPreserved: queuedTasks.length
27149
+ };
27150
+ }
27151
+ const latestTask = targetTasksArray[0];
27152
+ console.log(
27153
+ `\u{1F6D1} [Stop] Stopping task ${shortId6(latestTask.task_id)} for session ${shortId6(sessionId)}${options.reason ? ` (reason: ${options.reason})` : ""}`
27154
+ );
27155
+ const processKilled = deps.killExecutorProcess(sessionId);
27156
+ if (!processKilled) {
27157
+ console.warn(
27158
+ `\u26A0\uFE0F [Stop] No tracked process for session ${shortId6(sessionId)} \u2014 executor may have already exited`
27159
+ );
27160
+ }
27161
+ try {
27162
+ await deps.tasksService.patch(
27163
+ latestTask.task_id,
27164
+ {
27165
+ status: TaskStatus.STOPPED,
27166
+ completed_at: (/* @__PURE__ */ new Date()).toISOString()
27167
+ },
27168
+ {
27169
+ ...params,
27170
+ suppressTerminalQueueProcessing: true,
27171
+ suppressCompletionCallbacks: true
27172
+ }
27173
+ );
27174
+ } catch (error51) {
27175
+ console.error(`\u274C [Stop] Failed to patch task to STOPPED:`, error51);
27176
+ }
27177
+ await markStoppedSessionPromptableNoDrain(deps.sessionsService, sessionId, params);
27178
+ return {
27179
+ success: true,
27180
+ status: SessionStatus2.IDLE,
27181
+ stoppedTaskId: latestTask.task_id,
27182
+ queuedTasksPreserved: queuedTasks.length
27183
+ };
27184
+ }
27185
+
26975
27186
  // src/utils/session-task-state.ts
26976
- import { isTerminalTaskStatus, SessionStatus as SessionStatus2, TaskStatus } from "@agor/core/types";
27187
+ import {
27188
+ isTerminalTaskStatus,
27189
+ SessionStatus as SessionStatus3,
27190
+ sessionCanStartTask,
27191
+ TaskStatus as TaskStatus2
27192
+ } from "@agor/core/types";
26977
27193
  function isTaskBlockingPrompt(task) {
26978
- return task.status !== TaskStatus.QUEUED && !isTerminalTaskStatus(task.status);
26979
- }
26980
- function sessionCanStartTask(status, readyForPrompt) {
26981
- return status === SessionStatus2.IDLE || status === SessionStatus2.FAILED && readyForPrompt === true;
27194
+ return task.status !== TaskStatus2.QUEUED && !isTerminalTaskStatus(task.status);
26982
27195
  }
26983
27196
  function shouldReconcileSessionPromptState(session, tasks, options = {}) {
26984
- if (session.status !== SessionStatus2.FAILED) return false;
27197
+ if (session.status !== SessionStatus3.FAILED) return false;
26985
27198
  if (session.ready_for_prompt === true) return false;
26986
27199
  const ignoredTaskIds = new Set(options.ignoredTaskIds ?? []);
26987
27200
  return !tasks.some((task) => !ignoredTaskIds.has(task.task_id) && isTaskBlockingPrompt(task));
26988
27201
  }
26989
27202
 
26990
- // src/register-routes.ts
26991
- init_session_tasks();
26992
-
26993
27203
  // src/utils/session-turn-lock.ts
26994
27204
  async function withSessionTurnLock(locks, sessionId, fn) {
26995
27205
  while (locks.has(sessionId)) {
@@ -27009,7 +27219,7 @@ async function withSessionTurnLock(locks, sessionId, fn) {
27009
27219
  }
27010
27220
 
27011
27221
  // src/utils/task-runner.ts
27012
- import { shortId as shortId6 } from "@agor/core/db";
27222
+ import { shortId as shortId7 } from "@agor/core/db";
27013
27223
  import { Conflict, NotFound as NotFound2 } from "@agor/core/feathers";
27014
27224
  import { TaskStatus as TaskStatus3 } from "@agor/core/types";
27015
27225
  async function runExistingTask(task, options, params, deps) {
@@ -27019,7 +27229,7 @@ async function runExistingTask(task, options, params, deps) {
27019
27229
  }
27020
27230
  if (fresh.status !== TaskStatus3.CREATED) {
27021
27231
  throw new Conflict(
27022
- `Task ${shortId6(task.task_id)} cannot be run: status is '${fresh.status}' (only 'created' tasks may be triggered; the task may have been started by another caller or drained from the queue).`
27232
+ `Task ${shortId7(task.task_id)} cannot be run: status is '${fresh.status}' (only 'created' tasks may be triggered; the task may have been started by another caller or drained from the queue).`
27023
27233
  );
27024
27234
  }
27025
27235
  return await deps.spawnFn(fresh, options, params);
@@ -27035,7 +27245,7 @@ function normalizeMessageSource(input, params) {
27035
27245
  import fs from "fs/promises";
27036
27246
  import os from "os";
27037
27247
  import path from "path";
27038
- import { shortId as shortId7 } from "@agor/core/db";
27248
+ import { shortId as shortId8 } from "@agor/core/db";
27039
27249
  import multer from "multer";
27040
27250
  var ALLOWED_UPLOAD_MIME_TYPES = /* @__PURE__ */ new Set([
27041
27251
  // Images
@@ -27074,7 +27284,7 @@ function createUploadStorage(sessionRepo, branchRepo) {
27074
27284
  }
27075
27285
  if (DEBUG_UPLOAD) {
27076
27286
  console.log(
27077
- `\u{1F4C2} [Upload Storage] Processing upload for session ${sessionId ? shortId7(sessionId) : "unknown"}`
27287
+ `\u{1F4C2} [Upload Storage] Processing upload for session ${sessionId ? shortId8(sessionId) : "unknown"}`
27078
27288
  );
27079
27289
  console.log(` Destination type: ${destination}`);
27080
27290
  }
@@ -27084,16 +27294,16 @@ function createUploadStorage(sessionRepo, branchRepo) {
27084
27294
  }
27085
27295
  const session = await sessionRepo.findById(sessionId);
27086
27296
  if (!session) {
27087
- console.error(`\u274C [Upload Storage] Session not found: ${shortId7(sessionId)}`);
27297
+ console.error(`\u274C [Upload Storage] Session not found: ${shortId8(sessionId)}`);
27088
27298
  return cb(new Error(`Session not found: ${sessionId}`), "");
27089
27299
  }
27090
27300
  if (!session.branch_id) {
27091
- console.error(`\u274C [Upload Storage] Session ${shortId7(sessionId)} has no branch`);
27301
+ console.error(`\u274C [Upload Storage] Session ${shortId8(sessionId)} has no branch`);
27092
27302
  return cb(new Error(`Session ${sessionId} has no associated branch`), "");
27093
27303
  }
27094
27304
  const branch = await branchRepo.findById(session.branch_id);
27095
27305
  if (!branch) {
27096
- console.error(`\u274C [Upload Storage] Branch not found: ${shortId7(session.branch_id)}`);
27306
+ console.error(`\u274C [Upload Storage] Branch not found: ${shortId8(session.branch_id)}`);
27097
27307
  return cb(new Error(`Branch not found: ${session.branch_id}`), "");
27098
27308
  }
27099
27309
  const paths = {
@@ -27358,6 +27568,9 @@ var AgorLocalStrategy = class extends LocalStrategy {
27358
27568
  return super.findEntity(username, params);
27359
27569
  }
27360
27570
  };
27571
+ function isServiceAccountRoute(params) {
27572
+ return params.user?._isServiceAccount === true;
27573
+ }
27361
27574
  function isPaginated(result) {
27362
27575
  return !Array.isArray(result) && "data" in result && "total" in result;
27363
27576
  }
@@ -27632,6 +27845,12 @@ async function registerRoutes(ctx) {
27632
27845
  {
27633
27846
  async create(data, params) {
27634
27847
  app.service("messages").emit(data.event, data.data);
27848
+ if (isServiceAccountRoute(params) && (data.event === "streaming:start" || data.event === "streaming:chunk" || data.event === "streaming:end" || data.event === "streaming:error")) {
27849
+ void app.service("gateway").handleMessageStreamingEvent(
27850
+ data.event,
27851
+ data.data
27852
+ );
27853
+ }
27635
27854
  return { success: true };
27636
27855
  }
27637
27856
  },
@@ -27645,8 +27864,19 @@ async function registerRoutes(ctx) {
27645
27864
  "/tasks/streaming",
27646
27865
  {
27647
27866
  async create(data, params) {
27648
- const _ = params;
27649
27867
  app.service("tasks").emit(data.event, data.data);
27868
+ if (isServiceAccountRoute(params) && data.event === "tool:start") {
27869
+ const sessionId = typeof data.data.session_id === "string" ? data.data.session_id : void 0;
27870
+ const toolName = typeof data.data.tool_name === "string" ? data.data.tool_name : void 0;
27871
+ if (sessionId) {
27872
+ void app.service("gateway").updateProgress({
27873
+ session_id: sessionId,
27874
+ state: "working",
27875
+ task_id: typeof data.data.task_id === "string" ? data.data.task_id : void 0,
27876
+ tool_name: toolName
27877
+ });
27878
+ }
27879
+ }
27650
27880
  return { success: true };
27651
27881
  }
27652
27882
  },
@@ -27662,9 +27892,9 @@ async function registerRoutes(ctx) {
27662
27892
  async create(data, params) {
27663
27893
  const id = params.route?.id;
27664
27894
  if (!id) throw new Error("Session ID required");
27665
- console.log(`\u{1F500} Forking session: ${shortId14(id)}`);
27895
+ console.log(`\u{1F500} Forking session: ${shortId15(id)}`);
27666
27896
  const forkedSession = await sessionsService.fork(id, data, params);
27667
- console.log(`\u2705 Fork created: ${shortId14(forkedSession.session_id)}`);
27897
+ console.log(`\u2705 Fork created: ${shortId15(forkedSession.session_id)}`);
27668
27898
  console.log("\u{1F4E1} [FORK] Manually broadcasting created event to all clients");
27669
27899
  if (app.io) {
27670
27900
  app.io.emit("sessions created", forkedSession);
@@ -27684,9 +27914,9 @@ async function registerRoutes(ctx) {
27684
27914
  async create(data, params) {
27685
27915
  const id = params.route?.id;
27686
27916
  if (!id) throw new Error("Session ID required");
27687
- console.log(`\u{1F331} Spawning session from: ${shortId14(id)}`);
27917
+ console.log(`\u{1F331} Spawning session from: ${shortId15(id)}`);
27688
27918
  const spawnedSession = await sessionsService.spawn(id, data, params);
27689
- console.log(`\u2705 Spawn created: ${shortId14(spawnedSession.session_id)}`);
27919
+ console.log(`\u2705 Spawn created: ${shortId15(spawnedSession.session_id)}`);
27690
27920
  console.log("\u{1F4E1} [SPAWN] Manually broadcasting created event to all clients");
27691
27921
  if (app.io) {
27692
27922
  app.io.emit("sessions created", spawnedSession);
@@ -27737,7 +27967,7 @@ async function registerRoutes(ctx) {
27737
27967
  })) {
27738
27968
  throw new Forbidden9("You can only restart Claude CLI sessions you created.");
27739
27969
  }
27740
- const tabName = `cli-${shortId14(session.session_id)}`;
27970
+ const tabName = `cli-${shortId15(session.session_id)}`;
27741
27971
  const channel = `user/${targetUserId}/terminal`;
27742
27972
  try {
27743
27973
  const { spawn: spawnProc } = await import("child_process");
@@ -27797,25 +28027,25 @@ async function registerRoutes(ctx) {
27797
28027
  return true;
27798
28028
  } catch (error51) {
27799
28029
  if (error51 instanceof NotFoundError4 || error51 instanceof Error && error51.message.includes("No record found")) {
27800
- console.log(`\u26A0\uFE0F ${entityType} ${shortId14(id)} was deleted mid-execution - skipping update`);
28030
+ console.log(`\u26A0\uFE0F ${entityType} ${shortId15(id)} was deleted mid-execution - skipping update`);
27801
28031
  return false;
27802
28032
  }
27803
28033
  throw error51;
27804
28034
  }
27805
28035
  }
27806
28036
  async function reconcileSessionPromptStateIfStuck(session, taskRepo, params, options = {}) {
27807
- if (session.status !== SessionStatus4.FAILED || session.ready_for_prompt === true) {
28037
+ if (session.status !== SessionStatus5.FAILED || session.ready_for_prompt === true) {
27808
28038
  return session;
27809
28039
  }
27810
28040
  const sessionTasks = await taskRepo.findBySession(session.session_id);
27811
28041
  if (!shouldReconcileSessionPromptState(session, sessionTasks, options)) return session;
27812
28042
  console.warn(
27813
- `\u{1F9F9} [PromptState] Repairing stuck session ${shortId14(session.session_id)} (status=${session.status}, ready_for_prompt=${session.ready_for_prompt})`
28043
+ `\u{1F9F9} [PromptState] Repairing stuck session ${shortId15(session.session_id)} (status=${session.status}, ready_for_prompt=${session.ready_for_prompt})`
27814
28044
  );
27815
28045
  return await app.service("sessions").patch(
27816
28046
  session.session_id,
27817
28047
  {
27818
- status: SessionStatus4.IDLE,
28048
+ status: SessionStatus5.IDLE,
27819
28049
  ready_for_prompt: true
27820
28050
  },
27821
28051
  params
@@ -27871,7 +28101,7 @@ async function registerRoutes(ctx) {
27871
28101
  await app.service("messages").create(userMessage, params);
27872
28102
  } catch (msgErr) {
27873
28103
  console.warn(
27874
- `\u26A0\uFE0F [Daemon] Failed to write initial user-message row for task ${shortId14(task.task_id)} (executor will retry):`,
28104
+ `\u26A0\uFE0F [Daemon] Failed to write initial user-message row for task ${shortId15(task.task_id)} (executor will retry):`,
27875
28105
  msgErr
27876
28106
  );
27877
28107
  }
@@ -27879,7 +28109,7 @@ async function registerRoutes(ctx) {
27879
28109
  await app.service("sessions").patch(
27880
28110
  task.session_id,
27881
28111
  {
27882
- status: SessionStatus4.RUNNING,
28112
+ status: SessionStatus5.RUNNING,
27883
28113
  ready_for_prompt: false,
27884
28114
  tasks: [...session.tasks, task.task_id]
27885
28115
  },
@@ -27904,7 +28134,7 @@ async function registerRoutes(ctx) {
27904
28134
  throw new Error("CLI session has no created_by \u2014 cannot route PTY injection");
27905
28135
  }
27906
28136
  const channel = `user/${targetUserId}/terminal`;
27907
- const tabName = `cli-${shortId14(session.session_id)}`;
28137
+ const tabName = `cli-${shortId15(session.session_id)}`;
27908
28138
  const io = app.io;
27909
28139
  io?.to(channel).emit("terminal:tab", {
27910
28140
  userId: targetUserId,
@@ -27915,11 +28145,11 @@ async function registerRoutes(ctx) {
27915
28145
  const payload = `${promptForExecutor}\r`;
27916
28146
  io?.to(channel).emit("terminal:input", { userId: targetUserId, input: payload });
27917
28147
  console.log(
27918
- `[claude-cli] PTY-injected prompt into ${channel} \u2192 tab ${tabName} (task ${shortId14(taskId)}, ${promptForExecutor.length} chars)`
28148
+ `[claude-cli] PTY-injected prompt into ${channel} \u2192 tab ${tabName} (task ${shortId15(taskId)}, ${promptForExecutor.length} chars)`
27919
28149
  );
27920
28150
  } catch (err) {
27921
28151
  const msg = err instanceof Error ? err.message : String(err);
27922
- console.error(`[claude-cli] PTY injection failed for task ${shortId14(taskId)}: ${msg}`);
28152
+ console.error(`[claude-cli] PTY injection failed for task ${shortId15(taskId)}: ${msg}`);
27923
28153
  await safePatch(
27924
28154
  "tasks",
27925
28155
  taskId,
@@ -27931,7 +28161,7 @@ async function registerRoutes(ctx) {
27931
28161
  "Task",
27932
28162
  params
27933
28163
  );
27934
- await app.service("sessions").patch(sessionId, { status: SessionStatus4.IDLE, ready_for_prompt: true }, params).catch(() => {
28164
+ await app.service("sessions").patch(sessionId, { status: SessionStatus5.IDLE, ready_for_prompt: true }, params).catch(() => {
27935
28165
  });
27936
28166
  }
27937
28167
  });
@@ -27940,7 +28170,7 @@ async function registerRoutes(ctx) {
27940
28170
  setImmediate(async () => {
27941
28171
  try {
27942
28172
  console.log(
27943
- `\u{1F680} [Daemon] Routing ${session.agentic_tool} to Feathers/WebSocket executor (task ${shortId14(taskId)})`
28173
+ `\u{1F680} [Daemon] Routing ${session.agentic_tool} to Feathers/WebSocket executor (task ${shortId15(taskId)})`
27944
28174
  );
27945
28175
  await sessionsService.executeTask(
27946
28176
  sessionId,
@@ -27954,12 +28184,12 @@ async function registerRoutes(ctx) {
27954
28184
  params
27955
28185
  );
27956
28186
  console.log(
27957
- `\u2705 [Daemon] Executor spawned for session ${shortId14(sessionId)}, waiting for task completion`
28187
+ `\u2705 [Daemon] Executor spawned for session ${shortId15(sessionId)}, waiting for task completion`
27958
28188
  );
27959
28189
  } catch (error51) {
27960
28190
  const errorMessage = error51 instanceof Error ? error51.message : String(error51);
27961
28191
  console.error(
27962
- `\u274C [Daemon] Executor spawn failed for session=${shortId14(sessionId)} task=${shortId14(taskId)} agent=${session.agentic_tool} unix_username=${session.unix_username ?? "null"}: ${errorMessage}`,
28192
+ `\u274C [Daemon] Executor spawn failed for session=${shortId15(sessionId)} task=${shortId15(taskId)} agent=${session.agentic_tool} unix_username=${session.unix_username ?? "null"}: ${errorMessage}`,
27963
28193
  error51
27964
28194
  );
27965
28195
  await safePatch(
@@ -28012,7 +28242,7 @@ ${errorMessage}`;
28012
28242
  {
28013
28243
  async create(data, params) {
28014
28244
  console.log(
28015
- `\u{1F4E8} [Daemon] Prompt request for session ${params.route?.id ? shortId14(params.route.id) : "unknown"}`
28245
+ `\u{1F4E8} [Daemon] Prompt request for session ${params.route?.id ? shortId15(params.route.id) : "unknown"}`
28016
28246
  );
28017
28247
  console.log(` Permission mode: ${data.permissionMode || "not specified"}`);
28018
28248
  console.log(` Streaming: ${data.stream !== false}`);
@@ -28040,7 +28270,7 @@ ${errorMessage}`;
28040
28270
  }
28041
28271
  if (session.archived) {
28042
28272
  console.log(
28043
- `\u{1F4E6} [Prompt] Auto-unarchiving session ${shortId14(id)} (was archived: ${session.archived_reason || "unknown reason"})`
28273
+ `\u{1F4E6} [Prompt] Auto-unarchiving session ${shortId15(id)} (was archived: ${session.archived_reason || "unknown reason"})`
28044
28274
  );
28045
28275
  session = await sessionsService.patch(
28046
28276
  id,
@@ -28048,7 +28278,7 @@ ${errorMessage}`;
28048
28278
  params
28049
28279
  );
28050
28280
  }
28051
- if (session.status === SessionStatus4.STOPPING) {
28281
+ if (session.status === SessionStatus5.STOPPING) {
28052
28282
  throw new Error("Cannot send prompt: session is currently stopping");
28053
28283
  }
28054
28284
  const taskRepo = new TaskRepository2(db);
@@ -28058,7 +28288,7 @@ ${errorMessage}`;
28058
28288
  const createdBy = params.user.user_id;
28059
28289
  return await withSessionTurnLock(sessionTurnLocks, id, async () => {
28060
28290
  let lockedSession = await sessionsService.get(id, params);
28061
- if (lockedSession.status === SessionStatus4.STOPPING) {
28291
+ if (lockedSession.status === SessionStatus5.STOPPING) {
28062
28292
  throw new Error("Cannot send prompt: session is currently stopping");
28063
28293
  }
28064
28294
  lockedSession = await reconcileSessionPromptStateIfStuck(lockedSession, taskRepo, params);
@@ -28077,7 +28307,7 @@ ${errorMessage}`;
28077
28307
  }
28078
28308
  });
28079
28309
  console.log(
28080
- `\u{1F4EC} [Prompt] Auto-queued task for session ${shortId14(id)} at position ${queuedTask.queue_position} (session status: ${lockedSession.status}, existing queue items: ${queuedTasks.length})`
28310
+ `\u{1F4EC} [Prompt] Auto-queued task for session ${shortId15(id)} at position ${queuedTask.queue_position} (session status: ${lockedSession.status}, existing queue items: ${queuedTasks.length})`
28081
28311
  );
28082
28312
  app.service("tasks").emit("queued", queuedTask);
28083
28313
  if (sessionCanStartTask(lockedSession.status, lockedSession.ready_for_prompt)) {
@@ -28142,7 +28372,7 @@ ${errorMessage}`;
28142
28372
  if (task.status !== TaskStatus5.CREATED) {
28143
28373
  const hint = task.status === TaskStatus5.QUEUED ? `Queued tasks drain automatically in queue-position order when the session becomes idle \u2014 wait for it, or stop the currently running task to free the queue.` : `Only 'created' tasks may be triggered.`;
28144
28374
  throw new Conflict2(
28145
- `Task ${shortId14(taskId)} cannot be run: status is '${task.status}'. ${hint}`
28375
+ `Task ${shortId15(taskId)} cannot be run: status is '${task.status}'. ${hint}`
28146
28376
  );
28147
28377
  }
28148
28378
  const isInternalCall = !params.provider;
@@ -28184,12 +28414,12 @@ ${errorMessage}`;
28184
28414
  params,
28185
28415
  { ignoredTaskIds: [task.task_id] }
28186
28416
  );
28187
- if (session.status === SessionStatus4.STOPPING) {
28417
+ if (session.status === SessionStatus5.STOPPING) {
28188
28418
  throw new BadRequest5("Cannot run task: session is currently stopping");
28189
28419
  }
28190
28420
  if (!sessionCanStartTask(session.status, session.ready_for_prompt)) {
28191
28421
  throw new Conflict2(
28192
- `Cannot run task ${shortId14(taskId)}: session is '${session.status}'. To enqueue a prompt on a busy session, POST to /sessions/:id/prompt instead \u2014 it creates and queues a task atomically.`
28422
+ `Cannot run task ${shortId15(taskId)}: session is '${session.status}'. To enqueue a prompt on a busy session, POST to /sessions/:id/prompt instead \u2014 it creates and queues a task atomically.`
28193
28423
  );
28194
28424
  }
28195
28425
  return await runExistingTask(
@@ -28308,7 +28538,7 @@ ${errorMessage}`;
28308
28538
  const files = req.files;
28309
28539
  if (DEBUG_UPLOAD2) {
28310
28540
  console.log(
28311
- `\u{1F4CE} [Upload Handler] Processing for session ${sessionId ? shortId14(sessionId) : "unknown"}`
28541
+ `\u{1F4CE} [Upload Handler] Processing for session ${sessionId ? shortId15(sessionId) : "unknown"}`
28312
28542
  );
28313
28543
  console.log(` Destination: ${destination || "branch"}`);
28314
28544
  console.log(` Notify agent: ${notifyAgent === "true" || notifyAgent === true}`);
@@ -28318,14 +28548,14 @@ ${errorMessage}`;
28318
28548
  if (DEBUG_UPLOAD2) {
28319
28549
  console.log(` Auth params:`, {
28320
28550
  hasUser: !!params?.user,
28321
- userId: params?.user?.user_id ? shortId14(params.user.user_id) : void 0,
28551
+ userId: params?.user?.user_id ? shortId15(params.user.user_id) : void 0,
28322
28552
  provider: params?.provider
28323
28553
  });
28324
28554
  }
28325
28555
  ensureMinimumRole(params, ROLES9.MEMBER, "upload files");
28326
28556
  const session = await sessionsService.get(sessionId, params);
28327
28557
  if (!session) {
28328
- console.error(`\u274C [Upload Handler] Session not found: ${shortId14(sessionId)}`);
28558
+ console.error(`\u274C [Upload Handler] Session not found: ${shortId15(sessionId)}`);
28329
28559
  return res.status(404).json({ error: "Session not found" });
28330
28560
  }
28331
28561
  if (branchRbacEnabled) {
@@ -28350,7 +28580,7 @@ ${errorMessage}`;
28350
28580
  const canUpload = PERMISSION_RANK[effectiveLevel] >= PERMISSION_RANK.prompt || effectiveLevel === "session" && session.created_by === userId;
28351
28581
  if (!canUpload) {
28352
28582
  console.error(
28353
- `\u274C [Upload Handler] User ${shortId14(userId)} has '${effectiveLevel}' permission, cannot upload to branch ${shortId14(wt.branch_id)}`
28583
+ `\u274C [Upload Handler] User ${shortId15(userId)} has '${effectiveLevel}' permission, cannot upload to branch ${shortId15(wt.branch_id)}`
28354
28584
  );
28355
28585
  return res.status(403).json({ error: "Not authorized to upload to this session" });
28356
28586
  }
@@ -28418,7 +28648,7 @@ ${errorMessage}`;
28418
28648
  console.log(" Has auth header:", !!req.headers.authorization);
28419
28649
  console.log(
28420
28650
  " Session ID param:",
28421
- req.params.sessionId ? shortId14(req.params.sessionId) : "unknown"
28651
+ req.params.sessionId ? shortId15(req.params.sessionId) : "unknown"
28422
28652
  );
28423
28653
  }
28424
28654
  next();
@@ -28444,7 +28674,7 @@ ${errorMessage}`;
28444
28674
  });
28445
28675
  if (DEBUG_UPLOAD2) {
28446
28676
  console.log("\u2705 [Upload Auth] Authentication successful");
28447
- console.log(" User:", result.user?.user_id ? shortId14(result.user.user_id) : "unknown");
28677
+ console.log(" User:", result.user?.user_id ? shortId15(result.user.user_id) : "unknown");
28448
28678
  }
28449
28679
  req.feathers = {
28450
28680
  user: result.user,
@@ -28467,7 +28697,7 @@ ${errorMessage}`;
28467
28697
  console.log("\u2705 [Upload Route] Authentication passed");
28468
28698
  console.log(
28469
28699
  " User:",
28470
- req.feathers?.user?.user_id ? shortId14(req.feathers.user.user_id) : "unknown"
28700
+ req.feathers?.user?.user_id ? shortId15(req.feathers.user.user_id) : "unknown"
28471
28701
  );
28472
28702
  }
28473
28703
  next();
@@ -28509,68 +28739,36 @@ ${errorMessage}`;
28509
28739
  const id = params.route?.id;
28510
28740
  if (!id) throw new Error("Session ID required");
28511
28741
  const stopReason = data && typeof data === "object" && "reason" in data && typeof data.reason === "string" ? data.reason : void 0;
28512
- const session = await sessionsService.get(id, params);
28513
- const activeStates = [
28514
- SessionStatus4.RUNNING,
28515
- SessionStatus4.AWAITING_PERMISSION,
28516
- SessionStatus4.STOPPING
28517
- ];
28518
- if (!activeStates.includes(session.status)) {
28519
- return {
28520
- success: false,
28521
- reason: `Session cannot be stopped (status: ${session.status})`
28522
- };
28523
- }
28524
- const targetTasksArray = await findActiveTasksForSession(app, id);
28525
- if (targetTasksArray.length === 0) {
28526
- console.warn(
28527
- `\u26A0\uFE0F [Stop] No active tasks for session ${shortId14(id)}, resetting to IDLE${stopReason ? ` (reason: ${stopReason})` : ""}`
28528
- );
28529
- await app.service("sessions").patch(
28530
- id,
28742
+ const sessionsServiceWithHooks = app.service("sessions");
28743
+ const result = await withSessionTurnLock(
28744
+ sessionTurnLocks,
28745
+ id,
28746
+ async () => stopSessionPreserveQueue(
28531
28747
  {
28532
- status: SessionStatus4.IDLE,
28533
- ready_for_prompt: true
28748
+ app,
28749
+ taskRepo: new TaskRepository2(db),
28750
+ sessionsService: sessionsServiceWithHooks,
28751
+ tasksService,
28752
+ killExecutorProcess
28534
28753
  },
28535
- params
28536
- );
28537
- return {
28538
- success: true,
28539
- status: SessionStatus4.IDLE,
28540
- reason: "No active tasks found, session reset to idle"
28541
- };
28542
- }
28543
- const latestTask = targetTasksArray[0];
28544
- console.log(
28545
- `\u{1F6D1} [Stop] Stopping task ${shortId14(latestTask.task_id)} for session ${shortId14(id)}${stopReason ? ` (reason: ${stopReason})` : ""}`
28754
+ id,
28755
+ params,
28756
+ { reason: stopReason }
28757
+ )
28546
28758
  );
28547
- const processKilled = killExecutorProcess(id);
28548
- if (!processKilled) {
28549
- console.warn(
28550
- `\u26A0\uFE0F [Stop] No tracked process for session ${shortId14(id)} \u2014 executor may have already exited`
28551
- );
28552
- }
28553
- try {
28554
- await tasksService.patch(latestTask.task_id, {
28555
- status: TaskStatus5.STOPPED,
28556
- completed_at: (/* @__PURE__ */ new Date()).toISOString()
28759
+ if (result.success) {
28760
+ setImmediate(async () => {
28761
+ try {
28762
+ await sessionsServiceWithHooks.triggerQueueProcessing(id, params);
28763
+ } catch (error51) {
28764
+ console.error(
28765
+ `\u274C [Stop] Failed to process queue after stopping session ${shortId15(id)}:`,
28766
+ error51
28767
+ );
28768
+ }
28557
28769
  });
28558
- } catch (error51) {
28559
- console.error(`\u274C [Stop] Failed to patch task to STOPPED:`, error51);
28560
28770
  }
28561
- try {
28562
- await app.service("sessions").patch(
28563
- id,
28564
- {
28565
- status: SessionStatus4.IDLE,
28566
- ready_for_prompt: true
28567
- },
28568
- params
28569
- );
28570
- } catch (error51) {
28571
- console.error(`\u274C [Stop] Failed to patch session to IDLE:`, error51);
28572
- }
28573
- return { success: true, status: SessionStatus4.IDLE };
28771
+ return result;
28574
28772
  }
28575
28773
  },
28576
28774
  {
@@ -28603,7 +28801,7 @@ ${errorMessage}`;
28603
28801
  async function processNextQueuedTask(sessionId, params) {
28604
28802
  const existingLock = sessionTurnLocks.get(sessionId);
28605
28803
  if (existingLock) {
28606
- console.log(`\u23F3 [Queue] Session turn in progress for ${shortId14(sessionId)}, waiting...`);
28804
+ console.log(`\u23F3 [Queue] Session turn in progress for ${shortId15(sessionId)}, waiting...`);
28607
28805
  await existingLock.catch(() => void 0);
28608
28806
  if (!queueRetryScheduled.has(sessionId)) {
28609
28807
  queueRetryScheduled.add(sessionId);
@@ -28612,7 +28810,7 @@ ${errorMessage}`;
28612
28810
  try {
28613
28811
  await processNextQueuedTask(sessionId, params);
28614
28812
  } catch (error51) {
28615
- console.error(`\u274C [Queue] Retry failed for session ${shortId14(sessionId)}:`, error51);
28813
+ console.error(`\u274C [Queue] Retry failed for session ${shortId15(sessionId)}:`, error51);
28616
28814
  }
28617
28815
  });
28618
28816
  }
@@ -28634,7 +28832,7 @@ ${errorMessage}`;
28634
28832
  const taskRepo = new TaskRepository2(db);
28635
28833
  const nextTask = await taskRepo.getNextQueued(sessionId);
28636
28834
  if (!nextTask) {
28637
- taskQueueDebug(`\u{1F4ED} No queued tasks for session ${shortId14(sessionId)}`);
28835
+ taskQueueDebug(`\u{1F4ED} No queued tasks for session ${shortId15(sessionId)}`);
28638
28836
  return;
28639
28837
  }
28640
28838
  const userId = nextTask.metadata?.queued_by_user_id;
@@ -28645,7 +28843,7 @@ ${errorMessage}`;
28645
28843
  user: queuedByUser
28646
28844
  } : params;
28647
28845
  console.log(
28648
- `\u{1F4EC} Processing queued task ${shortId14(nextTask.task_id)} (position ${nextTask.queue_position}) with user context: ${queuedByUser ? shortId14(queuedByUser.user_id) : "none"}`
28846
+ `\u{1F4EC} Processing queued task ${shortId15(nextTask.task_id)} (position ${nextTask.queue_position}) with user context: ${queuedByUser ? shortId15(queuedByUser.user_id) : "none"}`
28649
28847
  );
28650
28848
  const session = await reconcileSessionPromptStateIfStuck(
28651
28849
  await sessionsService.get(sessionId, taskParams),
@@ -28654,13 +28852,13 @@ ${errorMessage}`;
28654
28852
  );
28655
28853
  if (!sessionCanStartTask(session.status, session.ready_for_prompt)) {
28656
28854
  console.log(
28657
- `\u23F8\uFE0F [Queue] Session ${shortId14(sessionId)} is ${session.status}, task ${shortId14(nextTask.task_id)} waiting in queue (will be processed when session becomes IDLE via patch hook)`
28855
+ `\u23F8\uFE0F [Queue] Session ${shortId15(sessionId)} is ${session.status}, task ${shortId15(nextTask.task_id)} waiting in queue (will be processed when session becomes IDLE via patch hook)`
28658
28856
  );
28659
28857
  return;
28660
28858
  }
28661
28859
  const stillQueued = await taskRepo.findById(nextTask.task_id);
28662
28860
  if (!stillQueued || stillQueued.status !== TaskStatus5.QUEUED) {
28663
- console.log(`\u26A0\uFE0F Queued task ${shortId14(nextTask.task_id)} no longer queued, skipping`);
28861
+ console.log(`\u26A0\uFE0F Queued task ${shortId15(nextTask.task_id)} no longer queued, skipping`);
28664
28862
  return;
28665
28863
  }
28666
28864
  const source = nextTask.metadata?.source;
@@ -28672,7 +28870,7 @@ ${errorMessage}`;
28672
28870
  },
28673
28871
  taskParams
28674
28872
  );
28675
- console.log(`\u2705 Queued task drained for session ${shortId14(sessionId)}`);
28873
+ console.log(`\u2705 Queued task drained for session ${shortId15(sessionId)}`);
28676
28874
  }
28677
28875
  sessionsService.setQueueProcessor(async (sessionId, params) => {
28678
28876
  try {