@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
@@ -978,8 +978,8 @@ export function createAgentRouter(dependencies: AgentRouterDependencies): expres
978
978
  });
979
979
  }
980
980
 
981
- const codexModels = (await providerModelsService.getProviderModels('codex')).models;
982
- const opencodeModels = (await providerModelsService.getProviderModels('opencode')).models;
981
+ const codexModels = await providerModelsService.getProviderModels('codex');
982
+ const opencodeModels = await providerModelsService.getProviderModels('opencode');
983
983
 
984
984
  // Start the appropriate session
985
985
  if (provider === 'claude') {
@@ -182,7 +182,7 @@ test('Agent route reuses a matching checkout without cloning or deleting it', as
182
182
  } as unknown as AgentDependencies['fileSystem'],
183
183
  spawnProcess,
184
184
  models: {
185
- getProviderModels: async () => ({ models: { DEFAULT: 'default-model' } }),
185
+ getProviderModels: async () => ({ OPTIONS: [], DEFAULT: 'default-model' }),
186
186
  } as unknown as AgentDependencies['models'],
187
187
  queryClaude: (async () => undefined) as AgentDependencies['queryClaude'],
188
188
  }), async (baseUrl) => {
@@ -203,3 +203,35 @@ test('Agent route reuses a matching checkout without cloning or deleting it', as
203
203
  assert.deepEqual(spawnedArguments, [['config', '--get', 'remote.origin.url']]);
204
204
  assert.deepEqual(removedPaths, []);
205
205
  });
206
+
207
+ test('Agent route starts codex on the catalog default when the request names no model', async () => {
208
+ const codexCalls: { model?: string }[] = [];
209
+
210
+ await withAgentServer(createDependencies({
211
+ fileSystem: {
212
+ access: async () => undefined,
213
+ } as unknown as AgentDependencies['fileSystem'],
214
+ models: {
215
+ // `getProviderModels` resolves to a `ProviderModelsDefinition` - `OPTIONS`
216
+ // and `DEFAULT`, with nothing wrapped around it.
217
+ getProviderModels: async () => ({ OPTIONS: [], DEFAULT: 'catalog-default' }),
218
+ } as unknown as AgentDependencies['models'],
219
+ queryCodex: (async (_prompt: string, options: { model?: string }) => {
220
+ codexCalls.push(options);
221
+ }) as unknown as AgentDependencies['queryCodex'],
222
+ }), async (baseUrl) => {
223
+ const response = await fetch(`${baseUrl}/api/agent`, {
224
+ method: 'POST',
225
+ headers: { 'content-type': 'application/json' },
226
+ body: JSON.stringify({
227
+ projectPath: '/home/test/project',
228
+ message: 'Run',
229
+ provider: 'codex',
230
+ stream: false,
231
+ }),
232
+ });
233
+ assert.equal(response.status, 200);
234
+ });
235
+
236
+ assert.deepEqual(codexCalls.map((call) => call.model), ['catalog-default']);
237
+ });
@@ -1,9 +1,9 @@
1
1
  // @ts-nocheck -- JWT request augmentation is narrowed by Auth route contracts.
2
2
  import jwt from 'jsonwebtoken';
3
3
 
4
- import { userDb, appConfigDb } from '../database/index.js';
4
+ import { IS_PLATFORM } from '@/shared/utils.js';
5
5
 
6
- const IS_PLATFORM = process.env.VITE_IS_PLATFORM === 'true';
6
+ import { userDb, appConfigDb } from '../database/index.js';
7
7
 
8
8
  // Use env var if set, otherwise auto-generate a unique secret per installation
9
9
  const JWT_SECRET = process.env.JWT_SECRET || appConfigDb.getOrCreateJwtSecret();
@@ -0,0 +1,10 @@
1
+ import { IS_PLATFORM } from '@/shared/utils.js';
2
+
3
+ /**
4
+ * Resolves the runtime label exposed by Browser Use status and session APIs.
5
+ * The Browser Use service and CLI environment-mode regression coverage consume
6
+ * this after the server or CLI entrypoint has completed environment bootstrapping.
7
+ */
8
+ export function getBrowserUseRuntime(): 'cloud' | 'local' {
9
+ return IS_PLATFORM ? 'cloud' : 'local';
10
+ }
@@ -1,9 +1,45 @@
1
1
  import express from 'express';
2
+ import type { Response } from 'express';
2
3
 
3
4
  import { browserUseService } from '@/modules/browser-use/browser-use.service.js';
4
5
 
5
6
  const router = express.Router();
6
7
 
8
+ /**
9
+ * Stable machine-readable error codes for the browser-use API.
10
+ *
11
+ * The server always replies with the structured envelope used by AppError
12
+ * (`{ success: false, error: { code, message, details } }`). Clients map
13
+ * `code` to localized copy; `message` is an English fallback and `details`
14
+ * may carry the underlying error text for diagnostics.
15
+ */
16
+ export const BROWSER_USE_ERROR_CODES = {
17
+ STATUS_LOAD_FAILED: 'BROWSER_USE_STATUS_LOAD_FAILED',
18
+ SETTINGS_LOAD_FAILED: 'BROWSER_USE_SETTINGS_LOAD_FAILED',
19
+ SETTINGS_SAVE_FAILED: 'BROWSER_USE_SETTINGS_SAVE_FAILED',
20
+ RUNTIME_INSTALL_FAILED: 'BROWSER_USE_RUNTIME_INSTALL_FAILED',
21
+ SESSIONS_LOAD_FAILED: 'BROWSER_USE_SESSIONS_LOAD_FAILED',
22
+ SESSION_STOP_FAILED: 'BROWSER_USE_SESSION_STOP_FAILED',
23
+ SESSION_DELETE_FAILED: 'BROWSER_USE_SESSION_DELETE_FAILED',
24
+ } as const;
25
+
26
+ function sendError(
27
+ res: Response,
28
+ statusCode: number,
29
+ code: string,
30
+ message: string,
31
+ details?: unknown,
32
+ ): void {
33
+ res.status(statusCode).json({
34
+ success: false,
35
+ error: {
36
+ code,
37
+ message,
38
+ details,
39
+ },
40
+ });
41
+ }
42
+
7
43
  function readParam(value: string | string[] | undefined): string {
8
44
  return Array.isArray(value) ? value[0] || '' : value || '';
9
45
  }
@@ -12,10 +48,13 @@ router.get('/status', async (_req, res) => {
12
48
  try {
13
49
  res.json({ success: true, data: await browserUseService.getStatus() });
14
50
  } catch (error) {
15
- res.status(500).json({
16
- success: false,
17
- error: error instanceof Error ? error.message : 'Failed to load Browser status.',
18
- });
51
+ sendError(
52
+ res,
53
+ 500,
54
+ BROWSER_USE_ERROR_CODES.STATUS_LOAD_FAILED,
55
+ 'Failed to load Browser status.',
56
+ error instanceof Error ? error.message : undefined,
57
+ );
19
58
  }
20
59
  });
21
60
 
@@ -23,10 +62,13 @@ router.get('/settings', async (_req, res) => {
23
62
  try {
24
63
  res.json({ success: true, data: { settings: await browserUseService.getSettings() } });
25
64
  } catch (error) {
26
- res.status(500).json({
27
- success: false,
28
- error: error instanceof Error ? error.message : 'Failed to load Browser settings.',
29
- });
65
+ sendError(
66
+ res,
67
+ 500,
68
+ BROWSER_USE_ERROR_CODES.SETTINGS_LOAD_FAILED,
69
+ 'Failed to load Browser settings.',
70
+ error instanceof Error ? error.message : undefined,
71
+ );
30
72
  }
31
73
  });
32
74
 
@@ -35,26 +77,38 @@ router.put('/settings', async (req, res) => {
35
77
  const settings = await browserUseService.updateSettings(req.body || {});
36
78
  res.json({ success: true, data: { settings } });
37
79
  } catch (error) {
38
- res.status(400).json({
39
- success: false,
40
- error: error instanceof Error ? error.message : 'Failed to save Browser settings.',
41
- });
80
+ sendError(
81
+ res,
82
+ 400,
83
+ BROWSER_USE_ERROR_CODES.SETTINGS_SAVE_FAILED,
84
+ 'Failed to save Browser settings.',
85
+ error instanceof Error ? error.message : undefined,
86
+ );
42
87
  }
43
88
  });
44
89
 
45
90
  router.post('/runtime/install', async (_req, res) => {
46
91
  try {
47
92
  const result = await browserUseService.installRuntime();
48
- res.status(result.success ? 200 : 500).json({
49
- success: result.success,
50
- data: result,
51
- error: result.success ? undefined : result.message,
52
- });
93
+ if (result.success) {
94
+ res.json({ success: true, data: result });
95
+ return;
96
+ }
97
+ sendError(
98
+ res,
99
+ 500,
100
+ BROWSER_USE_ERROR_CODES.RUNTIME_INSTALL_FAILED,
101
+ 'Failed to install Browser runtime.',
102
+ result.message,
103
+ );
53
104
  } catch (error) {
54
- res.status(500).json({
55
- success: false,
56
- error: error instanceof Error ? error.message : 'Failed to install Browser runtime.',
57
- });
105
+ sendError(
106
+ res,
107
+ 500,
108
+ BROWSER_USE_ERROR_CODES.RUNTIME_INSTALL_FAILED,
109
+ 'Failed to install Browser runtime.',
110
+ error instanceof Error ? error.message : undefined,
111
+ );
58
112
  }
59
113
  });
60
114
 
@@ -62,10 +116,13 @@ router.get('/sessions', async (_req, res) => {
62
116
  try {
63
117
  res.json({ success: true, data: { sessions: await browserUseService.listSessions() } });
64
118
  } catch (error) {
65
- res.status(401).json({
66
- success: false,
67
- error: error instanceof Error ? error.message : 'Failed to list browser sessions.',
68
- });
119
+ sendError(
120
+ res,
121
+ 401,
122
+ BROWSER_USE_ERROR_CODES.SESSIONS_LOAD_FAILED,
123
+ 'Failed to list browser sessions.',
124
+ error instanceof Error ? error.message : undefined,
125
+ );
69
126
  }
70
127
  });
71
128
 
@@ -74,10 +131,13 @@ router.post('/sessions/:sessionId/stop', async (req, res) => {
74
131
  const result = await browserUseService.stopSession(readParam(req.params.sessionId));
75
132
  res.json({ success: true, data: result });
76
133
  } catch (error) {
77
- res.status(400).json({
78
- success: false,
79
- error: error instanceof Error ? error.message : 'Failed to stop browser session.',
80
- });
134
+ sendError(
135
+ res,
136
+ 400,
137
+ BROWSER_USE_ERROR_CODES.SESSION_STOP_FAILED,
138
+ 'Failed to stop browser session.',
139
+ error instanceof Error ? error.message : undefined,
140
+ );
81
141
  }
82
142
  });
83
143
 
@@ -86,10 +146,13 @@ router.delete('/sessions/:sessionId', async (req, res) => {
86
146
  const result = await browserUseService.deleteSession(readParam(req.params.sessionId));
87
147
  res.json({ success: true, data: result });
88
148
  } catch (error) {
89
- res.status(400).json({
90
- success: false,
91
- error: error instanceof Error ? error.message : 'Failed to delete browser session.',
92
- });
149
+ sendError(
150
+ res,
151
+ 400,
152
+ BROWSER_USE_ERROR_CODES.SESSION_DELETE_FAILED,
153
+ 'Failed to delete browser session.',
154
+ error instanceof Error ? error.message : undefined,
155
+ );
93
156
  }
94
157
  });
95
158
 
@@ -11,15 +11,16 @@ import { appConfigDb } from '@/modules/database/index.js';
11
11
  import { providerMcpService } from '@/modules/providers/index.js';
12
12
  import { getModuleDirectory } from '@/shared/utils.js';
13
13
 
14
+ import { getBrowserUseRuntime } from './browser-use-runtime.js';
15
+
14
16
  const require = createRequire(import.meta.url);
15
17
  const __dirname = getModuleDirectory(import.meta.url);
16
- const IS_PLATFORM = process.env.VITE_IS_PLATFORM === 'true';
17
18
  const MAX_SESSIONS_PER_OWNER = Number.parseInt(process.env.CLOUDCLI_BROWSER_USE_MAX_SESSIONS_PER_OWNER || '3', 10);
18
19
  const SESSION_TTL_MS = Number.parseInt(process.env.CLOUDCLI_BROWSER_USE_SESSION_TTL_MS || String(30 * 60 * 1000), 10);
19
20
  const BROWSER_USE_SETTINGS_KEY = 'browser_use_settings';
20
21
  const BROWSER_USE_MCP_TOKEN_KEY = 'browser_use_mcp_token';
21
22
 
22
- type BrowserUseRuntime = 'cloud' | 'local';
23
+ type BrowserUseRuntime = ReturnType<typeof getBrowserUseRuntime>;
23
24
  type BrowserUseSessionStatus = 'ready' | 'stopped' | 'unavailable';
24
25
 
25
26
  type BrowserUseSession = {
@@ -85,10 +86,6 @@ const MCP_SERVER_NAME = 'cloudcli-browser';
85
86
  const LEGACY_MCP_SERVER_NAMES = ['cloudcli-browser-use'];
86
87
  const RUNTIME_READINESS_CACHE_TTL_MS = 30_000;
87
88
 
88
- function getRuntime(): BrowserUseRuntime {
89
- return IS_PLATFORM ? 'cloud' : 'local';
90
- }
91
-
92
89
  function readSettings(): BrowserUseSettings {
93
90
  try {
94
91
  const raw = appConfigDb.get(BROWSER_USE_SETTINGS_KEY);
@@ -446,7 +443,7 @@ export const browserUseService = {
446
443
 
447
444
  return {
448
445
  enabled: settings.enabled,
449
- runtime: getRuntime(),
446
+ runtime: getBrowserUseRuntime(),
450
447
  available,
451
448
  playwrightInstalled: readiness.playwrightInstalled,
452
449
  chromiumInstalled: readiness.chromiumInstalled,
@@ -515,7 +512,7 @@ export const browserUseService = {
515
512
  id: randomUUID(),
516
513
  ownerId: AGENT_OWNER_ID,
517
514
  createdBy: 'agent',
518
- runtime: getRuntime(),
515
+ runtime: getBrowserUseRuntime(),
519
516
  status: 'unavailable',
520
517
  url: null,
521
518
  title: null,
@@ -6,3 +6,6 @@
6
6
  export async function startBrowserUseMcp(): Promise<void> {
7
7
  await import('./browser-use-mcp.js');
8
8
  }
9
+
10
+ // getBrowserUseRuntime: used by Browser Use services and environment-mode regression coverage.
11
+ export { getBrowserUseRuntime } from './browser-use-runtime.js';
@@ -28,7 +28,6 @@ export function createCliApplication(): CliApplication {
28
28
  bugsUrl: packageMetadataJson.bugs?.url,
29
29
  };
30
30
  const fileSystem = {
31
- readTextFile: (filePath: string) => fs.readFileSync(filePath, 'utf8'),
32
31
  pathExists: (filePath: string) => fs.existsSync(filePath),
33
32
  getFileStats: (filePath: string) => {
34
33
  const stats = fs.statSync(filePath);
@@ -77,27 +77,7 @@ function isNewerVersion(candidateVersion: string, currentVersion: string): boole
77
77
  return false;
78
78
  }
79
79
 
80
- function loadEnvironmentFile(dependencies: CliServiceDependencies): void {
81
- try {
82
- const environmentFile = dependencies.fileSystem.readTextFile(
83
- path.join(dependencies.applicationRoot, '.env'),
84
- );
85
- for (const line of environmentFile.split('\n')) {
86
- const trimmedLine = line.trim();
87
- if (!trimmedLine || trimmedLine.startsWith('#')) continue;
88
-
89
- const [key, ...valueParts] = trimmedLine.split('=');
90
- if (key && valueParts.length > 0 && !dependencies.environment[key]) {
91
- dependencies.environment[key] = valueParts.join('=').trim();
92
- }
93
- }
94
- } catch {
95
- // The repository-level .env file is optional for every CLI command.
96
- }
97
- }
98
-
99
80
  function showStatus(dependencies: CliServiceDependencies): void {
100
- loadEnvironmentFile(dependencies);
101
81
  const { environment, fileSystem, output } = dependencies;
102
82
  const databasePath = environment.DATABASE_PATH || dependencies.defaultDatabasePath;
103
83
  const databaseExists = fileSystem.pathExists(databasePath);
@@ -1,10 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { createCliApplication } from './index.js';
3
+ // The CLI can reach shared environment constants through its composition root,
4
+ // so finish the root environment bootstrap before loading that import graph.
5
+ // eslint-disable-next-line boundaries/no-unknown
6
+ import '../../load-env.js';
4
7
 
5
- const cliApplication = createCliApplication();
8
+ async function runCli(): Promise<number> {
9
+ const { createCliApplication } = await import('./index.js');
10
+ return createCliApplication().run(process.argv.slice(2));
11
+ }
6
12
 
7
- cliApplication.run(process.argv.slice(2)).then((exitCode) => {
13
+ runCli().then((exitCode) => {
8
14
  process.exitCode = exitCode;
9
15
  }).catch((error: unknown) => {
10
16
  const message = error instanceof Error ? error.message : String(error);
@@ -0,0 +1,186 @@
1
+ import assert from 'node:assert/strict';
2
+ import { execFileSync } from 'node:child_process';
3
+ import { copyFile, mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import test from 'node:test';
7
+ import { fileURLToPath, pathToFileURL } from 'node:url';
8
+
9
+ type BootstrapResult = {
10
+ command: string | null;
11
+ environmentFileReads: number;
12
+ mode: string | null;
13
+ authNextCalled: boolean;
14
+ authStatus: number;
15
+ authenticatedUsername: string | null;
16
+ runtime: string;
17
+ };
18
+
19
+ const RESULT_PREFIX = '__CLOUDCLI_BOOTSTRAP_RESULT__';
20
+ const testDirectory = path.dirname(fileURLToPath(import.meta.url));
21
+ const applicationRoot = path.resolve(testDirectory, '..', '..', '..', '..');
22
+
23
+ function sourceModuleUrl(...segments: string[]): string {
24
+ return pathToFileURL(path.join(applicationRoot, ...segments)).href;
25
+ }
26
+
27
+ async function runCliBootstrapFixture(isPlatform: boolean): Promise<BootstrapResult> {
28
+ const fixtureRoot = await mkdtemp(path.join(os.tmpdir(), 'cloudcli-cli-bootstrap-'));
29
+ const fixtureServerDirectory = path.join(fixtureRoot, 'server');
30
+ const fixtureCliDirectory = path.join(fixtureServerDirectory, 'modules', 'cli');
31
+ const fixtureDatabasePath = path.join(fixtureRoot, 'auth.db');
32
+
33
+ try {
34
+ await mkdir(fixtureCliDirectory, { recursive: true });
35
+ await Promise.all([
36
+ copyFile(
37
+ path.join(applicationRoot, 'server', 'load-env.ts'),
38
+ path.join(fixtureServerDirectory, 'load-env.ts'),
39
+ ),
40
+ copyFile(
41
+ path.join(applicationRoot, 'server', 'modules', 'cli', 'cli.ts'),
42
+ path.join(fixtureCliDirectory, 'cli.ts'),
43
+ ),
44
+ ]);
45
+ await writeFile(
46
+ path.join(fixtureRoot, '.env'),
47
+ [
48
+ `VITE_IS_PLATFORM=${String(isPlatform)}`,
49
+ `DATABASE_PATH=${fixtureDatabasePath.replace(/\\/g, '/')}`,
50
+ ].join('\n'),
51
+ 'utf8',
52
+ );
53
+
54
+ const fixtureIndexSource = `
55
+ import { createCliService } from ${JSON.stringify(sourceModuleUrl('server', 'modules', 'cli', 'cli.service.ts'))};
56
+ import { authenticateToken } from ${JSON.stringify(sourceModuleUrl('server', 'modules', 'auth', 'index.ts'))};
57
+ import { getBrowserUseRuntime } from ${JSON.stringify(sourceModuleUrl('server', 'modules', 'browser-use', 'index.ts'))};
58
+ import { closeConnection, initializeDatabase, userDb } from ${JSON.stringify(sourceModuleUrl('server', 'modules', 'database', 'index.ts'))};
59
+
60
+ let environmentFileReads = 0;
61
+
62
+ export function createCliApplication() {
63
+ const service = createCliService({
64
+ applicationRoot: ${JSON.stringify(fixtureRoot)},
65
+ defaultDatabasePath: ${JSON.stringify(fixtureDatabasePath)},
66
+ homeDirectory: ${JSON.stringify(fixtureRoot)},
67
+ packageMetadata: { version: '1.0.0' },
68
+ environment: process.env,
69
+ fileSystem: {
70
+ readTextFile: () => {
71
+ environmentFileReads += 1;
72
+ return '';
73
+ },
74
+ pathExists: () => false,
75
+ getFileStats: () => ({ size: 0, modifiedAt: new Date(0) }),
76
+ },
77
+ output: { log: () => undefined, error: () => undefined },
78
+ sandboxService: { execute: async () => 0 },
79
+ getLatestPackageVersion: async () => '1.0.0',
80
+ updateGlobalPackage: () => undefined,
81
+ startServer: async () => undefined,
82
+ startBrowserUseMcp: async () => undefined,
83
+ });
84
+
85
+ return {
86
+ async run(argumentsList: string[]) {
87
+ const exitCode = await service.run(argumentsList);
88
+ await initializeDatabase();
89
+ userDb.createUser('bootstrap-user', 'password-hash');
90
+
91
+ const request: any = { headers: {}, query: {} };
92
+ const response: any = {
93
+ statusCode: 200,
94
+ body: null,
95
+ headers: {},
96
+ setHeader(name: string, value: string) {
97
+ this.headers[name] = value;
98
+ },
99
+ status(statusCode: number) {
100
+ this.statusCode = statusCode;
101
+ return this;
102
+ },
103
+ json(body: unknown) {
104
+ this.body = body;
105
+ return this;
106
+ },
107
+ };
108
+ let authNextCalled = false;
109
+ await authenticateToken(request, response, () => {
110
+ authNextCalled = true;
111
+ });
112
+ const runtime = getBrowserUseRuntime();
113
+
114
+ console.log(${JSON.stringify(RESULT_PREFIX)} + JSON.stringify({
115
+ command: argumentsList[0] ?? null,
116
+ environmentFileReads,
117
+ mode: process.env.VITE_IS_PLATFORM ?? null,
118
+ authNextCalled,
119
+ authStatus: response.statusCode,
120
+ authenticatedUsername: request.user?.username ?? null,
121
+ runtime,
122
+ }));
123
+ closeConnection();
124
+ return exitCode;
125
+ },
126
+ };
127
+ }
128
+ `;
129
+ await writeFile(path.join(fixtureCliDirectory, 'index.ts'), fixtureIndexSource, 'utf8');
130
+
131
+ const childEnvironment = { ...process.env };
132
+ delete childEnvironment.VITE_IS_PLATFORM;
133
+ delete childEnvironment.DATABASE_PATH;
134
+ const stdout = execFileSync(
135
+ process.execPath,
136
+ [
137
+ path.join(applicationRoot, 'node_modules', 'tsx', 'dist', 'cli.mjs'),
138
+ '--tsconfig',
139
+ path.join(applicationRoot, 'server', 'tsconfig.json'),
140
+ path.join(fixtureCliDirectory, 'cli.ts'),
141
+ 'status',
142
+ ],
143
+ {
144
+ cwd: applicationRoot,
145
+ encoding: 'utf8',
146
+ env: childEnvironment,
147
+ timeout: 30_000,
148
+ },
149
+ );
150
+ const resultLine = stdout
151
+ .split(/\r?\n/)
152
+ .find((line) => line.startsWith(RESULT_PREFIX));
153
+ assert.ok(resultLine, `Missing bootstrap result in child output:\n${stdout}`);
154
+ return JSON.parse(resultLine.slice(RESULT_PREFIX.length)) as BootstrapResult;
155
+ } finally {
156
+ await rm(fixtureRoot, { recursive: true, force: true });
157
+ }
158
+ }
159
+
160
+ test('CLI bootstrap selects Platform authentication and cloud runtime from .env', async () => {
161
+ const result = await runCliBootstrapFixture(true);
162
+
163
+ assert.deepEqual(result, {
164
+ command: 'status',
165
+ environmentFileReads: 0,
166
+ mode: 'true',
167
+ authNextCalled: true,
168
+ authStatus: 200,
169
+ authenticatedUsername: 'bootstrap-user',
170
+ runtime: 'cloud',
171
+ });
172
+ });
173
+
174
+ test('CLI bootstrap selects OSS authentication and local runtime from .env', async () => {
175
+ const result = await runCliBootstrapFixture(false);
176
+
177
+ assert.deepEqual(result, {
178
+ command: 'status',
179
+ environmentFileReads: 0,
180
+ mode: 'false',
181
+ authNextCalled: false,
182
+ authStatus: 401,
183
+ authenticatedUsername: null,
184
+ runtime: 'local',
185
+ });
186
+ });
@@ -26,9 +26,6 @@ function createHarness() {
26
26
  },
27
27
  environment,
28
28
  fileSystem: {
29
- readTextFile: () => {
30
- throw new Error('missing');
31
- },
32
29
  pathExists: () => false,
33
30
  getFileStats: () => ({ size: 0, modifiedAt: new Date(0) }),
34
31
  },
@@ -10,11 +10,12 @@
10
10
  * `getConnection()` to obtain the shared singleton.
11
11
  */
12
12
 
13
- import Database from 'better-sqlite3';
14
13
  import fs from 'fs';
15
14
  import path from 'path';
16
15
  import { fileURLToPath } from 'url';
17
16
 
17
+ import Database from 'better-sqlite3';
18
+
18
19
  import { APP_CONFIG_TABLE_SCHEMA_SQL } from '@/modules/database/schema.js';
19
20
 
20
21
  const __filename = fileURLToPath(import.meta.url);
@@ -12,6 +12,16 @@ export { providerModelsDb } from '@/modules/database/repositories/provider-model
12
12
  export { projectsDb } from '@/modules/database/repositories/projects.db.js';
13
13
  export { pushSubscriptionsDb } from '@/modules/database/repositories/push-subscriptions.js';
14
14
  export { scanStateDb } from '@/modules/database/repositories/scan-state.db.js';
15
+ // sessionDraftsDb: used by User for drafts and Scheduled Messages for server-owned queued turns.
16
+ export { sessionDraftsDb } from '@/modules/database/repositories/session-drafts.db.js';
17
+ export type {
18
+ QueuedSessionMessageRecord,
19
+ SessionDraftRecord,
20
+ } from '@/modules/database/repositories/session-drafts.db.js';
15
21
  export { sessionsDb } from '@/modules/database/repositories/sessions.db.js';
16
22
  export { userDb } from '@/modules/database/repositories/users.js';
23
+ // userPreferencesDb: used by the User module to persist the settings that used to live in browser localStorage.
24
+ export { userPreferencesDb } from '@/modules/database/repositories/user-preferences.db.js';
17
25
  export { vapidKeysDb } from '@/modules/database/repositories/vapid-keys.js';
26
+ export { scheduledMessagesDb } from './repositories/scheduled-messages.db.js';
27
+ export type { ScheduledMessageRow, ScheduledMessageStatus } from './repositories/scheduled-messages.db.js';