agor-live 0.17.2 → 0.17.3

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 (316) hide show
  1. package/dist/cli/lib/banner.d.ts +1 -1
  2. package/dist/cli/lib/banner.js +1 -1
  3. package/dist/cli/lib/check-migrations.test.js +9627 -9112
  4. package/dist/cli/lib/daemon-manager.test.js +9632 -9117
  5. package/dist/cli/lib/help.js +1 -1
  6. package/dist/core/api/index.d.cts +3 -3
  7. package/dist/core/api/index.d.ts +3 -3
  8. package/dist/core/{board-comment-DIdOJrSF.d.cts → board-comment-CCFVVN7K.d.cts} +0 -2
  9. package/dist/core/{board-comment-3N-jSgsk.d.ts → board-comment-iT3DgZb4.d.ts} +0 -2
  10. package/dist/core/claude/index.cjs +29 -19
  11. package/dist/core/claude/index.d.cts +2 -2
  12. package/dist/core/claude/index.d.ts +2 -2
  13. package/dist/core/claude/index.js +32 -33
  14. package/dist/core/client/index.cjs +49 -0
  15. package/dist/core/client/index.d.cts +7 -7
  16. package/dist/core/client/index.d.ts +7 -7
  17. package/dist/core/client/index.js +46 -0
  18. package/dist/core/{client-B5PyIvNc.d.cts → client-CemqXk0v.d.cts} +116 -100
  19. package/dist/core/{client-C1CsRi19.d.ts → client-uYEOha6g.d.ts} +116 -100
  20. package/dist/core/config/browser.d.cts +3 -3
  21. package/dist/core/config/browser.d.ts +3 -3
  22. package/dist/core/config/index.cjs +84 -41
  23. package/dist/core/config/index.d.cts +59 -17
  24. package/dist/core/config/index.d.ts +59 -17
  25. package/dist/core/config/index.js +86 -55
  26. package/dist/core/{config-manager-TxxjFMRd.d.cts → config-manager-B8TP9Kz0.d.cts} +12 -3
  27. package/dist/core/{config-manager-DTrsj6G3.d.ts → config-manager-CDEB0FY4.d.ts} +12 -3
  28. package/dist/core/{config-services-YEZ4DwCD.d.cts → config-services-CXyQKEK5.d.cts} +1 -1
  29. package/dist/core/{config-services-DcO2GRgh.d.ts → config-services-DhM7_yWn.d.ts} +1 -1
  30. package/dist/core/db/index.cjs +235 -175
  31. package/dist/core/db/index.d.cts +190 -147
  32. package/dist/core/db/index.d.ts +190 -147
  33. package/dist/core/db/index.js +239 -190
  34. package/dist/core/db/session-guard.d.cts +4 -4
  35. package/dist/core/db/session-guard.d.ts +4 -4
  36. package/dist/core/drizzle/postgres/0028_queued_tasks.sql +8 -0
  37. package/dist/core/drizzle/postgres/0030_migrate_queued_messages.sql +24 -0
  38. package/dist/core/drizzle/postgres/0031_restructure_agentic_tool_config.sql +201 -0
  39. package/dist/core/drizzle/postgres/meta/_journal.json +21 -0
  40. package/dist/core/drizzle/sqlite/0039_queued_tasks.sql +13 -0
  41. package/dist/core/drizzle/sqlite/0040_migrate_queued_messages.sql +61 -0
  42. package/dist/core/drizzle/sqlite/0041_restructure_agentic_tool_config.sql +204 -0
  43. package/dist/core/drizzle/sqlite/meta/_journal.json +21 -0
  44. package/dist/core/gateway/index.d.cts +2 -2
  45. package/dist/core/gateway/index.d.ts +2 -2
  46. package/dist/core/{gateway-BnOlAelY.d.cts → gateway-BWq4j_Ll.d.cts} +1 -1
  47. package/dist/core/{gateway-B_4X-v07.d.ts → gateway-C3Jm_akw.d.ts} +1 -1
  48. package/dist/core/git/index.d.cts +4 -4
  49. package/dist/core/git/index.d.ts +4 -4
  50. package/dist/core/index.cjs +474 -201
  51. package/dist/core/index.d.cts +12 -10
  52. package/dist/core/index.d.ts +12 -10
  53. package/dist/core/index.js +473 -216
  54. package/dist/core/lib/feathers-validation.cjs +2 -1
  55. package/dist/core/lib/feathers-validation.d.cts +1 -1
  56. package/dist/core/lib/feathers-validation.d.ts +1 -1
  57. package/dist/core/lib/feathers-validation.js +2 -1
  58. package/dist/core/mcp/index.cjs +26 -16
  59. package/dist/core/mcp/index.js +26 -16
  60. package/dist/core/{message-DinITA7a.d.cts → message-CSWOsdcZ.d.cts} +1 -9
  61. package/dist/core/{message-CHUUP6OS.d.ts → message-DZa8g0s0.d.ts} +1 -9
  62. package/dist/core/models/index.d.cts +3 -73
  63. package/dist/core/models/index.d.ts +3 -73
  64. package/dist/core/package.json +5 -0
  65. package/dist/core/permissions/index.d.cts +1 -1
  66. package/dist/core/permissions/index.d.ts +1 -1
  67. package/dist/core/resolve-config-BcL-Hv8k.d.ts +74 -0
  68. package/dist/core/resolve-config-DTCxuSBx.d.cts +74 -0
  69. package/dist/core/seed/index.cjs +145 -98
  70. package/dist/core/seed/index.js +148 -112
  71. package/dist/core/{session-guard-C0LkDEN7.d.ts → session-guard-BFqVtBoS.d.ts} +1 -1
  72. package/dist/core/{session-guard-kvAx_8Fb.d.cts → session-guard-KHh0cnET.d.cts} +1 -1
  73. package/dist/core/sessions/index.cjs +184 -0
  74. package/dist/core/sessions/index.d.cts +79 -0
  75. package/dist/core/sessions/index.d.ts +79 -0
  76. package/dist/core/sessions/index.js +157 -0
  77. package/dist/core/{task-BLPFCORT.d.ts → task-BHV-YHg1.d.ts} +41 -3
  78. package/dist/core/{task-wht1RJEL.d.cts → task-C2Hy7H6u.d.cts} +41 -3
  79. package/dist/core/templates/session-context.d.cts +1 -1
  80. package/dist/core/templates/session-context.d.ts +1 -1
  81. package/dist/core/tools/mcp/oauth-mcp-transport.cjs +168 -66
  82. package/dist/core/tools/mcp/oauth-mcp-transport.d.cts +92 -16
  83. package/dist/core/tools/mcp/oauth-mcp-transport.d.ts +92 -16
  84. package/dist/core/tools/mcp/oauth-mcp-transport.js +165 -66
  85. package/dist/core/tools/mcp/oauth-refresh.cjs +43 -53
  86. package/dist/core/tools/mcp/oauth-refresh.d.cts +3 -3
  87. package/dist/core/tools/mcp/oauth-refresh.d.ts +3 -3
  88. package/dist/core/tools/mcp/oauth-refresh.js +58 -78
  89. package/dist/core/types/index.cjs +49 -0
  90. package/dist/core/types/index.d.cts +7 -7
  91. package/dist/core/types/index.d.ts +7 -7
  92. package/dist/core/types/index.js +46 -0
  93. package/dist/core/{types-DNqfdt1z.d.cts → types-D4Rl6ZKN.d.cts} +18 -2
  94. package/dist/core/{types-DqPMmTad.d.ts → types-n61iaXub.d.ts} +18 -2
  95. package/dist/core/unix/index.cjs +164 -110
  96. package/dist/core/unix/index.d.cts +7 -8
  97. package/dist/core/unix/index.d.ts +7 -8
  98. package/dist/core/unix/index.js +167 -124
  99. package/dist/core/{user-DkNdeFoz.d.cts → user-CpfkcV2C.d.cts} +139 -13
  100. package/dist/core/{user-BfVWBmXA.d.ts → user-DP-XZMIM.d.ts} +139 -13
  101. package/dist/core/utils/permission-mode-mapper.d.cts +0 -2
  102. package/dist/core/utils/permission-mode-mapper.d.ts +0 -2
  103. package/dist/daemon/index.js +2976 -2791
  104. package/dist/daemon/main.js +2976 -2791
  105. package/dist/daemon/mcp/server.js +177 -134
  106. package/dist/daemon/mcp/tools/analytics.js +19 -5
  107. package/dist/daemon/mcp/tools/artifacts.js +19 -5
  108. package/dist/daemon/mcp/tools/boards.js +19 -5
  109. package/dist/daemon/mcp/tools/card-types.js +19 -5
  110. package/dist/daemon/mcp/tools/cards.js +19 -5
  111. package/dist/daemon/mcp/tools/environment.js +19 -5
  112. package/dist/daemon/mcp/tools/mcp-servers.d.ts +29 -2
  113. package/dist/daemon/mcp/tools/mcp-servers.js +64 -54
  114. package/dist/daemon/mcp/tools/messages.js +19 -5
  115. package/dist/daemon/mcp/tools/repos.js +19 -5
  116. package/dist/daemon/mcp/tools/search.js +19 -5
  117. package/dist/daemon/mcp/tools/sessions.js +175 -53
  118. package/dist/daemon/mcp/tools/tasks.js +19 -5
  119. package/dist/daemon/mcp/tools/users.js +19 -5
  120. package/dist/daemon/mcp/tools/worktrees.js +37 -38
  121. package/dist/daemon/register-hooks.js +52 -1
  122. package/dist/daemon/register-routes.js +436 -424
  123. package/dist/daemon/register-services.js +255 -140
  124. package/dist/daemon/services/config.d.ts +7 -1
  125. package/dist/daemon/services/config.js +3 -2
  126. package/dist/daemon/services/gateway.js +28 -15
  127. package/dist/daemon/services/mcp-servers.d.ts +7 -2
  128. package/dist/daemon/services/repos.js +2 -0
  129. package/dist/daemon/services/sessions.d.ts +1 -1
  130. package/dist/daemon/services/sessions.js +8 -16
  131. package/dist/daemon/services/tasks.js +16 -10
  132. package/dist/daemon/services/terminals.js +2 -0
  133. package/dist/daemon/services/users.d.ts +27 -11
  134. package/dist/daemon/services/users.js +89 -43
  135. package/dist/daemon/services/worktree-owners.js +2 -0
  136. package/dist/daemon/services/worktrees.js +2 -0
  137. package/dist/daemon/setup/index.js +5 -2
  138. package/dist/daemon/setup/socketio.d.ts +10 -1
  139. package/dist/daemon/setup/socketio.js +7 -3
  140. package/dist/daemon/startup.js +13 -1
  141. package/dist/daemon/utils/apply-session-config-defaults.d.ts +54 -0
  142. package/dist/daemon/utils/apply-session-config-defaults.js +46 -0
  143. package/dist/daemon/utils/spawn-executor.js +2 -0
  144. package/dist/daemon/utils/worktree-authorization.d.ts +2 -4
  145. package/dist/executor/commands/zellij.d.ts.map +1 -1
  146. package/dist/executor/commands/zellij.js +2 -2
  147. package/dist/executor/handlers/sdk/base-executor.d.ts +4 -3
  148. package/dist/executor/handlers/sdk/base-executor.d.ts.map +1 -1
  149. package/dist/executor/handlers/sdk/base-executor.js +11 -5
  150. package/dist/executor/payload-types.d.ts +14 -14
  151. package/dist/executor/sdk-handlers/claude/claude-tool.d.ts.map +1 -1
  152. package/dist/executor/sdk-handlers/claude/claude-tool.js +9 -4
  153. package/dist/executor/sdk-handlers/claude/import/task-extractor.d.ts.map +1 -1
  154. package/dist/executor/sdk-handlers/claude/import/task-extractor.js +0 -5
  155. package/dist/executor/sdk-handlers/claude/message-builder.d.ts +23 -2
  156. package/dist/executor/sdk-handlers/claude/message-builder.d.ts.map +1 -1
  157. package/dist/executor/sdk-handlers/claude/message-builder.js +33 -2
  158. package/dist/executor/sdk-handlers/claude/permissions/permission-hooks.d.ts +9 -1
  159. package/dist/executor/sdk-handlers/claude/permissions/permission-hooks.d.ts.map +1 -1
  160. package/dist/executor/sdk-handlers/claude/permissions/permission-hooks.js +12 -0
  161. package/dist/executor/sdk-handlers/claude/query-builder.d.ts.map +1 -1
  162. package/dist/executor/sdk-handlers/claude/query-builder.js +11 -6
  163. package/dist/executor/sdk-handlers/codex/codex-tool.d.ts +0 -5
  164. package/dist/executor/sdk-handlers/codex/codex-tool.d.ts.map +1 -1
  165. package/dist/executor/sdk-handlers/codex/codex-tool.js +9 -24
  166. package/dist/executor/sdk-handlers/codex/prompt-service.d.ts +15 -2
  167. package/dist/executor/sdk-handlers/codex/prompt-service.d.ts.map +1 -1
  168. package/dist/executor/sdk-handlers/codex/prompt-service.js +39 -10
  169. package/dist/executor/sdk-handlers/copilot/copilot-tool.d.ts +0 -5
  170. package/dist/executor/sdk-handlers/copilot/copilot-tool.d.ts.map +1 -1
  171. package/dist/executor/sdk-handlers/copilot/copilot-tool.js +5 -22
  172. package/dist/executor/sdk-handlers/gemini/gemini-tool.d.ts +0 -5
  173. package/dist/executor/sdk-handlers/gemini/gemini-tool.d.ts.map +1 -1
  174. package/dist/executor/sdk-handlers/gemini/gemini-tool.js +9 -24
  175. package/dist/ui/assets/{CodeEditor.inner-CO-5PAnZ.js → CodeEditor.inner-CVLqZBtM.js} +1 -1
  176. package/dist/ui/assets/{CodeEditor.inner-CO-5PAnZ.js.gz → CodeEditor.inner-CVLqZBtM.js.gz} +0 -0
  177. package/dist/ui/assets/{_basePickBy-DfxojsEt.js → _basePickBy-CFq5ES2J.js} +1 -1
  178. package/dist/ui/assets/_basePickBy-CFq5ES2J.js.gz +0 -0
  179. package/dist/ui/assets/{_baseUniq-DWFPJOTC.js → _baseUniq-C4uKBvNt.js} +1 -1
  180. package/dist/ui/assets/_baseUniq-C4uKBvNt.js.gz +0 -0
  181. package/dist/ui/assets/{arc-vMZ_XGSI.js → arc-BnrcXDJJ.js} +1 -1
  182. package/dist/ui/assets/arc-BnrcXDJJ.js.gz +0 -0
  183. package/dist/ui/assets/{architectureDiagram-VXUJARFQ-DGpk_uOD.js → architectureDiagram-VXUJARFQ-DD9HD-WR.js} +1 -1
  184. package/dist/ui/assets/architectureDiagram-VXUJARFQ-DD9HD-WR.js.gz +0 -0
  185. package/dist/ui/assets/{base-80a1f760-BsVlOKqO.js → base-80a1f760-BK1VmxWU.js} +1 -1
  186. package/dist/ui/assets/{blockDiagram-VD42YOAC-BkRnxc94.js → blockDiagram-VD42YOAC-LBAckZZe.js} +1 -1
  187. package/dist/ui/assets/blockDiagram-VD42YOAC-LBAckZZe.js.gz +0 -0
  188. package/dist/ui/assets/{c4Diagram-YG6GDRKO-Dcf-anJy.js → c4Diagram-YG6GDRKO-yEdylcYP.js} +1 -1
  189. package/dist/ui/assets/{c4Diagram-YG6GDRKO-Dcf-anJy.js.gz → c4Diagram-YG6GDRKO-yEdylcYP.js.gz} +0 -0
  190. package/dist/ui/assets/channel-CMN-iY3Q.js +1 -0
  191. package/dist/ui/assets/{chunk-4BX2VUAB-C4oVWDo8.js → chunk-4BX2VUAB-IHtzKbmQ.js} +1 -1
  192. package/dist/ui/assets/{chunk-55IACEB6-CsBbTu57.js → chunk-55IACEB6-C4o5tv_F.js} +1 -1
  193. package/dist/ui/assets/{chunk-B4BG7PRW-DtkeCZab.js → chunk-B4BG7PRW-EPkzLvlB.js} +1 -1
  194. package/dist/ui/assets/chunk-B4BG7PRW-EPkzLvlB.js.gz +0 -0
  195. package/dist/ui/assets/{chunk-DI55MBZ5-BQ_asW-1.js → chunk-DI55MBZ5-CW-Bzkzj.js} +1 -1
  196. package/dist/ui/assets/chunk-DI55MBZ5-CW-Bzkzj.js.gz +0 -0
  197. package/dist/ui/assets/{chunk-FMBD7UC4-DAdcLNG-.js → chunk-FMBD7UC4-DvGU02Io.js} +1 -1
  198. package/dist/ui/assets/{chunk-QN33PNHL-Do2zad3m.js → chunk-QN33PNHL-C-PIlz9n.js} +1 -1
  199. package/dist/ui/assets/{chunk-QZHKN3VN-CyhMmSdC.js → chunk-QZHKN3VN-BhpJFm6h.js} +1 -1
  200. package/dist/ui/assets/{chunk-TZMSLE5B-DlPypnIq.js → chunk-TZMSLE5B-Biake8IU.js} +1 -1
  201. package/dist/ui/assets/chunk-TZMSLE5B-Biake8IU.js.gz +0 -0
  202. package/dist/ui/assets/classDiagram-2ON5EDUG-Bz1et8oA.js +1 -0
  203. package/dist/ui/assets/classDiagram-v2-WZHVMYZB-Bz1et8oA.js +1 -0
  204. package/dist/ui/assets/clone-Dxo5sEAf.js +1 -0
  205. package/dist/ui/assets/{consoleHook-59e792cb-DHYIclEd.js → consoleHook-59e792cb-BzEkHWE8.js} +1 -1
  206. package/dist/ui/assets/consoleHook-59e792cb-BzEkHWE8.js.gz +0 -0
  207. package/dist/ui/assets/{cose-bilkent-S5V4N54A-DotJH9qH.js → cose-bilkent-S5V4N54A-vAiVi74s.js} +1 -1
  208. package/dist/ui/assets/cose-bilkent-S5V4N54A-vAiVi74s.js.gz +0 -0
  209. package/dist/ui/assets/{dagre-6UL2VRFP-Btssr8QF.js → dagre-6UL2VRFP-C8w7TshD.js} +1 -1
  210. package/dist/ui/assets/dagre-6UL2VRFP-C8w7TshD.js.gz +0 -0
  211. package/dist/ui/assets/{diagram-PSM6KHXK-D5_Jkog3.js → diagram-PSM6KHXK-CvnjEmtQ.js} +1 -1
  212. package/dist/ui/assets/diagram-PSM6KHXK-CvnjEmtQ.js.gz +0 -0
  213. package/dist/ui/assets/{diagram-QEK2KX5R-DlPEVSL5.js → diagram-QEK2KX5R-D245unng.js} +1 -1
  214. package/dist/ui/assets/diagram-QEK2KX5R-D245unng.js.gz +0 -0
  215. package/dist/ui/assets/{diagram-S2PKOQOG-CjO1k8aG.js → diagram-S2PKOQOG-DgGUHL8Z.js} +1 -1
  216. package/dist/ui/assets/diagram-S2PKOQOG-DgGUHL8Z.js.gz +0 -0
  217. package/dist/ui/assets/{erDiagram-Q2GNP2WA-3cO02-K3.js → erDiagram-Q2GNP2WA-Cf5paK9b.js} +1 -1
  218. package/dist/ui/assets/erDiagram-Q2GNP2WA-Cf5paK9b.js.gz +0 -0
  219. package/dist/ui/assets/{flowDiagram-NV44I4VS-CajTpSxI.js → flowDiagram-NV44I4VS-BJpHmEXV.js} +1 -1
  220. package/dist/ui/assets/flowDiagram-NV44I4VS-BJpHmEXV.js.gz +0 -0
  221. package/dist/ui/assets/{ganttDiagram-LVOFAZNH-CnY_bV3o.js → ganttDiagram-LVOFAZNH-zOyTZcXC.js} +1 -1
  222. package/dist/ui/assets/{ganttDiagram-LVOFAZNH-CnY_bV3o.js.gz → ganttDiagram-LVOFAZNH-zOyTZcXC.js.gz} +0 -0
  223. package/dist/ui/assets/{gitGraphDiagram-NY62KEGX-CH16bg-j.js → gitGraphDiagram-NY62KEGX-B0uxwqMv.js} +1 -1
  224. package/dist/ui/assets/gitGraphDiagram-NY62KEGX-B0uxwqMv.js.gz +0 -0
  225. package/dist/ui/assets/{graph-IQoZvE3o.js → graph-NWXc73TO.js} +1 -1
  226. package/dist/ui/assets/graph-NWXc73TO.js.gz +0 -0
  227. package/dist/ui/assets/{index-599aeaf7-RUCkgwsg.js → index-599aeaf7-BKmNqoNF.js} +1 -1
  228. package/dist/ui/assets/index-599aeaf7-BKmNqoNF.js.gz +0 -0
  229. package/dist/ui/assets/{index-B3AvIgqP.js → index-BRYNiHLB.js} +345 -349
  230. package/dist/ui/assets/index-BRYNiHLB.js.gz +0 -0
  231. package/dist/ui/assets/{index-QV5-5yA2.js → index-BX6Xmhes.js} +1 -1
  232. package/dist/ui/assets/index-BX6Xmhes.js.gz +0 -0
  233. package/dist/ui/assets/{index-ChmRuj_T.js → index-W1hIq1uU.js} +1 -1
  234. package/dist/ui/assets/index-W1hIq1uU.js.gz +0 -0
  235. package/dist/ui/assets/{index-C-quzPWC.js → index-ctuok0zf.js} +1 -1
  236. package/dist/ui/assets/index-ctuok0zf.js.gz +0 -0
  237. package/dist/ui/assets/{infoDiagram-ER5ION4S-2e4gZVGT.js → infoDiagram-ER5ION4S-CquCuoTH.js} +1 -1
  238. package/dist/ui/assets/{journeyDiagram-XKPGCS4Q-B5bgV3GH.js → journeyDiagram-XKPGCS4Q-B_XkufZ8.js} +1 -1
  239. package/dist/ui/assets/journeyDiagram-XKPGCS4Q-B_XkufZ8.js.gz +0 -0
  240. package/dist/ui/assets/{kanban-definition-3W4ZIXB7-Bp-aWRSc.js → kanban-definition-3W4ZIXB7-C2Bo9HkB.js} +1 -1
  241. package/dist/ui/assets/kanban-definition-3W4ZIXB7-C2Bo9HkB.js.gz +0 -0
  242. package/dist/ui/assets/katex-C6wkUDai.css +1 -0
  243. package/dist/ui/assets/{katex-DGRguze2.css.gz → katex-C6wkUDai.css.gz} +0 -0
  244. package/dist/ui/assets/{layout-BH-2XJZq.js → layout-D9A7Uaku.js} +1 -1
  245. package/dist/ui/assets/layout-D9A7Uaku.js.gz +0 -0
  246. package/dist/ui/assets/{linear-DCYXhl_f.js → linear-BJUwJsxE.js} +1 -1
  247. package/dist/ui/assets/linear-BJUwJsxE.js.gz +0 -0
  248. package/dist/ui/assets/{mermaid.core-BAuL6kgQ.js → mermaid.core-DcOEcjcA.js} +5 -5
  249. package/dist/ui/assets/mermaid.core-DcOEcjcA.js.gz +0 -0
  250. package/dist/ui/assets/{mindmap-definition-VGOIOE7T-DpH5N-N0.js → mindmap-definition-VGOIOE7T-BFT1m7BG.js} +1 -1
  251. package/dist/ui/assets/mindmap-definition-VGOIOE7T-BFT1m7BG.js.gz +0 -0
  252. package/dist/ui/assets/{pieDiagram-ADFJNKIX-BB8fBxj1.js → pieDiagram-ADFJNKIX-BFaX1oBV.js} +1 -1
  253. package/dist/ui/assets/pieDiagram-ADFJNKIX-BFaX1oBV.js.gz +0 -0
  254. package/dist/ui/assets/{quadrantDiagram-AYHSOK5B-D6oZLdUD.js → quadrantDiagram-AYHSOK5B-DQps5392.js} +1 -1
  255. package/dist/ui/assets/quadrantDiagram-AYHSOK5B-DQps5392.js.gz +0 -0
  256. package/dist/ui/assets/{requirementDiagram-UZGBJVZJ-B4uGPp8w.js → requirementDiagram-UZGBJVZJ-3EZ5KWEi.js} +1 -1
  257. package/dist/ui/assets/requirementDiagram-UZGBJVZJ-3EZ5KWEi.js.gz +0 -0
  258. package/dist/ui/assets/{sankeyDiagram-TZEHDZUN-MXhIjhme.js → sankeyDiagram-TZEHDZUN-D0qcydqq.js} +1 -1
  259. package/dist/ui/assets/sankeyDiagram-TZEHDZUN-D0qcydqq.js.gz +0 -0
  260. package/dist/ui/assets/{sequenceDiagram-WL72ISMW-Cm53TYug.js → sequenceDiagram-WL72ISMW-BCR5gaaN.js} +1 -1
  261. package/dist/ui/assets/sequenceDiagram-WL72ISMW-BCR5gaaN.js.gz +0 -0
  262. package/dist/ui/assets/{stateDiagram-FKZM4ZOC-BVuxUkj5.js → stateDiagram-FKZM4ZOC-BvX4FLQ9.js} +1 -1
  263. package/dist/ui/assets/stateDiagram-FKZM4ZOC-BvX4FLQ9.js.gz +0 -0
  264. package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-CxLDvgTF.js +1 -0
  265. package/dist/ui/assets/{timeline-definition-IT6M3QCI-CMypNiEP.js → timeline-definition-IT6M3QCI-_AWp5LJn.js} +1 -1
  266. package/dist/ui/assets/timeline-definition-IT6M3QCI-_AWp5LJn.js.gz +0 -0
  267. package/dist/ui/assets/{treemap-KMMF4GRG-BEtnV3BT.js → treemap-KMMF4GRG-BZ9FBl5-.js} +1 -1
  268. package/dist/ui/assets/treemap-KMMF4GRG-BZ9FBl5-.js.gz +0 -0
  269. package/dist/ui/assets/{xychartDiagram-PRI3JC2R-BnioEYUM.js → xychartDiagram-PRI3JC2R-_wB7yuVd.js} +1 -1
  270. package/dist/ui/assets/xychartDiagram-PRI3JC2R-_wB7yuVd.js.gz +0 -0
  271. package/dist/ui/index.html +1 -1
  272. package/package.json +8 -8
  273. package/dist/ui/assets/_basePickBy-DfxojsEt.js.gz +0 -0
  274. package/dist/ui/assets/_baseUniq-DWFPJOTC.js.gz +0 -0
  275. package/dist/ui/assets/arc-vMZ_XGSI.js.gz +0 -0
  276. package/dist/ui/assets/architectureDiagram-VXUJARFQ-DGpk_uOD.js.gz +0 -0
  277. package/dist/ui/assets/blockDiagram-VD42YOAC-BkRnxc94.js.gz +0 -0
  278. package/dist/ui/assets/channel-B9aI4bYN.js +0 -1
  279. package/dist/ui/assets/chunk-B4BG7PRW-DtkeCZab.js.gz +0 -0
  280. package/dist/ui/assets/chunk-DI55MBZ5-BQ_asW-1.js.gz +0 -0
  281. package/dist/ui/assets/chunk-TZMSLE5B-DlPypnIq.js.gz +0 -0
  282. package/dist/ui/assets/classDiagram-2ON5EDUG-p-68WO4Z.js +0 -1
  283. package/dist/ui/assets/classDiagram-v2-WZHVMYZB-p-68WO4Z.js +0 -1
  284. package/dist/ui/assets/clone-DzK5ogfn.js +0 -1
  285. package/dist/ui/assets/consoleHook-59e792cb-DHYIclEd.js.gz +0 -0
  286. package/dist/ui/assets/cose-bilkent-S5V4N54A-DotJH9qH.js.gz +0 -0
  287. package/dist/ui/assets/dagre-6UL2VRFP-Btssr8QF.js.gz +0 -0
  288. package/dist/ui/assets/diagram-PSM6KHXK-D5_Jkog3.js.gz +0 -0
  289. package/dist/ui/assets/diagram-QEK2KX5R-DlPEVSL5.js.gz +0 -0
  290. package/dist/ui/assets/diagram-S2PKOQOG-CjO1k8aG.js.gz +0 -0
  291. package/dist/ui/assets/erDiagram-Q2GNP2WA-3cO02-K3.js.gz +0 -0
  292. package/dist/ui/assets/flowDiagram-NV44I4VS-CajTpSxI.js.gz +0 -0
  293. package/dist/ui/assets/gitGraphDiagram-NY62KEGX-CH16bg-j.js.gz +0 -0
  294. package/dist/ui/assets/graph-IQoZvE3o.js.gz +0 -0
  295. package/dist/ui/assets/index-599aeaf7-RUCkgwsg.js.gz +0 -0
  296. package/dist/ui/assets/index-B3AvIgqP.js.gz +0 -0
  297. package/dist/ui/assets/index-C-quzPWC.js.gz +0 -0
  298. package/dist/ui/assets/index-ChmRuj_T.js.gz +0 -0
  299. package/dist/ui/assets/index-QV5-5yA2.js.gz +0 -0
  300. package/dist/ui/assets/journeyDiagram-XKPGCS4Q-B5bgV3GH.js.gz +0 -0
  301. package/dist/ui/assets/kanban-definition-3W4ZIXB7-Bp-aWRSc.js.gz +0 -0
  302. package/dist/ui/assets/katex-DGRguze2.css +0 -1
  303. package/dist/ui/assets/layout-BH-2XJZq.js.gz +0 -0
  304. package/dist/ui/assets/linear-DCYXhl_f.js.gz +0 -0
  305. package/dist/ui/assets/mermaid.core-BAuL6kgQ.js.gz +0 -0
  306. package/dist/ui/assets/mindmap-definition-VGOIOE7T-DpH5N-N0.js.gz +0 -0
  307. package/dist/ui/assets/pieDiagram-ADFJNKIX-BB8fBxj1.js.gz +0 -0
  308. package/dist/ui/assets/quadrantDiagram-AYHSOK5B-D6oZLdUD.js.gz +0 -0
  309. package/dist/ui/assets/requirementDiagram-UZGBJVZJ-B4uGPp8w.js.gz +0 -0
  310. package/dist/ui/assets/sankeyDiagram-TZEHDZUN-MXhIjhme.js.gz +0 -0
  311. package/dist/ui/assets/sequenceDiagram-WL72ISMW-Cm53TYug.js.gz +0 -0
  312. package/dist/ui/assets/stateDiagram-FKZM4ZOC-BVuxUkj5.js.gz +0 -0
  313. package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-8Jeww6Dc.js +0 -1
  314. package/dist/ui/assets/timeline-definition-IT6M3QCI-CMypNiEP.js.gz +0 -0
  315. package/dist/ui/assets/treemap-KMMF4GRG-BEtnV3BT.js.gz +0 -0
  316. package/dist/ui/assets/xychartDiagram-PRI3JC2R-BnioEYUM.js.gz +0 -0
@@ -168,6 +168,7 @@ __export(config_manager_exports, {
168
168
  getWorktreesDir: () => getWorktreesDir,
169
169
  getWorktreesDirAsync: () => getWorktreesDirAsync,
170
170
  initConfig: () => initConfig,
171
+ isConfigCredentialKey: () => isConfigCredentialKey,
171
172
  isUnixImpersonationEnabled: () => isUnixImpersonationEnabled,
172
173
  isWorktreeRbacEnabled: () => isWorktreeRbacEnabled,
173
174
  loadConfig: () => loadConfig,
@@ -439,6 +440,9 @@ function loadConfigSync() {
439
440
  );
440
441
  }
441
442
  }
443
+ function isConfigCredentialKey(key) {
444
+ return CONFIG_CREDENTIAL_KEYS.has(key);
445
+ }
442
446
  function getCredential(key) {
443
447
  try {
444
448
  const config = loadConfigSync();
@@ -534,7 +538,7 @@ async function getReposDirAsync() {
534
538
  async function getWorktreesDirAsync() {
535
539
  return path2.join(await getDataHomeAsync(), "worktrees");
536
540
  }
537
- var PublicBaseUrlNotConfiguredError;
541
+ var PublicBaseUrlNotConfiguredError, CONFIG_CREDENTIAL_KEYS;
538
542
  var init_config_manager = __esm({
539
543
  "src/config/config-manager.ts"() {
540
544
  "use strict";
@@ -547,6 +551,13 @@ var init_config_manager = __esm({
547
551
  this.name = "PublicBaseUrlNotConfiguredError";
548
552
  }
549
553
  };
554
+ CONFIG_CREDENTIAL_KEYS = /* @__PURE__ */ new Set([
555
+ "ANTHROPIC_API_KEY",
556
+ "ANTHROPIC_AUTH_TOKEN",
557
+ "ANTHROPIC_BASE_URL",
558
+ "OPENAI_API_KEY",
559
+ "GEMINI_API_KEY"
560
+ ]);
550
561
  }
551
562
  });
552
563
 
@@ -1234,6 +1245,8 @@ var init_task = __esm({
1234
1245
  "use strict";
1235
1246
  init_esm_shims();
1236
1247
  TaskStatus = {
1248
+ QUEUED: "queued",
1249
+ // Task created but not yet running (waiting for executor to drain queue)
1237
1250
  CREATED: "created",
1238
1251
  RUNNING: "running",
1239
1252
  STOPPING: "stopping",
@@ -1268,7 +1281,44 @@ function hasMinimumRole(userRole, minimumRole) {
1268
1281
  const normalized = normalizeRole(userRole);
1269
1282
  return (ROLE_RANK[normalized] ?? 0) >= ROLE_RANK[minimumRole];
1270
1283
  }
1271
- var ROLES, ROLE_RANK, ENV_VAR_SCOPES_V05;
1284
+ function toAgenticToolsStatus(stored) {
1285
+ if (!stored) return void 0;
1286
+ const out = {};
1287
+ for (const [tool, fields] of Object.entries(stored)) {
1288
+ if (!fields) continue;
1289
+ const flags = {};
1290
+ for (const [field, value] of Object.entries(fields)) {
1291
+ if (value) flags[field] = true;
1292
+ }
1293
+ if (Object.keys(flags).length > 0) {
1294
+ out[tool] = flags;
1295
+ }
1296
+ }
1297
+ return Object.keys(out).length > 0 ? out : void 0;
1298
+ }
1299
+ function extractAgenticToolsPublicValues(stored, decrypt) {
1300
+ if (!stored) return void 0;
1301
+ const out = {};
1302
+ for (const [tool, fields] of Object.entries(stored)) {
1303
+ if (!fields) continue;
1304
+ const whitelist = AGENTIC_TOOLS_PUBLIC_FIELDS[tool];
1305
+ if (!whitelist || whitelist.length === 0) continue;
1306
+ const plaintext = {};
1307
+ for (const field of whitelist) {
1308
+ const ciphertext = fields[field];
1309
+ if (!ciphertext) continue;
1310
+ try {
1311
+ plaintext[field] = decrypt(ciphertext);
1312
+ } catch {
1313
+ }
1314
+ }
1315
+ if (Object.keys(plaintext).length > 0) {
1316
+ out[tool] = plaintext;
1317
+ }
1318
+ }
1319
+ return Object.keys(out).length > 0 ? out : void 0;
1320
+ }
1321
+ var ROLES, ROLE_RANK, AGENTIC_TOOLS_PUBLIC_FIELDS, ENV_VAR_SCOPES_V05;
1272
1322
  var init_user = __esm({
1273
1323
  "src/types/user.ts"() {
1274
1324
  "use strict";
@@ -1286,6 +1336,10 @@ var init_user = __esm({
1286
1336
  [ROLES.SUPERADMIN]: 3,
1287
1337
  owner: 3
1288
1338
  };
1339
+ AGENTIC_TOOLS_PUBLIC_FIELDS = {
1340
+ "claude-code": ["ANTHROPIC_BASE_URL"],
1341
+ codex: ["OPENAI_BASE_URL"]
1342
+ };
1289
1343
  ENV_VAR_SCOPES_V05 = ["global", "session"];
1290
1344
  }
1291
1345
  });
@@ -1492,6 +1546,7 @@ var init_schema_postgres = __esm({
1492
1546
  completed_at: t.timestamp("completed_at"),
1493
1547
  status: text("status", {
1494
1548
  enum: [
1549
+ "queued",
1495
1550
  "created",
1496
1551
  "running",
1497
1552
  "stopping",
@@ -1503,6 +1558,8 @@ var init_schema_postgres = __esm({
1503
1558
  "stopped"
1504
1559
  ]
1505
1560
  }).notNull(),
1561
+ // Queue position (lower drains first); only populated for status='queued'
1562
+ queue_position: integer("queue_position"),
1506
1563
  // User attribution
1507
1564
  created_by: varchar("created_by", { length: 36 }).notNull().default("anonymous"),
1508
1565
  // MD5 of SDK session file at task completion (only populated when stateless_fs_mode is enabled)
@@ -1512,7 +1569,12 @@ var init_schema_postgres = __esm({
1512
1569
  (table) => ({
1513
1570
  sessionIdx: index("tasks_session_idx").on(table.session_id),
1514
1571
  statusIdx: index("tasks_status_idx").on(table.status),
1515
- createdIdx: index("tasks_created_idx").on(table.created_at)
1572
+ createdIdx: index("tasks_created_idx").on(table.created_at),
1573
+ queueIdx: index("tasks_queue_idx").on(table.session_id, table.status, table.queue_position),
1574
+ // Partial unique index — defense-in-depth for `tasks.createPending` race
1575
+ // serialization. Only QUEUED rows are constrained; CREATED/RUNNING/done
1576
+ // rows have NULL queue_position and are unaffected.
1577
+ queuedPositionUnique: uniqueIndex("tasks_queued_position_unique").on(table.session_id, table.queue_position).where(sql2`${table.status} = 'queued'`)
1516
1578
  })
1517
1579
  );
1518
1580
  serializedSessions = pgTable(
@@ -1572,11 +1634,9 @@ var init_schema_postgres = __esm({
1572
1634
  // First 200 chars for list views
1573
1635
  // Parent tool use ID (for nested tool calls - e.g., Task tool spawning Read/Grep)
1574
1636
  parent_tool_use_id: text("parent_tool_use_id"),
1575
- // Message queueing fields
1576
- status: text("status", { enum: ["queued"] }),
1577
- // 'queued' or null (normal message)
1578
- queue_position: integer("queue_position"),
1579
- // Position in queue (1, 2, 3, ...)
1637
+ // NOTE: queueing moved off `messages` and onto `tasks.status='queued'` as
1638
+ // of migration sqlite/0040 (postgres/0030). The legacy `status` and
1639
+ // `queue_position` columns are gone — see `tasks.queue_position` instead.
1580
1640
  // Full data (JSON blob)
1581
1641
  data: t.json("data").$type().notNull()
1582
1642
  },
@@ -1584,8 +1644,7 @@ var init_schema_postgres = __esm({
1584
1644
  // Indexes for efficient lookups
1585
1645
  sessionIdx: index("messages_session_id_idx").on(table.session_id),
1586
1646
  taskIdx: index("messages_task_id_idx").on(table.task_id),
1587
- sessionIndexIdx: index("messages_session_index_idx").on(table.session_id, table.index),
1588
- queueIdx: index("messages_queue_idx").on(table.session_id, table.status, table.queue_position)
1647
+ sessionIndexIdx: index("messages_session_index_idx").on(table.session_id, table.index)
1589
1648
  })
1590
1649
  );
1591
1650
  boards = pgTable(
@@ -2230,6 +2289,7 @@ var init_schema_sqlite = __esm({
2230
2289
  completed_at: t2.timestamp("completed_at"),
2231
2290
  status: text2("status", {
2232
2291
  enum: [
2292
+ "queued",
2233
2293
  "created",
2234
2294
  "running",
2235
2295
  "stopping",
@@ -2241,6 +2301,8 @@ var init_schema_sqlite = __esm({
2241
2301
  "stopped"
2242
2302
  ]
2243
2303
  }).notNull(),
2304
+ // Queue position (lower drains first); only populated for status='queued'
2305
+ queue_position: integer2("queue_position"),
2244
2306
  // User attribution
2245
2307
  created_by: text2("created_by", { length: 36 }).notNull().default("anonymous"),
2246
2308
  // MD5 of SDK session file at task completion (only populated when stateless_fs_mode is enabled)
@@ -2250,7 +2312,12 @@ var init_schema_sqlite = __esm({
2250
2312
  (table) => ({
2251
2313
  sessionIdx: index2("tasks_session_idx").on(table.session_id),
2252
2314
  statusIdx: index2("tasks_status_idx").on(table.status),
2253
- createdIdx: index2("tasks_created_idx").on(table.created_at)
2315
+ createdIdx: index2("tasks_created_idx").on(table.created_at),
2316
+ queueIdx: index2("tasks_queue_idx").on(table.session_id, table.status, table.queue_position),
2317
+ // Partial unique index — defense-in-depth for `tasks.createPending` race
2318
+ // serialization. Only QUEUED rows are constrained; CREATED/RUNNING/done
2319
+ // rows have NULL queue_position and are unaffected.
2320
+ queuedPositionUnique: uniqueIndex2("tasks_queued_position_unique").on(table.session_id, table.queue_position).where(sql3`${table.status} = 'queued'`)
2254
2321
  })
2255
2322
  );
2256
2323
  serializedSessions2 = sqliteTable(
@@ -2310,11 +2377,9 @@ var init_schema_sqlite = __esm({
2310
2377
  // First 200 chars for list views
2311
2378
  // Parent tool use ID (for nested tool calls - e.g., Task tool spawning Read/Grep)
2312
2379
  parent_tool_use_id: text2("parent_tool_use_id"),
2313
- // Message queueing fields
2314
- status: text2("status", { enum: ["queued"] }),
2315
- // 'queued' or null (normal message)
2316
- queue_position: integer2("queue_position"),
2317
- // Position in queue (1, 2, 3, ...)
2380
+ // NOTE: queueing moved off `messages` and onto `tasks.status='queued'` as
2381
+ // of migration sqlite/0040 (postgres/0030). The legacy `status` and
2382
+ // `queue_position` columns are gone — see `tasks.queue_position` instead.
2318
2383
  // Full data (JSON blob)
2319
2384
  data: t2.json("data").$type().notNull()
2320
2385
  },
@@ -2322,8 +2387,7 @@ var init_schema_sqlite = __esm({
2322
2387
  // Indexes for efficient lookups
2323
2388
  sessionIdx: index2("messages_session_id_idx").on(table.session_id),
2324
2389
  taskIdx: index2("messages_task_id_idx").on(table.task_id),
2325
- sessionIndexIdx: index2("messages_session_index_idx").on(table.session_id, table.index),
2326
- queueIdx: index2("messages_queue_idx").on(table.session_id, table.status, table.queue_position)
2390
+ sessionIndexIdx: index2("messages_session_index_idx").on(table.session_id, table.index)
2327
2391
  })
2328
2392
  );
2329
2393
  boards2 = sqliteTable(
@@ -4027,6 +4091,7 @@ var ALLOWED_ENV_VARS = /* @__PURE__ */ new Set([
4027
4091
  "ANTHROPIC_BASE_URL",
4028
4092
  "ANTHROPIC_AUTH_TOKEN",
4029
4093
  "OPENAI_API_KEY",
4094
+ "OPENAI_BASE_URL",
4030
4095
  "GEMINI_API_KEY",
4031
4096
  "GOOGLE_API_KEY",
4032
4097
  // Vertex AI (Claude Code on GCP)
@@ -4067,7 +4132,7 @@ var AGOR_INTERNAL_ENV_VARS = /* @__PURE__ */ new Set([
4067
4132
  ]);
4068
4133
  async function resolveUserEnvironment(userId, db, options = {}) {
4069
4134
  const env = {};
4070
- const { sessionId } = options;
4135
+ const { sessionId, tool } = options;
4071
4136
  try {
4072
4137
  const row = await select(db).from(users3).where(eq2(users3.user_id, userId)).one();
4073
4138
  if (row) {
@@ -4101,16 +4166,22 @@ async function resolveUserEnvironment(userId, db, options = {}) {
4101
4166
  console.error(`Failed to decrypt env var ${key} for user ${userId}:`, err);
4102
4167
  }
4103
4168
  }
4104
- const encryptedApiKeys = data.api_keys;
4105
- if (encryptedApiKeys) {
4106
- for (const [key, encryptedValue] of Object.entries(encryptedApiKeys)) {
4107
- try {
4108
- const decryptedValue = decryptApiKey(encryptedValue);
4109
- if (decryptedValue && decryptedValue.trim() !== "") {
4110
- env[key] = decryptedValue;
4169
+ if (tool) {
4170
+ const toolFields = data.agentic_tools?.[tool];
4171
+ if (toolFields) {
4172
+ for (const [key, encryptedValue] of Object.entries(toolFields)) {
4173
+ if (!encryptedValue) continue;
4174
+ try {
4175
+ const decryptedValue = decryptApiKey(encryptedValue);
4176
+ if (decryptedValue && decryptedValue.trim() !== "") {
4177
+ env[key] = decryptedValue;
4178
+ }
4179
+ } catch (err) {
4180
+ console.error(
4181
+ `Failed to decrypt agentic_tools.${tool}.${key} for user ${userId}:`,
4182
+ err
4183
+ );
4111
4184
  }
4112
- } catch (err) {
4113
- console.error(`Failed to decrypt API key ${key} for user ${userId}:`, err);
4114
4185
  }
4115
4186
  }
4116
4187
  }
@@ -4148,7 +4219,7 @@ function buildAllowlistedEnv() {
4148
4219
  }
4149
4220
  return env;
4150
4221
  }
4151
- async function createUserProcessEnvironment(userId, db, additionalEnv, forImpersonation = false, gatewayEnv, sessionId) {
4222
+ async function createUserProcessEnvironment(userId, db, additionalEnv, forImpersonation = false, gatewayEnv, sessionId, tool) {
4152
4223
  const env = buildAllowlistedEnv();
4153
4224
  const USER_IDENTITY_VARS = ["HOME", "USER", "LOGNAME", "SHELL"];
4154
4225
  if (forImpersonation) {
@@ -4166,7 +4237,7 @@ async function createUserProcessEnvironment(userId, db, additionalEnv, forImpers
4166
4237
  }
4167
4238
  }
4168
4239
  if (userId && db) {
4169
- const userEnv = await resolveUserEnvironment(userId, db, { sessionId });
4240
+ const userEnv = await resolveUserEnvironment(userId, db, { sessionId, tool });
4170
4241
  for (const [key, value] of Object.entries(userEnv)) {
4171
4242
  if (value && value.trim() !== "") {
4172
4243
  env[key] = value;
@@ -7237,8 +7308,6 @@ var MessagesRepository = class {
7237
7308
  content: row.data.content,
7238
7309
  tool_uses: row.data.tool_uses,
7239
7310
  parent_tool_use_id: row.parent_tool_use_id || void 0,
7240
- status: row.status,
7241
- queue_position: row.queue_position ?? void 0,
7242
7311
  metadata: row.data.metadata
7243
7312
  };
7244
7313
  }
@@ -7257,8 +7326,6 @@ var MessagesRepository = class {
7257
7326
  timestamp: new Date(message.timestamp),
7258
7327
  content_preview: message.content_preview,
7259
7328
  parent_tool_use_id: message.parent_tool_use_id || null,
7260
- status: message.status || null,
7261
- queue_position: message.queue_position ?? null,
7262
7329
  data: {
7263
7330
  content: message.content,
7264
7331
  tool_uses: message.tool_uses,
@@ -7357,68 +7424,6 @@ var MessagesRepository = class {
7357
7424
  async delete(messageId) {
7358
7425
  await deleteFrom(this.db, messages3).where(eq12(messages3.message_id, messageId)).run();
7359
7426
  }
7360
- /**
7361
- * Create a queued message
7362
- * NOTE: Queued messages always store prompt as string content
7363
- * This ensures compatibility with prompt execution endpoint
7364
- *
7365
- * @param sessionId - Session to queue message for
7366
- * @param prompt - Message content (string)
7367
- * @param metadata - Optional metadata (e.g., is_agor_callback, source, child_session_id)
7368
- */
7369
- async createQueued(sessionId, prompt, metadata) {
7370
- if (!prompt || typeof prompt !== "string") {
7371
- throw new Error("Prompt must be a non-empty string");
7372
- }
7373
- const { generateId: generateId2 } = await Promise.resolve().then(() => (init_ids(), ids_exports));
7374
- const result = await select(this.db).from(messages3).where(and7(eq12(messages3.session_id, sessionId), eq12(messages3.status, "queued"))).all();
7375
- const maxPosition = result.reduce(
7376
- (max, row) => Math.max(max, row.queue_position || 0),
7377
- 0
7378
- );
7379
- const nextPosition = maxPosition + 1;
7380
- const messageType = metadata?.is_agor_callback ? "system" : "user";
7381
- const message = {
7382
- message_id: generateId2(),
7383
- session_id: sessionId,
7384
- type: messageType,
7385
- role: "user",
7386
- // Always 'user' for right-side positioning
7387
- index: -1,
7388
- // Not in conversation yet
7389
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7390
- content_preview: prompt.substring(0, 200),
7391
- content: prompt,
7392
- // Always string for queued messages
7393
- status: "queued",
7394
- queue_position: nextPosition,
7395
- task_id: void 0,
7396
- metadata
7397
- // Include metadata (is_agor_callback, source, child_session_id, etc.)
7398
- };
7399
- return this.create(message);
7400
- }
7401
- /**
7402
- * Find queued messages for a session
7403
- */
7404
- async findQueued(sessionId) {
7405
- const { asc: asc2 } = await import("drizzle-orm");
7406
- const rows = await select(this.db).from(messages3).where(and7(eq12(messages3.session_id, sessionId), eq12(messages3.status, "queued"))).orderBy(asc2(messages3.queue_position)).all();
7407
- return rows.map((r) => this.rowToMessage(r));
7408
- }
7409
- /**
7410
- * Get next queued message
7411
- */
7412
- async getNextQueued(sessionId) {
7413
- const queued = await this.findQueued(sessionId);
7414
- return queued[0] || null;
7415
- }
7416
- /**
7417
- * Delete queued message (when processing or user cancels)
7418
- */
7419
- async deleteQueued(messageId) {
7420
- await this.delete(messageId);
7421
- }
7422
7427
  };
7423
7428
 
7424
7429
  // src/db/repositories/repos.ts
@@ -7945,7 +7950,7 @@ init_esm_shims();
7945
7950
  init_types();
7946
7951
  init_config_manager();
7947
7952
  init_ids();
7948
- import { and as and9, desc as desc2, eq as eq15, inArray as inArray2, isNotNull as isNotNull2, isNull as isNull2, like as like9, or as or3, sql as sql7 } from "drizzle-orm";
7953
+ import { and as and9, desc as desc2, eq as eq15, inArray as inArray2, isNotNull as isNotNull2, like as like9, or as or3, sql as sql7 } from "drizzle-orm";
7949
7954
  init_database_wrapper();
7950
7955
  init_schema();
7951
7956
  var SessionRepository = class {
@@ -8431,14 +8436,7 @@ var SessionRepository = class {
8431
8436
  for (const sessionId of sessionIds) {
8432
8437
  const query = select(this.db, {
8433
8438
  data: messagesTable.data
8434
- }).from(messagesTable).where(
8435
- and9(
8436
- eq15(messagesTable.session_id, sessionId),
8437
- eq15(messagesTable.role, "assistant"),
8438
- isNull2(messagesTable.status)
8439
- // Exclude queued messages
8440
- )
8441
- );
8439
+ }).from(messagesTable).where(and9(eq15(messagesTable.session_id, sessionId), eq15(messagesTable.role, "assistant")));
8442
8440
  const lastMessage = await query.orderBy(desc2(messagesTable.index)).limit(1).one();
8443
8441
  if (lastMessage) {
8444
8442
  const messageData = lastMessage.data;
@@ -8726,6 +8724,7 @@ var TaskRepository = class {
8726
8724
  task_id: row.task_id,
8727
8725
  session_id: row.session_id,
8728
8726
  status: row.status,
8727
+ queue_position: row.queue_position ?? void 0,
8729
8728
  created_at: new Date(row.created_at).toISOString(),
8730
8729
  completed_at: row.completed_at ? new Date(row.completed_at).toISOString() : void 0,
8731
8730
  created_by: row.created_by,
@@ -8753,11 +8752,11 @@ var TaskRepository = class {
8753
8752
  // Always use server timestamp, ignore client-provided value
8754
8753
  completed_at: task.completed_at ? new Date(task.completed_at) : void 0,
8755
8754
  status: task.status ?? TaskStatus.CREATED,
8755
+ queue_position: task.queue_position ?? null,
8756
8756
  created_by: task.created_by ?? "anonymous",
8757
8757
  session_md5: task.session_md5 ?? null,
8758
8758
  data: {
8759
- description: task.description ?? "",
8760
- full_prompt: task.full_prompt ?? task.description ?? "",
8759
+ full_prompt: task.full_prompt ?? "",
8761
8760
  message_range: task.message_range ?? {
8762
8761
  start_index: 0,
8763
8762
  end_index: 0,
@@ -8779,8 +8778,10 @@ var TaskRepository = class {
8779
8778
  computed_context_window: task.computed_context_window,
8780
8779
  // Cumulative context window (computed by tool.computeContextWindow())
8781
8780
  report: task.report,
8782
- permission_request: task.permission_request
8781
+ permission_request: task.permission_request,
8783
8782
  // Permission state for UI approval flow
8783
+ metadata: task.metadata
8784
+ // Generic metadata bag (e.g., is_agor_callback, source)
8784
8785
  }
8785
8786
  };
8786
8787
  }
@@ -8907,7 +8908,12 @@ var TaskRepository = class {
8907
8908
  }
8908
8909
  /**
8909
8910
  * Find orphaned tasks (running, stopping, awaiting permission, or awaiting input)
8910
- * These are tasks that were interrupted when daemon stopped
8911
+ * These are tasks that were interrupted when daemon stopped.
8912
+ *
8913
+ * NOTE: QUEUED tasks are intentionally NOT considered orphans — they were
8914
+ * never spawned, so they have no executor to recover. The startup queue
8915
+ * drainer (see register-routes.ts processNextQueuedTask) picks them up
8916
+ * once any session goes idle. See never-lose-prompt §C.
8911
8917
  */
8912
8918
  async findOrphaned() {
8913
8919
  try {
@@ -8959,6 +8965,7 @@ var TaskRepository = class {
8959
8965
  const insertData = this.taskToInsert(merged);
8960
8966
  await update(txAsDb(tx), tasks3).set({
8961
8967
  status: insertData.status,
8968
+ queue_position: insertData.queue_position,
8962
8969
  completed_at: insertData.completed_at,
8963
8970
  session_md5: insertData.session_md5,
8964
8971
  data: insertData.data
@@ -8993,6 +9000,92 @@ var TaskRepository = class {
8993
9000
  );
8994
9001
  }
8995
9002
  }
9003
+ /**
9004
+ * Create a pending task — either CREATED (will spawn immediately) or
9005
+ * QUEUED (will drain later) — owning the sentinel defaults that the
9006
+ * caller would otherwise have to assemble by hand.
9007
+ *
9008
+ * For QUEUED tasks, `queue_position = max(queue_position) + 1` is computed
9009
+ * inside a transaction so concurrent writers don't both observe the same
9010
+ * max and collide. (The schema also carries a partial unique index on
9011
+ * `(session_id, queue_position) WHERE status='queued'` as a belt-and-
9012
+ * suspenders against transaction-isolation surprises.)
9013
+ *
9014
+ * Sentinel contract: while a task carries `message_range.start_index = -1`
9015
+ * and `git_state.sha_at_start = ''`, it has not yet been pinned to real
9016
+ * conversation/git state. spawnTaskExecutor is the sole place that
9017
+ * overwrites these on the way to RUNNING.
9018
+ */
9019
+ async createPending(input) {
9020
+ const taskBase = {
9021
+ session_id: input.session_id,
9022
+ full_prompt: input.full_prompt,
9023
+ created_by: input.created_by,
9024
+ status: input.status,
9025
+ metadata: input.metadata,
9026
+ // Sentinels — overwritten by spawnTaskExecutor at the status → RUNNING
9027
+ // transition. While `start_index === -1` / `sha_at_start === ''`, the
9028
+ // task is intentionally unpinned.
9029
+ message_range: {
9030
+ start_index: -1,
9031
+ end_index: -1,
9032
+ start_timestamp: (/* @__PURE__ */ new Date()).toISOString()
9033
+ },
9034
+ git_state: {
9035
+ ref_at_start: "",
9036
+ sha_at_start: ""
9037
+ },
9038
+ tool_use_count: 0
9039
+ };
9040
+ if (input.status === TaskStatus.CREATED) {
9041
+ return this.create(taskBase);
9042
+ }
9043
+ return this.db.transaction(async (tx) => {
9044
+ const positionRow = await select(txAsDb(tx), {
9045
+ maxPos: sql8`max(${tasks3.queue_position})`
9046
+ }).from(tasks3).where(sql8`${tasks3.session_id} = ${input.session_id} AND ${tasks3.status} = 'queued'`).one();
9047
+ const nextPosition = (positionRow?.maxPos ?? 0) + 1;
9048
+ const insertData = this.taskToInsert({
9049
+ ...taskBase,
9050
+ queue_position: nextPosition
9051
+ });
9052
+ await insert(txAsDb(tx), tasks3).values(insertData).run();
9053
+ const row = await select(txAsDb(tx)).from(tasks3).where(eq17(tasks3.task_id, insertData.task_id)).one();
9054
+ if (!row) {
9055
+ throw new RepositoryError("Failed to retrieve created queued task");
9056
+ }
9057
+ return this.rowToTask(row);
9058
+ });
9059
+ }
9060
+ /**
9061
+ * Find all QUEUED tasks for a session, ordered by queue_position ascending.
9062
+ */
9063
+ async findQueued(sessionId) {
9064
+ try {
9065
+ const rows = await select(this.db).from(tasks3).where(sql8`${tasks3.session_id} = ${sessionId} AND ${tasks3.status} = 'queued'`).orderBy(tasks3.queue_position).all();
9066
+ return rows.map((row) => this.rowToTask(row));
9067
+ } catch (error) {
9068
+ throw new RepositoryError(
9069
+ `Failed to find queued tasks: ${error instanceof Error ? error.message : String(error)}`,
9070
+ error
9071
+ );
9072
+ }
9073
+ }
9074
+ /**
9075
+ * Return the next QUEUED task to drain (lowest queue_position) for a session,
9076
+ * or null if none.
9077
+ */
9078
+ async getNextQueued(sessionId) {
9079
+ try {
9080
+ const row = await select(this.db).from(tasks3).where(sql8`${tasks3.session_id} = ${sessionId} AND ${tasks3.status} = 'queued'`).orderBy(tasks3.queue_position).limit(1).one();
9081
+ return row ? this.rowToTask(row) : null;
9082
+ } catch (error) {
9083
+ throw new RepositoryError(
9084
+ `Failed to get next queued task: ${error instanceof Error ? error.message : String(error)}`,
9085
+ error
9086
+ );
9087
+ }
9088
+ }
8996
9089
  /**
8997
9090
  * Count tasks for a session
8998
9091
  */
@@ -9393,7 +9486,7 @@ var UserApiKeysRepository = class {
9393
9486
  init_esm_shims();
9394
9487
  init_database_wrapper();
9395
9488
  init_schema();
9396
- import { and as and13, eq as eq20, isNull as isNull3 } from "drizzle-orm";
9489
+ import { and as and13, eq as eq20, isNull as isNull2 } from "drizzle-orm";
9397
9490
  function rowToToken(row) {
9398
9491
  return {
9399
9492
  user_id: row.user_id ?? null,
@@ -9409,7 +9502,7 @@ function rowToToken(row) {
9409
9502
  }
9410
9503
  function matchKey(userId, serverId) {
9411
9504
  return and13(
9412
- userId === null ? isNull3(userMcpOauthTokens3.user_id) : eq20(userMcpOauthTokens3.user_id, userId),
9505
+ userId === null ? isNull2(userMcpOauthTokens3.user_id) : eq20(userMcpOauthTokens3.user_id, userId),
9413
9506
  eq20(userMcpOauthTokens3.mcp_server_id, serverId)
9414
9507
  );
9415
9508
  }
@@ -9561,6 +9654,7 @@ var UserMCPOAuthTokenRepository = class {
9561
9654
 
9562
9655
  // src/db/repositories/users.ts
9563
9656
  init_esm_shims();
9657
+ init_types();
9564
9658
  import { eq as eq21, like as like12 } from "drizzle-orm";
9565
9659
  init_ids();
9566
9660
  init_database_wrapper();
@@ -9570,8 +9664,9 @@ var UsersRepository = class {
9570
9664
  this.db = db;
9571
9665
  }
9572
9666
  /**
9573
- * Convert database row to User type
9574
- * Note: Converts encrypted API keys (strings) to boolean flags for API exposure
9667
+ * Convert database row to User type.
9668
+ * Converts the encrypted `agentic_tools` blob to a boolean presence DTO so
9669
+ * decrypted credentials never leave this repository.
9575
9670
  */
9576
9671
  rowToUser(row) {
9577
9672
  return {
@@ -9587,13 +9682,8 @@ var UsersRepository = class {
9587
9682
  must_change_password: row.must_change_password,
9588
9683
  avatar: row.data.avatar,
9589
9684
  preferences: row.data.preferences,
9590
- // Convert encrypted keys to boolean flags (true = key exists, false/undefined = no key)
9591
- api_keys: row.data.api_keys ? {
9592
- ANTHROPIC_API_KEY: !!row.data.api_keys.ANTHROPIC_API_KEY,
9593
- OPENAI_API_KEY: !!row.data.api_keys.OPENAI_API_KEY,
9594
- GEMINI_API_KEY: !!row.data.api_keys.GEMINI_API_KEY,
9595
- COPILOT_GITHUB_TOKEN: !!row.data.api_keys.COPILOT_GITHUB_TOKEN
9596
- } : void 0,
9685
+ // Convert encrypted per-tool credential blobs into boolean presence flags.
9686
+ agentic_tools: toAgenticToolsStatus(row.data.agentic_tools),
9597
9687
  // Convert stored env vars to presence + scope metadata (never exposes secrets).
9598
9688
  // Handles both legacy string form and v0.5 object form via normalizeStoredEnvMap.
9599
9689
  // The schema stores `scope` as a generic string (no SQL CHECK constraint); the
@@ -9637,10 +9727,17 @@ var UsersRepository = class {
9637
9727
  data: {
9638
9728
  avatar: user.avatar,
9639
9729
  preferences: user.preferences,
9640
- // Use raw API keys if provided (for internal operations like setApiKey)
9641
- api_keys: user.api_keys_raw,
9642
- env_vars: void 0,
9643
- // Not implemented yet
9730
+ // Encrypted per-tool credentials. Only forwarded when caller passes the
9731
+ // raw shape (internal credential mutators); regular updates leave it undefined,
9732
+ // letting the merge in `update()` reuse the existing on-disk blob.
9733
+ // Cast: schema declares `opencode: Record<string, never>` (no fields by
9734
+ // contract); StoredAgenticTools widens that to string values for shape
9735
+ // uniformity. Runtime never writes opencode, so the cast is safe.
9736
+ agentic_tools: user.agentic_tools_raw,
9737
+ // Same pass-through as agentic_tools: env_vars are encrypted blobs
9738
+ // not represented on the public DTO. `update()` threads the raw value
9739
+ // from the existing row so a generic field update doesn't wipe them.
9740
+ env_vars: user.env_vars_raw,
9644
9741
  default_agentic_config: user.default_agentic_config
9645
9742
  }
9646
9743
  };
@@ -9752,7 +9849,14 @@ var UsersRepository = class {
9752
9849
  );
9753
9850
  }
9754
9851
  }
9852
+ const rawRow = await this.getRawRow(fullId);
9755
9853
  const merged = { ...current, ...updates };
9854
+ if (rawRow?.data.agentic_tools) {
9855
+ merged.agentic_tools_raw = rawRow.data.agentic_tools;
9856
+ }
9857
+ if (rawRow?.data.env_vars) {
9858
+ merged.env_vars_raw = rawRow.data.env_vars;
9859
+ }
9756
9860
  const insertData = this.userToInsert(merged);
9757
9861
  await update(this.db, users3).set({
9758
9862
  ...insertData,
@@ -9787,96 +9891,103 @@ var UsersRepository = class {
9787
9891
  }
9788
9892
  }
9789
9893
  /**
9790
- * Get decrypted API key for a user and service
9894
+ * Get the full decrypted credential bag for a single agentic tool.
9791
9895
  *
9792
- * @param userId - User ID
9793
- * @param service - Service name ('anthropic', 'openai', 'gemini')
9794
- * @returns Decrypted API key or null if not found
9896
+ * Returns `null` when the user has no stored config for that tool.
9897
+ * Fields that fail to decrypt are dropped from the returned object and
9898
+ * logged callers see "missing field" rather than a thrown error so a
9899
+ * single corrupt value doesn't poison an entire SDK spawn.
9795
9900
  */
9796
- async getApiKey(userId, service) {
9901
+ async getToolConfig(userId, tool) {
9797
9902
  const row = await this.getRawRow(userId);
9798
- if (!row || !row.data.api_keys) {
9799
- return null;
9800
- }
9801
- const keyMap = {
9802
- anthropic: "ANTHROPIC_API_KEY",
9803
- openai: "OPENAI_API_KEY",
9804
- gemini: "GEMINI_API_KEY",
9805
- copilot: "COPILOT_GITHUB_TOKEN"
9806
- };
9807
- const encryptedKey = row.data.api_keys[keyMap[service]];
9808
- if (!encryptedKey) {
9809
- return null;
9903
+ if (!row) return null;
9904
+ const stored = row.data.agentic_tools;
9905
+ const fields = stored?.[tool];
9906
+ if (!fields || Object.keys(fields).length === 0) return null;
9907
+ const out = {};
9908
+ for (const [field, encrypted] of Object.entries(fields)) {
9909
+ if (!encrypted) continue;
9910
+ try {
9911
+ out[field] = decryptApiKey(encrypted);
9912
+ } catch (error) {
9913
+ console.error(
9914
+ `[users] Failed to decrypt ${tool}.${field} for user ${userId.substring(0, 8)}: ${error.message}`
9915
+ );
9916
+ }
9810
9917
  }
9918
+ return Object.keys(out).length > 0 ? out : null;
9919
+ }
9920
+ /**
9921
+ * Get a single decrypted credential field for a tool.
9922
+ *
9923
+ * Returns `null` when the field is unset OR when decryption fails (logged).
9924
+ * Throws only on storage-layer errors, not on missing/corrupt values.
9925
+ */
9926
+ async getToolConfigField(userId, tool, field) {
9927
+ const row = await this.getRawRow(userId);
9928
+ if (!row) return null;
9929
+ const stored = row.data.agentic_tools;
9930
+ const encrypted = stored?.[tool]?.[field];
9931
+ if (!encrypted) return null;
9811
9932
  try {
9812
- return decryptApiKey(encryptedKey);
9933
+ return decryptApiKey(encrypted);
9813
9934
  } catch (error) {
9814
- throw new RepositoryError(`Failed to decrypt API key for service ${service}`, error);
9935
+ console.error(
9936
+ `[users] Failed to decrypt ${tool}.${field} for user ${userId.substring(0, 8)}: ${error.message}`
9937
+ );
9938
+ return null;
9815
9939
  }
9816
9940
  }
9817
9941
  /**
9818
- * Set encrypted API key for a user and service
9942
+ * Set (encrypt + persist) a single credential field for a tool.
9819
9943
  *
9820
- * @param userId - User ID
9821
- * @param service - Service name ('anthropic', 'openai', 'gemini')
9822
- * @param apiKey - Plaintext API key to encrypt and store
9944
+ * Field names are env-var-shaped (e.g. ANTHROPIC_API_KEY, ANTHROPIC_BASE_URL)
9945
+ * and are stored encrypted regardless of whether the value is a secret —
9946
+ * keeping the on-disk shape uniform avoids decrypt-vs-plain branching at
9947
+ * read time. UI controls own the text-vs-password rendering distinction.
9823
9948
  */
9824
- async setApiKey(userId, service, apiKey) {
9949
+ async setToolConfigField(userId, tool, field, value) {
9825
9950
  const fullId = await this.resolveId(userId);
9826
9951
  const row = await this.getRawRow(fullId);
9827
9952
  if (!row) {
9828
9953
  throw new EntityNotFoundError("User", userId);
9829
9954
  }
9830
- const keyMap = {
9831
- anthropic: "ANTHROPIC_API_KEY",
9832
- openai: "OPENAI_API_KEY",
9833
- gemini: "GEMINI_API_KEY",
9834
- copilot: "COPILOT_GITHUB_TOKEN"
9835
- };
9836
- const encryptedKey = encryptApiKey(apiKey);
9837
- const updatedApiKeys = {
9838
- ...row.data.api_keys || {},
9839
- [keyMap[service]]: encryptedKey
9840
- };
9841
- const user = this.rowToUser(row);
9842
- const updateData = {
9843
- ...user,
9844
- api_keys_raw: updatedApiKeys
9955
+ const stored = row.data.agentic_tools ?? {};
9956
+ const next = {
9957
+ ...stored,
9958
+ [tool]: {
9959
+ ...stored[tool] ?? {},
9960
+ [field]: encryptApiKey(value)
9961
+ }
9845
9962
  };
9846
- const insertData = this.userToInsert(updateData);
9847
9963
  await update(this.db, users3).set({
9848
- ...insertData,
9964
+ data: { ...row.data, agentic_tools: next },
9849
9965
  updated_at: /* @__PURE__ */ new Date()
9850
9966
  }).where(eq21(users3.user_id, fullId)).run();
9851
9967
  }
9852
9968
  /**
9853
- * Delete API key for a user and service
9969
+ * Delete a single credential field for a tool.
9854
9970
  *
9855
- * @param userId - User ID
9856
- * @param service - Service name ('anthropic', 'openai', 'gemini')
9971
+ * If the tool's bucket becomes empty after the delete, the bucket itself is
9972
+ * removed so `data.agentic_tools` doesn't accumulate empty objects.
9857
9973
  */
9858
- async deleteApiKey(userId, service) {
9974
+ async deleteToolConfigField(userId, tool, field) {
9859
9975
  const fullId = await this.resolveId(userId);
9860
9976
  const row = await this.getRawRow(fullId);
9861
9977
  if (!row) {
9862
9978
  throw new EntityNotFoundError("User", userId);
9863
9979
  }
9864
- const keyMap = {
9865
- anthropic: "ANTHROPIC_API_KEY",
9866
- openai: "OPENAI_API_KEY",
9867
- gemini: "GEMINI_API_KEY",
9868
- copilot: "COPILOT_GITHUB_TOKEN"
9869
- };
9870
- const updatedApiKeys = { ...row.data.api_keys || {} };
9871
- delete updatedApiKeys[keyMap[service]];
9872
- const user = this.rowToUser(row);
9873
- const updateData = {
9874
- ...user,
9875
- api_keys_raw: updatedApiKeys
9876
- };
9877
- const insertData = this.userToInsert(updateData);
9980
+ const stored = row.data.agentic_tools ?? {};
9981
+ const toolFields = { ...stored[tool] ?? {} };
9982
+ delete toolFields[field];
9983
+ const next = { ...stored };
9984
+ if (Object.keys(toolFields).length > 0) {
9985
+ next[tool] = toolFields;
9986
+ } else {
9987
+ delete next[tool];
9988
+ }
9878
9989
  await update(this.db, users3).set({
9879
- ...insertData,
9990
+ data: { ...row.data, agentic_tools: next },
9880
9991
  updated_at: /* @__PURE__ */ new Date()
9881
9992
  }).where(eq21(users3.user_id, fullId)).run();
9882
9993
  }
@@ -9888,18 +9999,7 @@ init_types();
9888
9999
  init_ids();
9889
10000
  init_database_wrapper();
9890
10001
  init_schema();
9891
- import {
9892
- and as and14,
9893
- desc as desc3,
9894
- eq as eq22,
9895
- getTableColumns,
9896
- inArray as inArray3,
9897
- isNotNull as isNotNull3,
9898
- isNull as isNull4,
9899
- like as like13,
9900
- or as or4,
9901
- sql as sql9
9902
- } from "drizzle-orm";
10002
+ import { and as and14, desc as desc3, eq as eq22, getTableColumns, inArray as inArray3, isNotNull as isNotNull3, like as like13, or as or4, sql as sql9 } from "drizzle-orm";
9903
10003
  var WorktreeRepository = class {
9904
10004
  constructor(db) {
9905
10005
  this.db = db;
@@ -10427,14 +10527,7 @@ var WorktreeRepository = class {
10427
10527
  for (const sessionId of sessionIds) {
10428
10528
  const query = select(this.db, {
10429
10529
  data: messagesTable.data
10430
- }).from(messagesTable).where(
10431
- and14(
10432
- eq22(messagesTable.session_id, sessionId),
10433
- eq22(messagesTable.role, "assistant"),
10434
- isNull4(messagesTable.status)
10435
- // Exclude queued messages
10436
- )
10437
- );
10530
+ }).from(messagesTable).where(and14(eq22(messagesTable.session_id, sessionId), eq22(messagesTable.role, "assistant")));
10438
10531
  const lastMessage = await query.orderBy(desc3(messagesTable.index)).limit(1).one();
10439
10532
  if (lastMessage) {
10440
10533
  const messageData = lastMessage.data;
@@ -10626,7 +10719,18 @@ async function resolveApiKey(keyName, context = {}) {
10626
10719
  const row = await select(context.db).from(users3).where(eq24(users3.user_id, context.userId)).one();
10627
10720
  if (row) {
10628
10721
  const data = row.data;
10629
- const encryptedKey = data.api_keys?.[keyName];
10722
+ let encryptedKey;
10723
+ const tools = data.agentic_tools ?? {};
10724
+ if (context.tool) {
10725
+ encryptedKey = tools[context.tool]?.[keyName];
10726
+ } else {
10727
+ for (const fields of Object.values(tools)) {
10728
+ if (fields?.[keyName]) {
10729
+ encryptedKey = fields[keyName];
10730
+ break;
10731
+ }
10732
+ }
10733
+ }
10630
10734
  if (encryptedKey) {
10631
10735
  try {
10632
10736
  const decryptedKey = decryptApiKey(encryptedKey);
@@ -10651,12 +10755,13 @@ async function resolveApiKey(keyName, context = {}) {
10651
10755
  } else if (!context.db) {
10652
10756
  console.log(` \u2192 Skipping user-level check (no database connection)`);
10653
10757
  }
10654
- console.log(` \u2192 Checking app-level configuration (config.yaml)...`);
10655
- const globalKey = getCredential(keyName);
10656
- if (globalKey && globalKey.length > 0) {
10657
- console.log(` \u2713 Found app-level API key for ${keyName} (from config.yaml)`);
10658
- return { apiKey: globalKey, source: "config", useNativeAuth: false };
10659
- } else {
10758
+ if (isConfigCredentialKey(keyName)) {
10759
+ console.log(` \u2192 Checking app-level configuration (config.yaml)...`);
10760
+ const globalKey = getCredential(keyName);
10761
+ if (globalKey && globalKey.length > 0) {
10762
+ console.log(` \u2713 Found app-level API key for ${keyName} (from config.yaml)`);
10763
+ return { apiKey: globalKey, source: "config", useNativeAuth: false };
10764
+ }
10660
10765
  console.log(` \u2717 No app-level API key for ${keyName}`);
10661
10766
  }
10662
10767
  console.log(` \u2192 Checking OS-level environment variables...`);
@@ -10664,16 +10769,17 @@ async function resolveApiKey(keyName, context = {}) {
10664
10769
  if (envKey && envKey.length > 0) {
10665
10770
  console.log(` \u2713 Found OS-level environment variable ${keyName}`);
10666
10771
  return { apiKey: envKey, source: "env", useNativeAuth: false };
10667
- } else {
10668
- console.log(` \u2717 No OS-level environment variable ${keyName}`);
10669
10772
  }
10773
+ console.log(` \u2717 No OS-level environment variable ${keyName}`);
10670
10774
  console.log(` \u2139\uFE0F No API key found for ${keyName} - SDK will use native authentication`);
10671
10775
  return { apiKey: void 0, source: "none", useNativeAuth: true };
10672
10776
  }
10673
10777
  function resolveApiKeySync(keyName) {
10674
- const globalKey = getCredential(keyName);
10675
- if (globalKey && globalKey.length > 0) {
10676
- return { apiKey: globalKey, source: "config", useNativeAuth: false };
10778
+ if (isConfigCredentialKey(keyName)) {
10779
+ const globalKey = getCredential(keyName);
10780
+ if (globalKey && globalKey.length > 0) {
10781
+ return { apiKey: globalKey, source: "config", useNativeAuth: false };
10782
+ }
10677
10783
  }
10678
10784
  const envKey = process.env[keyName];
10679
10785
  if (envKey && envKey.length > 0) {
@@ -12109,6 +12215,152 @@ function resolveMcpServersTemplates(servers, context) {
12109
12215
  return servers.map((server) => resolveMcpServerTemplates(server, context));
12110
12216
  }
12111
12217
 
12218
+ // src/sessions/index.ts
12219
+ init_esm_shims();
12220
+
12221
+ // src/sessions/resolve-session-defaults.ts
12222
+ init_esm_shims();
12223
+
12224
+ // src/models/resolve-config.ts
12225
+ init_esm_shims();
12226
+ function resolveModelConfig(input, opts) {
12227
+ if (!input?.model) return void 0;
12228
+ return {
12229
+ mode: input.mode ?? "alias",
12230
+ model: input.model,
12231
+ updated_at: (opts?.now ?? /* @__PURE__ */ new Date()).toISOString(),
12232
+ ...input.effort !== void 0 && { effort: input.effort },
12233
+ ...input.provider !== void 0 && { provider: input.provider }
12234
+ };
12235
+ }
12236
+
12237
+ // src/sessions/resolve-session-defaults.ts
12238
+ init_session();
12239
+
12240
+ // src/utils/permission-mode-mapper.ts
12241
+ init_esm_shims();
12242
+ function mapPermissionMode(mode, agenticTool) {
12243
+ switch (agenticTool) {
12244
+ case "claude-code":
12245
+ case "copilot":
12246
+ switch (mode) {
12247
+ // Native Claude modes - pass through
12248
+ case "default":
12249
+ case "acceptEdits":
12250
+ case "bypassPermissions":
12251
+ case "plan":
12252
+ case "dontAsk":
12253
+ return mode;
12254
+ // Gemini modes → Claude equivalents
12255
+ case "autoEdit":
12256
+ return "acceptEdits";
12257
+ case "yolo":
12258
+ return "bypassPermissions";
12259
+ // Codex modes → Claude equivalents
12260
+ case "ask":
12261
+ return "default";
12262
+ case "auto":
12263
+ return "acceptEdits";
12264
+ case "on-failure":
12265
+ return "acceptEdits";
12266
+ case "allow-all":
12267
+ return "bypassPermissions";
12268
+ default:
12269
+ return "acceptEdits";
12270
+ }
12271
+ case "gemini":
12272
+ case "opencode":
12273
+ switch (mode) {
12274
+ // Native Gemini modes - pass through
12275
+ case "default":
12276
+ case "autoEdit":
12277
+ case "yolo":
12278
+ return mode;
12279
+ // Claude modes → Gemini equivalents
12280
+ case "acceptEdits":
12281
+ return "autoEdit";
12282
+ case "bypassPermissions":
12283
+ case "dontAsk":
12284
+ return "yolo";
12285
+ case "plan":
12286
+ return "default";
12287
+ // Plan mode → restrictive
12288
+ // Codex modes → Gemini equivalents
12289
+ case "ask":
12290
+ return "default";
12291
+ case "auto":
12292
+ return "autoEdit";
12293
+ case "on-failure":
12294
+ return "autoEdit";
12295
+ case "allow-all":
12296
+ return "yolo";
12297
+ default:
12298
+ return "autoEdit";
12299
+ }
12300
+ case "codex":
12301
+ switch (mode) {
12302
+ // Native Codex modes - pass through
12303
+ case "ask":
12304
+ case "auto":
12305
+ case "on-failure":
12306
+ case "allow-all":
12307
+ return mode;
12308
+ // Claude modes → Codex equivalents
12309
+ case "default":
12310
+ return "ask";
12311
+ case "acceptEdits":
12312
+ return "auto";
12313
+ case "bypassPermissions":
12314
+ case "dontAsk":
12315
+ return "allow-all";
12316
+ case "plan":
12317
+ return "ask";
12318
+ // Gemini modes → Codex equivalents
12319
+ case "autoEdit":
12320
+ return "auto";
12321
+ case "yolo":
12322
+ return "allow-all";
12323
+ default:
12324
+ return "auto";
12325
+ }
12326
+ default:
12327
+ return mode;
12328
+ }
12329
+ }
12330
+
12331
+ // src/sessions/resolve-session-defaults.ts
12332
+ function resolveSessionDefaults(args) {
12333
+ const { agenticTool, user, worktree, overrides, now } = args;
12334
+ const userToolDefaults = user?.default_agentic_config?.[agenticTool];
12335
+ const requestedMode = overrides?.permissionMode ?? userToolDefaults?.permissionMode ?? getDefaultPermissionMode(agenticTool);
12336
+ const permissionMode = mapPermissionMode(requestedMode, agenticTool);
12337
+ const permission_config = {
12338
+ mode: permissionMode
12339
+ };
12340
+ if (agenticTool === "codex") {
12341
+ const sandboxMode = overrides?.codexSandboxMode ?? userToolDefaults?.codexSandboxMode;
12342
+ const approvalPolicy = overrides?.codexApprovalPolicy ?? userToolDefaults?.codexApprovalPolicy;
12343
+ const networkAccess = overrides?.codexNetworkAccess ?? userToolDefaults?.codexNetworkAccess;
12344
+ if (sandboxMode && approvalPolicy) {
12345
+ permission_config.codex = {
12346
+ sandboxMode,
12347
+ approvalPolicy,
12348
+ ...networkAccess !== void 0 && { networkAccess }
12349
+ };
12350
+ }
12351
+ }
12352
+ const model_config = resolveModelConfig(overrides?.modelConfig, { now }) ?? resolveModelConfig(userToolDefaults?.modelConfig, { now });
12353
+ let mcp_server_ids;
12354
+ if (overrides?.mcpServerIds !== void 0) {
12355
+ mcp_server_ids = overrides.mcpServerIds;
12356
+ } else if (worktree?.mcp_server_ids && worktree.mcp_server_ids.length > 0) {
12357
+ mcp_server_ids = worktree.mcp_server_ids;
12358
+ } else {
12359
+ mcp_server_ids = userToolDefaults?.mcpServerIds ?? [];
12360
+ }
12361
+ return { permission_config, model_config, mcp_server_ids };
12362
+ }
12363
+
12112
12364
  // src/index.ts
12113
12365
  init_types();
12114
12366
 
@@ -14707,6 +14959,7 @@ function unpatchConsole() {
14707
14959
  }
14708
14960
  }
14709
14961
  export {
14962
+ AGENTIC_TOOLS_PUBLIC_FIELDS,
14710
14963
  AGENTIC_TOOL_CAPABILITIES,
14711
14964
  AGOR_DEFAULT_SHELL,
14712
14965
  AGOR_HOME_BASE,
@@ -14857,6 +15110,7 @@ export {
14857
15110
  executeRaw,
14858
15111
  executeRun,
14859
15112
  expandHomePath,
15113
+ extractAgenticToolsPublicValues,
14860
15114
  extractRepoName,
14861
15115
  extractSlugFromUrl,
14862
15116
  filterEnv,
@@ -14935,6 +15189,7 @@ export {
14935
15189
  isAssistant,
14936
15190
  isAutoGeneratedUsername,
14937
15191
  isClean,
15192
+ isConfigCredentialKey,
14938
15193
  isDaemonRunning,
14939
15194
  isDefined,
14940
15195
  isEncrypted,
@@ -15012,6 +15267,7 @@ export {
15012
15267
  resolvePassword,
15013
15268
  resolveRepoReference,
15014
15269
  resolveSecurity,
15270
+ resolveSessionDefaults,
15015
15271
  resolveShortId,
15016
15272
  resolveSystemEnvironment,
15017
15273
  resolveUnixUserForImpersonation,
@@ -15038,6 +15294,7 @@ export {
15038
15294
  sql10 as sql,
15039
15295
  tasks3 as tasks,
15040
15296
  threadSessionMap3 as threadSessionMap,
15297
+ toAgenticToolsStatus,
15041
15298
  toShortId,
15042
15299
  tryUnlinkEnvFile,
15043
15300
  tryUnlinkEnvFileAsUser,