@cloudcli-ai/cloudcli 1.37.1 → 1.37.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 (402) hide show
  1. package/README.md +1 -1
  2. package/dist/assets/abnfDiagram-N423BO3Z-CJntskwA.js +1 -0
  3. package/dist/assets/arc-CIfH4uMN.js +1 -0
  4. package/dist/assets/architectureDiagram-T3A2C74G-_IpEkukg.js +36 -0
  5. package/dist/assets/blockDiagram-VBNYF7ZC-BttxrpgZ.js +132 -0
  6. package/dist/assets/c4Diagram-5PPSVZJV-g51dSRr1.js +10 -0
  7. package/dist/assets/channel-C5xU9jMw.js +1 -0
  8. package/dist/assets/chunk-2GRJ4B5K-D_-LbQUa.js +1 -0
  9. package/dist/assets/chunk-2Q5K7J3B-BtlHzwaO.js +1 -0
  10. package/dist/assets/chunk-5RXB4S5H-UzkpvpAT.js +231 -0
  11. package/dist/assets/chunk-5VM5RSS4-BKwx5Gag.js +15 -0
  12. package/dist/assets/chunk-6Q2QTUOP-D_KEBH5f.js +88 -0
  13. package/dist/assets/chunk-GF5L2VYU-rK2DGyto.js +206 -0
  14. package/dist/assets/chunk-JWPE2WC7-CeBl_N9i.js +1 -0
  15. package/dist/assets/chunk-KBJHAD2P-BiQLWVIr.js +1 -0
  16. package/dist/assets/chunk-RYQCIY6F-C1knVGV5.js +1 -0
  17. package/dist/assets/chunk-XXDRQBXY-CtKbJkvF.js +1 -0
  18. package/dist/assets/classDiagram-JCYQIIEL-CRrL3vp7.js +1 -0
  19. package/dist/assets/classDiagram-v2-OCEON4UE-CRrL3vp7.js +1 -0
  20. package/dist/assets/cose-bilkent-JH36ORCC-DjX8y40Z.js +1 -0
  21. package/dist/assets/cynefin-VYW2F7L2-DM6YeRba.js +178 -0
  22. package/dist/assets/cynefinDiagram-MW4NZA55-wZJ-vy5B.js +62 -0
  23. package/dist/assets/cytoscape.esm-C10L9Icf.js +331 -0
  24. package/dist/assets/dagre-VZM6K2ZE-BzP0ejkH.js +4 -0
  25. package/dist/assets/defaultLocale-DX6XiGOO.js +1 -0
  26. package/dist/assets/diagram-7IWD3JNH-BTL_j23J.js +30 -0
  27. package/dist/assets/diagram-B4RE2ZJO-Cf1Norgu.js +3 -0
  28. package/dist/assets/diagram-LBJQPF4R-DPiUEKr-.js +24 -0
  29. package/dist/assets/diagram-Q27KOJAE-CTcTpiz5.js +24 -0
  30. package/dist/assets/diagram-UB23O5K3-DPMSdYm0.js +41 -0
  31. package/dist/assets/ebnfDiagram-BXEA7PRR-7yvD6uiF.js +1 -0
  32. package/dist/assets/erDiagram-JOGREHBK-CfgeDoV6.js +85 -0
  33. package/dist/assets/flowDiagram-UKHOOZJN-B27ng5zu.js +156 -0
  34. package/dist/assets/ganttDiagram-PKOTCBZU-CcC6b_7t.js +292 -0
  35. package/dist/assets/gitGraphDiagram-DS77QQ5N-BX5kPGrO.js +106 -0
  36. package/dist/assets/graph-Cx-EqisW.js +1 -0
  37. package/dist/assets/index-BTDHQ6Id.css +32 -0
  38. package/dist/assets/index-sFfz8iBR.js +4931 -0
  39. package/dist/assets/infoDiagram-6WML65LV-CUP-SlN4.js +2 -0
  40. package/dist/assets/init-Gi6I4Gst.js +1 -0
  41. package/dist/assets/ishikawaDiagram-WSZJBQD7-BTTDhOpX.js +70 -0
  42. package/dist/assets/journeyDiagram-NVQOT4AX-ARXcc61m.js +139 -0
  43. package/dist/assets/kanban-definition-27J2QSJJ-BieMpqMA.js +89 -0
  44. package/dist/assets/layout-D6BstSzF.js +1 -0
  45. package/dist/assets/linear-61vxjRnP.js +1 -0
  46. package/dist/assets/map-CV9uif0g.js +1 -0
  47. package/dist/assets/mermaid.core-nhnwkfQx.js +312 -0
  48. package/dist/assets/mindmap-definition-FAOFIHXS-Cm6x5vT1.js +96 -0
  49. package/dist/assets/ordinal-Cboi1Yqb.js +1 -0
  50. package/dist/assets/pegDiagram-VL7TDLO6-CcYBq_9H.js +1 -0
  51. package/dist/assets/pieDiagram-7S7Q4E2Y-CfvIjfzo.js +39 -0
  52. package/dist/assets/quadrantDiagram-CIZ2JOQS-SgYoWPNb.js +7 -0
  53. package/dist/assets/railroadDiagram-AXF67PYL-D2Mu5E_f.js +1 -0
  54. package/dist/assets/requirementDiagram-LRYGKXZP-Azwe_k4Q.js +84 -0
  55. package/dist/assets/sankeyDiagram-W5VNT64P-DN1Ju3PA.js +40 -0
  56. package/dist/assets/sequenceDiagram-SI44F4Z6-Bj4qC34S.js +162 -0
  57. package/dist/assets/server.browser-CtX3Hdl5.js +27 -0
  58. package/dist/assets/sizeCapture-X5ZJPWSS-Co4PdklG.js +1 -0
  59. package/dist/assets/stateDiagram-OKZ733FA-nOvL9dRC.js +1 -0
  60. package/dist/assets/stateDiagram-v2-UEYNNEHI-DNv8ppw7.js +1 -0
  61. package/dist/assets/swimlanes-SLNWSIFB-CCK3wMid.js +2 -0
  62. package/dist/assets/swimlanesDiagram-ULZ7WXOC-DnfbNQEp.js +8 -0
  63. package/dist/assets/timeline-definition-Z64GVDOM-BC29RNFm.js +120 -0
  64. package/dist/assets/{vendor-codemirror-OwyKSvPE.js → vendor-codemirror-CYrSt7-U.js} +18 -18
  65. package/dist/assets/vennDiagram-T6HMQDX7-pZlZCtEo.js +34 -0
  66. package/dist/assets/wardleyDiagram-T6FBY63Y-De8k2-zM.js +78 -0
  67. package/dist/assets/xychartDiagram-ELKLHX3M-Bk8ykH0w.js +7 -0
  68. package/dist/index.html +3 -3
  69. package/dist-server/server/index.js +8 -5
  70. package/dist-server/server/index.js.map +1 -1
  71. package/dist-server/server/modules/agent/agent.module.js +2 -1
  72. package/dist-server/server/modules/agent/agent.module.js.map +1 -1
  73. package/dist-server/server/modules/agent/agent.routes.js +2 -2
  74. package/dist-server/server/modules/agent/agent.routes.js.map +1 -1
  75. package/dist-server/server/modules/agent/tests/agent.routes.test.js +30 -1
  76. package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -1
  77. package/dist-server/server/modules/auth/auth.middleware.js +1 -1
  78. package/dist-server/server/modules/auth/auth.middleware.js.map +1 -1
  79. package/dist-server/server/modules/browser-use/browser-use-runtime.js +10 -0
  80. package/dist-server/server/modules/browser-use/browser-use-runtime.js.map +1 -0
  81. package/dist-server/server/modules/browser-use/browser-use.routes.js +39 -33
  82. package/dist-server/server/modules/browser-use/browser-use.routes.js.map +1 -1
  83. package/dist-server/server/modules/browser-use/browser-use.service.js +3 -6
  84. package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
  85. package/dist-server/server/modules/browser-use/index.js +2 -0
  86. package/dist-server/server/modules/browser-use/index.js.map +1 -1
  87. package/dist-server/server/modules/cli/cli.js +9 -3
  88. package/dist-server/server/modules/cli/cli.js.map +1 -1
  89. package/dist-server/server/modules/cli/cli.module.js +0 -1
  90. package/dist-server/server/modules/cli/cli.module.js.map +1 -1
  91. package/dist-server/server/modules/cli/cli.service.js +0 -18
  92. package/dist-server/server/modules/cli/cli.service.js.map +1 -1
  93. package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js +154 -0
  94. package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js.map +1 -0
  95. package/dist-server/server/modules/cli/tests/cli.service.test.js +0 -3
  96. package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -1
  97. package/dist-server/server/modules/database/connection.js +1 -1
  98. package/dist-server/server/modules/database/connection.js.map +1 -1
  99. package/dist-server/server/modules/database/index.js +5 -0
  100. package/dist-server/server/modules/database/index.js.map +1 -1
  101. package/dist-server/server/modules/database/migrations.js +32 -1
  102. package/dist-server/server/modules/database/migrations.js.map +1 -1
  103. package/dist-server/server/modules/database/repositories/scheduled-messages.db.js +71 -0
  104. package/dist-server/server/modules/database/repositories/scheduled-messages.db.js.map +1 -0
  105. package/dist-server/server/modules/database/repositories/session-drafts.db.js +105 -0
  106. package/dist-server/server/modules/database/repositories/session-drafts.db.js.map +1 -0
  107. package/dist-server/server/modules/database/repositories/sessions.db.js +137 -5
  108. package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
  109. package/dist-server/server/modules/database/repositories/user-preferences.db.js +65 -0
  110. package/dist-server/server/modules/database/repositories/user-preferences.db.js.map +1 -0
  111. package/dist-server/server/modules/database/schema.js +92 -0
  112. package/dist-server/server/modules/database/schema.js.map +1 -1
  113. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js +39 -0
  114. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -1
  115. package/dist-server/server/modules/database/tests/user-preferences.db.integration.test.js +105 -0
  116. package/dist-server/server/modules/database/tests/user-preferences.db.integration.test.js.map +1 -0
  117. package/dist-server/server/modules/file-tree/file-tree.service.js +18 -10
  118. package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -1
  119. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +62 -11
  120. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -1
  121. package/dist-server/server/modules/git/git-branch.service.js +15 -0
  122. package/dist-server/server/modules/git/git-branch.service.js.map +1 -0
  123. package/dist-server/server/modules/git/git.routes.js +15 -7
  124. package/dist-server/server/modules/git/git.routes.js.map +1 -1
  125. package/dist-server/server/modules/git/tests/git-branch.service.test.js +52 -0
  126. package/dist-server/server/modules/git/tests/git-branch.service.test.js.map +1 -0
  127. package/dist-server/server/modules/git/tests/git-init.routes.test.js +84 -0
  128. package/dist-server/server/modules/git/tests/git-init.routes.test.js.map +1 -1
  129. package/dist-server/server/modules/notifications/index.js +3 -1
  130. package/dist-server/server/modules/notifications/index.js.map +1 -1
  131. package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js +22 -1
  132. package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js.map +1 -1
  133. package/dist-server/server/modules/projects/services/project-delete.service.js +12 -1
  134. package/dist-server/server/modules/projects/services/project-delete.service.js.map +1 -1
  135. package/dist-server/server/modules/projects/services/project-star.service.js +2 -2
  136. package/dist-server/server/modules/projects/services/project-star.service.js.map +1 -1
  137. package/dist-server/server/modules/providers/index.js +3 -0
  138. package/dist-server/server/modules/providers/index.js.map +1 -1
  139. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +20 -1
  140. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -1
  141. package/dist-server/server/modules/providers/list/claude/claude-fork.provider.js +46 -0
  142. package/dist-server/server/modules/providers/list/claude/claude-fork.provider.js.map +1 -0
  143. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +35 -6
  144. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
  145. package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js +422 -86
  146. package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -1
  147. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +388 -50
  148. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
  149. package/dist-server/server/modules/providers/list/claude/claude-skills.provider.js +4 -1
  150. package/dist-server/server/modules/providers/list/claude/claude-skills.provider.js.map +1 -1
  151. package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
  152. package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
  153. package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js +204 -0
  154. package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js.map +1 -0
  155. package/dist-server/server/modules/providers/list/codex/codex-fork.provider.js +32 -0
  156. package/dist-server/server/modules/providers/list/codex/codex-fork.provider.js.map +1 -0
  157. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +16 -0
  158. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
  159. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js +60 -49
  160. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -1
  161. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js +8 -0
  162. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -1
  163. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +1565 -432
  164. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
  165. package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
  166. package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
  167. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js +8 -6
  168. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -1
  169. package/dist-server/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.js.map +1 -1
  170. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +258 -6
  171. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
  172. package/dist-server/server/modules/providers/provider.routes.js +29 -0
  173. package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
  174. package/dist-server/server/modules/providers/services/provider-capabilities.service.js +14 -0
  175. package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
  176. package/dist-server/server/modules/providers/services/provider-token-usage.service.js +139 -35
  177. package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -1
  178. package/dist-server/server/modules/providers/services/session-conversations-search.service.js +63 -7
  179. package/dist-server/server/modules/providers/services/session-conversations-search.service.js.map +1 -1
  180. package/dist-server/server/modules/providers/services/session-history-cache.service.js +87 -0
  181. package/dist-server/server/modules/providers/services/session-history-cache.service.js.map +1 -0
  182. package/dist-server/server/modules/providers/services/session-synchronizer.service.js +105 -32
  183. package/dist-server/server/modules/providers/services/session-synchronizer.service.js.map +1 -1
  184. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +3 -60
  185. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
  186. package/dist-server/server/modules/providers/services/sessions.service.js +179 -9
  187. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
  188. package/dist-server/server/modules/providers/tests/claude-auth.test.js +52 -0
  189. package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -1
  190. package/dist-server/server/modules/providers/tests/claude-models.test.js +39 -0
  191. package/dist-server/server/modules/providers/tests/claude-models.test.js.map +1 -0
  192. package/dist-server/server/modules/providers/tests/claude-sessions.test.js +465 -39
  193. package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -1
  194. package/dist-server/server/modules/providers/tests/claude-subagent-echo.test.js +16 -0
  195. package/dist-server/server/modules/providers/tests/claude-subagent-echo.test.js.map +1 -0
  196. package/dist-server/server/modules/providers/tests/claude-token-budget.test.js +85 -0
  197. package/dist-server/server/modules/providers/tests/claude-token-budget.test.js.map +1 -0
  198. package/dist-server/server/modules/providers/tests/codex-message-editing.test.js +338 -0
  199. package/dist-server/server/modules/providers/tests/codex-message-editing.test.js.map +1 -0
  200. package/dist-server/server/modules/providers/tests/codex-runtime.test.js +51 -0
  201. package/dist-server/server/modules/providers/tests/codex-runtime.test.js.map +1 -0
  202. package/dist-server/server/modules/providers/tests/codex-session-fork.test.js +54 -0
  203. package/dist-server/server/modules/providers/tests/codex-session-fork.test.js.map +1 -0
  204. package/dist-server/server/modules/providers/tests/codex-sessions.test.js +304 -15
  205. package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
  206. package/dist-server/server/modules/providers/tests/opencode-models.test.js +117 -4
  207. package/dist-server/server/modules/providers/tests/opencode-models.test.js.map +1 -1
  208. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +164 -1
  209. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -1
  210. package/dist-server/server/modules/providers/tests/provider.routes.test.js +35 -0
  211. package/dist-server/server/modules/providers/tests/provider.routes.test.js.map +1 -1
  212. package/dist-server/server/modules/providers/tests/session-fork.test.js +113 -0
  213. package/dist-server/server/modules/providers/tests/session-fork.test.js.map +1 -0
  214. package/dist-server/server/modules/providers/tests/session-history-cache.service.test.js +120 -0
  215. package/dist-server/server/modules/providers/tests/session-history-cache.service.test.js.map +1 -0
  216. package/dist-server/server/modules/providers/tests/session-orphan-prune.test.js +90 -0
  217. package/dist-server/server/modules/providers/tests/session-orphan-prune.test.js.map +1 -0
  218. package/dist-server/server/modules/providers/tests/session-synchronizer-coalescing.test.js +122 -0
  219. package/dist-server/server/modules/providers/tests/session-synchronizer-coalescing.test.js.map +1 -0
  220. package/dist-server/server/modules/providers/tests/sessions.service.test.js +45 -1
  221. package/dist-server/server/modules/providers/tests/sessions.service.test.js.map +1 -1
  222. package/dist-server/server/modules/providers/tests/skills.test.js +15 -3
  223. package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
  224. package/dist-server/server/modules/scheduled-messages/index.js +5 -0
  225. package/dist-server/server/modules/scheduled-messages/index.js.map +1 -0
  226. package/dist-server/server/modules/scheduled-messages/scheduled-messages.routes.js +47 -0
  227. package/dist-server/server/modules/scheduled-messages/scheduled-messages.routes.js.map +1 -0
  228. package/dist-server/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.js +163 -0
  229. package/dist-server/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.js.map +1 -0
  230. package/dist-server/server/modules/scheduled-messages/services/scheduled-messages.service.js +95 -0
  231. package/dist-server/server/modules/scheduled-messages/services/scheduled-messages.service.js.map +1 -0
  232. package/dist-server/server/modules/scheduled-messages/tests/scheduled-messages.test.js +255 -0
  233. package/dist-server/server/modules/scheduled-messages/tests/scheduled-messages.test.js.map +1 -0
  234. package/dist-server/server/modules/taskmaster/taskmaster.routes.js +23 -23
  235. package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -1
  236. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +48 -0
  237. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -1
  238. package/dist-server/server/modules/user/tests/user.service.test.js +70 -0
  239. package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -1
  240. package/dist-server/server/modules/user/user.module.js +10 -1
  241. package/dist-server/server/modules/user/user.module.js.map +1 -1
  242. package/dist-server/server/modules/user/user.routes.js +44 -0
  243. package/dist-server/server/modules/user/user.routes.js.map +1 -1
  244. package/dist-server/server/modules/user/user.service.js +75 -0
  245. package/dist-server/server/modules/user/user.service.js.map +1 -1
  246. package/dist-server/server/modules/voice/tests/voice.service.test.js +3 -2
  247. package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -1
  248. package/dist-server/server/modules/websocket/index.js +7 -0
  249. package/dist-server/server/modules/websocket/index.js.map +1 -1
  250. package/dist-server/server/modules/websocket/services/chat-run-registry.service.js +10 -44
  251. package/dist-server/server/modules/websocket/services/chat-run-registry.service.js.map +1 -1
  252. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +35 -5
  253. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js.map +1 -1
  254. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +166 -9
  255. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
  256. package/dist-server/server/modules/websocket/services/session-upsert-broadcast.service.js +94 -0
  257. package/dist-server/server/modules/websocket/services/session-upsert-broadcast.service.js.map +1 -0
  258. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +9 -3
  259. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
  260. package/dist-server/server/modules/websocket/tests/chat-edit-send.test.js +263 -0
  261. package/dist-server/server/modules/websocket/tests/chat-edit-send.test.js.map +1 -0
  262. package/dist-server/server/modules/websocket/tests/chat-run-registry.test.js +29 -3
  263. package/dist-server/server/modules/websocket/tests/chat-run-registry.test.js.map +1 -1
  264. package/dist-server/server/modules/websocket/tests/session-upsert-broadcast.test.js +106 -0
  265. package/dist-server/server/modules/websocket/tests/session-upsert-broadcast.test.js.map +1 -0
  266. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +80 -0
  267. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -1
  268. package/dist-server/server/shared/claude-cli-path.js +22 -5
  269. package/dist-server/server/shared/claude-cli-path.js.map +1 -1
  270. package/dist-server/server/shared/index.js +3 -0
  271. package/dist-server/server/shared/index.js.map +1 -0
  272. package/dist-server/server/shared/message-unification.js +376 -0
  273. package/dist-server/server/shared/message-unification.js.map +1 -0
  274. package/dist-server/server/shared/tests/claude-cli-path.test.js +45 -1
  275. package/dist-server/server/shared/tests/claude-cli-path.test.js.map +1 -1
  276. package/dist-server/server/shared/tests/message-unification.test.js +174 -0
  277. package/dist-server/server/shared/tests/message-unification.test.js.map +1 -0
  278. package/dist-server/server/shared/utils.js +42 -0
  279. package/dist-server/server/shared/utils.js.map +1 -1
  280. package/package.json +23 -16
  281. package/scripts/promote-dist-server.mjs +50 -0
  282. package/server/index.ts +12 -6
  283. package/server/modules/agent/agent.module.ts +2 -1
  284. package/server/modules/agent/agent.routes.ts +2 -2
  285. package/server/modules/agent/tests/agent.routes.test.ts +33 -1
  286. package/server/modules/auth/auth.middleware.ts +2 -2
  287. package/server/modules/browser-use/browser-use-runtime.ts +10 -0
  288. package/server/modules/browser-use/browser-use.routes.ts +96 -33
  289. package/server/modules/browser-use/browser-use.service.ts +5 -8
  290. package/server/modules/browser-use/index.ts +3 -0
  291. package/server/modules/cli/cli.module.ts +0 -1
  292. package/server/modules/cli/cli.service.ts +0 -20
  293. package/server/modules/cli/cli.ts +9 -3
  294. package/server/modules/cli/tests/cli-environment-bootstrap.test.ts +186 -0
  295. package/server/modules/cli/tests/cli.service.test.ts +0 -3
  296. package/server/modules/database/connection.ts +2 -1
  297. package/server/modules/database/index.ts +10 -0
  298. package/server/modules/database/migrations.ts +37 -0
  299. package/server/modules/database/repositories/scheduled-messages.db.ts +127 -0
  300. package/server/modules/database/repositories/session-drafts.db.ts +171 -0
  301. package/server/modules/database/repositories/sessions.db.ts +196 -3
  302. package/server/modules/database/repositories/user-preferences.db.ts +80 -0
  303. package/server/modules/database/schema.ts +96 -0
  304. package/server/modules/database/tests/sessions.db.integration.test.ts +52 -0
  305. package/server/modules/database/tests/user-preferences.db.integration.test.ts +135 -0
  306. package/server/modules/file-tree/file-tree.service.ts +21 -10
  307. package/server/modules/file-tree/tests/file-tree.service.test.ts +65 -11
  308. package/server/modules/git/git-branch.service.ts +43 -0
  309. package/server/modules/git/git.routes.ts +16 -9
  310. package/server/modules/git/tests/git-branch.service.test.ts +60 -0
  311. package/server/modules/git/tests/git-init.routes.test.ts +83 -0
  312. package/server/modules/notifications/index.ts +2 -0
  313. package/server/modules/notifications/services/notification-orchestrator.service.js +24 -1
  314. package/server/modules/projects/services/project-delete.service.ts +13 -1
  315. package/server/modules/projects/services/project-star.service.ts +2 -2
  316. package/server/modules/providers/index.ts +4 -0
  317. package/server/modules/providers/list/claude/claude-auth.provider.ts +21 -1
  318. package/server/modules/providers/list/claude/claude-fork.provider.ts +57 -0
  319. package/server/modules/providers/list/claude/claude-models.provider.ts +38 -6
  320. package/server/modules/providers/list/claude/claude-runtime.provider.js +463 -93
  321. package/server/modules/providers/list/claude/claude-sessions.provider.ts +478 -54
  322. package/server/modules/providers/list/claude/claude-skills.provider.ts +4 -1
  323. package/server/modules/providers/list/claude/claude.provider.ts +3 -0
  324. package/server/modules/providers/list/codex/codex-app-server.client.ts +243 -0
  325. package/server/modules/providers/list/codex/codex-fork.provider.ts +40 -0
  326. package/server/modules/providers/list/codex/codex-models.provider.ts +16 -0
  327. package/server/modules/providers/list/codex/{codex-runtime.provider.js → codex-runtime.provider.ts} +93 -66
  328. package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +9 -0
  329. package/server/modules/providers/list/codex/codex-sessions.provider.ts +1806 -477
  330. package/server/modules/providers/list/codex/codex.provider.ts +3 -0
  331. package/server/modules/providers/list/cursor/cursor-runtime.provider.js +8 -6
  332. package/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.ts +0 -1
  333. package/server/modules/providers/list/opencode/opencode-models.provider.ts +279 -6
  334. package/server/modules/providers/provider.routes.ts +36 -0
  335. package/server/modules/providers/services/provider-capabilities.service.ts +23 -0
  336. package/server/modules/providers/services/provider-token-usage.service.ts +166 -39
  337. package/server/modules/providers/services/session-conversations-search.service.ts +94 -7
  338. package/server/modules/providers/services/session-history-cache.service.ts +139 -0
  339. package/server/modules/providers/services/session-synchronizer.service.ts +125 -38
  340. package/server/modules/providers/services/sessions-watcher.service.ts +3 -64
  341. package/server/modules/providers/services/sessions.service.ts +201 -9
  342. package/server/modules/providers/tests/claude-auth.test.ts +58 -0
  343. package/server/modules/providers/tests/claude-models.test.ts +87 -0
  344. package/server/modules/providers/tests/claude-sessions.test.ts +552 -40
  345. package/server/modules/providers/tests/claude-subagent-echo.test.ts +25 -0
  346. package/server/modules/providers/tests/claude-token-budget.test.ts +104 -0
  347. package/server/modules/providers/tests/codex-message-editing.test.ts +419 -0
  348. package/server/modules/providers/tests/codex-runtime.test.ts +58 -0
  349. package/server/modules/providers/tests/codex-session-fork.test.ts +59 -0
  350. package/server/modules/providers/tests/codex-sessions.test.ts +337 -15
  351. package/server/modules/providers/tests/opencode-models.test.ts +166 -8
  352. package/server/modules/providers/tests/provider-token-usage.service.test.ts +188 -1
  353. package/server/modules/providers/tests/provider.routes.test.ts +61 -0
  354. package/server/modules/providers/tests/session-fork.test.ts +173 -0
  355. package/server/modules/providers/tests/session-history-cache.service.test.ts +143 -0
  356. package/server/modules/providers/tests/session-orphan-prune.test.ts +107 -0
  357. package/server/modules/providers/tests/session-synchronizer-coalescing.test.ts +136 -0
  358. package/server/modules/providers/tests/sessions.service.test.ts +67 -1
  359. package/server/modules/providers/tests/skills.test.ts +21 -5
  360. package/server/modules/scheduled-messages/index.ts +8 -0
  361. package/server/modules/scheduled-messages/scheduled-messages.routes.ts +68 -0
  362. package/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.ts +203 -0
  363. package/server/modules/scheduled-messages/services/scheduled-messages.service.ts +121 -0
  364. package/server/modules/scheduled-messages/tests/scheduled-messages.test.ts +310 -0
  365. package/server/modules/taskmaster/taskmaster.routes.ts +23 -33
  366. package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +57 -0
  367. package/server/modules/user/tests/user.service.test.ts +90 -0
  368. package/server/modules/user/user.module.ts +10 -1
  369. package/server/modules/user/user.routes.ts +44 -0
  370. package/server/modules/user/user.service.ts +105 -0
  371. package/server/modules/voice/tests/voice.service.test.ts +3 -2
  372. package/server/modules/websocket/index.ts +8 -0
  373. package/server/modules/websocket/services/chat-run-registry.service.ts +17 -50
  374. package/server/modules/websocket/services/chat-session-writer.service.ts +36 -6
  375. package/server/modules/websocket/services/chat-websocket.service.ts +244 -15
  376. package/server/modules/websocket/services/session-upsert-broadcast.service.ts +108 -0
  377. package/server/modules/websocket/services/shell-websocket.service.ts +10 -3
  378. package/server/modules/websocket/tests/chat-edit-send.test.ts +309 -0
  379. package/server/modules/websocket/tests/chat-run-registry.test.ts +34 -3
  380. package/server/modules/websocket/tests/session-upsert-broadcast.test.ts +138 -0
  381. package/server/modules/websocket/tests/shell-websocket.service.test.ts +108 -0
  382. package/server/shared/claude-cli-path.ts +24 -6
  383. package/server/shared/index.ts +3 -0
  384. package/server/shared/interfaces.ts +62 -0
  385. package/server/shared/message-unification.ts +449 -0
  386. package/server/shared/tests/claude-cli-path.test.ts +58 -1
  387. package/server/shared/tests/message-unification.test.ts +218 -0
  388. package/server/shared/types.ts +123 -3
  389. package/server/shared/utils.ts +50 -0
  390. package/server/tsconfig.json +6 -2
  391. package/README.de.md +0 -257
  392. package/README.ja.md +0 -249
  393. package/README.ko.md +0 -249
  394. package/README.ru.md +0 -257
  395. package/README.tr.md +0 -258
  396. package/README.zh-CN.md +0 -249
  397. package/README.zh-TW.md +0 -249
  398. package/dist/assets/index-D3jfzuKN.css +0 -32
  399. package/dist/assets/index-DTMWjJj8.js +0 -1550
  400. package/dist-server/server/constants/config.js +0 -6
  401. package/dist-server/server/constants/config.js.map +0 -1
  402. package/server/constants/config.ts +0 -5
@@ -1,5 +1,6 @@
1
1
  import { AbstractProvider } from '@/modules/providers/shared/base/abstract.provider.js';
2
2
  import { CodexProviderAuth } from '@/modules/providers/list/codex/codex-auth.provider.js';
3
+ import { CodexForkProvider } from '@/modules/providers/list/codex/codex-fork.provider.js';
3
4
  import { CodexProviderModels } from '@/modules/providers/list/codex/codex-models.provider.js';
4
5
  import { codexRuntime } from '@/modules/providers/list/codex/codex-runtime.provider.js';
5
6
  import { CodexMcpProvider } from '@/modules/providers/list/codex/codex-mcp.provider.js';
@@ -8,6 +9,7 @@ import { CodexSessionsProvider } from '@/modules/providers/list/codex/codex-sess
8
9
  import { CodexSkillsProvider } from '@/modules/providers/list/codex/codex-skills.provider.js';
9
10
  import type {
10
11
  IProviderAuth,
12
+ IProviderFork,
11
13
  IProviderModels,
12
14
  IProviderRuntime,
13
15
  IProviderSessionSynchronizer,
@@ -22,6 +24,7 @@ export class CodexProvider extends AbstractProvider {
22
24
  readonly auth: IProviderAuth = new CodexProviderAuth();
23
25
  readonly skills: IProviderSkills = new CodexSkillsProvider();
24
26
  readonly sessions: IProviderSessions = new CodexSessionsProvider();
27
+ readonly fork: IProviderFork = new CodexForkProvider();
25
28
  readonly sessionSynchronizer: IProviderSessionSynchronizer = new CodexSessionSynchronizer();
26
29
 
27
30
  constructor() {
@@ -30,22 +30,24 @@ function isWorkspaceTrustPrompt(text = '') {
30
30
  }
31
31
 
32
32
  async function spawnCursor(command, options = {}, ws, context) {
33
- return new Promise(async (resolve, reject) => {
33
+ // Callers pass the stable app session id; the CLI resumes with the
34
+ // provider-native id recorded on the session row. Both lookups run before the
35
+ // promise is created: inside an async executor a rejected `resolveResumeModel`
36
+ // would be swallowed and leave the returned promise pending forever.
37
+ const providerSessionId = context.resolveProviderSessionId(options.sessionId);
38
+ const resolvedModel = await context.resolveResumeModel(options.sessionId, options.model);
39
+
40
+ return new Promise((resolve, reject) => {
34
41
  const {
35
42
  sessionId,
36
43
  projectPath,
37
44
  cwd,
38
45
  toolsSettings,
39
46
  skipPermissions,
40
- model,
41
47
  sessionSummary,
42
48
  images,
43
49
  files
44
50
  } = options;
45
- // Callers pass the stable app session id; the CLI resumes with the
46
- // provider-native id recorded on the session row.
47
- const providerSessionId = context.resolveProviderSessionId(sessionId);
48
- const resolvedModel = await context.resolveResumeModel(sessionId, model);
49
51
  let capturedSessionId = providerSessionId; // Track the provider-native session id throughout the process
50
52
  let sessionCreatedSent = false; // Track if we've already sent session-created event
51
53
  let hasRetriedWithTrust = false;
@@ -1,4 +1,3 @@
1
- import crypto from 'node:crypto';
2
1
  import fs from 'node:fs';
3
2
  import fsp from 'node:fs/promises';
4
3
  import os from 'node:os';
@@ -1,3 +1,7 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+
1
5
  import Database from 'better-sqlite3';
2
6
 
3
7
  import { sessionsDb } from '@/modules/database/index.js';
@@ -17,9 +21,9 @@ import {
17
21
  * Curated OpenCode catalog shipped as immutable CloudCLI defaults.
18
22
  *
19
23
  * OpenCode routes by `<providerID>/<modelID>`, so this list mirrors the
20
- * providers `opencode models --verbose` reports: the OpenCode Zen gateway plus
21
- * the Anthropic and OpenAI providers OpenCode can address directly with the
22
- * user's own credentials.
24
+ * providers `opencode models --verbose` reports: the OpenCode Zen gateway, the
25
+ * OpenCode Go subscription gateway, and the Anthropic and OpenAI providers
26
+ * OpenCode can address directly with the user's own credentials.
23
27
  */
24
28
  export const OPENCODE_PREDEFINED_MODELS: ProviderModelsDefinition = {
25
29
  OPTIONS: [
@@ -77,6 +81,178 @@ export const OPENCODE_PREDEFINED_MODELS: ProviderModelsDefinition = {
77
81
  { value: 'opencode/north-mini-code-free', label: 'North Mini Code Free', description: 'OpenCode Zen · Free' },
78
82
  { value: 'opencode/nemotron-3-ultra-free', label: 'Nemotron 3 Ultra Free', description: 'OpenCode Zen · Free' },
79
83
  { value: 'opencode/deepseek-v4-flash-free', label: 'DeepSeek V4 Flash Free', description: 'OpenCode Zen · Free' },
84
+ {
85
+ value: 'opencode-go/grok-4.6',
86
+ label: 'Grok 4.6',
87
+ description: 'OpenCode Go',
88
+ effort: {
89
+ values: [{ value: 'low' }, { value: 'medium' }, { value: 'high' }, { value: 'xhigh' }],
90
+ },
91
+ },
92
+ {
93
+ value: 'opencode-go/glm-5.3-flash',
94
+ label: 'GLM 5.3 Flash',
95
+ description: 'OpenCode Go',
96
+ effort: {
97
+ values: [{ value: 'low' }, { value: 'high' }, { value: 'max' }],
98
+ },
99
+ },
100
+ {
101
+ value: 'opencode-go/glm-5.3',
102
+ label: 'GLM 5.3',
103
+ description: 'OpenCode Go',
104
+ effort: {
105
+ values: [{ value: 'low' }, { value: 'high' }, { value: 'max' }],
106
+ },
107
+ },
108
+ {
109
+ value: 'opencode-go/glm-5.2',
110
+ label: 'GLM 5.2',
111
+ description: 'OpenCode Go',
112
+ effort: {
113
+ values: [{ value: 'high' }, { value: 'max' }],
114
+ },
115
+ },
116
+ { value: 'opencode-go/glm-5.1', label: 'GLM 5.1', description: 'OpenCode Go' },
117
+ {
118
+ value: 'opencode-go/gpt-5.6-luna',
119
+ label: 'GPT 5.6 Luna',
120
+ description: 'OpenCode Go',
121
+ effort: {
122
+ values: [
123
+ { value: 'none' },
124
+ { value: 'low' },
125
+ { value: 'medium' },
126
+ { value: 'high' },
127
+ { value: 'xhigh' },
128
+ { value: 'max' },
129
+ ],
130
+ },
131
+ },
132
+ {
133
+ value: 'opencode-go/kimi-k3',
134
+ label: 'Kimi K3',
135
+ description: 'OpenCode Go',
136
+ effort: {
137
+ values: [{ value: 'max' }],
138
+ },
139
+ },
140
+ { value: 'opencode-go/kimi-k2.7-code', label: 'Kimi K2.7 Code', description: 'OpenCode Go' },
141
+ { value: 'opencode-go/kimi-k2.6', label: 'Kimi K2.6', description: 'OpenCode Go' },
142
+ {
143
+ value: 'opencode-go/longcat-2.0',
144
+ label: 'LongCat 2.0',
145
+ description: 'OpenCode Go',
146
+ effort: {
147
+ values: [{ value: 'low' }, { value: 'medium' }, { value: 'high' }],
148
+ },
149
+ },
150
+ { value: 'opencode-go/mimo-v2.5', label: 'MiMo V2.5', description: 'OpenCode Go' },
151
+ { value: 'opencode-go/mimo-v2.5-pro', label: 'MiMo V2.5 Pro', description: 'OpenCode Go' },
152
+ {
153
+ value: 'opencode-go/minimax-m3',
154
+ label: 'MiniMax M3',
155
+ description: 'OpenCode Go',
156
+ effort: {
157
+ values: [{ value: 'none' }, { value: 'thinking' }],
158
+ },
159
+ },
160
+ { value: 'opencode-go/minimax-m2.7', label: 'MiniMax M2.7', description: 'OpenCode Go' },
161
+ {
162
+ value: 'opencode-go/muse-spark-1.3-contributor',
163
+ label: 'Muse Spark 1.3 Contributor',
164
+ description: 'OpenCode Go',
165
+ effort: {
166
+ values: [
167
+ { value: 'minimal' },
168
+ { value: 'low' },
169
+ { value: 'medium' },
170
+ { value: 'high' },
171
+ { value: 'xhigh' },
172
+ ],
173
+ },
174
+ },
175
+ {
176
+ value: 'opencode-go/muse-spark-1.2-contributor',
177
+ label: 'Muse Spark 1.2 Contributor',
178
+ description: 'OpenCode Go',
179
+ effort: {
180
+ values: [
181
+ { value: 'minimal' },
182
+ { value: 'low' },
183
+ { value: 'medium' },
184
+ { value: 'high' },
185
+ { value: 'xhigh' },
186
+ ],
187
+ },
188
+ },
189
+ {
190
+ value: 'opencode-go/qwen3.8-max',
191
+ label: 'Qwen3.8 Max',
192
+ description: 'OpenCode Go',
193
+ effort: {
194
+ values: [{ value: 'low' }, { value: 'medium' }, { value: 'xhigh' }],
195
+ },
196
+ },
197
+ {
198
+ value: 'opencode-go/qwen3.8-flash',
199
+ label: 'Qwen3.8 Flash',
200
+ description: 'OpenCode Go',
201
+ effort: {
202
+ values: [{ value: 'low' }, { value: 'medium' }, { value: 'xhigh' }],
203
+ },
204
+ },
205
+ { value: 'opencode-go/qwen3.7-max', label: 'Qwen3.7 Max', description: 'OpenCode Go' },
206
+ { value: 'opencode-go/qwen3.7-plus', label: 'Qwen3.7 Plus', description: 'OpenCode Go' },
207
+ { value: 'opencode-go/qwen3.6-plus', label: 'Qwen3.6 Plus', description: 'OpenCode Go' },
208
+ {
209
+ value: 'opencode-go/deepseek-v4-pro',
210
+ label: 'DeepSeek V4 Pro',
211
+ description: 'OpenCode Go',
212
+ effort: {
213
+ values: [{ value: 'high' }, { value: 'max' }],
214
+ },
215
+ },
216
+ {
217
+ value: 'opencode-go/deepseek-v4-flash',
218
+ label: 'DeepSeek V4 Flash',
219
+ description: 'OpenCode Go',
220
+ effort: {
221
+ values: [{ value: 'low' }, { value: 'high' }, { value: 'max' }],
222
+ },
223
+ },
224
+ {
225
+ value: 'opencode-go/deepseek-v4-flash-vision-exp',
226
+ label: 'DeepSeek V4 Flash Vision Exp',
227
+ description: 'OpenCode Go',
228
+ effort: {
229
+ values: [{ value: 'low' }, { value: 'high' }, { value: 'max' }],
230
+ },
231
+ },
232
+ {
233
+ value: 'opencode-go/hy4-preview',
234
+ label: 'Hy4 Preview',
235
+ description: 'OpenCode Go',
236
+ effort: {
237
+ values: [{ value: 'none' }, { value: 'high' }],
238
+ },
239
+ },
240
+ {
241
+ value: 'opencode-go/hy3',
242
+ label: 'Hy3',
243
+ description: 'OpenCode Go',
244
+ effort: {
245
+ values: [{ value: 'none' }, { value: 'low' }, { value: 'high' }],
246
+ },
247
+ },
248
+ {
249
+ value: 'opencode-go/omen-alpha',
250
+ label: 'Omen Alpha',
251
+ description: 'OpenCode Go',
252
+ effort: {
253
+ values: [{ value: 'low' }, { value: 'high' }],
254
+ },
255
+ },
80
256
  { value: 'anthropic/claude-opus-5', label: 'Claude Opus 5', description: 'Anthropic' },
81
257
  { value: 'anthropic/claude-opus-5-fast', label: 'Claude Opus 5 Fast', description: 'Anthropic' },
82
258
  { value: 'anthropic/claude-fable-5', label: 'Claude Fable 5', description: 'Anthropic' },
@@ -117,6 +293,100 @@ export const OPENCODE_PREDEFINED_MODELS: ProviderModelsDefinition = {
117
293
  DEFAULT: 'opencode/gpt-5.6-terra',
118
294
  };
119
295
 
296
+ /** Global OpenCode config files, in the order the CLI loads them. */
297
+ const OPENCODE_CONFIG_FILES = ['config.json', 'opencode.json', 'opencode.jsonc'];
298
+
299
+ /** Provider API keys OpenCode reads straight from the environment. */
300
+ const OPENCODE_ENV_PROVIDER_IDS: Record<string, string> = {
301
+ OPENCODE_API_KEY: 'opencode',
302
+ ANTHROPIC_API_KEY: 'anthropic',
303
+ OPENAI_API_KEY: 'openai',
304
+ };
305
+
306
+ const readOpenCodeJsonFile = async (filePath: string): Promise<Record<string, unknown> | null> => {
307
+ try {
308
+ return readObjectRecord(JSON.parse(await readFile(filePath, 'utf8')));
309
+ } catch {
310
+ // Missing, unreadable, or comment-bearing (.jsonc) files simply contribute
311
+ // nothing; the auth store is the authoritative source below.
312
+ return null;
313
+ }
314
+ };
315
+
316
+ /**
317
+ * Lists the upstream providers this OpenCode install can actually route to.
318
+ *
319
+ * OpenCode resolves `<providerID>/<modelID>` against the providers the user has
320
+ * connected, and rejects anything else outright - `Model
321
+ * opencode/claude-sonnet-4-6 is not valid` is what a run gets for asking for an
322
+ * OpenCode Zen model on a machine that only has an Anthropic key. The curated
323
+ * catalog spans every provider OpenCode can address, so it has to be narrowed
324
+ * to this machine's providers before it reaches the model picker.
325
+ *
326
+ * Returns null when nothing can be read, so the caller keeps the full catalog
327
+ * rather than leaving the picker empty. Providers declared only in a
328
+ * project-level `opencode.json` are not visible here; the null fallback and the
329
+ * env-key sweep keep those installs on the full list.
330
+ */
331
+ const readConnectedOpenCodeProviderIds = async (): Promise<Set<string> | null> => {
332
+ const providerIds = new Set<string>();
333
+ const configDir = path.join(os.homedir(), '.config', 'opencode');
334
+
335
+ const auth = await readOpenCodeJsonFile(
336
+ path.join(os.homedir(), '.local', 'share', 'opencode', 'auth.json'),
337
+ );
338
+ for (const [providerId, credential] of Object.entries(auth ?? {})) {
339
+ if (readObjectRecord(credential)) {
340
+ providerIds.add(providerId);
341
+ }
342
+ }
343
+
344
+ for (const configFile of OPENCODE_CONFIG_FILES) {
345
+ const config = await readOpenCodeJsonFile(path.join(configDir, configFile));
346
+ for (const providerId of Object.keys(readObjectRecord(config?.provider) ?? {})) {
347
+ providerIds.add(providerId);
348
+ }
349
+ }
350
+
351
+ for (const [envKey, providerId] of Object.entries(OPENCODE_ENV_PROVIDER_IDS)) {
352
+ if (readOptionalString(process.env[envKey])) {
353
+ providerIds.add(providerId);
354
+ }
355
+ }
356
+
357
+ return providerIds.size > 0 ? providerIds : null;
358
+ };
359
+
360
+ /**
361
+ * Narrows the curated catalog to the providers OpenCode can route to.
362
+ *
363
+ * The default has to move with the list: leaving it on an OpenCode Zen model
364
+ * would hand every new session a model the CLI refuses to run.
365
+ */
366
+ const filterOpenCodeModelsByProvider = (
367
+ definition: ProviderModelsDefinition,
368
+ connectedProviderIds: Set<string> | null,
369
+ ): ProviderModelsDefinition => {
370
+ if (!connectedProviderIds) {
371
+ return definition;
372
+ }
373
+
374
+ const options = definition.OPTIONS.filter(
375
+ (option) => connectedProviderIds.has(option.value.split('/')[0]),
376
+ );
377
+ if (options.length === 0) {
378
+ return definition;
379
+ }
380
+
381
+ return {
382
+ ...definition,
383
+ OPTIONS: options,
384
+ DEFAULT: options.some((option) => option.value === definition.DEFAULT)
385
+ ? definition.DEFAULT
386
+ : options[0].value,
387
+ };
388
+ };
389
+
120
390
  const parseOpenCodeSessionModelValue = (rawModel: unknown): string | null => {
121
391
  if (typeof rawModel === 'string') {
122
392
  const trimmed = rawModel.trim();
@@ -146,12 +416,15 @@ const parseOpenCodeSessionModelValue = (rawModel: unknown): string | null => {
146
416
  /** Provider registry model adapter for OpenCode predefined models and session metadata. */
147
417
  export class OpenCodeProviderModels implements IProviderModels {
148
418
  async getSupportedModels(): Promise<ProviderModelsDefinition> {
149
- return OPENCODE_PREDEFINED_MODELS;
419
+ return filterOpenCodeModelsByProvider(
420
+ OPENCODE_PREDEFINED_MODELS,
421
+ await readConnectedOpenCodeProviderIds(),
422
+ );
150
423
  }
151
424
 
152
425
  async getCurrentActiveModel(sessionId?: string): Promise<ProviderCurrentActiveModel> {
153
426
  if (!sessionId?.trim()) {
154
- return buildDefaultProviderCurrentActiveModel(OPENCODE_PREDEFINED_MODELS);
427
+ return buildDefaultProviderCurrentActiveModel(await this.getSupportedModels());
155
428
  }
156
429
 
157
430
  // OpenCode's `session` table is keyed by its own session id, so the stable
@@ -198,6 +471,6 @@ export class OpenCodeProviderModels implements IProviderModels {
198
471
  // Fall through to the curated default when OpenCode session lookup fails.
199
472
  }
200
473
 
201
- return buildDefaultProviderCurrentActiveModel(OPENCODE_PREDEFINED_MODELS);
474
+ return buildDefaultProviderCurrentActiveModel(await this.getSupportedModels());
202
475
  }
203
476
  }
@@ -297,6 +297,28 @@ const parseProvider = (value: unknown): LLMProvider => {
297
297
  });
298
298
  };
299
299
 
300
+ /** Both fields are optional: an empty body forks the whole conversation. */
301
+ const parseSessionForkPayload = (payload: unknown): { upToAnchorId?: string; title?: string } => {
302
+ if (payload === undefined || payload === null) {
303
+ return {};
304
+ }
305
+ if (typeof payload !== 'object') {
306
+ throw new AppError('Request body must be an object.', {
307
+ code: 'INVALID_REQUEST_BODY',
308
+ statusCode: 400,
309
+ });
310
+ }
311
+
312
+ const body = payload as Record<string, unknown>;
313
+ const upToAnchorId = typeof body.upToAnchorId === 'string' ? body.upToAnchorId.trim() : '';
314
+ const title = typeof body.title === 'string' ? body.title.trim() : '';
315
+
316
+ return {
317
+ ...(upToAnchorId ? { upToAnchorId } : {}),
318
+ ...(title ? { title } : {}),
319
+ };
320
+ };
321
+
300
322
  const parseSessionRenameSummary = (payload: unknown): string => {
301
323
  if (!payload || typeof payload !== 'object') {
302
324
  throw new AppError('Request body must be an object.', {
@@ -792,6 +814,15 @@ router.post(
792
814
  }),
793
815
  );
794
816
 
817
+ router.post(
818
+ '/sessions/:sessionId/fork',
819
+ asyncHandler(async (req: Request, res: Response) => {
820
+ const sessionId = parseSessionId(req.params.sessionId);
821
+ const result = await sessionsService.forkSessionById(sessionId, parseSessionForkPayload(req.body));
822
+ res.status(201).json(createApiSuccessResponse(result));
823
+ }),
824
+ );
825
+
795
826
  router.put(
796
827
  '/sessions/:sessionId',
797
828
  asyncHandler(async (req: Request, res: Response) => {
@@ -840,6 +871,11 @@ router.get('/search/sessions', asyncHandler(async (req: Request, res: Response)
840
871
  query,
841
872
  limit,
842
873
  signal: abortController.signal,
874
+ onTitleResults: (titleResults) => {
875
+ if (!closed) {
876
+ res.write(`event: title-results\ndata: ${JSON.stringify({ titleResults })}\n\n`);
877
+ }
878
+ },
843
879
  onProgress: ({ projectResult, totalMatches, scannedProjects, totalProjects }) => {
844
880
  if (closed) {
845
881
  return;
@@ -25,6 +25,15 @@ type ProviderCapabilities = {
25
25
  supportsTokenUsage: boolean;
26
26
  /** Whether the provider runtime can accept model-level reasoning effort. */
27
27
  supportsEffort: boolean;
28
+ /**
29
+ * Whether an already-sent message can be replaced, which requires the
30
+ * provider to re-run a conversation truncated at a chosen point.
31
+ */
32
+ supportsMessageEditing: boolean;
33
+ /**
34
+ * Whether a session's transcript can be branched into an independent one.
35
+ */
36
+ supportsSessionForking: boolean;
28
37
  };
29
38
 
30
39
  /**
@@ -44,6 +53,10 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
44
53
  supportsPermissionRequests: true,
45
54
  supportsTokenUsage: true,
46
55
  supportsEffort: true,
56
+ // `resumeSessionAt` re-runs a conversation truncated at a message, and
57
+ // `forkSession` copies a transcript prefix into a new session file.
58
+ supportsMessageEditing: true,
59
+ supportsSessionForking: true,
47
60
  },
48
61
  cursor: {
49
62
  provider: 'cursor',
@@ -55,6 +68,8 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
55
68
  supportsPermissionRequests: false,
56
69
  supportsTokenUsage: false,
57
70
  supportsEffort: false,
71
+ supportsMessageEditing: false,
72
+ supportsSessionForking: false,
58
73
  },
59
74
  codex: {
60
75
  provider: 'codex',
@@ -66,6 +81,12 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
66
81
  supportsPermissionRequests: false,
67
82
  supportsTokenUsage: true,
68
83
  supportsEffort: true,
84
+ // Not from the Codex SDK, which only starts and resumes threads: both ride
85
+ // the same CLI's `app-server` protocol, whose `thread/fork` copies a
86
+ // thread up to a chosen turn. Editing is that fork plus a new prompt,
87
+ // which is how Codex's own IDE clients do it.
88
+ supportsMessageEditing: true,
89
+ supportsSessionForking: true,
69
90
  },
70
91
  opencode: {
71
92
  provider: 'opencode',
@@ -80,6 +101,8 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
80
101
  supportsPermissionRequests: false,
81
102
  supportsTokenUsage: true,
82
103
  supportsEffort: true,
104
+ supportsMessageEditing: false,
105
+ supportsSessionForking: false,
83
106
  },
84
107
  };
85
108