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() {
@@ -1166,15 +1172,35 @@ var init_schedule = __esm({
1166
1172
  });
1167
1173
 
1168
1174
  // src/types/session.ts
1175
+ var SessionStatus, EXECUTING_SESSION_STATUSES;
1169
1176
  var init_session = __esm({
1170
1177
  "src/types/session.ts"() {
1171
1178
  "use strict";
1172
1179
  init_cjs_shims();
1180
+ SessionStatus = {
1181
+ IDLE: "idle",
1182
+ RUNNING: "running",
1183
+ STOPPING: "stopping",
1184
+ // Stop requested, waiting for task to stop
1185
+ AWAITING_PERMISSION: "awaiting_permission",
1186
+ AWAITING_INPUT: "awaiting_input",
1187
+ // Legacy / pre-#1177: AskUserQuestion was disallowed at the SDK; new sessions never enter this state, kept for historical rows
1188
+ TIMED_OUT: "timed_out",
1189
+ // Permission/input request timed out, executor exited — user must re-prompt
1190
+ COMPLETED: "completed",
1191
+ FAILED: "failed"
1192
+ };
1193
+ EXECUTING_SESSION_STATUSES = /* @__PURE__ */ new Set([
1194
+ SessionStatus.RUNNING,
1195
+ SessionStatus.STOPPING,
1196
+ SessionStatus.AWAITING_PERMISSION,
1197
+ SessionStatus.AWAITING_INPUT
1198
+ ]);
1173
1199
  }
1174
1200
  });
1175
1201
 
1176
1202
  // src/types/task.ts
1177
- var TaskStatus, TERMINAL_TASK_STATUSES;
1203
+ var TaskStatus, TERMINAL_TASK_STATUSES, EXECUTING_TASK_STATUSES;
1178
1204
  var init_task = __esm({
1179
1205
  "src/types/task.ts"() {
1180
1206
  "use strict";
@@ -1202,6 +1228,12 @@ var init_task = __esm({
1202
1228
  TaskStatus.STOPPED,
1203
1229
  TaskStatus.TIMED_OUT
1204
1230
  ]);
1231
+ EXECUTING_TASK_STATUSES = /* @__PURE__ */ new Set([
1232
+ TaskStatus.RUNNING,
1233
+ TaskStatus.STOPPING,
1234
+ TaskStatus.AWAITING_PERMISSION,
1235
+ TaskStatus.AWAITING_INPUT
1236
+ ]);
1205
1237
  }
1206
1238
  });
1207
1239
 
@@ -1361,6 +1393,8 @@ __export(schema_postgres_exports, {
1361
1393
  serializedSessions: () => serializedSessions,
1362
1394
  sessionEnvSelections: () => sessionEnvSelections,
1363
1395
  sessionMcpServers: () => sessionMcpServers,
1396
+ sessionRelationships: () => sessionRelationships,
1397
+ sessionRelationshipsRelations: () => sessionRelationshipsRelations,
1364
1398
  sessions: () => sessions,
1365
1399
  sessionsRelations: () => sessionsRelations,
1366
1400
  tasks: () => tasks,
@@ -1369,7 +1403,7 @@ __export(schema_postgres_exports, {
1369
1403
  userMcpOauthTokens: () => userMcpOauthTokens,
1370
1404
  users: () => users
1371
1405
  });
1372
- 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;
1406
+ 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;
1373
1407
  var init_schema_postgres = __esm({
1374
1408
  "src/db/schema.postgres.ts"() {
1375
1409
  "use strict";
@@ -1464,6 +1498,36 @@ var init_schema_postgres = __esm({
1464
1498
  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`)
1465
1499
  })
1466
1500
  );
1501
+ sessionRelationships = (0, import_pg_core.pgTable)(
1502
+ "session_relationships",
1503
+ {
1504
+ relationship_id: (0, import_pg_core.varchar)("relationship_id", { length: 36 }).primaryKey(),
1505
+ source_session_id: (0, import_pg_core.varchar)("source_session_id", { length: 36 }).notNull().references(() => sessions.session_id, { onDelete: "cascade" }),
1506
+ target_session_id: (0, import_pg_core.varchar)("target_session_id", { length: 36 }).notNull().references(() => sessions.session_id, { onDelete: "cascade" }),
1507
+ relationship_type: (0, import_pg_core.text)("relationship_type", { enum: ["remote_create"] }).notNull(),
1508
+ created_by: (0, import_pg_core.varchar)("created_by", { length: 36 }).notNull(),
1509
+ created_at: t.timestamp("created_at").notNull(),
1510
+ updated_at: t.timestamp("updated_at"),
1511
+ callback_enabled: t.bool("callback_enabled").notNull().default(false),
1512
+ callback_session_id: (0, import_pg_core.varchar)("callback_session_id", { length: 36 }).references(
1513
+ () => sessions.session_id,
1514
+ {
1515
+ onDelete: "set null"
1516
+ }
1517
+ ),
1518
+ data: t.json("data")
1519
+ },
1520
+ (table) => ({
1521
+ sourceIdx: (0, import_pg_core.index)("session_relationships_source_idx").on(table.source_session_id),
1522
+ targetIdx: (0, import_pg_core.index)("session_relationships_target_idx").on(table.target_session_id),
1523
+ callbackIdx: (0, import_pg_core.index)("session_relationships_callback_idx").on(table.callback_session_id),
1524
+ sourceTargetTypeUnique: (0, import_pg_core.uniqueIndex)("session_relationships_source_target_type_unique").on(
1525
+ table.source_session_id,
1526
+ table.target_session_id,
1527
+ table.relationship_type
1528
+ )
1529
+ })
1530
+ );
1467
1531
  tasks = (0, import_pg_core.pgTable)(
1468
1532
  "tasks",
1469
1533
  {
@@ -2000,6 +2064,12 @@ var init_schema_postgres = __esm({
2000
2064
  branch_id: (0, import_pg_core.varchar)("branch_id", { length: 36 }).references(() => branches.branch_id, {
2001
2065
  onDelete: "set null"
2002
2066
  }),
2067
+ source_session_id: (0, import_pg_core.varchar)("source_session_id", { length: 36 }).references(
2068
+ () => sessions.session_id,
2069
+ {
2070
+ onDelete: "set null"
2071
+ }
2072
+ ),
2003
2073
  board_id: (0, import_pg_core.varchar)("board_id", { length: 36 }).notNull().references(() => boards.board_id, { onDelete: "cascade" }),
2004
2074
  name: (0, import_pg_core.text)("name").notNull(),
2005
2075
  description: (0, import_pg_core.text)("description"),
@@ -2026,6 +2096,7 @@ var init_schema_postgres = __esm({
2026
2096
  },
2027
2097
  (table) => ({
2028
2098
  branchIdx: (0, import_pg_core.index)("artifacts_branch_idx").on(table.branch_id),
2099
+ sourceSessionIdx: (0, import_pg_core.index)("artifacts_source_session_idx").on(table.source_session_id),
2029
2100
  boardIdx: (0, import_pg_core.index)("artifacts_board_idx").on(table.board_id),
2030
2101
  archivedIdx: (0, import_pg_core.index)("artifacts_archived_idx").on(table.archived),
2031
2102
  publicIdx: (0, import_pg_core.index)("artifacts_public_idx").on(table.public)
@@ -2182,7 +2253,7 @@ var init_schema_postgres = __esm({
2182
2253
  // Materialized for queries
2183
2254
  name: (0, import_pg_core.text)("name").notNull(),
2184
2255
  channel_type: (0, import_pg_core.text)("channel_type", {
2185
- enum: ["slack", "discord", "whatsapp", "telegram", "github"]
2256
+ enum: ["slack", "discord", "whatsapp", "telegram", "github", "teams"]
2186
2257
  }).notNull(),
2187
2258
  target_branch_id: (0, import_pg_core.varchar)("target_branch_id", { length: 36 }).notNull().references(() => branches.branch_id, { onDelete: "cascade" }),
2188
2259
  agor_user_id: (0, import_pg_core.varchar)("agor_user_id", { length: 36 }).notNull(),
@@ -2566,7 +2637,7 @@ var init_schema_postgres = __esm({
2566
2637
  archivedIdx: (0, import_pg_core.index)("kb_graph_edges_archived_idx").on(table.archived)
2567
2638
  })
2568
2639
  );
2569
- sessionsRelations = (0, import_drizzle_orm2.relations)(sessions, ({ one }) => ({
2640
+ sessionsRelations = (0, import_drizzle_orm2.relations)(sessions, ({ one, many }) => ({
2570
2641
  branch: one(branches, {
2571
2642
  fields: [sessions.branch_id],
2572
2643
  references: [branches.branch_id]
@@ -2574,6 +2645,24 @@ var init_schema_postgres = __esm({
2574
2645
  schedule: one(schedules, {
2575
2646
  fields: [sessions.schedule_id],
2576
2647
  references: [schedules.schedule_id]
2648
+ }),
2649
+ outboundRelationships: many(sessionRelationships, { relationName: "relationshipSource" }),
2650
+ inboundRelationships: many(sessionRelationships, { relationName: "relationshipTarget" })
2651
+ }));
2652
+ sessionRelationshipsRelations = (0, import_drizzle_orm2.relations)(sessionRelationships, ({ one }) => ({
2653
+ sourceSession: one(sessions, {
2654
+ fields: [sessionRelationships.source_session_id],
2655
+ references: [sessions.session_id],
2656
+ relationName: "relationshipSource"
2657
+ }),
2658
+ targetSession: one(sessions, {
2659
+ fields: [sessionRelationships.target_session_id],
2660
+ references: [sessions.session_id],
2661
+ relationName: "relationshipTarget"
2662
+ }),
2663
+ callbackSession: one(sessions, {
2664
+ fields: [sessionRelationships.callback_session_id],
2665
+ references: [sessions.session_id]
2577
2666
  })
2578
2667
  }));
2579
2668
  branchesRelations = (0, import_drizzle_orm2.relations)(branches, ({ many }) => ({
@@ -2626,6 +2715,8 @@ __export(schema_sqlite_exports, {
2626
2715
  serializedSessions: () => serializedSessions2,
2627
2716
  sessionEnvSelections: () => sessionEnvSelections2,
2628
2717
  sessionMcpServers: () => sessionMcpServers2,
2718
+ sessionRelationships: () => sessionRelationships2,
2719
+ sessionRelationshipsRelations: () => sessionRelationshipsRelations2,
2629
2720
  sessions: () => sessions2,
2630
2721
  sessionsRelations: () => sessionsRelations2,
2631
2722
  tasks: () => tasks2,
@@ -2634,7 +2725,7 @@ __export(schema_sqlite_exports, {
2634
2725
  userMcpOauthTokens: () => userMcpOauthTokens2,
2635
2726
  users: () => users2
2636
2727
  });
2637
- 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;
2728
+ 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;
2638
2729
  var init_schema_sqlite = __esm({
2639
2730
  "src/db/schema.sqlite.ts"() {
2640
2731
  "use strict";
@@ -2726,6 +2817,36 @@ var init_schema_sqlite = __esm({
2726
2817
  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`)
2727
2818
  })
2728
2819
  );
2820
+ sessionRelationships2 = (0, import_sqlite_core.sqliteTable)(
2821
+ "session_relationships",
2822
+ {
2823
+ relationship_id: (0, import_sqlite_core.text)("relationship_id", { length: 36 }).primaryKey(),
2824
+ source_session_id: (0, import_sqlite_core.text)("source_session_id", { length: 36 }).notNull().references(() => sessions2.session_id, { onDelete: "cascade" }),
2825
+ target_session_id: (0, import_sqlite_core.text)("target_session_id", { length: 36 }).notNull().references(() => sessions2.session_id, { onDelete: "cascade" }),
2826
+ relationship_type: (0, import_sqlite_core.text)("relationship_type", { enum: ["remote_create"] }).notNull(),
2827
+ created_by: (0, import_sqlite_core.text)("created_by", { length: 36 }).notNull(),
2828
+ created_at: t2.timestamp("created_at").notNull(),
2829
+ updated_at: t2.timestamp("updated_at"),
2830
+ callback_enabled: t2.bool("callback_enabled").notNull().default(false),
2831
+ callback_session_id: (0, import_sqlite_core.text)("callback_session_id", { length: 36 }).references(
2832
+ () => sessions2.session_id,
2833
+ {
2834
+ onDelete: "set null"
2835
+ }
2836
+ ),
2837
+ data: t2.json("data")
2838
+ },
2839
+ (table) => ({
2840
+ sourceIdx: (0, import_sqlite_core.index)("session_relationships_source_idx").on(table.source_session_id),
2841
+ targetIdx: (0, import_sqlite_core.index)("session_relationships_target_idx").on(table.target_session_id),
2842
+ callbackIdx: (0, import_sqlite_core.index)("session_relationships_callback_idx").on(table.callback_session_id),
2843
+ sourceTargetTypeUnique: (0, import_sqlite_core.uniqueIndex)("session_relationships_source_target_type_unique").on(
2844
+ table.source_session_id,
2845
+ table.target_session_id,
2846
+ table.relationship_type
2847
+ )
2848
+ })
2849
+ );
2729
2850
  tasks2 = (0, import_sqlite_core.sqliteTable)(
2730
2851
  "tasks",
2731
2852
  {
@@ -3270,6 +3391,12 @@ var init_schema_sqlite = __esm({
3270
3391
  branch_id: (0, import_sqlite_core.text)("branch_id", { length: 36 }).references(() => branches2.branch_id, {
3271
3392
  onDelete: "set null"
3272
3393
  }),
3394
+ source_session_id: (0, import_sqlite_core.text)("source_session_id", { length: 36 }).references(
3395
+ () => sessions2.session_id,
3396
+ {
3397
+ onDelete: "set null"
3398
+ }
3399
+ ),
3273
3400
  board_id: (0, import_sqlite_core.text)("board_id", { length: 36 }).notNull().references(() => boards2.board_id, { onDelete: "cascade" }),
3274
3401
  name: (0, import_sqlite_core.text)("name").notNull(),
3275
3402
  description: (0, import_sqlite_core.text)("description"),
@@ -3296,6 +3423,7 @@ var init_schema_sqlite = __esm({
3296
3423
  },
3297
3424
  (table) => ({
3298
3425
  branchIdx: (0, import_sqlite_core.index)("artifacts_branch_idx").on(table.branch_id),
3426
+ sourceSessionIdx: (0, import_sqlite_core.index)("artifacts_source_session_idx").on(table.source_session_id),
3299
3427
  boardIdx: (0, import_sqlite_core.index)("artifacts_board_idx").on(table.board_id),
3300
3428
  archivedIdx: (0, import_sqlite_core.index)("artifacts_archived_idx").on(table.archived),
3301
3429
  publicIdx: (0, import_sqlite_core.index)("artifacts_public_idx").on(table.public)
@@ -3454,7 +3582,7 @@ var init_schema_sqlite = __esm({
3454
3582
  // Materialized for queries
3455
3583
  name: (0, import_sqlite_core.text)("name").notNull(),
3456
3584
  channel_type: (0, import_sqlite_core.text)("channel_type", {
3457
- enum: ["slack", "discord", "whatsapp", "telegram", "github"]
3585
+ enum: ["slack", "discord", "whatsapp", "telegram", "github", "teams"]
3458
3586
  }).notNull(),
3459
3587
  target_branch_id: (0, import_sqlite_core.text)("target_branch_id", { length: 36 }).notNull().references(() => branches2.branch_id, { onDelete: "cascade" }),
3460
3588
  agor_user_id: (0, import_sqlite_core.text)("agor_user_id", { length: 36 }).notNull(),
@@ -3837,7 +3965,7 @@ var init_schema_sqlite = __esm({
3837
3965
  archivedIdx: (0, import_sqlite_core.index)("kb_graph_edges_archived_idx").on(table.archived)
3838
3966
  })
3839
3967
  );
3840
- sessionsRelations2 = (0, import_drizzle_orm3.relations)(sessions2, ({ one }) => ({
3968
+ sessionsRelations2 = (0, import_drizzle_orm3.relations)(sessions2, ({ one, many }) => ({
3841
3969
  branch: one(branches2, {
3842
3970
  fields: [sessions2.branch_id],
3843
3971
  references: [branches2.branch_id]
@@ -3845,6 +3973,24 @@ var init_schema_sqlite = __esm({
3845
3973
  schedule: one(schedules2, {
3846
3974
  fields: [sessions2.schedule_id],
3847
3975
  references: [schedules2.schedule_id]
3976
+ }),
3977
+ outboundRelationships: many(sessionRelationships2, { relationName: "relationshipSource" }),
3978
+ inboundRelationships: many(sessionRelationships2, { relationName: "relationshipTarget" })
3979
+ }));
3980
+ sessionRelationshipsRelations2 = (0, import_drizzle_orm3.relations)(sessionRelationships2, ({ one }) => ({
3981
+ sourceSession: one(sessions2, {
3982
+ fields: [sessionRelationships2.source_session_id],
3983
+ references: [sessions2.session_id],
3984
+ relationName: "relationshipSource"
3985
+ }),
3986
+ targetSession: one(sessions2, {
3987
+ fields: [sessionRelationships2.target_session_id],
3988
+ references: [sessions2.session_id],
3989
+ relationName: "relationshipTarget"
3990
+ }),
3991
+ callbackSession: one(sessions2, {
3992
+ fields: [sessionRelationships2.callback_session_id],
3993
+ references: [sessions2.session_id]
3848
3994
  })
3849
3995
  }));
3850
3996
  branchesRelations2 = (0, import_drizzle_orm3.relations)(branches2, ({ many }) => ({
@@ -3940,6 +4086,7 @@ __export(schema_exports, {
3940
4086
  serializedSessions: () => serializedSessions3,
3941
4087
  sessionEnvSelections: () => sessionEnvSelections3,
3942
4088
  sessionMcpServers: () => sessionMcpServers3,
4089
+ sessionRelationships: () => sessionRelationships3,
3943
4090
  sessions: () => sessions3,
3944
4091
  tasks: () => tasks3,
3945
4092
  threadSessionMap: () => threadSessionMap3,
@@ -3947,7 +4094,7 @@ __export(schema_exports, {
3947
4094
  userMcpOauthTokens: () => userMcpOauthTokens3,
3948
4095
  users: () => users3
3949
4096
  });
3950
- 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;
4097
+ 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;
3951
4098
  var init_schema = __esm({
3952
4099
  "src/db/schema.ts"() {
3953
4100
  "use strict";
@@ -3979,6 +4126,7 @@ var init_schema = __esm({
3979
4126
  artifactTrustGrants3 = schema.artifactTrustGrants;
3980
4127
  boardObjects3 = schema.boardObjects;
3981
4128
  sessionMcpServers3 = schema.sessionMcpServers;
4129
+ sessionRelationships3 = schema.sessionRelationships;
3982
4130
  sessionEnvSelections3 = schema.sessionEnvSelections;
3983
4131
  userMcpOauthTokens3 = schema.userMcpOauthTokens;
3984
4132
  boardComments3 = schema.boardComments;
@@ -5253,7 +5401,7 @@ init_cjs_shims();
5253
5401
 
5254
5402
  // src/db/index.ts
5255
5403
  init_cjs_shims();
5256
- var import_drizzle_orm34 = require("drizzle-orm");
5404
+ var import_drizzle_orm35 = require("drizzle-orm");
5257
5405
  var import_bcryptjs3 = __toESM(require("bcryptjs"), 1);
5258
5406
  init_ids();
5259
5407
 
@@ -5814,6 +5962,7 @@ var FS_ACCESS_RANK = {
5814
5962
  };
5815
5963
  var VIEW_OR_BETTER_BRANCH_PERMISSIONS = ["view", "session", "prompt", "all"];
5816
5964
  var BRANCH_PERMISSION_SOURCES = ["board", "override"];
5965
+ var FS_ACCESS_BRANCH_PERMISSIONS = ["read", "write"];
5817
5966
  var BranchRepository = class {
5818
5967
  constructor(db) {
5819
5968
  this.db = db;
@@ -6307,6 +6456,83 @@ var BranchRepository = class {
6307
6456
  }
6308
6457
  return Array.from(userIds);
6309
6458
  }
6459
+ /**
6460
+ * Find users whose explicit branch or aligned-board grants should materialize
6461
+ * into filesystem access for the branch.
6462
+ *
6463
+ * This intentionally excludes ambient "others" access because there is no
6464
+ * bounded user set to expand. Board owners apply whenever the branch is
6465
+ * explicitly aligned to board permissions (`permission_source = 'board'`);
6466
+ * board group grants additionally require a shared board. Override branches
6467
+ * must not inherit board grants.
6468
+ */
6469
+ async findExplicitFsAccessUserIds(branchId) {
6470
+ const branchRow = await select(this.db, {
6471
+ board_id: branches3.board_id,
6472
+ permission_source: branches3.permission_source
6473
+ }).from(branches3).where((0, import_drizzle_orm16.eq)(branches3.branch_id, branchId)).one();
6474
+ const ownerRows = await select(this.db, { user_id: branchOwners3.user_id }).from(branchOwners3).where((0, import_drizzle_orm16.eq)(branchOwners3.branch_id, branchId)).all();
6475
+ const groupRows = await select(this.db, { user_id: groupMemberships3.user_id }).from(branchGroupGrants3).innerJoin(groupMemberships3, (0, import_drizzle_orm16.eq)(groupMemberships3.group_id, branchGroupGrants3.group_id)).innerJoin(
6476
+ groups3,
6477
+ (0, import_drizzle_orm16.and)((0, import_drizzle_orm16.eq)(groups3.group_id, branchGroupGrants3.group_id), (0, import_drizzle_orm16.eq)(groups3.archived, false))
6478
+ ).where(
6479
+ (0, import_drizzle_orm16.and)(
6480
+ (0, import_drizzle_orm16.eq)(branchGroupGrants3.branch_id, branchId),
6481
+ (0, import_drizzle_orm16.inArray)(
6482
+ import_drizzle_orm16.sql`coalesce(${branchGroupGrants3.fs_access}, 'read')`,
6483
+ FS_ACCESS_BRANCH_PERMISSIONS
6484
+ )
6485
+ )
6486
+ ).all();
6487
+ const isBoardAligned = branchRow?.permission_source === "board" && branchRow.board_id;
6488
+ const boardOwnerRows = isBoardAligned ? await select(this.db, { user_id: boardOwners3.user_id }).from(boardOwners3).where((0, import_drizzle_orm16.eq)(boardOwners3.board_id, branchRow.board_id)).all() : [];
6489
+ const boardGroupRows = isBoardAligned ? await select(this.db, { user_id: groupMemberships3.user_id }).from(boardGroupGrants3).innerJoin(groupMemberships3, (0, import_drizzle_orm16.eq)(groupMemberships3.group_id, boardGroupGrants3.group_id)).innerJoin(
6490
+ groups3,
6491
+ (0, import_drizzle_orm16.and)((0, import_drizzle_orm16.eq)(groups3.group_id, boardGroupGrants3.group_id), (0, import_drizzle_orm16.eq)(groups3.archived, false))
6492
+ ).innerJoin(
6493
+ boards3,
6494
+ (0, import_drizzle_orm16.and)(
6495
+ (0, import_drizzle_orm16.eq)(boards3.board_id, boardGroupGrants3.board_id),
6496
+ (0, import_drizzle_orm16.eq)(
6497
+ import_drizzle_orm16.sql`coalesce(${jsonExtract(this.db, boards3.data, "access_mode")}, 'shared')`,
6498
+ "shared"
6499
+ )
6500
+ )
6501
+ ).where(
6502
+ (0, import_drizzle_orm16.and)(
6503
+ (0, import_drizzle_orm16.eq)(boardGroupGrants3.board_id, branchRow.board_id),
6504
+ (0, import_drizzle_orm16.inArray)(
6505
+ import_drizzle_orm16.sql`coalesce(${boardGroupGrants3.fs_access}, 'read')`,
6506
+ FS_ACCESS_BRANCH_PERMISSIONS
6507
+ )
6508
+ )
6509
+ ).all() : [];
6510
+ const userIds = /* @__PURE__ */ new Set();
6511
+ for (const row of ownerRows) {
6512
+ userIds.add(row.user_id);
6513
+ }
6514
+ for (const row of groupRows) {
6515
+ userIds.add(row.user_id);
6516
+ }
6517
+ for (const row of boardOwnerRows) {
6518
+ userIds.add(row.user_id);
6519
+ }
6520
+ for (const row of boardGroupRows) {
6521
+ userIds.add(row.user_id);
6522
+ }
6523
+ return Array.from(userIds);
6524
+ }
6525
+ async findBoardAlignedBranches(boardId) {
6526
+ const rows = await select(this.db).from(branches3).where(
6527
+ (0, import_drizzle_orm16.and)(
6528
+ (0, import_drizzle_orm16.eq)(branches3.board_id, boardId),
6529
+ (0, import_drizzle_orm16.eq)(branches3.permission_source, "board"),
6530
+ (0, import_drizzle_orm16.eq)(branches3.archived, false)
6531
+ )
6532
+ ).all();
6533
+ const baseUrl = await getBaseUrl();
6534
+ return rows.map((row) => this.rowToBranch(row, baseUrl));
6535
+ }
6310
6536
  /**
6311
6537
  * Get all owners of a branch
6312
6538
  *
@@ -7119,10 +7345,17 @@ init_ids();
7119
7345
  init_database_wrapper();
7120
7346
  init_schema();
7121
7347
 
7348
+ // src/db/repositories/session-relationships.ts
7349
+ init_cjs_shims();
7350
+ var import_drizzle_orm29 = require("drizzle-orm");
7351
+ init_ids();
7352
+ init_database_wrapper();
7353
+ init_schema();
7354
+
7122
7355
  // src/db/repositories/tasks.ts
7123
7356
  init_cjs_shims();
7124
7357
  init_types2();
7125
- var import_drizzle_orm29 = require("drizzle-orm");
7358
+ var import_drizzle_orm30 = require("drizzle-orm");
7126
7359
  init_ids();
7127
7360
  init_database_wrapper();
7128
7361
  init_schema();
@@ -7130,7 +7363,7 @@ init_schema();
7130
7363
  // src/db/repositories/thread-session-map.ts
7131
7364
  init_cjs_shims();
7132
7365
  init_types2();
7133
- var import_drizzle_orm30 = require("drizzle-orm");
7366
+ var import_drizzle_orm31 = require("drizzle-orm");
7134
7367
  init_ids();
7135
7368
  init_database_wrapper();
7136
7369
  init_schema();
@@ -7139,21 +7372,21 @@ init_schema();
7139
7372
  init_cjs_shims();
7140
7373
  var import_node_crypto5 = require("crypto");
7141
7374
  var import_bcryptjs2 = __toESM(require("bcryptjs"), 1);
7142
- var import_drizzle_orm31 = require("drizzle-orm");
7375
+ var import_drizzle_orm32 = require("drizzle-orm");
7143
7376
  init_ids();
7144
7377
  init_database_wrapper();
7145
7378
  init_schema();
7146
7379
 
7147
7380
  // src/db/repositories/user-mcp-oauth-tokens.ts
7148
7381
  init_cjs_shims();
7149
- var import_drizzle_orm32 = require("drizzle-orm");
7382
+ var import_drizzle_orm33 = require("drizzle-orm");
7150
7383
  init_database_wrapper();
7151
7384
  init_schema();
7152
7385
 
7153
7386
  // src/db/repositories/users.ts
7154
7387
  init_cjs_shims();
7155
7388
  init_types2();
7156
- var import_drizzle_orm33 = require("drizzle-orm");
7389
+ var import_drizzle_orm34 = require("drizzle-orm");
7157
7390
  init_ids();
7158
7391
  init_database_wrapper();
7159
7392
  init_schema();
@@ -7245,7 +7478,7 @@ var UsersRepository = class {
7245
7478
  */
7246
7479
  async resolveId(id) {
7247
7480
  return resolveByShortIdPrefix(id, "User", async (pattern) => {
7248
- const rows = await select(this.db).from(users3).where((0, import_drizzle_orm33.like)(users3.user_id, pattern)).limit(RESOLVE_SHORT_ID_FETCH_LIMIT).all();
7481
+ const rows = await select(this.db).from(users3).where((0, import_drizzle_orm34.like)(users3.user_id, pattern)).limit(RESOLVE_SHORT_ID_FETCH_LIMIT).all();
7249
7482
  return rows.map((r) => r.user_id);
7250
7483
  });
7251
7484
  }
@@ -7253,7 +7486,7 @@ var UsersRepository = class {
7253
7486
  * Check if unix_username is already taken by another user
7254
7487
  */
7255
7488
  async isUnixUsernameTaken(unixUsername, excludeUserId) {
7256
- const result = await select(this.db).from(users3).where((0, import_drizzle_orm33.eq)(users3.unix_username, unixUsername)).one();
7489
+ const result = await select(this.db).from(users3).where((0, import_drizzle_orm34.eq)(users3.unix_username, unixUsername)).one();
7257
7490
  if (!result) {
7258
7491
  return false;
7259
7492
  }
@@ -7276,7 +7509,7 @@ var UsersRepository = class {
7276
7509
  }
7277
7510
  const insertData = this.userToInsert(data);
7278
7511
  await insert(this.db, users3).values(insertData).run();
7279
- const row = await select(this.db).from(users3).where((0, import_drizzle_orm33.eq)(users3.user_id, insertData.user_id)).one();
7512
+ const row = await select(this.db).from(users3).where((0, import_drizzle_orm34.eq)(users3.user_id, insertData.user_id)).one();
7280
7513
  if (!row) {
7281
7514
  throw new RepositoryError("Failed to retrieve created user");
7282
7515
  }
@@ -7288,7 +7521,7 @@ var UsersRepository = class {
7288
7521
  async findById(id) {
7289
7522
  try {
7290
7523
  const fullId = await this.resolveId(id);
7291
- const result = await select(this.db).from(users3).where((0, import_drizzle_orm33.eq)(users3.user_id, fullId)).one();
7524
+ const result = await select(this.db).from(users3).where((0, import_drizzle_orm34.eq)(users3.user_id, fullId)).one();
7292
7525
  if (!result) {
7293
7526
  return null;
7294
7527
  }
@@ -7304,12 +7537,41 @@ var UsersRepository = class {
7304
7537
  * Find user by email
7305
7538
  */
7306
7539
  async findByEmail(email) {
7307
- const result = await select(this.db).from(users3).where((0, import_drizzle_orm33.eq)(users3.email, email)).one();
7540
+ const result = await select(this.db).from(users3).where((0, import_drizzle_orm34.eq)(users3.email, email)).one();
7308
7541
  if (!result) {
7309
7542
  return null;
7310
7543
  }
7311
7544
  return this.rowToUser(result);
7312
7545
  }
7546
+ /**
7547
+ * Find user by email for external identity providers.
7548
+ *
7549
+ * Agor intentionally keeps exact/case-sensitive email lookup semantics for
7550
+ * auth paths because the schema historically allowed case-distinct emails.
7551
+ * External providers such as Slack and GitHub treat email addresses as a
7552
+ * canonical identity hint, so their alignment path needs a case-insensitive
7553
+ * match. Prefer an exact match when present; otherwise return a
7554
+ * case-insensitive match only when it is unambiguous.
7555
+ */
7556
+ async findByEmailForAlignment(email) {
7557
+ const normalizedEmail = email.trim().toLowerCase();
7558
+ if (!normalizedEmail) return null;
7559
+ const exact = await this.findByEmail(normalizedEmail);
7560
+ if (exact) return exact;
7561
+ const results = await select(this.db).from(users3).where(import_drizzle_orm34.sql`LOWER(${users3.email}) = ${normalizedEmail}`).all();
7562
+ if (results.length !== 1) {
7563
+ if (results.length > 1) {
7564
+ console.warn(
7565
+ `[users] Ambiguous case-insensitive email alignment for ${normalizedEmail}: ${results.map((row) => {
7566
+ const userRow = row;
7567
+ return `${shortId(userRow.user_id)}:${userRow.email}`;
7568
+ }).join(", ")}`
7569
+ );
7570
+ }
7571
+ return null;
7572
+ }
7573
+ return this.rowToUser(results[0]);
7574
+ }
7313
7575
  /**
7314
7576
  * Find all users
7315
7577
  */
@@ -7346,8 +7608,8 @@ var UsersRepository = class {
7346
7608
  await update(this.db, users3).set({
7347
7609
  ...insertData,
7348
7610
  updated_at: /* @__PURE__ */ new Date()
7349
- }).where((0, import_drizzle_orm33.eq)(users3.user_id, fullId)).run();
7350
- const row = await select(this.db).from(users3).where((0, import_drizzle_orm33.eq)(users3.user_id, fullId)).one();
7611
+ }).where((0, import_drizzle_orm34.eq)(users3.user_id, fullId)).run();
7612
+ const row = await select(this.db).from(users3).where((0, import_drizzle_orm34.eq)(users3.user_id, fullId)).one();
7351
7613
  if (!row) {
7352
7614
  throw new RepositoryError("Failed to retrieve updated user");
7353
7615
  }
@@ -7358,7 +7620,7 @@ var UsersRepository = class {
7358
7620
  */
7359
7621
  async delete(id) {
7360
7622
  const fullId = await this.resolveId(id);
7361
- await deleteFrom(this.db, users3).where((0, import_drizzle_orm33.eq)(users3.user_id, fullId)).run();
7623
+ await deleteFrom(this.db, users3).where((0, import_drizzle_orm34.eq)(users3.user_id, fullId)).run();
7362
7624
  }
7363
7625
  /**
7364
7626
  * Get raw database row (internal use only - includes encrypted keys)
@@ -7366,7 +7628,7 @@ var UsersRepository = class {
7366
7628
  async getRawRow(id) {
7367
7629
  try {
7368
7630
  const fullId = await this.resolveId(id);
7369
- const result = await select(this.db).from(users3).where((0, import_drizzle_orm33.eq)(users3.user_id, fullId)).one();
7631
+ const result = await select(this.db).from(users3).where((0, import_drizzle_orm34.eq)(users3.user_id, fullId)).one();
7370
7632
  return result;
7371
7633
  } catch (error) {
7372
7634
  if (error instanceof EntityNotFoundError) {
@@ -7448,7 +7710,7 @@ var UsersRepository = class {
7448
7710
  await update(this.db, users3).set({
7449
7711
  data: { ...row.data, agentic_tools: next },
7450
7712
  updated_at: /* @__PURE__ */ new Date()
7451
- }).where((0, import_drizzle_orm33.eq)(users3.user_id, fullId)).run();
7713
+ }).where((0, import_drizzle_orm34.eq)(users3.user_id, fullId)).run();
7452
7714
  }
7453
7715
  /**
7454
7716
  * Delete a single credential field for a tool.
@@ -7474,7 +7736,7 @@ var UsersRepository = class {
7474
7736
  await update(this.db, users3).set({
7475
7737
  data: { ...row.data, agentic_tools: next },
7476
7738
  updated_at: /* @__PURE__ */ new Date()
7477
- }).where((0, import_drizzle_orm33.eq)(users3.user_id, fullId)).run();
7739
+ }).where((0, import_drizzle_orm34.eq)(users3.user_id, fullId)).run();
7478
7740
  }
7479
7741
  };
7480
7742
 
@@ -8842,6 +9104,30 @@ var UnixIntegrationService = class {
8842
9104
  this.usersRepo = new UsersRepository(db);
8843
9105
  this.repoRepo = new RepoRepository(db);
8844
9106
  }
9107
+ async getUnixUsernamesForUsers(userIds) {
9108
+ const unixUsernames = /* @__PURE__ */ new Set();
9109
+ for (const userId of userIds) {
9110
+ const user = await this.usersRepo.findById(userId);
9111
+ if (user?.unix_username) {
9112
+ unixUsernames.add(user.unix_username);
9113
+ }
9114
+ }
9115
+ return unixUsernames;
9116
+ }
9117
+ async reconcileUnixGroupMembers(groupName, allowedUnixUsernames, options) {
9118
+ if (this.config.daemonUser) {
9119
+ allowedUnixUsernames.add(this.config.daemonUser);
9120
+ }
9121
+ const result = await this.executor.exec(UnixGroupCommands.listGroupMembers(groupName));
9122
+ const currentMembers = result.stdout.trim().split(",").filter(Boolean);
9123
+ for (const unixUsername of currentMembers) {
9124
+ if (allowedUnixUsernames.has(unixUsername)) continue;
9125
+ console.log(
9126
+ `[UnixIntegration] Removing stale ${options.label} group member ${unixUsername} from ${groupName}`
9127
+ );
9128
+ await this.executor.exec(UnixGroupCommands.removeUserFromGroup(unixUsername, groupName));
9129
+ }
9130
+ }
8845
9131
  /**
8846
9132
  * Get the configured daemon user
8847
9133
  *
@@ -9085,19 +9371,26 @@ var UnixIntegrationService = class {
9085
9371
  /**
9086
9372
  * Initialize Unix group for an existing branch
9087
9373
  *
9088
- * Creates group and adds all current owners.
9374
+ * Creates group and adds all users with explicit filesystem access.
9089
9375
  *
9090
9376
  * @param branchId - Branch ID
9091
9377
  */
9092
9378
  async initializeBranchGroup(branchId) {
9093
9379
  const groupName = await this.createBranchGroup(branchId);
9094
- const ownerIds = await this.branchRepo.getOwners(branchId);
9095
- for (const ownerId of ownerIds) {
9096
- await this.addUserToBranchGroup(branchId, ownerId);
9380
+ const userIds = await this.branchRepo.findExplicitFsAccessUserIds(branchId);
9381
+ for (const userId of userIds) {
9382
+ await this.addUserToBranchGroup(branchId, userId);
9097
9383
  }
9384
+ await this.reconcileUnixGroupMembers(groupName, await this.getUnixUsernamesForUsers(userIds), {
9385
+ label: "branch"
9386
+ });
9098
9387
  console.log(
9099
- `[UnixIntegration] Initialized group ${groupName} with ${ownerIds.length} owner(s)`
9388
+ `[UnixIntegration] Initialized group ${groupName} with ${userIds.length} explicit filesystem user(s)`
9100
9389
  );
9390
+ const branch = await this.branchRepo.findById(branchId);
9391
+ if (branch?.repo_id) {
9392
+ await this.syncRepo(branch.repo_id);
9393
+ }
9101
9394
  }
9102
9395
  // ============================================================
9103
9396
  // REPO GROUP MANAGEMENT
@@ -9329,8 +9622,8 @@ var UnixIntegrationService = class {
9329
9622
  /**
9330
9623
  * Check if a user should be in a repo's Unix group
9331
9624
  *
9332
- * A user should be in the repo group if they have ownership
9333
- * of ANY branch in that repo.
9625
+ * A user should be in the repo group if they have explicit filesystem access
9626
+ * to ANY branch in that repo.
9334
9627
  *
9335
9628
  * @param repoId - Repo ID
9336
9629
  * @param userId - User ID to check
@@ -9339,8 +9632,8 @@ var UnixIntegrationService = class {
9339
9632
  async shouldUserBeInRepoGroup(repoId, userId) {
9340
9633
  const branches4 = await this.branchRepo.findAll({ repo_id: repoId });
9341
9634
  for (const wt of branches4) {
9342
- const isOwner = await this.branchRepo.isOwner(wt.branch_id, userId);
9343
- if (isOwner) {
9635
+ const userIds = await this.branchRepo.findExplicitFsAccessUserIds(wt.branch_id);
9636
+ if (userIds.includes(userId)) {
9344
9637
  return true;
9345
9638
  }
9346
9639
  }
@@ -9349,33 +9642,36 @@ var UnixIntegrationService = class {
9349
9642
  /**
9350
9643
  * Initialize Unix group for an existing repo
9351
9644
  *
9352
- * Creates group, sets .git permissions, and adds all users who
9353
- * own any branch in the repo.
9645
+ * Creates group, sets .git permissions, and adds all users who have explicit
9646
+ * filesystem access to any branch in the repo.
9354
9647
  *
9355
9648
  * @param repoId - Repo ID
9356
9649
  */
9357
9650
  async initializeRepoGroup(repoId) {
9358
9651
  const groupName = await this.createRepoGroup(repoId);
9359
9652
  const branches4 = await this.branchRepo.findAll({ repo_id: repoId });
9360
- const ownerIds = /* @__PURE__ */ new Set();
9653
+ const userIds = /* @__PURE__ */ new Set();
9361
9654
  for (const wt of branches4) {
9362
- const wtOwners = await this.branchRepo.getOwners(wt.branch_id);
9363
- for (const ownerId of wtOwners) {
9364
- ownerIds.add(ownerId);
9655
+ const branchUserIds = await this.branchRepo.findExplicitFsAccessUserIds(wt.branch_id);
9656
+ for (const userId of branchUserIds) {
9657
+ userIds.add(userId);
9365
9658
  }
9366
9659
  }
9367
- for (const ownerId of ownerIds) {
9368
- await this.addUserToRepoGroup(repoId, ownerId);
9660
+ for (const userId of userIds) {
9661
+ await this.addUserToRepoGroup(repoId, userId);
9369
9662
  }
9663
+ await this.reconcileUnixGroupMembers(groupName, await this.getUnixUsernamesForUsers(userIds), {
9664
+ label: "repo"
9665
+ });
9370
9666
  console.log(
9371
- `[UnixIntegration] Initialized repo group ${groupName} with ${ownerIds.size} unique owner(s)`
9667
+ `[UnixIntegration] Initialized repo group ${groupName} with ${userIds.size} unique filesystem user(s)`
9372
9668
  );
9373
9669
  }
9374
9670
  /**
9375
9671
  * Full sync for a repo
9376
9672
  *
9377
9673
  * Ensures repo group exists, .git permissions are set, and all
9378
- * branch owners are in the repo group.
9674
+ * branch filesystem-access users are in the repo group.
9379
9675
  *
9380
9676
  * @param repoId - Repo ID
9381
9677
  */
@@ -9383,15 +9679,23 @@ var UnixIntegrationService = class {
9383
9679
  console.log(`[UnixIntegration] Full sync for repo ${shortId(repoId)}`);
9384
9680
  await this.createRepoGroup(repoId);
9385
9681
  const branches4 = await this.branchRepo.findAll({ repo_id: repoId });
9386
- const ownerIds = /* @__PURE__ */ new Set();
9682
+ const userIds = /* @__PURE__ */ new Set();
9387
9683
  for (const wt of branches4) {
9388
- const wtOwners = await this.branchRepo.getOwners(wt.branch_id);
9389
- for (const ownerId of wtOwners) {
9390
- ownerIds.add(ownerId);
9684
+ const branchUserIds = await this.branchRepo.findExplicitFsAccessUserIds(wt.branch_id);
9685
+ for (const userId of branchUserIds) {
9686
+ userIds.add(userId);
9391
9687
  }
9392
9688
  }
9393
- for (const ownerId of ownerIds) {
9394
- await this.addUserToRepoGroup(repoId, ownerId);
9689
+ for (const userId of userIds) {
9690
+ await this.addUserToRepoGroup(repoId, userId);
9691
+ }
9692
+ const repo = await this.repoRepo.findById(repoId);
9693
+ if (repo?.unix_group) {
9694
+ await this.reconcileUnixGroupMembers(
9695
+ repo.unix_group,
9696
+ await this.getUnixUsernamesForUsers(userIds),
9697
+ { label: "repo" }
9698
+ );
9395
9699
  }
9396
9700
  }
9397
9701
  // ============================================================
@@ -9668,16 +9972,28 @@ var UnixIntegrationService = class {
9668
9972
  /**
9669
9973
  * Full sync for a branch
9670
9974
  *
9671
- * Ensures group exists, all owners are in group, and symlinks are created.
9975
+ * Ensures group exists, all explicit filesystem-access users are in group,
9976
+ * and symlinks are created.
9672
9977
  *
9673
9978
  * @param branchId - Branch ID
9674
9979
  */
9675
9980
  async syncBranch(branchId) {
9676
9981
  console.log(`[UnixIntegration] Full sync for branch ${shortId(branchId)}`);
9677
9982
  await this.createBranchGroup(branchId);
9678
- const ownerIds = await this.branchRepo.getOwners(branchId);
9679
- for (const ownerId of ownerIds) {
9680
- await this.addUserToBranchGroup(branchId, ownerId);
9983
+ const userIds = await this.branchRepo.findExplicitFsAccessUserIds(branchId);
9984
+ for (const userId of userIds) {
9985
+ await this.addUserToBranchGroup(branchId, userId);
9986
+ }
9987
+ const branch = await this.branchRepo.findById(branchId);
9988
+ if (branch?.unix_group) {
9989
+ await this.reconcileUnixGroupMembers(
9990
+ branch.unix_group,
9991
+ await this.getUnixUsernamesForUsers(userIds),
9992
+ { label: "branch" }
9993
+ );
9994
+ }
9995
+ if (branch?.repo_id) {
9996
+ await this.syncRepo(branch.repo_id);
9681
9997
  }
9682
9998
  }
9683
9999
  /**