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
@@ -495,6 +495,9 @@ async function getBaseUrl() {
495
495
  if (config.daemon?.base_url) {
496
496
  return validateBaseUrl(config.daemon.base_url);
497
497
  }
498
+ if (config.ui?.base_url) {
499
+ return validateBaseUrl(config.ui.base_url);
500
+ }
498
501
  const defaults = getDefaultConfig();
499
502
  const envPort = process.env.PORT ? Number.parseInt(process.env.PORT, 10) : void 0;
500
503
  const port = envPort || config.daemon?.port || defaults.daemon?.port || DAEMON.DEFAULT_PORT;
@@ -509,8 +512,11 @@ async function requirePublicBaseUrl() {
509
512
  if (config.daemon?.base_url) {
510
513
  return validateBaseUrl(config.daemon.base_url);
511
514
  }
515
+ if (config.ui?.base_url) {
516
+ return validateBaseUrl(config.ui.base_url);
517
+ }
512
518
  throw new PublicBaseUrlNotConfiguredError(
513
- "No public base URL configured. Set the AGOR_BASE_URL environment variable or `daemon.base_url` in ~/.agor/config.yaml to the daemon's browser-reachable URL (e.g. https://agor.example.com). This is required so OAuth providers can redirect users back to a URL their browser can reach \u2014 the localhost fallback only works for browsers on the daemon machine."
519
+ "No public base URL configured. Set the AGOR_BASE_URL environment variable or `daemon.base_url` (preferred) / `ui.base_url` (legacy) in ~/.agor/config.yaml to the daemon's browser-reachable URL (e.g. https://agor.example.com). This is required so OAuth providers can redirect users back to a URL their browser can reach \u2014 the localhost fallback only works for browsers on the daemon machine."
514
520
  );
515
521
  }
516
522
  function loadConfigSync() {
@@ -1189,15 +1195,35 @@ var init_schedule = __esm({
1189
1195
  });
1190
1196
 
1191
1197
  // src/types/session.ts
1198
+ var SessionStatus, EXECUTING_SESSION_STATUSES;
1192
1199
  var init_session = __esm({
1193
1200
  "src/types/session.ts"() {
1194
1201
  "use strict";
1195
1202
  init_cjs_shims();
1203
+ SessionStatus = {
1204
+ IDLE: "idle",
1205
+ RUNNING: "running",
1206
+ STOPPING: "stopping",
1207
+ // Stop requested, waiting for task to stop
1208
+ AWAITING_PERMISSION: "awaiting_permission",
1209
+ AWAITING_INPUT: "awaiting_input",
1210
+ // Legacy / pre-#1177: AskUserQuestion was disallowed at the SDK; new sessions never enter this state, kept for historical rows
1211
+ TIMED_OUT: "timed_out",
1212
+ // Permission/input request timed out, executor exited — user must re-prompt
1213
+ COMPLETED: "completed",
1214
+ FAILED: "failed"
1215
+ };
1216
+ EXECUTING_SESSION_STATUSES = /* @__PURE__ */ new Set([
1217
+ SessionStatus.RUNNING,
1218
+ SessionStatus.STOPPING,
1219
+ SessionStatus.AWAITING_PERMISSION,
1220
+ SessionStatus.AWAITING_INPUT
1221
+ ]);
1196
1222
  }
1197
1223
  });
1198
1224
 
1199
1225
  // src/types/task.ts
1200
- var TaskStatus, TERMINAL_TASK_STATUSES;
1226
+ var TaskStatus, TERMINAL_TASK_STATUSES, EXECUTING_TASK_STATUSES;
1201
1227
  var init_task = __esm({
1202
1228
  "src/types/task.ts"() {
1203
1229
  "use strict";
@@ -1225,6 +1251,12 @@ var init_task = __esm({
1225
1251
  TaskStatus.STOPPED,
1226
1252
  TaskStatus.TIMED_OUT
1227
1253
  ]);
1254
+ EXECUTING_TASK_STATUSES = /* @__PURE__ */ new Set([
1255
+ TaskStatus.RUNNING,
1256
+ TaskStatus.STOPPING,
1257
+ TaskStatus.AWAITING_PERMISSION,
1258
+ TaskStatus.AWAITING_INPUT
1259
+ ]);
1228
1260
  }
1229
1261
  });
1230
1262
 
@@ -1388,6 +1420,8 @@ __export(schema_postgres_exports, {
1388
1420
  serializedSessions: () => serializedSessions,
1389
1421
  sessionEnvSelections: () => sessionEnvSelections,
1390
1422
  sessionMcpServers: () => sessionMcpServers,
1423
+ sessionRelationships: () => sessionRelationships,
1424
+ sessionRelationshipsRelations: () => sessionRelationshipsRelations,
1391
1425
  sessions: () => sessions,
1392
1426
  sessionsRelations: () => sessionsRelations,
1393
1427
  tasks: () => tasks,
@@ -1396,7 +1430,7 @@ __export(schema_postgres_exports, {
1396
1430
  userMcpOauthTokens: () => userMcpOauthTokens,
1397
1431
  users: () => users
1398
1432
  });
1399
- var import_drizzle_orm2, import_pg_core, bytea, t, sessions, tasks, serializedSessions, messages, boards, repos, branches, branchOwners, boardOwners, schedules, users, groups, groupMemberships, branchGroupGrants, boardGroupGrants, appVariables, userApiKeys, mcpServers, cardTypes, cards, artifacts, artifactTrustGrants, boardObjects, sessionMcpServers, userMcpOauthTokens, boardComments, gatewayChannels, threadSessionMap, sessionEnvSelections, kbNamespaces, kbNamespaceAcl, kbDocuments, kbDocumentVersions, kbDocumentUnits, kbEmbeddingSpaces, kbGraphNodes, kbGraphEdges, sessionsRelations, branchesRelations, schedulesRelations;
1433
+ var import_drizzle_orm2, import_pg_core, bytea, t, sessions, sessionRelationships, tasks, serializedSessions, messages, boards, repos, branches, branchOwners, boardOwners, schedules, users, groups, groupMemberships, branchGroupGrants, boardGroupGrants, appVariables, userApiKeys, mcpServers, cardTypes, cards, artifacts, artifactTrustGrants, boardObjects, sessionMcpServers, userMcpOauthTokens, boardComments, gatewayChannels, threadSessionMap, sessionEnvSelections, kbNamespaces, kbNamespaceAcl, kbDocuments, kbDocumentVersions, kbDocumentUnits, kbEmbeddingSpaces, kbGraphNodes, kbGraphEdges, sessionsRelations, sessionRelationshipsRelations, branchesRelations, schedulesRelations;
1400
1434
  var init_schema_postgres = __esm({
1401
1435
  "src/db/schema.postgres.ts"() {
1402
1436
  "use strict";
@@ -1491,6 +1525,36 @@ var init_schema_postgres = __esm({
1491
1525
  scheduleRunUnique: (0, import_pg_core.uniqueIndex)("sessions_schedule_run_unique").on(table.schedule_id, table.scheduled_run_at).where(import_drizzle_orm2.sql`${table.schedule_id} IS NOT NULL AND ${table.scheduled_run_at} IS NOT NULL`)
1492
1526
  })
1493
1527
  );
1528
+ sessionRelationships = (0, import_pg_core.pgTable)(
1529
+ "session_relationships",
1530
+ {
1531
+ relationship_id: (0, import_pg_core.varchar)("relationship_id", { length: 36 }).primaryKey(),
1532
+ source_session_id: (0, import_pg_core.varchar)("source_session_id", { length: 36 }).notNull().references(() => sessions.session_id, { onDelete: "cascade" }),
1533
+ target_session_id: (0, import_pg_core.varchar)("target_session_id", { length: 36 }).notNull().references(() => sessions.session_id, { onDelete: "cascade" }),
1534
+ relationship_type: (0, import_pg_core.text)("relationship_type", { enum: ["remote_create"] }).notNull(),
1535
+ created_by: (0, import_pg_core.varchar)("created_by", { length: 36 }).notNull(),
1536
+ created_at: t.timestamp("created_at").notNull(),
1537
+ updated_at: t.timestamp("updated_at"),
1538
+ callback_enabled: t.bool("callback_enabled").notNull().default(false),
1539
+ callback_session_id: (0, import_pg_core.varchar)("callback_session_id", { length: 36 }).references(
1540
+ () => sessions.session_id,
1541
+ {
1542
+ onDelete: "set null"
1543
+ }
1544
+ ),
1545
+ data: t.json("data")
1546
+ },
1547
+ (table) => ({
1548
+ sourceIdx: (0, import_pg_core.index)("session_relationships_source_idx").on(table.source_session_id),
1549
+ targetIdx: (0, import_pg_core.index)("session_relationships_target_idx").on(table.target_session_id),
1550
+ callbackIdx: (0, import_pg_core.index)("session_relationships_callback_idx").on(table.callback_session_id),
1551
+ sourceTargetTypeUnique: (0, import_pg_core.uniqueIndex)("session_relationships_source_target_type_unique").on(
1552
+ table.source_session_id,
1553
+ table.target_session_id,
1554
+ table.relationship_type
1555
+ )
1556
+ })
1557
+ );
1494
1558
  tasks = (0, import_pg_core.pgTable)(
1495
1559
  "tasks",
1496
1560
  {
@@ -2027,6 +2091,12 @@ var init_schema_postgres = __esm({
2027
2091
  branch_id: (0, import_pg_core.varchar)("branch_id", { length: 36 }).references(() => branches.branch_id, {
2028
2092
  onDelete: "set null"
2029
2093
  }),
2094
+ source_session_id: (0, import_pg_core.varchar)("source_session_id", { length: 36 }).references(
2095
+ () => sessions.session_id,
2096
+ {
2097
+ onDelete: "set null"
2098
+ }
2099
+ ),
2030
2100
  board_id: (0, import_pg_core.varchar)("board_id", { length: 36 }).notNull().references(() => boards.board_id, { onDelete: "cascade" }),
2031
2101
  name: (0, import_pg_core.text)("name").notNull(),
2032
2102
  description: (0, import_pg_core.text)("description"),
@@ -2053,6 +2123,7 @@ var init_schema_postgres = __esm({
2053
2123
  },
2054
2124
  (table) => ({
2055
2125
  branchIdx: (0, import_pg_core.index)("artifacts_branch_idx").on(table.branch_id),
2126
+ sourceSessionIdx: (0, import_pg_core.index)("artifacts_source_session_idx").on(table.source_session_id),
2056
2127
  boardIdx: (0, import_pg_core.index)("artifacts_board_idx").on(table.board_id),
2057
2128
  archivedIdx: (0, import_pg_core.index)("artifacts_archived_idx").on(table.archived),
2058
2129
  publicIdx: (0, import_pg_core.index)("artifacts_public_idx").on(table.public)
@@ -2209,7 +2280,7 @@ var init_schema_postgres = __esm({
2209
2280
  // Materialized for queries
2210
2281
  name: (0, import_pg_core.text)("name").notNull(),
2211
2282
  channel_type: (0, import_pg_core.text)("channel_type", {
2212
- enum: ["slack", "discord", "whatsapp", "telegram", "github"]
2283
+ enum: ["slack", "discord", "whatsapp", "telegram", "github", "teams"]
2213
2284
  }).notNull(),
2214
2285
  target_branch_id: (0, import_pg_core.varchar)("target_branch_id", { length: 36 }).notNull().references(() => branches.branch_id, { onDelete: "cascade" }),
2215
2286
  agor_user_id: (0, import_pg_core.varchar)("agor_user_id", { length: 36 }).notNull(),
@@ -2593,7 +2664,7 @@ var init_schema_postgres = __esm({
2593
2664
  archivedIdx: (0, import_pg_core.index)("kb_graph_edges_archived_idx").on(table.archived)
2594
2665
  })
2595
2666
  );
2596
- sessionsRelations = (0, import_drizzle_orm2.relations)(sessions, ({ one }) => ({
2667
+ sessionsRelations = (0, import_drizzle_orm2.relations)(sessions, ({ one, many }) => ({
2597
2668
  branch: one(branches, {
2598
2669
  fields: [sessions.branch_id],
2599
2670
  references: [branches.branch_id]
@@ -2601,6 +2672,24 @@ var init_schema_postgres = __esm({
2601
2672
  schedule: one(schedules, {
2602
2673
  fields: [sessions.schedule_id],
2603
2674
  references: [schedules.schedule_id]
2675
+ }),
2676
+ outboundRelationships: many(sessionRelationships, { relationName: "relationshipSource" }),
2677
+ inboundRelationships: many(sessionRelationships, { relationName: "relationshipTarget" })
2678
+ }));
2679
+ sessionRelationshipsRelations = (0, import_drizzle_orm2.relations)(sessionRelationships, ({ one }) => ({
2680
+ sourceSession: one(sessions, {
2681
+ fields: [sessionRelationships.source_session_id],
2682
+ references: [sessions.session_id],
2683
+ relationName: "relationshipSource"
2684
+ }),
2685
+ targetSession: one(sessions, {
2686
+ fields: [sessionRelationships.target_session_id],
2687
+ references: [sessions.session_id],
2688
+ relationName: "relationshipTarget"
2689
+ }),
2690
+ callbackSession: one(sessions, {
2691
+ fields: [sessionRelationships.callback_session_id],
2692
+ references: [sessions.session_id]
2604
2693
  })
2605
2694
  }));
2606
2695
  branchesRelations = (0, import_drizzle_orm2.relations)(branches, ({ many }) => ({
@@ -2653,6 +2742,8 @@ __export(schema_sqlite_exports, {
2653
2742
  serializedSessions: () => serializedSessions2,
2654
2743
  sessionEnvSelections: () => sessionEnvSelections2,
2655
2744
  sessionMcpServers: () => sessionMcpServers2,
2745
+ sessionRelationships: () => sessionRelationships2,
2746
+ sessionRelationshipsRelations: () => sessionRelationshipsRelations2,
2656
2747
  sessions: () => sessions2,
2657
2748
  sessionsRelations: () => sessionsRelations2,
2658
2749
  tasks: () => tasks2,
@@ -2661,7 +2752,7 @@ __export(schema_sqlite_exports, {
2661
2752
  userMcpOauthTokens: () => userMcpOauthTokens2,
2662
2753
  users: () => users2
2663
2754
  });
2664
- var import_drizzle_orm3, import_sqlite_core, t2, sessions2, tasks2, serializedSessions2, messages2, boards2, repos2, branches2, branchOwners2, boardOwners2, schedules2, users2, groups2, groupMemberships2, branchGroupGrants2, boardGroupGrants2, appVariables2, userApiKeys2, mcpServers2, cardTypes2, cards2, artifacts2, artifactTrustGrants2, boardObjects2, sessionMcpServers2, userMcpOauthTokens2, boardComments2, gatewayChannels2, threadSessionMap2, sessionEnvSelections2, kbNamespaces2, kbNamespaceAcl2, kbDocuments2, kbDocumentVersions2, kbDocumentUnits2, kbEmbeddingSpaces2, kbGraphNodes2, kbGraphEdges2, sessionsRelations2, branchesRelations2, schedulesRelations2;
2755
+ var import_drizzle_orm3, import_sqlite_core, t2, sessions2, sessionRelationships2, tasks2, serializedSessions2, messages2, boards2, repos2, branches2, branchOwners2, boardOwners2, schedules2, users2, groups2, groupMemberships2, branchGroupGrants2, boardGroupGrants2, appVariables2, userApiKeys2, mcpServers2, cardTypes2, cards2, artifacts2, artifactTrustGrants2, boardObjects2, sessionMcpServers2, userMcpOauthTokens2, boardComments2, gatewayChannels2, threadSessionMap2, sessionEnvSelections2, kbNamespaces2, kbNamespaceAcl2, kbDocuments2, kbDocumentVersions2, kbDocumentUnits2, kbEmbeddingSpaces2, kbGraphNodes2, kbGraphEdges2, sessionsRelations2, sessionRelationshipsRelations2, branchesRelations2, schedulesRelations2;
2665
2756
  var init_schema_sqlite = __esm({
2666
2757
  "src/db/schema.sqlite.ts"() {
2667
2758
  "use strict";
@@ -2753,6 +2844,36 @@ var init_schema_sqlite = __esm({
2753
2844
  scheduleRunUnique: (0, import_sqlite_core.uniqueIndex)("sessions_schedule_run_unique").on(table.schedule_id, table.scheduled_run_at).where(import_drizzle_orm3.sql`${table.schedule_id} IS NOT NULL AND ${table.scheduled_run_at} IS NOT NULL`)
2754
2845
  })
2755
2846
  );
2847
+ sessionRelationships2 = (0, import_sqlite_core.sqliteTable)(
2848
+ "session_relationships",
2849
+ {
2850
+ relationship_id: (0, import_sqlite_core.text)("relationship_id", { length: 36 }).primaryKey(),
2851
+ source_session_id: (0, import_sqlite_core.text)("source_session_id", { length: 36 }).notNull().references(() => sessions2.session_id, { onDelete: "cascade" }),
2852
+ target_session_id: (0, import_sqlite_core.text)("target_session_id", { length: 36 }).notNull().references(() => sessions2.session_id, { onDelete: "cascade" }),
2853
+ relationship_type: (0, import_sqlite_core.text)("relationship_type", { enum: ["remote_create"] }).notNull(),
2854
+ created_by: (0, import_sqlite_core.text)("created_by", { length: 36 }).notNull(),
2855
+ created_at: t2.timestamp("created_at").notNull(),
2856
+ updated_at: t2.timestamp("updated_at"),
2857
+ callback_enabled: t2.bool("callback_enabled").notNull().default(false),
2858
+ callback_session_id: (0, import_sqlite_core.text)("callback_session_id", { length: 36 }).references(
2859
+ () => sessions2.session_id,
2860
+ {
2861
+ onDelete: "set null"
2862
+ }
2863
+ ),
2864
+ data: t2.json("data")
2865
+ },
2866
+ (table) => ({
2867
+ sourceIdx: (0, import_sqlite_core.index)("session_relationships_source_idx").on(table.source_session_id),
2868
+ targetIdx: (0, import_sqlite_core.index)("session_relationships_target_idx").on(table.target_session_id),
2869
+ callbackIdx: (0, import_sqlite_core.index)("session_relationships_callback_idx").on(table.callback_session_id),
2870
+ sourceTargetTypeUnique: (0, import_sqlite_core.uniqueIndex)("session_relationships_source_target_type_unique").on(
2871
+ table.source_session_id,
2872
+ table.target_session_id,
2873
+ table.relationship_type
2874
+ )
2875
+ })
2876
+ );
2756
2877
  tasks2 = (0, import_sqlite_core.sqliteTable)(
2757
2878
  "tasks",
2758
2879
  {
@@ -3297,6 +3418,12 @@ var init_schema_sqlite = __esm({
3297
3418
  branch_id: (0, import_sqlite_core.text)("branch_id", { length: 36 }).references(() => branches2.branch_id, {
3298
3419
  onDelete: "set null"
3299
3420
  }),
3421
+ source_session_id: (0, import_sqlite_core.text)("source_session_id", { length: 36 }).references(
3422
+ () => sessions2.session_id,
3423
+ {
3424
+ onDelete: "set null"
3425
+ }
3426
+ ),
3300
3427
  board_id: (0, import_sqlite_core.text)("board_id", { length: 36 }).notNull().references(() => boards2.board_id, { onDelete: "cascade" }),
3301
3428
  name: (0, import_sqlite_core.text)("name").notNull(),
3302
3429
  description: (0, import_sqlite_core.text)("description"),
@@ -3323,6 +3450,7 @@ var init_schema_sqlite = __esm({
3323
3450
  },
3324
3451
  (table) => ({
3325
3452
  branchIdx: (0, import_sqlite_core.index)("artifacts_branch_idx").on(table.branch_id),
3453
+ sourceSessionIdx: (0, import_sqlite_core.index)("artifacts_source_session_idx").on(table.source_session_id),
3326
3454
  boardIdx: (0, import_sqlite_core.index)("artifacts_board_idx").on(table.board_id),
3327
3455
  archivedIdx: (0, import_sqlite_core.index)("artifacts_archived_idx").on(table.archived),
3328
3456
  publicIdx: (0, import_sqlite_core.index)("artifacts_public_idx").on(table.public)
@@ -3481,7 +3609,7 @@ var init_schema_sqlite = __esm({
3481
3609
  // Materialized for queries
3482
3610
  name: (0, import_sqlite_core.text)("name").notNull(),
3483
3611
  channel_type: (0, import_sqlite_core.text)("channel_type", {
3484
- enum: ["slack", "discord", "whatsapp", "telegram", "github"]
3612
+ enum: ["slack", "discord", "whatsapp", "telegram", "github", "teams"]
3485
3613
  }).notNull(),
3486
3614
  target_branch_id: (0, import_sqlite_core.text)("target_branch_id", { length: 36 }).notNull().references(() => branches2.branch_id, { onDelete: "cascade" }),
3487
3615
  agor_user_id: (0, import_sqlite_core.text)("agor_user_id", { length: 36 }).notNull(),
@@ -3864,7 +3992,7 @@ var init_schema_sqlite = __esm({
3864
3992
  archivedIdx: (0, import_sqlite_core.index)("kb_graph_edges_archived_idx").on(table.archived)
3865
3993
  })
3866
3994
  );
3867
- sessionsRelations2 = (0, import_drizzle_orm3.relations)(sessions2, ({ one }) => ({
3995
+ sessionsRelations2 = (0, import_drizzle_orm3.relations)(sessions2, ({ one, many }) => ({
3868
3996
  branch: one(branches2, {
3869
3997
  fields: [sessions2.branch_id],
3870
3998
  references: [branches2.branch_id]
@@ -3872,6 +4000,24 @@ var init_schema_sqlite = __esm({
3872
4000
  schedule: one(schedules2, {
3873
4001
  fields: [sessions2.schedule_id],
3874
4002
  references: [schedules2.schedule_id]
4003
+ }),
4004
+ outboundRelationships: many(sessionRelationships2, { relationName: "relationshipSource" }),
4005
+ inboundRelationships: many(sessionRelationships2, { relationName: "relationshipTarget" })
4006
+ }));
4007
+ sessionRelationshipsRelations2 = (0, import_drizzle_orm3.relations)(sessionRelationships2, ({ one }) => ({
4008
+ sourceSession: one(sessions2, {
4009
+ fields: [sessionRelationships2.source_session_id],
4010
+ references: [sessions2.session_id],
4011
+ relationName: "relationshipSource"
4012
+ }),
4013
+ targetSession: one(sessions2, {
4014
+ fields: [sessionRelationships2.target_session_id],
4015
+ references: [sessions2.session_id],
4016
+ relationName: "relationshipTarget"
4017
+ }),
4018
+ callbackSession: one(sessions2, {
4019
+ fields: [sessionRelationships2.callback_session_id],
4020
+ references: [sessions2.session_id]
3875
4021
  })
3876
4022
  }));
3877
4023
  branchesRelations2 = (0, import_drizzle_orm3.relations)(branches2, ({ many }) => ({
@@ -3967,6 +4113,7 @@ __export(schema_exports, {
3967
4113
  serializedSessions: () => serializedSessions3,
3968
4114
  sessionEnvSelections: () => sessionEnvSelections3,
3969
4115
  sessionMcpServers: () => sessionMcpServers3,
4116
+ sessionRelationships: () => sessionRelationships3,
3970
4117
  sessions: () => sessions3,
3971
4118
  tasks: () => tasks3,
3972
4119
  threadSessionMap: () => threadSessionMap3,
@@ -3974,7 +4121,7 @@ __export(schema_exports, {
3974
4121
  userMcpOauthTokens: () => userMcpOauthTokens3,
3975
4122
  users: () => users3
3976
4123
  });
3977
- var dialect, schema, sessions3, tasks3, messages3, boards3, repos3, branches3, branchOwners3, boardOwners3, groups3, groupMemberships3, branchGroupGrants3, boardGroupGrants3, schedules3, users3, appVariables3, mcpServers3, cardTypes3, cards3, artifacts3, artifactTrustGrants3, boardObjects3, sessionMcpServers3, sessionEnvSelections3, userMcpOauthTokens3, boardComments3, gatewayChannels3, threadSessionMap3, userApiKeys3, serializedSessions3, kbNamespaces3, kbNamespaceAcl3, kbDocuments3, kbDocumentVersions3, kbDocumentUnits3, kbEmbeddingSpaces3, kbGraphNodes3, kbGraphEdges3;
4124
+ var dialect, schema, sessions3, tasks3, messages3, boards3, repos3, branches3, branchOwners3, boardOwners3, groups3, groupMemberships3, branchGroupGrants3, boardGroupGrants3, schedules3, users3, appVariables3, mcpServers3, cardTypes3, cards3, artifacts3, artifactTrustGrants3, boardObjects3, sessionMcpServers3, sessionRelationships3, sessionEnvSelections3, userMcpOauthTokens3, boardComments3, gatewayChannels3, threadSessionMap3, userApiKeys3, serializedSessions3, kbNamespaces3, kbNamespaceAcl3, kbDocuments3, kbDocumentVersions3, kbDocumentUnits3, kbEmbeddingSpaces3, kbGraphNodes3, kbGraphEdges3;
3978
4125
  var init_schema = __esm({
3979
4126
  "src/db/schema.ts"() {
3980
4127
  "use strict";
@@ -4006,6 +4153,7 @@ var init_schema = __esm({
4006
4153
  artifactTrustGrants3 = schema.artifactTrustGrants;
4007
4154
  boardObjects3 = schema.boardObjects;
4008
4155
  sessionMcpServers3 = schema.sessionMcpServers;
4156
+ sessionRelationships3 = schema.sessionRelationships;
4009
4157
  sessionEnvSelections3 = schema.sessionEnvSelections;
4010
4158
  userMcpOauthTokens3 = schema.userMcpOauthTokens;
4011
4159
  boardComments3 = schema.boardComments;
@@ -4228,8 +4376,8 @@ function createPostgresDatabase(config) {
4228
4376
  if (config.ssl !== void 0) {
4229
4377
  options.ssl = config.ssl;
4230
4378
  }
4231
- const sql15 = (0, import_postgres.default)(config.url, options);
4232
- return (0, import_postgres_js.drizzle)(sql15, { schema: schema_postgres_exports });
4379
+ const sql16 = (0, import_postgres.default)(config.url, options);
4380
+ return (0, import_postgres_js.drizzle)(sql16, { schema: schema_postgres_exports });
4233
4381
  } catch (error) {
4234
4382
  throw new DatabaseConnectionError(
4235
4383
  `Failed to create PostgreSQL client: ${error instanceof Error ? error.message : String(error)}`,
@@ -5365,6 +5513,7 @@ var FS_ACCESS_RANK = {
5365
5513
  };
5366
5514
  var VIEW_OR_BETTER_BRANCH_PERMISSIONS = ["view", "session", "prompt", "all"];
5367
5515
  var BRANCH_PERMISSION_SOURCES = ["board", "override"];
5516
+ var FS_ACCESS_BRANCH_PERMISSIONS = ["read", "write"];
5368
5517
  var BranchRepository = class {
5369
5518
  constructor(db) {
5370
5519
  this.db = db;
@@ -5858,6 +6007,83 @@ var BranchRepository = class {
5858
6007
  }
5859
6008
  return Array.from(userIds);
5860
6009
  }
6010
+ /**
6011
+ * Find users whose explicit branch or aligned-board grants should materialize
6012
+ * into filesystem access for the branch.
6013
+ *
6014
+ * This intentionally excludes ambient "others" access because there is no
6015
+ * bounded user set to expand. Board owners apply whenever the branch is
6016
+ * explicitly aligned to board permissions (`permission_source = 'board'`);
6017
+ * board group grants additionally require a shared board. Override branches
6018
+ * must not inherit board grants.
6019
+ */
6020
+ async findExplicitFsAccessUserIds(branchId) {
6021
+ const branchRow = await select(this.db, {
6022
+ board_id: branches3.board_id,
6023
+ permission_source: branches3.permission_source
6024
+ }).from(branches3).where((0, import_drizzle_orm11.eq)(branches3.branch_id, branchId)).one();
6025
+ const ownerRows = await select(this.db, { user_id: branchOwners3.user_id }).from(branchOwners3).where((0, import_drizzle_orm11.eq)(branchOwners3.branch_id, branchId)).all();
6026
+ const groupRows = await select(this.db, { user_id: groupMemberships3.user_id }).from(branchGroupGrants3).innerJoin(groupMemberships3, (0, import_drizzle_orm11.eq)(groupMemberships3.group_id, branchGroupGrants3.group_id)).innerJoin(
6027
+ groups3,
6028
+ (0, import_drizzle_orm11.and)((0, import_drizzle_orm11.eq)(groups3.group_id, branchGroupGrants3.group_id), (0, import_drizzle_orm11.eq)(groups3.archived, false))
6029
+ ).where(
6030
+ (0, import_drizzle_orm11.and)(
6031
+ (0, import_drizzle_orm11.eq)(branchGroupGrants3.branch_id, branchId),
6032
+ (0, import_drizzle_orm11.inArray)(
6033
+ import_drizzle_orm11.sql`coalesce(${branchGroupGrants3.fs_access}, 'read')`,
6034
+ FS_ACCESS_BRANCH_PERMISSIONS
6035
+ )
6036
+ )
6037
+ ).all();
6038
+ const isBoardAligned = branchRow?.permission_source === "board" && branchRow.board_id;
6039
+ const boardOwnerRows = isBoardAligned ? await select(this.db, { user_id: boardOwners3.user_id }).from(boardOwners3).where((0, import_drizzle_orm11.eq)(boardOwners3.board_id, branchRow.board_id)).all() : [];
6040
+ const boardGroupRows = isBoardAligned ? await select(this.db, { user_id: groupMemberships3.user_id }).from(boardGroupGrants3).innerJoin(groupMemberships3, (0, import_drizzle_orm11.eq)(groupMemberships3.group_id, boardGroupGrants3.group_id)).innerJoin(
6041
+ groups3,
6042
+ (0, import_drizzle_orm11.and)((0, import_drizzle_orm11.eq)(groups3.group_id, boardGroupGrants3.group_id), (0, import_drizzle_orm11.eq)(groups3.archived, false))
6043
+ ).innerJoin(
6044
+ boards3,
6045
+ (0, import_drizzle_orm11.and)(
6046
+ (0, import_drizzle_orm11.eq)(boards3.board_id, boardGroupGrants3.board_id),
6047
+ (0, import_drizzle_orm11.eq)(
6048
+ import_drizzle_orm11.sql`coalesce(${jsonExtract(this.db, boards3.data, "access_mode")}, 'shared')`,
6049
+ "shared"
6050
+ )
6051
+ )
6052
+ ).where(
6053
+ (0, import_drizzle_orm11.and)(
6054
+ (0, import_drizzle_orm11.eq)(boardGroupGrants3.board_id, branchRow.board_id),
6055
+ (0, import_drizzle_orm11.inArray)(
6056
+ import_drizzle_orm11.sql`coalesce(${boardGroupGrants3.fs_access}, 'read')`,
6057
+ FS_ACCESS_BRANCH_PERMISSIONS
6058
+ )
6059
+ )
6060
+ ).all() : [];
6061
+ const userIds = /* @__PURE__ */ new Set();
6062
+ for (const row of ownerRows) {
6063
+ userIds.add(row.user_id);
6064
+ }
6065
+ for (const row of groupRows) {
6066
+ userIds.add(row.user_id);
6067
+ }
6068
+ for (const row of boardOwnerRows) {
6069
+ userIds.add(row.user_id);
6070
+ }
6071
+ for (const row of boardGroupRows) {
6072
+ userIds.add(row.user_id);
6073
+ }
6074
+ return Array.from(userIds);
6075
+ }
6076
+ async findBoardAlignedBranches(boardId) {
6077
+ const rows = await select(this.db).from(branches3).where(
6078
+ (0, import_drizzle_orm11.and)(
6079
+ (0, import_drizzle_orm11.eq)(branches3.board_id, boardId),
6080
+ (0, import_drizzle_orm11.eq)(branches3.permission_source, "board"),
6081
+ (0, import_drizzle_orm11.eq)(branches3.archived, false)
6082
+ )
6083
+ ).all();
6084
+ const baseUrl = await getBaseUrl();
6085
+ return rows.map((row) => this.rowToBranch(row, baseUrl));
6086
+ }
5861
6087
  /**
5862
6088
  * Get all owners of a branch
5863
6089
  *
@@ -7542,10 +7768,17 @@ init_ids();
7542
7768
  init_database_wrapper();
7543
7769
  init_schema();
7544
7770
 
7771
+ // src/db/repositories/session-relationships.ts
7772
+ init_cjs_shims();
7773
+ var import_drizzle_orm27 = require("drizzle-orm");
7774
+ init_ids();
7775
+ init_database_wrapper();
7776
+ init_schema();
7777
+
7545
7778
  // src/db/repositories/tasks.ts
7546
7779
  init_cjs_shims();
7547
7780
  init_types2();
7548
- var import_drizzle_orm27 = require("drizzle-orm");
7781
+ var import_drizzle_orm28 = require("drizzle-orm");
7549
7782
  init_ids();
7550
7783
  init_database_wrapper();
7551
7784
  init_schema();
@@ -7553,7 +7786,7 @@ init_schema();
7553
7786
  // src/db/repositories/thread-session-map.ts
7554
7787
  init_cjs_shims();
7555
7788
  init_types2();
7556
- var import_drizzle_orm28 = require("drizzle-orm");
7789
+ var import_drizzle_orm29 = require("drizzle-orm");
7557
7790
  init_ids();
7558
7791
  init_database_wrapper();
7559
7792
  init_schema();
@@ -7562,21 +7795,21 @@ init_schema();
7562
7795
  init_cjs_shims();
7563
7796
  var import_node_crypto5 = require("crypto");
7564
7797
  var import_bcryptjs2 = __toESM(require("bcryptjs"), 1);
7565
- var import_drizzle_orm29 = require("drizzle-orm");
7798
+ var import_drizzle_orm30 = require("drizzle-orm");
7566
7799
  init_ids();
7567
7800
  init_database_wrapper();
7568
7801
  init_schema();
7569
7802
 
7570
7803
  // src/db/repositories/user-mcp-oauth-tokens.ts
7571
7804
  init_cjs_shims();
7572
- var import_drizzle_orm30 = require("drizzle-orm");
7805
+ var import_drizzle_orm31 = require("drizzle-orm");
7573
7806
  init_database_wrapper();
7574
7807
  init_schema();
7575
7808
 
7576
7809
  // src/db/repositories/users.ts
7577
7810
  init_cjs_shims();
7578
7811
  init_types2();
7579
- var import_drizzle_orm31 = require("drizzle-orm");
7812
+ var import_drizzle_orm32 = require("drizzle-orm");
7580
7813
 
7581
7814
  // src/config/env-vars.ts
7582
7815
  init_cjs_shims();
@@ -7698,7 +7931,7 @@ var UsersRepository = class {
7698
7931
  */
7699
7932
  async resolveId(id) {
7700
7933
  return resolveByShortIdPrefix(id, "User", async (pattern) => {
7701
- const rows = await select(this.db).from(users3).where((0, import_drizzle_orm31.like)(users3.user_id, pattern)).limit(RESOLVE_SHORT_ID_FETCH_LIMIT).all();
7934
+ const rows = await select(this.db).from(users3).where((0, import_drizzle_orm32.like)(users3.user_id, pattern)).limit(RESOLVE_SHORT_ID_FETCH_LIMIT).all();
7702
7935
  return rows.map((r) => r.user_id);
7703
7936
  });
7704
7937
  }
@@ -7706,7 +7939,7 @@ var UsersRepository = class {
7706
7939
  * Check if unix_username is already taken by another user
7707
7940
  */
7708
7941
  async isUnixUsernameTaken(unixUsername, excludeUserId) {
7709
- const result = await select(this.db).from(users3).where((0, import_drizzle_orm31.eq)(users3.unix_username, unixUsername)).one();
7942
+ const result = await select(this.db).from(users3).where((0, import_drizzle_orm32.eq)(users3.unix_username, unixUsername)).one();
7710
7943
  if (!result) {
7711
7944
  return false;
7712
7945
  }
@@ -7729,7 +7962,7 @@ var UsersRepository = class {
7729
7962
  }
7730
7963
  const insertData = this.userToInsert(data);
7731
7964
  await insert(this.db, users3).values(insertData).run();
7732
- const row = await select(this.db).from(users3).where((0, import_drizzle_orm31.eq)(users3.user_id, insertData.user_id)).one();
7965
+ const row = await select(this.db).from(users3).where((0, import_drizzle_orm32.eq)(users3.user_id, insertData.user_id)).one();
7733
7966
  if (!row) {
7734
7967
  throw new RepositoryError("Failed to retrieve created user");
7735
7968
  }
@@ -7741,7 +7974,7 @@ var UsersRepository = class {
7741
7974
  async findById(id) {
7742
7975
  try {
7743
7976
  const fullId = await this.resolveId(id);
7744
- const result = await select(this.db).from(users3).where((0, import_drizzle_orm31.eq)(users3.user_id, fullId)).one();
7977
+ const result = await select(this.db).from(users3).where((0, import_drizzle_orm32.eq)(users3.user_id, fullId)).one();
7745
7978
  if (!result) {
7746
7979
  return null;
7747
7980
  }
@@ -7757,12 +7990,41 @@ var UsersRepository = class {
7757
7990
  * Find user by email
7758
7991
  */
7759
7992
  async findByEmail(email) {
7760
- const result = await select(this.db).from(users3).where((0, import_drizzle_orm31.eq)(users3.email, email)).one();
7993
+ const result = await select(this.db).from(users3).where((0, import_drizzle_orm32.eq)(users3.email, email)).one();
7761
7994
  if (!result) {
7762
7995
  return null;
7763
7996
  }
7764
7997
  return this.rowToUser(result);
7765
7998
  }
7999
+ /**
8000
+ * Find user by email for external identity providers.
8001
+ *
8002
+ * Agor intentionally keeps exact/case-sensitive email lookup semantics for
8003
+ * auth paths because the schema historically allowed case-distinct emails.
8004
+ * External providers such as Slack and GitHub treat email addresses as a
8005
+ * canonical identity hint, so their alignment path needs a case-insensitive
8006
+ * match. Prefer an exact match when present; otherwise return a
8007
+ * case-insensitive match only when it is unambiguous.
8008
+ */
8009
+ async findByEmailForAlignment(email) {
8010
+ const normalizedEmail = email.trim().toLowerCase();
8011
+ if (!normalizedEmail) return null;
8012
+ const exact = await this.findByEmail(normalizedEmail);
8013
+ if (exact) return exact;
8014
+ const results = await select(this.db).from(users3).where(import_drizzle_orm32.sql`LOWER(${users3.email}) = ${normalizedEmail}`).all();
8015
+ if (results.length !== 1) {
8016
+ if (results.length > 1) {
8017
+ console.warn(
8018
+ `[users] Ambiguous case-insensitive email alignment for ${normalizedEmail}: ${results.map((row) => {
8019
+ const userRow = row;
8020
+ return `${shortId(userRow.user_id)}:${userRow.email}`;
8021
+ }).join(", ")}`
8022
+ );
8023
+ }
8024
+ return null;
8025
+ }
8026
+ return this.rowToUser(results[0]);
8027
+ }
7766
8028
  /**
7767
8029
  * Find all users
7768
8030
  */
@@ -7799,8 +8061,8 @@ var UsersRepository = class {
7799
8061
  await update(this.db, users3).set({
7800
8062
  ...insertData,
7801
8063
  updated_at: /* @__PURE__ */ new Date()
7802
- }).where((0, import_drizzle_orm31.eq)(users3.user_id, fullId)).run();
7803
- const row = await select(this.db).from(users3).where((0, import_drizzle_orm31.eq)(users3.user_id, fullId)).one();
8064
+ }).where((0, import_drizzle_orm32.eq)(users3.user_id, fullId)).run();
8065
+ const row = await select(this.db).from(users3).where((0, import_drizzle_orm32.eq)(users3.user_id, fullId)).one();
7804
8066
  if (!row) {
7805
8067
  throw new RepositoryError("Failed to retrieve updated user");
7806
8068
  }
@@ -7811,7 +8073,7 @@ var UsersRepository = class {
7811
8073
  */
7812
8074
  async delete(id) {
7813
8075
  const fullId = await this.resolveId(id);
7814
- await deleteFrom(this.db, users3).where((0, import_drizzle_orm31.eq)(users3.user_id, fullId)).run();
8076
+ await deleteFrom(this.db, users3).where((0, import_drizzle_orm32.eq)(users3.user_id, fullId)).run();
7815
8077
  }
7816
8078
  /**
7817
8079
  * Get raw database row (internal use only - includes encrypted keys)
@@ -7819,7 +8081,7 @@ var UsersRepository = class {
7819
8081
  async getRawRow(id) {
7820
8082
  try {
7821
8083
  const fullId = await this.resolveId(id);
7822
- const result = await select(this.db).from(users3).where((0, import_drizzle_orm31.eq)(users3.user_id, fullId)).one();
8084
+ const result = await select(this.db).from(users3).where((0, import_drizzle_orm32.eq)(users3.user_id, fullId)).one();
7823
8085
  return result;
7824
8086
  } catch (error) {
7825
8087
  if (error instanceof EntityNotFoundError) {
@@ -7901,7 +8163,7 @@ var UsersRepository = class {
7901
8163
  await update(this.db, users3).set({
7902
8164
  data: { ...row.data, agentic_tools: next },
7903
8165
  updated_at: /* @__PURE__ */ new Date()
7904
- }).where((0, import_drizzle_orm31.eq)(users3.user_id, fullId)).run();
8166
+ }).where((0, import_drizzle_orm32.eq)(users3.user_id, fullId)).run();
7905
8167
  }
7906
8168
  /**
7907
8169
  * Delete a single credential field for a tool.
@@ -7927,7 +8189,7 @@ var UsersRepository = class {
7927
8189
  await update(this.db, users3).set({
7928
8190
  data: { ...row.data, agentic_tools: next },
7929
8191
  updated_at: /* @__PURE__ */ new Date()
7930
- }).where((0, import_drizzle_orm31.eq)(users3.user_id, fullId)).run();
8192
+ }).where((0, import_drizzle_orm32.eq)(users3.user_id, fullId)).run();
7931
8193
  }
7932
8194
  };
7933
8195
 
@@ -8828,7 +9090,7 @@ init_cjs_shims();
8828
9090
 
8829
9091
  // src/config/env-resolver.ts
8830
9092
  init_cjs_shims();
8831
- var import_drizzle_orm32 = require("drizzle-orm");
9093
+ var import_drizzle_orm33 = require("drizzle-orm");
8832
9094
  init_database_wrapper();
8833
9095
  init_schema();
8834
9096
 
@@ -8850,7 +9112,7 @@ init_cjs_shims();
8850
9112
 
8851
9113
  // src/db/index.ts
8852
9114
  init_cjs_shims();
8853
- var import_drizzle_orm34 = require("drizzle-orm");
9115
+ var import_drizzle_orm35 = require("drizzle-orm");
8854
9116
  var import_bcryptjs3 = __toESM(require("bcryptjs"), 1);
8855
9117
  init_ids();
8856
9118
  init_client();
@@ -8861,7 +9123,7 @@ init_first_run_bootstrap();
8861
9123
  init_cjs_shims();
8862
9124
  var import_node_path4 = require("path");
8863
9125
  var import_node_url = require("url");
8864
- var import_drizzle_orm33 = require("drizzle-orm");
9126
+ var import_drizzle_orm34 = require("drizzle-orm");
8865
9127
  var import_migrator = require("drizzle-orm/libsql/migrator");
8866
9128
  var import_migrator2 = require("drizzle-orm/postgres-js/migrator");
8867
9129
  init_database_wrapper();
@@ -9340,6 +9602,30 @@ var UnixIntegrationService = class {
9340
9602
  this.usersRepo = new UsersRepository(db);
9341
9603
  this.repoRepo = new RepoRepository(db);
9342
9604
  }
9605
+ async getUnixUsernamesForUsers(userIds) {
9606
+ const unixUsernames = /* @__PURE__ */ new Set();
9607
+ for (const userId of userIds) {
9608
+ const user = await this.usersRepo.findById(userId);
9609
+ if (user?.unix_username) {
9610
+ unixUsernames.add(user.unix_username);
9611
+ }
9612
+ }
9613
+ return unixUsernames;
9614
+ }
9615
+ async reconcileUnixGroupMembers(groupName, allowedUnixUsernames, options) {
9616
+ if (this.config.daemonUser) {
9617
+ allowedUnixUsernames.add(this.config.daemonUser);
9618
+ }
9619
+ const result = await this.executor.exec(UnixGroupCommands.listGroupMembers(groupName));
9620
+ const currentMembers = result.stdout.trim().split(",").filter(Boolean);
9621
+ for (const unixUsername of currentMembers) {
9622
+ if (allowedUnixUsernames.has(unixUsername)) continue;
9623
+ console.log(
9624
+ `[UnixIntegration] Removing stale ${options.label} group member ${unixUsername} from ${groupName}`
9625
+ );
9626
+ await this.executor.exec(UnixGroupCommands.removeUserFromGroup(unixUsername, groupName));
9627
+ }
9628
+ }
9343
9629
  /**
9344
9630
  * Get the configured daemon user
9345
9631
  *
@@ -9583,19 +9869,26 @@ var UnixIntegrationService = class {
9583
9869
  /**
9584
9870
  * Initialize Unix group for an existing branch
9585
9871
  *
9586
- * Creates group and adds all current owners.
9872
+ * Creates group and adds all users with explicit filesystem access.
9587
9873
  *
9588
9874
  * @param branchId - Branch ID
9589
9875
  */
9590
9876
  async initializeBranchGroup(branchId) {
9591
9877
  const groupName = await this.createBranchGroup(branchId);
9592
- const ownerIds = await this.branchRepo.getOwners(branchId);
9593
- for (const ownerId of ownerIds) {
9594
- await this.addUserToBranchGroup(branchId, ownerId);
9878
+ const userIds = await this.branchRepo.findExplicitFsAccessUserIds(branchId);
9879
+ for (const userId of userIds) {
9880
+ await this.addUserToBranchGroup(branchId, userId);
9595
9881
  }
9882
+ await this.reconcileUnixGroupMembers(groupName, await this.getUnixUsernamesForUsers(userIds), {
9883
+ label: "branch"
9884
+ });
9596
9885
  console.log(
9597
- `[UnixIntegration] Initialized group ${groupName} with ${ownerIds.length} owner(s)`
9886
+ `[UnixIntegration] Initialized group ${groupName} with ${userIds.length} explicit filesystem user(s)`
9598
9887
  );
9888
+ const branch = await this.branchRepo.findById(branchId);
9889
+ if (branch?.repo_id) {
9890
+ await this.syncRepo(branch.repo_id);
9891
+ }
9599
9892
  }
9600
9893
  // ============================================================
9601
9894
  // REPO GROUP MANAGEMENT
@@ -9827,8 +10120,8 @@ var UnixIntegrationService = class {
9827
10120
  /**
9828
10121
  * Check if a user should be in a repo's Unix group
9829
10122
  *
9830
- * A user should be in the repo group if they have ownership
9831
- * of ANY branch in that repo.
10123
+ * A user should be in the repo group if they have explicit filesystem access
10124
+ * to ANY branch in that repo.
9832
10125
  *
9833
10126
  * @param repoId - Repo ID
9834
10127
  * @param userId - User ID to check
@@ -9837,8 +10130,8 @@ var UnixIntegrationService = class {
9837
10130
  async shouldUserBeInRepoGroup(repoId, userId) {
9838
10131
  const branches4 = await this.branchRepo.findAll({ repo_id: repoId });
9839
10132
  for (const wt of branches4) {
9840
- const isOwner = await this.branchRepo.isOwner(wt.branch_id, userId);
9841
- if (isOwner) {
10133
+ const userIds = await this.branchRepo.findExplicitFsAccessUserIds(wt.branch_id);
10134
+ if (userIds.includes(userId)) {
9842
10135
  return true;
9843
10136
  }
9844
10137
  }
@@ -9847,33 +10140,36 @@ var UnixIntegrationService = class {
9847
10140
  /**
9848
10141
  * Initialize Unix group for an existing repo
9849
10142
  *
9850
- * Creates group, sets .git permissions, and adds all users who
9851
- * own any branch in the repo.
10143
+ * Creates group, sets .git permissions, and adds all users who have explicit
10144
+ * filesystem access to any branch in the repo.
9852
10145
  *
9853
10146
  * @param repoId - Repo ID
9854
10147
  */
9855
10148
  async initializeRepoGroup(repoId) {
9856
10149
  const groupName = await this.createRepoGroup(repoId);
9857
10150
  const branches4 = await this.branchRepo.findAll({ repo_id: repoId });
9858
- const ownerIds = /* @__PURE__ */ new Set();
10151
+ const userIds = /* @__PURE__ */ new Set();
9859
10152
  for (const wt of branches4) {
9860
- const wtOwners = await this.branchRepo.getOwners(wt.branch_id);
9861
- for (const ownerId of wtOwners) {
9862
- ownerIds.add(ownerId);
10153
+ const branchUserIds = await this.branchRepo.findExplicitFsAccessUserIds(wt.branch_id);
10154
+ for (const userId of branchUserIds) {
10155
+ userIds.add(userId);
9863
10156
  }
9864
10157
  }
9865
- for (const ownerId of ownerIds) {
9866
- await this.addUserToRepoGroup(repoId, ownerId);
10158
+ for (const userId of userIds) {
10159
+ await this.addUserToRepoGroup(repoId, userId);
9867
10160
  }
10161
+ await this.reconcileUnixGroupMembers(groupName, await this.getUnixUsernamesForUsers(userIds), {
10162
+ label: "repo"
10163
+ });
9868
10164
  console.log(
9869
- `[UnixIntegration] Initialized repo group ${groupName} with ${ownerIds.size} unique owner(s)`
10165
+ `[UnixIntegration] Initialized repo group ${groupName} with ${userIds.size} unique filesystem user(s)`
9870
10166
  );
9871
10167
  }
9872
10168
  /**
9873
10169
  * Full sync for a repo
9874
10170
  *
9875
10171
  * Ensures repo group exists, .git permissions are set, and all
9876
- * branch owners are in the repo group.
10172
+ * branch filesystem-access users are in the repo group.
9877
10173
  *
9878
10174
  * @param repoId - Repo ID
9879
10175
  */
@@ -9881,15 +10177,23 @@ var UnixIntegrationService = class {
9881
10177
  console.log(`[UnixIntegration] Full sync for repo ${shortId(repoId)}`);
9882
10178
  await this.createRepoGroup(repoId);
9883
10179
  const branches4 = await this.branchRepo.findAll({ repo_id: repoId });
9884
- const ownerIds = /* @__PURE__ */ new Set();
10180
+ const userIds = /* @__PURE__ */ new Set();
9885
10181
  for (const wt of branches4) {
9886
- const wtOwners = await this.branchRepo.getOwners(wt.branch_id);
9887
- for (const ownerId of wtOwners) {
9888
- ownerIds.add(ownerId);
10182
+ const branchUserIds = await this.branchRepo.findExplicitFsAccessUserIds(wt.branch_id);
10183
+ for (const userId of branchUserIds) {
10184
+ userIds.add(userId);
9889
10185
  }
9890
10186
  }
9891
- for (const ownerId of ownerIds) {
9892
- await this.addUserToRepoGroup(repoId, ownerId);
10187
+ for (const userId of userIds) {
10188
+ await this.addUserToRepoGroup(repoId, userId);
10189
+ }
10190
+ const repo = await this.repoRepo.findById(repoId);
10191
+ if (repo?.unix_group) {
10192
+ await this.reconcileUnixGroupMembers(
10193
+ repo.unix_group,
10194
+ await this.getUnixUsernamesForUsers(userIds),
10195
+ { label: "repo" }
10196
+ );
9893
10197
  }
9894
10198
  }
9895
10199
  // ============================================================
@@ -10166,16 +10470,28 @@ var UnixIntegrationService = class {
10166
10470
  /**
10167
10471
  * Full sync for a branch
10168
10472
  *
10169
- * Ensures group exists, all owners are in group, and symlinks are created.
10473
+ * Ensures group exists, all explicit filesystem-access users are in group,
10474
+ * and symlinks are created.
10170
10475
  *
10171
10476
  * @param branchId - Branch ID
10172
10477
  */
10173
10478
  async syncBranch(branchId) {
10174
10479
  console.log(`[UnixIntegration] Full sync for branch ${shortId(branchId)}`);
10175
10480
  await this.createBranchGroup(branchId);
10176
- const ownerIds = await this.branchRepo.getOwners(branchId);
10177
- for (const ownerId of ownerIds) {
10178
- await this.addUserToBranchGroup(branchId, ownerId);
10481
+ const userIds = await this.branchRepo.findExplicitFsAccessUserIds(branchId);
10482
+ for (const userId of userIds) {
10483
+ await this.addUserToBranchGroup(branchId, userId);
10484
+ }
10485
+ const branch = await this.branchRepo.findById(branchId);
10486
+ if (branch?.unix_group) {
10487
+ await this.reconcileUnixGroupMembers(
10488
+ branch.unix_group,
10489
+ await this.getUnixUsernamesForUsers(userIds),
10490
+ { label: "branch" }
10491
+ );
10492
+ }
10493
+ if (branch?.repo_id) {
10494
+ await this.syncRepo(branch.repo_id);
10179
10495
  }
10180
10496
  }
10181
10497
  /**