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
@@ -480,6 +480,9 @@ async function getBaseUrl() {
480
480
  if (config.daemon?.base_url) {
481
481
  return validateBaseUrl(config.daemon.base_url);
482
482
  }
483
+ if (config.ui?.base_url) {
484
+ return validateBaseUrl(config.ui.base_url);
485
+ }
483
486
  const defaults = getDefaultConfig();
484
487
  const envPort = process.env.PORT ? Number.parseInt(process.env.PORT, 10) : void 0;
485
488
  const port = envPort || config.daemon?.port || defaults.daemon?.port || DAEMON.DEFAULT_PORT;
@@ -494,8 +497,11 @@ async function requirePublicBaseUrl() {
494
497
  if (config.daemon?.base_url) {
495
498
  return validateBaseUrl(config.daemon.base_url);
496
499
  }
500
+ if (config.ui?.base_url) {
501
+ return validateBaseUrl(config.ui.base_url);
502
+ }
497
503
  throw new PublicBaseUrlNotConfiguredError(
498
- "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."
504
+ "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."
499
505
  );
500
506
  }
501
507
  function loadConfigSync() {
@@ -1167,15 +1173,35 @@ var init_schedule = __esm({
1167
1173
  });
1168
1174
 
1169
1175
  // src/types/session.ts
1176
+ var SessionStatus, EXECUTING_SESSION_STATUSES;
1170
1177
  var init_session = __esm({
1171
1178
  "src/types/session.ts"() {
1172
1179
  "use strict";
1173
1180
  init_esm_shims();
1181
+ SessionStatus = {
1182
+ IDLE: "idle",
1183
+ RUNNING: "running",
1184
+ STOPPING: "stopping",
1185
+ // Stop requested, waiting for task to stop
1186
+ AWAITING_PERMISSION: "awaiting_permission",
1187
+ AWAITING_INPUT: "awaiting_input",
1188
+ // Legacy / pre-#1177: AskUserQuestion was disallowed at the SDK; new sessions never enter this state, kept for historical rows
1189
+ TIMED_OUT: "timed_out",
1190
+ // Permission/input request timed out, executor exited — user must re-prompt
1191
+ COMPLETED: "completed",
1192
+ FAILED: "failed"
1193
+ };
1194
+ EXECUTING_SESSION_STATUSES = /* @__PURE__ */ new Set([
1195
+ SessionStatus.RUNNING,
1196
+ SessionStatus.STOPPING,
1197
+ SessionStatus.AWAITING_PERMISSION,
1198
+ SessionStatus.AWAITING_INPUT
1199
+ ]);
1174
1200
  }
1175
1201
  });
1176
1202
 
1177
1203
  // src/types/task.ts
1178
- var TaskStatus, TERMINAL_TASK_STATUSES;
1204
+ var TaskStatus, TERMINAL_TASK_STATUSES, EXECUTING_TASK_STATUSES;
1179
1205
  var init_task = __esm({
1180
1206
  "src/types/task.ts"() {
1181
1207
  "use strict";
@@ -1203,6 +1229,12 @@ var init_task = __esm({
1203
1229
  TaskStatus.STOPPED,
1204
1230
  TaskStatus.TIMED_OUT
1205
1231
  ]);
1232
+ EXECUTING_TASK_STATUSES = /* @__PURE__ */ new Set([
1233
+ TaskStatus.RUNNING,
1234
+ TaskStatus.STOPPING,
1235
+ TaskStatus.AWAITING_PERMISSION,
1236
+ TaskStatus.AWAITING_INPUT
1237
+ ]);
1206
1238
  }
1207
1239
  });
1208
1240
 
@@ -1366,6 +1398,8 @@ __export(schema_postgres_exports, {
1366
1398
  serializedSessions: () => serializedSessions,
1367
1399
  sessionEnvSelections: () => sessionEnvSelections,
1368
1400
  sessionMcpServers: () => sessionMcpServers,
1401
+ sessionRelationships: () => sessionRelationships,
1402
+ sessionRelationshipsRelations: () => sessionRelationshipsRelations,
1369
1403
  sessions: () => sessions,
1370
1404
  sessionsRelations: () => sessionsRelations,
1371
1405
  tasks: () => tasks,
@@ -1389,7 +1423,7 @@ import {
1389
1423
  uniqueIndex,
1390
1424
  varchar
1391
1425
  } from "drizzle-orm/pg-core";
1392
- var 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;
1426
+ var 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;
1393
1427
  var init_schema_postgres = __esm({
1394
1428
  "src/db/schema.postgres.ts"() {
1395
1429
  "use strict";
@@ -1482,6 +1516,36 @@ var init_schema_postgres = __esm({
1482
1516
  scheduleRunUnique: uniqueIndex("sessions_schedule_run_unique").on(table.schedule_id, table.scheduled_run_at).where(sql2`${table.schedule_id} IS NOT NULL AND ${table.scheduled_run_at} IS NOT NULL`)
1483
1517
  })
1484
1518
  );
1519
+ sessionRelationships = pgTable(
1520
+ "session_relationships",
1521
+ {
1522
+ relationship_id: varchar("relationship_id", { length: 36 }).primaryKey(),
1523
+ source_session_id: varchar("source_session_id", { length: 36 }).notNull().references(() => sessions.session_id, { onDelete: "cascade" }),
1524
+ target_session_id: varchar("target_session_id", { length: 36 }).notNull().references(() => sessions.session_id, { onDelete: "cascade" }),
1525
+ relationship_type: text("relationship_type", { enum: ["remote_create"] }).notNull(),
1526
+ created_by: varchar("created_by", { length: 36 }).notNull(),
1527
+ created_at: t.timestamp("created_at").notNull(),
1528
+ updated_at: t.timestamp("updated_at"),
1529
+ callback_enabled: t.bool("callback_enabled").notNull().default(false),
1530
+ callback_session_id: varchar("callback_session_id", { length: 36 }).references(
1531
+ () => sessions.session_id,
1532
+ {
1533
+ onDelete: "set null"
1534
+ }
1535
+ ),
1536
+ data: t.json("data")
1537
+ },
1538
+ (table) => ({
1539
+ sourceIdx: index("session_relationships_source_idx").on(table.source_session_id),
1540
+ targetIdx: index("session_relationships_target_idx").on(table.target_session_id),
1541
+ callbackIdx: index("session_relationships_callback_idx").on(table.callback_session_id),
1542
+ sourceTargetTypeUnique: uniqueIndex("session_relationships_source_target_type_unique").on(
1543
+ table.source_session_id,
1544
+ table.target_session_id,
1545
+ table.relationship_type
1546
+ )
1547
+ })
1548
+ );
1485
1549
  tasks = pgTable(
1486
1550
  "tasks",
1487
1551
  {
@@ -2018,6 +2082,12 @@ var init_schema_postgres = __esm({
2018
2082
  branch_id: varchar("branch_id", { length: 36 }).references(() => branches.branch_id, {
2019
2083
  onDelete: "set null"
2020
2084
  }),
2085
+ source_session_id: varchar("source_session_id", { length: 36 }).references(
2086
+ () => sessions.session_id,
2087
+ {
2088
+ onDelete: "set null"
2089
+ }
2090
+ ),
2021
2091
  board_id: varchar("board_id", { length: 36 }).notNull().references(() => boards.board_id, { onDelete: "cascade" }),
2022
2092
  name: text("name").notNull(),
2023
2093
  description: text("description"),
@@ -2044,6 +2114,7 @@ var init_schema_postgres = __esm({
2044
2114
  },
2045
2115
  (table) => ({
2046
2116
  branchIdx: index("artifacts_branch_idx").on(table.branch_id),
2117
+ sourceSessionIdx: index("artifacts_source_session_idx").on(table.source_session_id),
2047
2118
  boardIdx: index("artifacts_board_idx").on(table.board_id),
2048
2119
  archivedIdx: index("artifacts_archived_idx").on(table.archived),
2049
2120
  publicIdx: index("artifacts_public_idx").on(table.public)
@@ -2200,7 +2271,7 @@ var init_schema_postgres = __esm({
2200
2271
  // Materialized for queries
2201
2272
  name: text("name").notNull(),
2202
2273
  channel_type: text("channel_type", {
2203
- enum: ["slack", "discord", "whatsapp", "telegram", "github"]
2274
+ enum: ["slack", "discord", "whatsapp", "telegram", "github", "teams"]
2204
2275
  }).notNull(),
2205
2276
  target_branch_id: varchar("target_branch_id", { length: 36 }).notNull().references(() => branches.branch_id, { onDelete: "cascade" }),
2206
2277
  agor_user_id: varchar("agor_user_id", { length: 36 }).notNull(),
@@ -2584,7 +2655,7 @@ var init_schema_postgres = __esm({
2584
2655
  archivedIdx: index("kb_graph_edges_archived_idx").on(table.archived)
2585
2656
  })
2586
2657
  );
2587
- sessionsRelations = relations(sessions, ({ one }) => ({
2658
+ sessionsRelations = relations(sessions, ({ one, many }) => ({
2588
2659
  branch: one(branches, {
2589
2660
  fields: [sessions.branch_id],
2590
2661
  references: [branches.branch_id]
@@ -2592,6 +2663,24 @@ var init_schema_postgres = __esm({
2592
2663
  schedule: one(schedules, {
2593
2664
  fields: [sessions.schedule_id],
2594
2665
  references: [schedules.schedule_id]
2666
+ }),
2667
+ outboundRelationships: many(sessionRelationships, { relationName: "relationshipSource" }),
2668
+ inboundRelationships: many(sessionRelationships, { relationName: "relationshipTarget" })
2669
+ }));
2670
+ sessionRelationshipsRelations = relations(sessionRelationships, ({ one }) => ({
2671
+ sourceSession: one(sessions, {
2672
+ fields: [sessionRelationships.source_session_id],
2673
+ references: [sessions.session_id],
2674
+ relationName: "relationshipSource"
2675
+ }),
2676
+ targetSession: one(sessions, {
2677
+ fields: [sessionRelationships.target_session_id],
2678
+ references: [sessions.session_id],
2679
+ relationName: "relationshipTarget"
2680
+ }),
2681
+ callbackSession: one(sessions, {
2682
+ fields: [sessionRelationships.callback_session_id],
2683
+ references: [sessions.session_id]
2595
2684
  })
2596
2685
  }));
2597
2686
  branchesRelations = relations(branches, ({ many }) => ({
@@ -2644,6 +2733,8 @@ __export(schema_sqlite_exports, {
2644
2733
  serializedSessions: () => serializedSessions2,
2645
2734
  sessionEnvSelections: () => sessionEnvSelections2,
2646
2735
  sessionMcpServers: () => sessionMcpServers2,
2736
+ sessionRelationships: () => sessionRelationships2,
2737
+ sessionRelationshipsRelations: () => sessionRelationshipsRelations2,
2647
2738
  sessions: () => sessions2,
2648
2739
  sessionsRelations: () => sessionsRelations2,
2649
2740
  tasks: () => tasks2,
@@ -2662,7 +2753,7 @@ import {
2662
2753
  text as text2,
2663
2754
  uniqueIndex as uniqueIndex2
2664
2755
  } from "drizzle-orm/sqlite-core";
2665
- var 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;
2756
+ var 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;
2666
2757
  var init_schema_sqlite = __esm({
2667
2758
  "src/db/schema.sqlite.ts"() {
2668
2759
  "use strict";
@@ -2752,6 +2843,36 @@ var init_schema_sqlite = __esm({
2752
2843
  scheduleRunUnique: uniqueIndex2("sessions_schedule_run_unique").on(table.schedule_id, table.scheduled_run_at).where(sql3`${table.schedule_id} IS NOT NULL AND ${table.scheduled_run_at} IS NOT NULL`)
2753
2844
  })
2754
2845
  );
2846
+ sessionRelationships2 = sqliteTable(
2847
+ "session_relationships",
2848
+ {
2849
+ relationship_id: text2("relationship_id", { length: 36 }).primaryKey(),
2850
+ source_session_id: text2("source_session_id", { length: 36 }).notNull().references(() => sessions2.session_id, { onDelete: "cascade" }),
2851
+ target_session_id: text2("target_session_id", { length: 36 }).notNull().references(() => sessions2.session_id, { onDelete: "cascade" }),
2852
+ relationship_type: text2("relationship_type", { enum: ["remote_create"] }).notNull(),
2853
+ created_by: text2("created_by", { length: 36 }).notNull(),
2854
+ created_at: t2.timestamp("created_at").notNull(),
2855
+ updated_at: t2.timestamp("updated_at"),
2856
+ callback_enabled: t2.bool("callback_enabled").notNull().default(false),
2857
+ callback_session_id: text2("callback_session_id", { length: 36 }).references(
2858
+ () => sessions2.session_id,
2859
+ {
2860
+ onDelete: "set null"
2861
+ }
2862
+ ),
2863
+ data: t2.json("data")
2864
+ },
2865
+ (table) => ({
2866
+ sourceIdx: index2("session_relationships_source_idx").on(table.source_session_id),
2867
+ targetIdx: index2("session_relationships_target_idx").on(table.target_session_id),
2868
+ callbackIdx: index2("session_relationships_callback_idx").on(table.callback_session_id),
2869
+ sourceTargetTypeUnique: uniqueIndex2("session_relationships_source_target_type_unique").on(
2870
+ table.source_session_id,
2871
+ table.target_session_id,
2872
+ table.relationship_type
2873
+ )
2874
+ })
2875
+ );
2755
2876
  tasks2 = sqliteTable(
2756
2877
  "tasks",
2757
2878
  {
@@ -3296,6 +3417,12 @@ var init_schema_sqlite = __esm({
3296
3417
  branch_id: text2("branch_id", { length: 36 }).references(() => branches2.branch_id, {
3297
3418
  onDelete: "set null"
3298
3419
  }),
3420
+ source_session_id: text2("source_session_id", { length: 36 }).references(
3421
+ () => sessions2.session_id,
3422
+ {
3423
+ onDelete: "set null"
3424
+ }
3425
+ ),
3299
3426
  board_id: text2("board_id", { length: 36 }).notNull().references(() => boards2.board_id, { onDelete: "cascade" }),
3300
3427
  name: text2("name").notNull(),
3301
3428
  description: text2("description"),
@@ -3322,6 +3449,7 @@ var init_schema_sqlite = __esm({
3322
3449
  },
3323
3450
  (table) => ({
3324
3451
  branchIdx: index2("artifacts_branch_idx").on(table.branch_id),
3452
+ sourceSessionIdx: index2("artifacts_source_session_idx").on(table.source_session_id),
3325
3453
  boardIdx: index2("artifacts_board_idx").on(table.board_id),
3326
3454
  archivedIdx: index2("artifacts_archived_idx").on(table.archived),
3327
3455
  publicIdx: index2("artifacts_public_idx").on(table.public)
@@ -3480,7 +3608,7 @@ var init_schema_sqlite = __esm({
3480
3608
  // Materialized for queries
3481
3609
  name: text2("name").notNull(),
3482
3610
  channel_type: text2("channel_type", {
3483
- enum: ["slack", "discord", "whatsapp", "telegram", "github"]
3611
+ enum: ["slack", "discord", "whatsapp", "telegram", "github", "teams"]
3484
3612
  }).notNull(),
3485
3613
  target_branch_id: text2("target_branch_id", { length: 36 }).notNull().references(() => branches2.branch_id, { onDelete: "cascade" }),
3486
3614
  agor_user_id: text2("agor_user_id", { length: 36 }).notNull(),
@@ -3863,7 +3991,7 @@ var init_schema_sqlite = __esm({
3863
3991
  archivedIdx: index2("kb_graph_edges_archived_idx").on(table.archived)
3864
3992
  })
3865
3993
  );
3866
- sessionsRelations2 = relations2(sessions2, ({ one }) => ({
3994
+ sessionsRelations2 = relations2(sessions2, ({ one, many }) => ({
3867
3995
  branch: one(branches2, {
3868
3996
  fields: [sessions2.branch_id],
3869
3997
  references: [branches2.branch_id]
@@ -3871,6 +3999,24 @@ var init_schema_sqlite = __esm({
3871
3999
  schedule: one(schedules2, {
3872
4000
  fields: [sessions2.schedule_id],
3873
4001
  references: [schedules2.schedule_id]
4002
+ }),
4003
+ outboundRelationships: many(sessionRelationships2, { relationName: "relationshipSource" }),
4004
+ inboundRelationships: many(sessionRelationships2, { relationName: "relationshipTarget" })
4005
+ }));
4006
+ sessionRelationshipsRelations2 = relations2(sessionRelationships2, ({ one }) => ({
4007
+ sourceSession: one(sessions2, {
4008
+ fields: [sessionRelationships2.source_session_id],
4009
+ references: [sessions2.session_id],
4010
+ relationName: "relationshipSource"
4011
+ }),
4012
+ targetSession: one(sessions2, {
4013
+ fields: [sessionRelationships2.target_session_id],
4014
+ references: [sessions2.session_id],
4015
+ relationName: "relationshipTarget"
4016
+ }),
4017
+ callbackSession: one(sessions2, {
4018
+ fields: [sessionRelationships2.callback_session_id],
4019
+ references: [sessions2.session_id]
3874
4020
  })
3875
4021
  }));
3876
4022
  branchesRelations2 = relations2(branches2, ({ many }) => ({
@@ -3966,6 +4112,7 @@ __export(schema_exports, {
3966
4112
  serializedSessions: () => serializedSessions3,
3967
4113
  sessionEnvSelections: () => sessionEnvSelections3,
3968
4114
  sessionMcpServers: () => sessionMcpServers3,
4115
+ sessionRelationships: () => sessionRelationships3,
3969
4116
  sessions: () => sessions3,
3970
4117
  tasks: () => tasks3,
3971
4118
  threadSessionMap: () => threadSessionMap3,
@@ -3973,7 +4120,7 @@ __export(schema_exports, {
3973
4120
  userMcpOauthTokens: () => userMcpOauthTokens3,
3974
4121
  users: () => users3
3975
4122
  });
3976
- 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;
4123
+ 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;
3977
4124
  var init_schema = __esm({
3978
4125
  "src/db/schema.ts"() {
3979
4126
  "use strict";
@@ -4005,6 +4152,7 @@ var init_schema = __esm({
4005
4152
  artifactTrustGrants3 = schema.artifactTrustGrants;
4006
4153
  boardObjects3 = schema.boardObjects;
4007
4154
  sessionMcpServers3 = schema.sessionMcpServers;
4155
+ sessionRelationships3 = schema.sessionRelationships;
4008
4156
  sessionEnvSelections3 = schema.sessionEnvSelections;
4009
4157
  userMcpOauthTokens3 = schema.userMcpOauthTokens;
4010
4158
  boardComments3 = schema.boardComments;
@@ -4229,8 +4377,8 @@ function createPostgresDatabase(config) {
4229
4377
  if (config.ssl !== void 0) {
4230
4378
  options.ssl = config.ssl;
4231
4379
  }
4232
- const sql15 = postgres(config.url, options);
4233
- return drizzlePostgres(sql15, { schema: schema_postgres_exports });
4380
+ const sql16 = postgres(config.url, options);
4381
+ return drizzlePostgres(sql16, { schema: schema_postgres_exports });
4234
4382
  } catch (error) {
4235
4383
  throw new DatabaseConnectionError(
4236
4384
  `Failed to create PostgreSQL client: ${error instanceof Error ? error.message : String(error)}`,
@@ -5356,6 +5504,7 @@ var FS_ACCESS_RANK = {
5356
5504
  };
5357
5505
  var VIEW_OR_BETTER_BRANCH_PERMISSIONS = ["view", "session", "prompt", "all"];
5358
5506
  var BRANCH_PERMISSION_SOURCES = ["board", "override"];
5507
+ var FS_ACCESS_BRANCH_PERMISSIONS = ["read", "write"];
5359
5508
  var BranchRepository = class {
5360
5509
  constructor(db) {
5361
5510
  this.db = db;
@@ -5849,6 +5998,83 @@ var BranchRepository = class {
5849
5998
  }
5850
5999
  return Array.from(userIds);
5851
6000
  }
6001
+ /**
6002
+ * Find users whose explicit branch or aligned-board grants should materialize
6003
+ * into filesystem access for the branch.
6004
+ *
6005
+ * This intentionally excludes ambient "others" access because there is no
6006
+ * bounded user set to expand. Board owners apply whenever the branch is
6007
+ * explicitly aligned to board permissions (`permission_source = 'board'`);
6008
+ * board group grants additionally require a shared board. Override branches
6009
+ * must not inherit board grants.
6010
+ */
6011
+ async findExplicitFsAccessUserIds(branchId) {
6012
+ const branchRow = await select(this.db, {
6013
+ board_id: branches3.board_id,
6014
+ permission_source: branches3.permission_source
6015
+ }).from(branches3).where(eq8(branches3.branch_id, branchId)).one();
6016
+ const ownerRows = await select(this.db, { user_id: branchOwners3.user_id }).from(branchOwners3).where(eq8(branchOwners3.branch_id, branchId)).all();
6017
+ const groupRows = await select(this.db, { user_id: groupMemberships3.user_id }).from(branchGroupGrants3).innerJoin(groupMemberships3, eq8(groupMemberships3.group_id, branchGroupGrants3.group_id)).innerJoin(
6018
+ groups3,
6019
+ and8(eq8(groups3.group_id, branchGroupGrants3.group_id), eq8(groups3.archived, false))
6020
+ ).where(
6021
+ and8(
6022
+ eq8(branchGroupGrants3.branch_id, branchId),
6023
+ inArray2(
6024
+ sql6`coalesce(${branchGroupGrants3.fs_access}, 'read')`,
6025
+ FS_ACCESS_BRANCH_PERMISSIONS
6026
+ )
6027
+ )
6028
+ ).all();
6029
+ const isBoardAligned = branchRow?.permission_source === "board" && branchRow.board_id;
6030
+ const boardOwnerRows = isBoardAligned ? await select(this.db, { user_id: boardOwners3.user_id }).from(boardOwners3).where(eq8(boardOwners3.board_id, branchRow.board_id)).all() : [];
6031
+ const boardGroupRows = isBoardAligned ? await select(this.db, { user_id: groupMemberships3.user_id }).from(boardGroupGrants3).innerJoin(groupMemberships3, eq8(groupMemberships3.group_id, boardGroupGrants3.group_id)).innerJoin(
6032
+ groups3,
6033
+ and8(eq8(groups3.group_id, boardGroupGrants3.group_id), eq8(groups3.archived, false))
6034
+ ).innerJoin(
6035
+ boards3,
6036
+ and8(
6037
+ eq8(boards3.board_id, boardGroupGrants3.board_id),
6038
+ eq8(
6039
+ sql6`coalesce(${jsonExtract(this.db, boards3.data, "access_mode")}, 'shared')`,
6040
+ "shared"
6041
+ )
6042
+ )
6043
+ ).where(
6044
+ and8(
6045
+ eq8(boardGroupGrants3.board_id, branchRow.board_id),
6046
+ inArray2(
6047
+ sql6`coalesce(${boardGroupGrants3.fs_access}, 'read')`,
6048
+ FS_ACCESS_BRANCH_PERMISSIONS
6049
+ )
6050
+ )
6051
+ ).all() : [];
6052
+ const userIds = /* @__PURE__ */ new Set();
6053
+ for (const row of ownerRows) {
6054
+ userIds.add(row.user_id);
6055
+ }
6056
+ for (const row of groupRows) {
6057
+ userIds.add(row.user_id);
6058
+ }
6059
+ for (const row of boardOwnerRows) {
6060
+ userIds.add(row.user_id);
6061
+ }
6062
+ for (const row of boardGroupRows) {
6063
+ userIds.add(row.user_id);
6064
+ }
6065
+ return Array.from(userIds);
6066
+ }
6067
+ async findBoardAlignedBranches(boardId) {
6068
+ const rows = await select(this.db).from(branches3).where(
6069
+ and8(
6070
+ eq8(branches3.board_id, boardId),
6071
+ eq8(branches3.permission_source, "board"),
6072
+ eq8(branches3.archived, false)
6073
+ )
6074
+ ).all();
6075
+ const baseUrl = await getBaseUrl();
6076
+ return rows.map((row) => this.rowToBranch(row, baseUrl));
6077
+ }
5852
6078
  /**
5853
6079
  * Get all owners of a branch
5854
6080
  *
@@ -7533,13 +7759,20 @@ import { and as and17, desc as desc5, eq as eq22, inArray as inArray5, like as l
7533
7759
  init_database_wrapper();
7534
7760
  init_schema();
7535
7761
 
7762
+ // src/db/repositories/session-relationships.ts
7763
+ init_esm_shims();
7764
+ init_ids();
7765
+ init_database_wrapper();
7766
+ init_schema();
7767
+ import { and as and19, eq as eq24, inArray as inArray6, or as or8 } from "drizzle-orm";
7768
+
7536
7769
  // src/db/repositories/tasks.ts
7537
7770
  init_esm_shims();
7538
7771
  init_types2();
7539
7772
  init_ids();
7540
7773
  init_database_wrapper();
7541
7774
  init_schema();
7542
- import { eq as eq24, inArray as inArray6, like as like13, sql as sql12 } from "drizzle-orm";
7775
+ import { eq as eq25, inArray as inArray7, like as like13, sql as sql12 } from "drizzle-orm";
7543
7776
 
7544
7777
  // src/db/repositories/thread-session-map.ts
7545
7778
  init_esm_shims();
@@ -7547,7 +7780,7 @@ init_types2();
7547
7780
  init_ids();
7548
7781
  init_database_wrapper();
7549
7782
  init_schema();
7550
- import { and as and19, eq as eq25, like as like14, lt as lt2 } from "drizzle-orm";
7783
+ import { and as and20, eq as eq26, like as like14, lt as lt2 } from "drizzle-orm";
7551
7784
 
7552
7785
  // src/db/repositories/user-api-keys.ts
7553
7786
  init_esm_shims();
@@ -7556,18 +7789,18 @@ init_database_wrapper();
7556
7789
  init_schema();
7557
7790
  import { randomBytes as randomBytes3 } from "crypto";
7558
7791
  import bcrypt2 from "bcryptjs";
7559
- import { and as and20, eq as eq26 } from "drizzle-orm";
7792
+ import { and as and21, eq as eq27 } from "drizzle-orm";
7560
7793
 
7561
7794
  // src/db/repositories/user-mcp-oauth-tokens.ts
7562
7795
  init_esm_shims();
7563
7796
  init_database_wrapper();
7564
7797
  init_schema();
7565
- import { and as and21, eq as eq27, isNull as isNull6 } from "drizzle-orm";
7798
+ import { and as and22, eq as eq28, isNull as isNull6 } from "drizzle-orm";
7566
7799
 
7567
7800
  // src/db/repositories/users.ts
7568
7801
  init_esm_shims();
7569
7802
  init_types2();
7570
- import { eq as eq28, like as like15 } from "drizzle-orm";
7803
+ import { eq as eq29, like as like15, sql as sql13 } from "drizzle-orm";
7571
7804
 
7572
7805
  // src/config/env-vars.ts
7573
7806
  init_esm_shims();
@@ -7697,7 +7930,7 @@ var UsersRepository = class {
7697
7930
  * Check if unix_username is already taken by another user
7698
7931
  */
7699
7932
  async isUnixUsernameTaken(unixUsername, excludeUserId) {
7700
- const result = await select(this.db).from(users3).where(eq28(users3.unix_username, unixUsername)).one();
7933
+ const result = await select(this.db).from(users3).where(eq29(users3.unix_username, unixUsername)).one();
7701
7934
  if (!result) {
7702
7935
  return false;
7703
7936
  }
@@ -7720,7 +7953,7 @@ var UsersRepository = class {
7720
7953
  }
7721
7954
  const insertData = this.userToInsert(data);
7722
7955
  await insert(this.db, users3).values(insertData).run();
7723
- const row = await select(this.db).from(users3).where(eq28(users3.user_id, insertData.user_id)).one();
7956
+ const row = await select(this.db).from(users3).where(eq29(users3.user_id, insertData.user_id)).one();
7724
7957
  if (!row) {
7725
7958
  throw new RepositoryError("Failed to retrieve created user");
7726
7959
  }
@@ -7732,7 +7965,7 @@ var UsersRepository = class {
7732
7965
  async findById(id) {
7733
7966
  try {
7734
7967
  const fullId = await this.resolveId(id);
7735
- const result = await select(this.db).from(users3).where(eq28(users3.user_id, fullId)).one();
7968
+ const result = await select(this.db).from(users3).where(eq29(users3.user_id, fullId)).one();
7736
7969
  if (!result) {
7737
7970
  return null;
7738
7971
  }
@@ -7748,12 +7981,41 @@ var UsersRepository = class {
7748
7981
  * Find user by email
7749
7982
  */
7750
7983
  async findByEmail(email) {
7751
- const result = await select(this.db).from(users3).where(eq28(users3.email, email)).one();
7984
+ const result = await select(this.db).from(users3).where(eq29(users3.email, email)).one();
7752
7985
  if (!result) {
7753
7986
  return null;
7754
7987
  }
7755
7988
  return this.rowToUser(result);
7756
7989
  }
7990
+ /**
7991
+ * Find user by email for external identity providers.
7992
+ *
7993
+ * Agor intentionally keeps exact/case-sensitive email lookup semantics for
7994
+ * auth paths because the schema historically allowed case-distinct emails.
7995
+ * External providers such as Slack and GitHub treat email addresses as a
7996
+ * canonical identity hint, so their alignment path needs a case-insensitive
7997
+ * match. Prefer an exact match when present; otherwise return a
7998
+ * case-insensitive match only when it is unambiguous.
7999
+ */
8000
+ async findByEmailForAlignment(email) {
8001
+ const normalizedEmail = email.trim().toLowerCase();
8002
+ if (!normalizedEmail) return null;
8003
+ const exact = await this.findByEmail(normalizedEmail);
8004
+ if (exact) return exact;
8005
+ const results = await select(this.db).from(users3).where(sql13`LOWER(${users3.email}) = ${normalizedEmail}`).all();
8006
+ if (results.length !== 1) {
8007
+ if (results.length > 1) {
8008
+ console.warn(
8009
+ `[users] Ambiguous case-insensitive email alignment for ${normalizedEmail}: ${results.map((row) => {
8010
+ const userRow = row;
8011
+ return `${shortId(userRow.user_id)}:${userRow.email}`;
8012
+ }).join(", ")}`
8013
+ );
8014
+ }
8015
+ return null;
8016
+ }
8017
+ return this.rowToUser(results[0]);
8018
+ }
7757
8019
  /**
7758
8020
  * Find all users
7759
8021
  */
@@ -7790,8 +8052,8 @@ var UsersRepository = class {
7790
8052
  await update(this.db, users3).set({
7791
8053
  ...insertData,
7792
8054
  updated_at: /* @__PURE__ */ new Date()
7793
- }).where(eq28(users3.user_id, fullId)).run();
7794
- const row = await select(this.db).from(users3).where(eq28(users3.user_id, fullId)).one();
8055
+ }).where(eq29(users3.user_id, fullId)).run();
8056
+ const row = await select(this.db).from(users3).where(eq29(users3.user_id, fullId)).one();
7795
8057
  if (!row) {
7796
8058
  throw new RepositoryError("Failed to retrieve updated user");
7797
8059
  }
@@ -7802,7 +8064,7 @@ var UsersRepository = class {
7802
8064
  */
7803
8065
  async delete(id) {
7804
8066
  const fullId = await this.resolveId(id);
7805
- await deleteFrom(this.db, users3).where(eq28(users3.user_id, fullId)).run();
8067
+ await deleteFrom(this.db, users3).where(eq29(users3.user_id, fullId)).run();
7806
8068
  }
7807
8069
  /**
7808
8070
  * Get raw database row (internal use only - includes encrypted keys)
@@ -7810,7 +8072,7 @@ var UsersRepository = class {
7810
8072
  async getRawRow(id) {
7811
8073
  try {
7812
8074
  const fullId = await this.resolveId(id);
7813
- const result = await select(this.db).from(users3).where(eq28(users3.user_id, fullId)).one();
8075
+ const result = await select(this.db).from(users3).where(eq29(users3.user_id, fullId)).one();
7814
8076
  return result;
7815
8077
  } catch (error) {
7816
8078
  if (error instanceof EntityNotFoundError) {
@@ -7892,7 +8154,7 @@ var UsersRepository = class {
7892
8154
  await update(this.db, users3).set({
7893
8155
  data: { ...row.data, agentic_tools: next },
7894
8156
  updated_at: /* @__PURE__ */ new Date()
7895
- }).where(eq28(users3.user_id, fullId)).run();
8157
+ }).where(eq29(users3.user_id, fullId)).run();
7896
8158
  }
7897
8159
  /**
7898
8160
  * Delete a single credential field for a tool.
@@ -7918,7 +8180,7 @@ var UsersRepository = class {
7918
8180
  await update(this.db, users3).set({
7919
8181
  data: { ...row.data, agentic_tools: next },
7920
8182
  updated_at: /* @__PURE__ */ new Date()
7921
- }).where(eq28(users3.user_id, fullId)).run();
8183
+ }).where(eq29(users3.user_id, fullId)).run();
7922
8184
  }
7923
8185
  };
7924
8186
 
@@ -8820,7 +9082,7 @@ init_esm_shims();
8820
9082
  // src/config/env-resolver.ts
8821
9083
  init_esm_shims();
8822
9084
  init_database_wrapper();
8823
- import { eq as eq29 } from "drizzle-orm";
9085
+ import { eq as eq30 } from "drizzle-orm";
8824
9086
  init_schema();
8825
9087
 
8826
9088
  // src/config/env-validation.ts
@@ -8846,17 +9108,17 @@ init_client();
8846
9108
  init_database_wrapper();
8847
9109
  init_first_run_bootstrap();
8848
9110
  import {
8849
- and as and22,
9111
+ and as and23,
8850
9112
  asc as asc3,
8851
9113
  desc as desc6,
8852
- eq as eq31,
9114
+ eq as eq32,
8853
9115
  gt,
8854
9116
  gte,
8855
- inArray as inArray7,
9117
+ inArray as inArray8,
8856
9118
  like as like16,
8857
9119
  lte as lte2,
8858
- or as or8,
8859
- sql as sql14
9120
+ or as or9,
9121
+ sql as sql15
8860
9122
  } from "drizzle-orm";
8861
9123
  import bcryptjs from "bcryptjs";
8862
9124
 
@@ -8866,7 +9128,7 @@ init_database_wrapper();
8866
9128
  init_schema();
8867
9129
  import { dirname as dirname2, join as join3 } from "path";
8868
9130
  import { fileURLToPath as fileURLToPath2 } from "url";
8869
- import { eq as eq30, sql as sql13 } from "drizzle-orm";
9131
+ import { eq as eq31, sql as sql14 } from "drizzle-orm";
8870
9132
  import { migrate as migrateSQLite } from "drizzle-orm/libsql/migrator";
8871
9133
  import { migrate as migratePostgres } from "drizzle-orm/postgres-js/migrator";
8872
9134
 
@@ -9343,6 +9605,30 @@ var UnixIntegrationService = class {
9343
9605
  this.usersRepo = new UsersRepository(db);
9344
9606
  this.repoRepo = new RepoRepository(db);
9345
9607
  }
9608
+ async getUnixUsernamesForUsers(userIds) {
9609
+ const unixUsernames = /* @__PURE__ */ new Set();
9610
+ for (const userId of userIds) {
9611
+ const user = await this.usersRepo.findById(userId);
9612
+ if (user?.unix_username) {
9613
+ unixUsernames.add(user.unix_username);
9614
+ }
9615
+ }
9616
+ return unixUsernames;
9617
+ }
9618
+ async reconcileUnixGroupMembers(groupName, allowedUnixUsernames, options) {
9619
+ if (this.config.daemonUser) {
9620
+ allowedUnixUsernames.add(this.config.daemonUser);
9621
+ }
9622
+ const result = await this.executor.exec(UnixGroupCommands.listGroupMembers(groupName));
9623
+ const currentMembers = result.stdout.trim().split(",").filter(Boolean);
9624
+ for (const unixUsername of currentMembers) {
9625
+ if (allowedUnixUsernames.has(unixUsername)) continue;
9626
+ console.log(
9627
+ `[UnixIntegration] Removing stale ${options.label} group member ${unixUsername} from ${groupName}`
9628
+ );
9629
+ await this.executor.exec(UnixGroupCommands.removeUserFromGroup(unixUsername, groupName));
9630
+ }
9631
+ }
9346
9632
  /**
9347
9633
  * Get the configured daemon user
9348
9634
  *
@@ -9586,19 +9872,26 @@ var UnixIntegrationService = class {
9586
9872
  /**
9587
9873
  * Initialize Unix group for an existing branch
9588
9874
  *
9589
- * Creates group and adds all current owners.
9875
+ * Creates group and adds all users with explicit filesystem access.
9590
9876
  *
9591
9877
  * @param branchId - Branch ID
9592
9878
  */
9593
9879
  async initializeBranchGroup(branchId) {
9594
9880
  const groupName = await this.createBranchGroup(branchId);
9595
- const ownerIds = await this.branchRepo.getOwners(branchId);
9596
- for (const ownerId of ownerIds) {
9597
- await this.addUserToBranchGroup(branchId, ownerId);
9881
+ const userIds = await this.branchRepo.findExplicitFsAccessUserIds(branchId);
9882
+ for (const userId of userIds) {
9883
+ await this.addUserToBranchGroup(branchId, userId);
9598
9884
  }
9885
+ await this.reconcileUnixGroupMembers(groupName, await this.getUnixUsernamesForUsers(userIds), {
9886
+ label: "branch"
9887
+ });
9599
9888
  console.log(
9600
- `[UnixIntegration] Initialized group ${groupName} with ${ownerIds.length} owner(s)`
9889
+ `[UnixIntegration] Initialized group ${groupName} with ${userIds.length} explicit filesystem user(s)`
9601
9890
  );
9891
+ const branch = await this.branchRepo.findById(branchId);
9892
+ if (branch?.repo_id) {
9893
+ await this.syncRepo(branch.repo_id);
9894
+ }
9602
9895
  }
9603
9896
  // ============================================================
9604
9897
  // REPO GROUP MANAGEMENT
@@ -9830,8 +10123,8 @@ var UnixIntegrationService = class {
9830
10123
  /**
9831
10124
  * Check if a user should be in a repo's Unix group
9832
10125
  *
9833
- * A user should be in the repo group if they have ownership
9834
- * of ANY branch in that repo.
10126
+ * A user should be in the repo group if they have explicit filesystem access
10127
+ * to ANY branch in that repo.
9835
10128
  *
9836
10129
  * @param repoId - Repo ID
9837
10130
  * @param userId - User ID to check
@@ -9840,8 +10133,8 @@ var UnixIntegrationService = class {
9840
10133
  async shouldUserBeInRepoGroup(repoId, userId) {
9841
10134
  const branches4 = await this.branchRepo.findAll({ repo_id: repoId });
9842
10135
  for (const wt of branches4) {
9843
- const isOwner = await this.branchRepo.isOwner(wt.branch_id, userId);
9844
- if (isOwner) {
10136
+ const userIds = await this.branchRepo.findExplicitFsAccessUserIds(wt.branch_id);
10137
+ if (userIds.includes(userId)) {
9845
10138
  return true;
9846
10139
  }
9847
10140
  }
@@ -9850,33 +10143,36 @@ var UnixIntegrationService = class {
9850
10143
  /**
9851
10144
  * Initialize Unix group for an existing repo
9852
10145
  *
9853
- * Creates group, sets .git permissions, and adds all users who
9854
- * own any branch in the repo.
10146
+ * Creates group, sets .git permissions, and adds all users who have explicit
10147
+ * filesystem access to any branch in the repo.
9855
10148
  *
9856
10149
  * @param repoId - Repo ID
9857
10150
  */
9858
10151
  async initializeRepoGroup(repoId) {
9859
10152
  const groupName = await this.createRepoGroup(repoId);
9860
10153
  const branches4 = await this.branchRepo.findAll({ repo_id: repoId });
9861
- const ownerIds = /* @__PURE__ */ new Set();
10154
+ const userIds = /* @__PURE__ */ new Set();
9862
10155
  for (const wt of branches4) {
9863
- const wtOwners = await this.branchRepo.getOwners(wt.branch_id);
9864
- for (const ownerId of wtOwners) {
9865
- ownerIds.add(ownerId);
10156
+ const branchUserIds = await this.branchRepo.findExplicitFsAccessUserIds(wt.branch_id);
10157
+ for (const userId of branchUserIds) {
10158
+ userIds.add(userId);
9866
10159
  }
9867
10160
  }
9868
- for (const ownerId of ownerIds) {
9869
- await this.addUserToRepoGroup(repoId, ownerId);
10161
+ for (const userId of userIds) {
10162
+ await this.addUserToRepoGroup(repoId, userId);
9870
10163
  }
10164
+ await this.reconcileUnixGroupMembers(groupName, await this.getUnixUsernamesForUsers(userIds), {
10165
+ label: "repo"
10166
+ });
9871
10167
  console.log(
9872
- `[UnixIntegration] Initialized repo group ${groupName} with ${ownerIds.size} unique owner(s)`
10168
+ `[UnixIntegration] Initialized repo group ${groupName} with ${userIds.size} unique filesystem user(s)`
9873
10169
  );
9874
10170
  }
9875
10171
  /**
9876
10172
  * Full sync for a repo
9877
10173
  *
9878
10174
  * Ensures repo group exists, .git permissions are set, and all
9879
- * branch owners are in the repo group.
10175
+ * branch filesystem-access users are in the repo group.
9880
10176
  *
9881
10177
  * @param repoId - Repo ID
9882
10178
  */
@@ -9884,15 +10180,23 @@ var UnixIntegrationService = class {
9884
10180
  console.log(`[UnixIntegration] Full sync for repo ${shortId(repoId)}`);
9885
10181
  await this.createRepoGroup(repoId);
9886
10182
  const branches4 = await this.branchRepo.findAll({ repo_id: repoId });
9887
- const ownerIds = /* @__PURE__ */ new Set();
10183
+ const userIds = /* @__PURE__ */ new Set();
9888
10184
  for (const wt of branches4) {
9889
- const wtOwners = await this.branchRepo.getOwners(wt.branch_id);
9890
- for (const ownerId of wtOwners) {
9891
- ownerIds.add(ownerId);
10185
+ const branchUserIds = await this.branchRepo.findExplicitFsAccessUserIds(wt.branch_id);
10186
+ for (const userId of branchUserIds) {
10187
+ userIds.add(userId);
9892
10188
  }
9893
10189
  }
9894
- for (const ownerId of ownerIds) {
9895
- await this.addUserToRepoGroup(repoId, ownerId);
10190
+ for (const userId of userIds) {
10191
+ await this.addUserToRepoGroup(repoId, userId);
10192
+ }
10193
+ const repo = await this.repoRepo.findById(repoId);
10194
+ if (repo?.unix_group) {
10195
+ await this.reconcileUnixGroupMembers(
10196
+ repo.unix_group,
10197
+ await this.getUnixUsernamesForUsers(userIds),
10198
+ { label: "repo" }
10199
+ );
9896
10200
  }
9897
10201
  }
9898
10202
  // ============================================================
@@ -10169,16 +10473,28 @@ var UnixIntegrationService = class {
10169
10473
  /**
10170
10474
  * Full sync for a branch
10171
10475
  *
10172
- * Ensures group exists, all owners are in group, and symlinks are created.
10476
+ * Ensures group exists, all explicit filesystem-access users are in group,
10477
+ * and symlinks are created.
10173
10478
  *
10174
10479
  * @param branchId - Branch ID
10175
10480
  */
10176
10481
  async syncBranch(branchId) {
10177
10482
  console.log(`[UnixIntegration] Full sync for branch ${shortId(branchId)}`);
10178
10483
  await this.createBranchGroup(branchId);
10179
- const ownerIds = await this.branchRepo.getOwners(branchId);
10180
- for (const ownerId of ownerIds) {
10181
- await this.addUserToBranchGroup(branchId, ownerId);
10484
+ const userIds = await this.branchRepo.findExplicitFsAccessUserIds(branchId);
10485
+ for (const userId of userIds) {
10486
+ await this.addUserToBranchGroup(branchId, userId);
10487
+ }
10488
+ const branch = await this.branchRepo.findById(branchId);
10489
+ if (branch?.unix_group) {
10490
+ await this.reconcileUnixGroupMembers(
10491
+ branch.unix_group,
10492
+ await this.getUnixUsernamesForUsers(userIds),
10493
+ { label: "branch" }
10494
+ );
10495
+ }
10496
+ if (branch?.repo_id) {
10497
+ await this.syncRepo(branch.repo_id);
10182
10498
  }
10183
10499
  }
10184
10500
  /**