@cloudcli-ai/cloudcli 1.36.3 → 1.37.1

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 (569) hide show
  1. package/dist/assets/index-D3jfzuKN.css +32 -0
  2. package/dist/assets/index-DTMWjJj8.js +1550 -0
  3. package/dist/index.html +2 -2
  4. package/dist-server/server/constants/config.js.map +1 -1
  5. package/dist-server/server/index.js +73 -1224
  6. package/dist-server/server/index.js.map +1 -1
  7. package/dist-server/server/load-env.js +17 -4
  8. package/dist-server/server/load-env.js.map +1 -1
  9. package/dist-server/server/modules/agent/agent.module.js +37 -0
  10. package/dist-server/server/modules/agent/agent.module.js.map +1 -0
  11. package/dist-server/server/modules/agent/agent.routes.js +1161 -0
  12. package/dist-server/server/modules/agent/agent.routes.js.map +1 -0
  13. package/dist-server/server/modules/agent/index.js +3 -0
  14. package/dist-server/server/modules/agent/index.js.map +1 -0
  15. package/dist-server/server/modules/agent/tests/agent.routes.test.js +176 -0
  16. package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -0
  17. package/dist-server/server/modules/assets/assets.routes.js +56 -15
  18. package/dist-server/server/modules/assets/assets.routes.js.map +1 -1
  19. package/dist-server/server/modules/assets/index.js +2 -2
  20. package/dist-server/server/modules/assets/index.js.map +1 -1
  21. package/dist-server/server/modules/assets/services/image-assets.service.js +39 -1
  22. package/dist-server/server/modules/assets/services/image-assets.service.js.map +1 -1
  23. package/dist-server/server/modules/assets/tests/image-assets.service.test.js +21 -1
  24. package/dist-server/server/modules/assets/tests/image-assets.service.test.js.map +1 -1
  25. package/dist-server/server/{middleware/auth.js → modules/auth/auth.middleware.js} +30 -8
  26. package/dist-server/server/modules/auth/auth.middleware.js.map +1 -0
  27. package/dist-server/server/modules/auth/auth.module.js +29 -0
  28. package/dist-server/server/modules/auth/auth.module.js.map +1 -0
  29. package/dist-server/server/modules/auth/auth.routes.js +45 -0
  30. package/dist-server/server/modules/auth/auth.routes.js.map +1 -0
  31. package/dist-server/server/modules/auth/auth.service.js +113 -0
  32. package/dist-server/server/modules/auth/auth.service.js.map +1 -0
  33. package/dist-server/server/modules/auth/index.js +9 -0
  34. package/dist-server/server/modules/auth/index.js.map +1 -0
  35. package/dist-server/server/modules/auth/tests/auth.service.test.js +80 -0
  36. package/dist-server/server/modules/auth/tests/auth.service.test.js.map +1 -0
  37. package/dist-server/server/{browser-use-mcp.js → modules/browser-use/browser-use-mcp.js} +3 -1
  38. package/dist-server/server/modules/browser-use/browser-use-mcp.js.map +1 -0
  39. package/dist-server/server/modules/browser-use/browser-use.service.js +3 -4
  40. package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
  41. package/dist-server/server/modules/browser-use/index.js +9 -0
  42. package/dist-server/server/modules/browser-use/index.js.map +1 -0
  43. package/dist-server/server/modules/cli/cli.js +11 -0
  44. package/dist-server/server/modules/cli/cli.js.map +1 -0
  45. package/dist-server/server/modules/cli/cli.module.js +86 -0
  46. package/dist-server/server/modules/cli/cli.module.js.map +1 -0
  47. package/dist-server/server/modules/cli/cli.service.js +244 -0
  48. package/dist-server/server/modules/cli/cli.service.js.map +1 -0
  49. package/dist-server/server/modules/cli/index.js +3 -0
  50. package/dist-server/server/modules/cli/index.js.map +1 -0
  51. package/dist-server/server/modules/cli/sandbox.service.js +332 -0
  52. package/dist-server/server/modules/cli/sandbox.service.js.map +1 -0
  53. package/dist-server/server/modules/cli/tests/cli.service.test.js +78 -0
  54. package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -0
  55. package/dist-server/server/modules/cli/tests/sandbox.service.test.js +55 -0
  56. package/dist-server/server/modules/cli/tests/sandbox.service.test.js.map +1 -0
  57. package/dist-server/server/modules/commands/commands.module.js +20 -0
  58. package/dist-server/server/modules/commands/commands.module.js.map +1 -0
  59. package/dist-server/server/modules/commands/commands.routes.js +497 -0
  60. package/dist-server/server/modules/commands/commands.routes.js.map +1 -0
  61. package/dist-server/server/modules/commands/index.js +3 -0
  62. package/dist-server/server/modules/commands/index.js.map +1 -0
  63. package/dist-server/server/modules/commands/tests/commands.test.js +91 -0
  64. package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -0
  65. package/dist-server/server/modules/database/index.js +3 -0
  66. package/dist-server/server/modules/database/index.js.map +1 -1
  67. package/dist-server/server/modules/database/migrations.js +31 -1
  68. package/dist-server/server/modules/database/migrations.js.map +1 -1
  69. package/dist-server/server/modules/database/repositories/provider-models.js +112 -0
  70. package/dist-server/server/modules/database/repositories/provider-models.js.map +1 -0
  71. package/dist-server/server/modules/database/repositories/sessions.db.js +76 -7
  72. package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
  73. package/dist-server/server/modules/database/schema.js +29 -0
  74. package/dist-server/server/modules/database/schema.js.map +1 -1
  75. package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js +102 -0
  76. package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js.map +1 -0
  77. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +2 -1
  78. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js.map +1 -1
  79. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js +22 -0
  80. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -1
  81. package/dist-server/server/modules/file-tree/file-tree.module.js +95 -0
  82. package/dist-server/server/modules/file-tree/file-tree.module.js.map +1 -0
  83. package/dist-server/server/modules/file-tree/file-tree.routes.js +208 -0
  84. package/dist-server/server/modules/file-tree/file-tree.routes.js.map +1 -0
  85. package/dist-server/server/modules/file-tree/file-tree.service.js +576 -0
  86. package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -0
  87. package/dist-server/server/modules/file-tree/index.js +3 -0
  88. package/dist-server/server/modules/file-tree/index.js.map +1 -0
  89. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js +123 -0
  90. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js.map +1 -0
  91. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +260 -0
  92. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -0
  93. package/dist-server/server/modules/git/git-parsing.service.js +61 -0
  94. package/dist-server/server/modules/git/git-parsing.service.js.map +1 -0
  95. package/dist-server/server/modules/git/git.module.js +14 -0
  96. package/dist-server/server/modules/git/git.module.js.map +1 -0
  97. package/dist-server/server/modules/git/git.routes.js +1339 -0
  98. package/dist-server/server/modules/git/git.routes.js.map +1 -0
  99. package/dist-server/server/modules/git/index.js +3 -0
  100. package/dist-server/server/modules/git/index.js.map +1 -0
  101. package/dist-server/server/modules/git/tests/git-init.routes.test.js +48 -0
  102. package/dist-server/server/modules/git/tests/git-init.routes.test.js.map +1 -0
  103. package/dist-server/server/{routes → modules/git/tests}/git.test.js +1 -1
  104. package/dist-server/server/modules/git/tests/git.test.js.map +1 -0
  105. package/dist-server/server/modules/notifications/index.js +15 -1
  106. package/dist-server/server/modules/notifications/index.js.map +1 -1
  107. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js +44 -0
  108. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js.map +1 -0
  109. package/dist-server/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.js} +3 -2
  110. package/dist-server/server/modules/notifications/vapid-keys.service.js.map +1 -0
  111. package/dist-server/server/modules/plugins/index.js +9 -0
  112. package/dist-server/server/modules/plugins/index.js.map +1 -0
  113. package/dist-server/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.js} +3 -2
  114. package/dist-server/server/modules/plugins/plugin-process.service.js.map +1 -0
  115. package/dist-server/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.js} +2 -1
  116. package/dist-server/server/modules/plugins/plugin-registry.service.js.map +1 -0
  117. package/dist-server/server/modules/plugins/plugins.module.js +30 -0
  118. package/dist-server/server/modules/plugins/plugins.module.js.map +1 -0
  119. package/dist-server/server/modules/plugins/plugins.routes.js +70 -0
  120. package/dist-server/server/modules/plugins/plugins.routes.js.map +1 -0
  121. package/dist-server/server/modules/plugins/plugins.service.js +123 -0
  122. package/dist-server/server/modules/plugins/plugins.service.js.map +1 -0
  123. package/dist-server/server/modules/plugins/tests/plugins.service.test.js +28 -0
  124. package/dist-server/server/modules/plugins/tests/plugins.service.test.js.map +1 -0
  125. package/dist-server/server/modules/projects/index.js +5 -0
  126. package/dist-server/server/modules/projects/index.js.map +1 -1
  127. package/dist-server/server/modules/providers/index.js +3 -0
  128. package/dist-server/server/modules/providers/index.js.map +1 -1
  129. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +6 -0
  130. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -1
  131. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +47 -18
  132. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
  133. package/dist-server/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +69 -55
  134. package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -0
  135. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +6 -4
  136. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -1
  137. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +23 -4
  138. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
  139. package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
  140. package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
  141. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +59 -75
  142. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
  143. package/dist-server/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +48 -34
  144. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -0
  145. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js +1 -54
  146. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -1
  147. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +290 -6
  148. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
  149. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +5 -0
  150. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -1
  151. package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
  152. package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
  153. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +33 -673
  154. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -1
  155. package/dist-server/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +40 -28
  156. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -0
  157. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +21 -14
  158. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -1
  159. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +2 -0
  160. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -1
  161. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +112 -333
  162. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
  163. package/dist-server/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +38 -25
  164. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js.map +1 -0
  165. package/dist-server/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +27 -4
  166. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js.map +1 -0
  167. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +0 -12
  168. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js.map +1 -1
  169. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +11 -5
  170. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -1
  171. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js +2 -0
  172. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js.map +1 -1
  173. package/dist-server/server/modules/providers/provider.routes.js +169 -37
  174. package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
  175. package/dist-server/server/modules/providers/services/provider-capabilities.service.js +5 -1
  176. package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
  177. package/dist-server/server/modules/providers/services/provider-models.service.js +247 -184
  178. package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
  179. package/dist-server/server/modules/providers/services/provider-runtime.service.js +66 -0
  180. package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -0
  181. package/dist-server/server/modules/providers/services/provider-token-usage.service.js +268 -0
  182. package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -0
  183. package/dist-server/server/modules/providers/services/session-conversations-search.service.js +12 -4
  184. package/dist-server/server/modules/providers/services/session-conversations-search.service.js.map +1 -1
  185. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +2 -0
  186. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
  187. package/dist-server/server/modules/providers/services/sessions.service.js +116 -3
  188. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
  189. package/dist-server/server/modules/providers/shared/base/abstract.provider.js +2 -3
  190. package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -1
  191. package/dist-server/server/modules/providers/tests/claude-auth.test.js +122 -0
  192. package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -0
  193. package/dist-server/server/modules/providers/tests/claude-sessions.test.js +44 -0
  194. package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -0
  195. package/dist-server/server/modules/providers/tests/codex-sessions.test.js +76 -4
  196. package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
  197. package/dist-server/server/modules/providers/tests/opencode-models.test.js +15 -126
  198. package/dist-server/server/modules/providers/tests/opencode-models.test.js.map +1 -1
  199. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +5 -5
  200. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -1
  201. package/dist-server/server/modules/providers/tests/{provider-image-history.test.js → provider-attachment-history.test.js} +60 -2
  202. package/dist-server/server/modules/providers/tests/provider-attachment-history.test.js.map +1 -0
  203. package/dist-server/server/modules/providers/tests/provider-models.service.test.js +241 -271
  204. package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
  205. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +126 -0
  206. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -0
  207. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +166 -0
  208. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -0
  209. package/dist-server/server/modules/providers/tests/provider.routes.test.js +126 -0
  210. package/dist-server/server/modules/providers/tests/provider.routes.test.js.map +1 -0
  211. package/dist-server/server/modules/providers/tests/sessions-details.test.js +62 -0
  212. package/dist-server/server/modules/providers/tests/sessions-details.test.js.map +1 -0
  213. package/dist-server/server/modules/providers/tests/sessions.service.test.js +87 -0
  214. package/dist-server/server/modules/providers/tests/sessions.service.test.js.map +1 -0
  215. package/dist-server/server/modules/providers/tests/skills.test.js +4 -2
  216. package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
  217. package/dist-server/server/modules/settings/index.js +3 -0
  218. package/dist-server/server/modules/settings/index.js.map +1 -0
  219. package/dist-server/server/modules/settings/settings.module.js +35 -0
  220. package/dist-server/server/modules/settings/settings.module.js.map +1 -0
  221. package/dist-server/server/modules/settings/settings.routes.js +34 -0
  222. package/dist-server/server/modules/settings/settings.routes.js.map +1 -0
  223. package/dist-server/server/modules/settings/settings.service.js +116 -0
  224. package/dist-server/server/modules/settings/settings.service.js.map +1 -0
  225. package/dist-server/server/modules/settings/tests/settings.service.test.js +48 -0
  226. package/dist-server/server/modules/settings/tests/settings.service.test.js.map +1 -0
  227. package/dist-server/server/modules/system/index.js +3 -0
  228. package/dist-server/server/modules/system/index.js.map +1 -0
  229. package/dist-server/server/modules/system/system.module.js +44 -0
  230. package/dist-server/server/modules/system/system.module.js.map +1 -0
  231. package/dist-server/server/modules/system/system.routes.js +16 -0
  232. package/dist-server/server/modules/system/system.routes.js.map +1 -0
  233. package/dist-server/server/modules/system/system.service.js +45 -0
  234. package/dist-server/server/modules/system/system.service.js.map +1 -0
  235. package/dist-server/server/modules/system/tests/system.service.test.js +100 -0
  236. package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -0
  237. package/dist-server/server/modules/taskmaster/index.js +3 -0
  238. package/dist-server/server/modules/taskmaster/index.js.map +1 -0
  239. package/dist-server/server/modules/taskmaster/taskmaster.module.js +20 -0
  240. package/dist-server/server/modules/taskmaster/taskmaster.module.js.map +1 -0
  241. package/dist-server/server/modules/taskmaster/taskmaster.routes.js +1372 -0
  242. package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -0
  243. package/dist-server/server/modules/taskmaster/taskmaster.service.js +107 -0
  244. package/dist-server/server/modules/taskmaster/taskmaster.service.js.map +1 -0
  245. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +132 -0
  246. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -0
  247. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js +85 -0
  248. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js.map +1 -0
  249. package/dist-server/server/modules/user/index.js +3 -0
  250. package/dist-server/server/modules/user/index.js.map +1 -0
  251. package/dist-server/server/modules/user/tests/user.service.test.js +53 -0
  252. package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -0
  253. package/dist-server/server/modules/user/user.module.js +47 -0
  254. package/dist-server/server/modules/user/user.module.js.map +1 -0
  255. package/dist-server/server/modules/user/user.routes.js +44 -0
  256. package/dist-server/server/modules/user/user.routes.js.map +1 -0
  257. package/dist-server/server/modules/user/user.service.js +59 -0
  258. package/dist-server/server/modules/user/user.service.js.map +1 -0
  259. package/dist-server/server/modules/voice/index.js +3 -0
  260. package/dist-server/server/modules/voice/index.js.map +1 -0
  261. package/dist-server/server/modules/voice/tests/voice.service.test.js +86 -0
  262. package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -0
  263. package/dist-server/server/modules/voice/voice.module.js +44 -0
  264. package/dist-server/server/modules/voice/voice.module.js.map +1 -0
  265. package/dist-server/server/modules/voice/voice.routes.js +87 -0
  266. package/dist-server/server/modules/voice/voice.routes.js.map +1 -0
  267. package/dist-server/server/modules/voice/voice.service.js +148 -0
  268. package/dist-server/server/modules/voice/voice.service.js.map +1 -0
  269. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +2 -2
  270. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +44 -29
  271. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
  272. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +76 -8
  273. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
  274. package/dist-server/server/modules/websocket/services/websocket-server.service.js +51 -20
  275. package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -1
  276. package/dist-server/server/modules/websocket/tests/{chat-image-filter.test.js → chat-attachment-filter.test.js} +10 -3
  277. package/dist-server/server/modules/websocket/tests/chat-attachment-filter.test.js.map +1 -0
  278. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +97 -0
  279. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -0
  280. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js +61 -0
  281. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js.map +1 -0
  282. package/dist-server/server/modules/worktrees/index.js +3 -0
  283. package/dist-server/server/modules/worktrees/index.js.map +1 -0
  284. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js +37 -0
  285. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js.map +1 -0
  286. package/dist-server/server/modules/worktrees/services/worktree-create.service.js +67 -0
  287. package/dist-server/server/modules/worktrees/services/worktree-create.service.js.map +1 -0
  288. package/dist-server/server/modules/worktrees/services/worktree-git.service.js +172 -0
  289. package/dist-server/server/modules/worktrees/services/worktree-git.service.js.map +1 -0
  290. package/dist-server/server/modules/worktrees/services/worktree-list.service.js +91 -0
  291. package/dist-server/server/modules/worktrees/services/worktree-list.service.js.map +1 -0
  292. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js +118 -0
  293. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js.map +1 -0
  294. package/dist-server/server/modules/worktrees/services/worktree-open.service.js +58 -0
  295. package/dist-server/server/modules/worktrees/services/worktree-open.service.js.map +1 -0
  296. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +65 -0
  297. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js.map +1 -0
  298. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js +58 -0
  299. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js.map +1 -0
  300. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js +85 -0
  301. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js.map +1 -0
  302. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js +58 -0
  303. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js.map +1 -0
  304. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js +34 -0
  305. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js.map +1 -0
  306. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js +137 -0
  307. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js.map +1 -0
  308. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js +99 -0
  309. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js.map +1 -0
  310. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js +157 -0
  311. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js.map +1 -0
  312. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js +167 -0
  313. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js.map +1 -0
  314. package/dist-server/server/modules/worktrees/worktrees.module.js +97 -0
  315. package/dist-server/server/modules/worktrees/worktrees.module.js.map +1 -0
  316. package/dist-server/server/modules/worktrees/worktrees.routes.js +84 -0
  317. package/dist-server/server/modules/worktrees/worktrees.routes.js.map +1 -0
  318. package/dist-server/server/shared/image-attachments.js +90 -17
  319. package/dist-server/server/shared/image-attachments.js.map +1 -1
  320. package/dist-server/server/shared/tests/image-attachments.test.js +43 -1
  321. package/dist-server/server/shared/tests/image-attachments.test.js.map +1 -1
  322. package/dist-server/server/shared/utils.js +66 -142
  323. package/dist-server/server/shared/utils.js.map +1 -1
  324. package/package.json +9 -5
  325. package/server/index.ts +401 -0
  326. package/server/{load-env.js → load-env.ts} +18 -5
  327. package/server/modules/agent/agent.module.ts +51 -0
  328. package/server/modules/agent/agent.routes.ts +1287 -0
  329. package/server/modules/agent/index.ts +2 -0
  330. package/server/modules/agent/tests/agent.routes.test.ts +205 -0
  331. package/server/modules/assets/assets.routes.ts +63 -16
  332. package/server/modules/assets/index.ts +2 -2
  333. package/server/modules/assets/services/image-assets.service.ts +46 -1
  334. package/server/modules/assets/tests/image-assets.service.test.ts +28 -0
  335. package/server/{middleware/auth.js → modules/auth/auth.middleware.ts} +38 -7
  336. package/server/modules/auth/auth.module.ts +38 -0
  337. package/server/modules/auth/auth.routes.ts +57 -0
  338. package/server/modules/auth/auth.service.ts +155 -0
  339. package/server/modules/auth/index.ts +9 -0
  340. package/server/modules/auth/tests/auth.service.test.ts +95 -0
  341. package/server/{browser-use-mcp.ts → modules/browser-use/browser-use-mcp.ts} +3 -1
  342. package/server/modules/browser-use/browser-use.service.ts +3 -4
  343. package/server/modules/browser-use/index.ts +8 -0
  344. package/server/modules/cli/cli.module.ts +96 -0
  345. package/server/modules/cli/cli.service.ts +281 -0
  346. package/server/modules/cli/cli.ts +13 -0
  347. package/server/modules/cli/index.ts +2 -0
  348. package/server/modules/cli/sandbox.service.ts +413 -0
  349. package/server/modules/cli/tests/cli.service.test.ts +91 -0
  350. package/server/modules/cli/tests/sandbox.service.test.ts +61 -0
  351. package/server/modules/commands/commands.module.ts +22 -0
  352. package/server/{routes/commands.js → modules/commands/commands.routes.ts} +46 -38
  353. package/server/modules/commands/index.ts +2 -0
  354. package/server/modules/commands/tests/commands.test.ts +114 -0
  355. package/server/modules/database/index.ts +3 -0
  356. package/server/modules/database/migrations.ts +35 -0
  357. package/server/modules/database/repositories/provider-models.ts +168 -0
  358. package/server/modules/database/repositories/sessions.db.ts +103 -8
  359. package/server/modules/database/schema.ts +30 -0
  360. package/server/modules/database/tests/provider-models.db.integration.test.ts +125 -0
  361. package/server/modules/database/tests/sessions-provider-mapping.test.ts +2 -1
  362. package/server/modules/database/tests/sessions.db.integration.test.ts +32 -0
  363. package/server/modules/file-tree/file-tree.module.ts +116 -0
  364. package/server/modules/file-tree/file-tree.routes.ts +258 -0
  365. package/server/modules/file-tree/file-tree.service.ts +664 -0
  366. package/server/modules/file-tree/index.ts +2 -0
  367. package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -0
  368. package/server/modules/file-tree/tests/file-tree.service.test.ts +317 -0
  369. package/server/modules/git/git-parsing.service.ts +66 -0
  370. package/server/modules/git/git.module.ts +22 -0
  371. package/server/{routes/git.js → modules/git/git.routes.ts} +91 -132
  372. package/server/modules/git/index.ts +2 -0
  373. package/server/modules/git/tests/git-init.routes.test.ts +52 -0
  374. package/server/{routes/git.test.js → modules/git/tests/git.test.ts} +3 -3
  375. package/server/modules/notifications/index.ts +9 -0
  376. package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -0
  377. package/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.ts} +3 -1
  378. package/server/modules/plugins/index.ts +9 -0
  379. package/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.ts} +3 -1
  380. package/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.ts} +1 -0
  381. package/server/modules/plugins/plugins.module.ts +33 -0
  382. package/server/modules/plugins/plugins.routes.ts +66 -0
  383. package/server/modules/plugins/plugins.service.ts +147 -0
  384. package/server/modules/plugins/tests/plugins.service.test.ts +32 -0
  385. package/server/modules/projects/index.ts +5 -0
  386. package/server/modules/providers/README.md +41 -9
  387. package/server/modules/providers/index.ts +4 -0
  388. package/server/modules/providers/list/claude/claude-auth.provider.ts +8 -0
  389. package/server/modules/providers/list/claude/claude-models.provider.ts +47 -26
  390. package/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +73 -59
  391. package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +6 -4
  392. package/server/modules/providers/list/claude/claude-sessions.provider.ts +27 -4
  393. package/server/modules/providers/list/claude/claude.provider.ts +3 -0
  394. package/server/modules/providers/list/codex/codex-models.provider.ts +58 -108
  395. package/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +54 -36
  396. package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +1 -60
  397. package/server/modules/providers/list/codex/codex-sessions.provider.ts +331 -7
  398. package/server/modules/providers/list/codex/codex-skills.provider.ts +5 -0
  399. package/server/modules/providers/list/codex/codex.provider.ts +3 -0
  400. package/server/modules/providers/list/cursor/cursor-models.provider.ts +32 -719
  401. package/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +58 -27
  402. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +26 -15
  403. package/server/modules/providers/list/cursor/cursor.provider.ts +3 -0
  404. package/server/modules/providers/list/opencode/opencode-models.provider.ts +112 -423
  405. package/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +56 -28
  406. package/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +41 -3
  407. package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +0 -13
  408. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +13 -5
  409. package/server/modules/providers/list/opencode/opencode.provider.ts +3 -0
  410. package/server/modules/providers/provider.routes.ts +228 -39
  411. package/server/modules/providers/services/provider-capabilities.service.ts +7 -1
  412. package/server/modules/providers/services/provider-models.service.ts +312 -269
  413. package/server/modules/providers/services/provider-runtime.service.ts +108 -0
  414. package/server/modules/providers/services/provider-token-usage.service.ts +357 -0
  415. package/server/modules/providers/services/session-conversations-search.service.ts +12 -4
  416. package/server/modules/providers/services/sessions-watcher.service.ts +2 -0
  417. package/server/modules/providers/services/sessions.service.ts +166 -3
  418. package/server/modules/providers/shared/base/abstract.provider.ts +4 -3
  419. package/server/modules/providers/tests/claude-auth.test.ts +150 -0
  420. package/server/modules/providers/tests/claude-sessions.test.ts +61 -0
  421. package/server/modules/providers/tests/codex-sessions.test.ts +83 -4
  422. package/server/modules/providers/tests/opencode-models.test.ts +34 -135
  423. package/server/modules/providers/tests/opencode-sessions.test.ts +5 -5
  424. package/server/modules/providers/tests/{provider-image-history.test.ts → provider-attachment-history.test.ts} +68 -1
  425. package/server/modules/providers/tests/provider-models.service.test.ts +300 -296
  426. package/server/modules/providers/tests/provider-runtime.service.test.ts +138 -0
  427. package/server/modules/providers/tests/provider-token-usage.service.test.ts +186 -0
  428. package/server/modules/providers/tests/provider.routes.test.ts +183 -0
  429. package/server/modules/providers/tests/sessions-details.test.ts +73 -0
  430. package/server/modules/providers/tests/sessions.service.test.ts +127 -0
  431. package/server/modules/providers/tests/skills.test.ts +9 -2
  432. package/server/modules/settings/index.ts +2 -0
  433. package/server/modules/settings/settings.module.ts +50 -0
  434. package/server/modules/settings/settings.routes.ts +51 -0
  435. package/server/modules/settings/settings.service.ts +186 -0
  436. package/server/modules/settings/tests/settings.service.test.ts +54 -0
  437. package/server/modules/system/index.ts +2 -0
  438. package/server/modules/system/system.module.ts +62 -0
  439. package/server/modules/system/system.routes.ts +21 -0
  440. package/server/modules/system/system.service.ts +76 -0
  441. package/server/modules/system/tests/system.service.test.ts +118 -0
  442. package/server/modules/taskmaster/index.ts +2 -0
  443. package/server/modules/taskmaster/taskmaster.module.ts +24 -0
  444. package/server/modules/taskmaster/taskmaster.routes.ts +1482 -0
  445. package/server/modules/taskmaster/taskmaster.service.ts +132 -0
  446. package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -0
  447. package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -0
  448. package/server/modules/user/index.ts +2 -0
  449. package/server/modules/user/tests/user.service.test.ts +61 -0
  450. package/server/modules/user/user.module.ts +58 -0
  451. package/server/modules/user/user.routes.ts +50 -0
  452. package/server/modules/user/user.service.ts +85 -0
  453. package/server/modules/voice/index.ts +2 -0
  454. package/server/modules/voice/tests/voice.service.test.ts +98 -0
  455. package/server/modules/voice/voice.module.ts +47 -0
  456. package/server/modules/voice/voice.routes.ts +113 -0
  457. package/server/modules/voice/voice.service.ts +192 -0
  458. package/server/modules/websocket/README.md +7 -7
  459. package/server/modules/websocket/services/chat-session-writer.service.ts +2 -2
  460. package/server/modules/websocket/services/chat-websocket.service.ts +77 -61
  461. package/server/modules/websocket/services/shell-websocket.service.ts +88 -12
  462. package/server/modules/websocket/services/websocket-server.service.ts +63 -19
  463. package/server/modules/websocket/tests/{chat-image-filter.test.ts → chat-attachment-filter.test.ts} +17 -2
  464. package/server/modules/websocket/tests/shell-websocket.service.test.ts +119 -0
  465. package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -0
  466. package/server/modules/worktrees/index.ts +2 -0
  467. package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -0
  468. package/server/modules/worktrees/services/worktree-create.service.ts +104 -0
  469. package/server/modules/worktrees/services/worktree-git.service.ts +207 -0
  470. package/server/modules/worktrees/services/worktree-list.service.ts +143 -0
  471. package/server/modules/worktrees/services/worktree-merge.service.ts +157 -0
  472. package/server/modules/worktrees/services/worktree-open.service.ts +85 -0
  473. package/server/modules/worktrees/services/worktree-remove.service.ts +88 -0
  474. package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -0
  475. package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -0
  476. package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -0
  477. package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -0
  478. package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -0
  479. package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -0
  480. package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -0
  481. package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -0
  482. package/server/modules/worktrees/worktrees.module.ts +113 -0
  483. package/server/modules/worktrees/worktrees.routes.ts +116 -0
  484. package/server/shared/image-attachments.ts +112 -18
  485. package/server/shared/interfaces.ts +33 -25
  486. package/server/shared/tests/image-attachments.test.ts +55 -0
  487. package/server/shared/types.ts +685 -36
  488. package/server/shared/utils.ts +77 -212
  489. package/dist/assets/index-CcCsKitq.js +0 -1423
  490. package/dist/assets/index-DLmhQ15L.css +0 -32
  491. package/dist-server/server/browser-use-mcp.js.map +0 -1
  492. package/dist-server/server/claude-sdk.js.map +0 -1
  493. package/dist-server/server/cli.js +0 -647
  494. package/dist-server/server/cli.js.map +0 -1
  495. package/dist-server/server/cursor-cli.js.map +0 -1
  496. package/dist-server/server/middleware/auth.js.map +0 -1
  497. package/dist-server/server/modules/providers/tests/provider-image-history.test.js.map +0 -1
  498. package/dist-server/server/modules/websocket/tests/chat-image-filter.test.js.map +0 -1
  499. package/dist-server/server/openai-codex.js.map +0 -1
  500. package/dist-server/server/opencode-cli.js.map +0 -1
  501. package/dist-server/server/opencode-cli.test.js.map +0 -1
  502. package/dist-server/server/routes/agent.js +0 -1155
  503. package/dist-server/server/routes/agent.js.map +0 -1
  504. package/dist-server/server/routes/auth.js +0 -119
  505. package/dist-server/server/routes/auth.js.map +0 -1
  506. package/dist-server/server/routes/commands.js +0 -492
  507. package/dist-server/server/routes/commands.js.map +0 -1
  508. package/dist-server/server/routes/cursor.js +0 -49
  509. package/dist-server/server/routes/cursor.js.map +0 -1
  510. package/dist-server/server/routes/git.js +0 -1389
  511. package/dist-server/server/routes/git.js.map +0 -1
  512. package/dist-server/server/routes/git.test.js.map +0 -1
  513. package/dist-server/server/routes/mcp-utils.js +0 -29
  514. package/dist-server/server/routes/mcp-utils.js.map +0 -1
  515. package/dist-server/server/routes/plugins.js +0 -266
  516. package/dist-server/server/routes/plugins.js.map +0 -1
  517. package/dist-server/server/routes/settings.js +0 -249
  518. package/dist-server/server/routes/settings.js.map +0 -1
  519. package/dist-server/server/routes/taskmaster.js +0 -1362
  520. package/dist-server/server/routes/taskmaster.js.map +0 -1
  521. package/dist-server/server/routes/tests/commands.test.js +0 -76
  522. package/dist-server/server/routes/tests/commands.test.js.map +0 -1
  523. package/dist-server/server/routes/user.js +0 -116
  524. package/dist-server/server/routes/user.js.map +0 -1
  525. package/dist-server/server/services/notification-orchestrator.js +0 -2
  526. package/dist-server/server/services/notification-orchestrator.js.map +0 -1
  527. package/dist-server/server/services/tests/notification-orchestrator.test.js +0 -64
  528. package/dist-server/server/services/tests/notification-orchestrator.test.js.map +0 -1
  529. package/dist-server/server/services/vapid-keys.js.map +0 -1
  530. package/dist-server/server/utils/colors.js +0 -20
  531. package/dist-server/server/utils/colors.js.map +0 -1
  532. package/dist-server/server/utils/commandParser.js +0 -255
  533. package/dist-server/server/utils/commandParser.js.map +0 -1
  534. package/dist-server/server/utils/gitConfig.js +0 -37
  535. package/dist-server/server/utils/gitConfig.js.map +0 -1
  536. package/dist-server/server/utils/mcp-detector.js +0 -134
  537. package/dist-server/server/utils/mcp-detector.js.map +0 -1
  538. package/dist-server/server/utils/plugin-loader.js.map +0 -1
  539. package/dist-server/server/utils/plugin-process-manager.js.map +0 -1
  540. package/dist-server/server/utils/runtime-paths.js +0 -30
  541. package/dist-server/server/utils/runtime-paths.js.map +0 -1
  542. package/dist-server/server/utils/taskmaster-websocket.js +0 -124
  543. package/dist-server/server/utils/taskmaster-websocket.js.map +0 -1
  544. package/dist-server/server/utils/url-detection.js +0 -58
  545. package/dist-server/server/utils/url-detection.js.map +0 -1
  546. package/dist-server/server/voice-proxy.js +0 -226
  547. package/dist-server/server/voice-proxy.js.map +0 -1
  548. package/server/cli.js +0 -695
  549. package/server/index.js +0 -1651
  550. package/server/routes/agent.js +0 -1257
  551. package/server/routes/auth.js +0 -137
  552. package/server/routes/cursor.js +0 -52
  553. package/server/routes/mcp-utils.js +0 -31
  554. package/server/routes/plugins.js +0 -307
  555. package/server/routes/settings.js +0 -282
  556. package/server/routes/taskmaster.js +0 -1470
  557. package/server/routes/tests/commands.test.js +0 -82
  558. package/server/routes/user.js +0 -124
  559. package/server/services/notification-orchestrator.js +0 -7
  560. package/server/services/tests/notification-orchestrator.test.js +0 -80
  561. package/server/utils/colors.js +0 -21
  562. package/server/utils/commandParser.js +0 -305
  563. package/server/utils/gitConfig.js +0 -35
  564. package/server/utils/mcp-detector.js +0 -147
  565. package/server/utils/runtime-paths.js +0 -37
  566. package/server/utils/taskmaster-websocket.js +0 -135
  567. package/server/utils/url-detection.js +0 -71
  568. package/server/voice-proxy.js +0 -224
  569. /package/server/constants/{config.js → config.ts} +0 -0
@@ -0,0 +1,155 @@
1
+ import { AppError } from '@/shared/utils.js';
2
+
3
+ type AuthUser = {
4
+ id: number | bigint;
5
+ username: string;
6
+ };
7
+
8
+ type AuthLoginUser = AuthUser & { password_hash: string };
9
+
10
+ type AuthDependencies = {
11
+ users: {
12
+ hasUsers(): boolean;
13
+ createUser(username: string, passwordHash: string): AuthUser;
14
+ getUserByUsername(username: string): AuthLoginUser | undefined;
15
+ updateLastLogin(userId: number): void;
16
+ };
17
+ transaction: {
18
+ begin(): void;
19
+ commit(): void;
20
+ rollback(): void;
21
+ };
22
+ hashPassword(password: string): Promise<string>;
23
+ comparePassword(password: string, passwordHash: string): Promise<boolean>;
24
+ generateToken(user: AuthUser): string;
25
+ };
26
+
27
+ function numericUserId(userId: number | bigint): number {
28
+ return Number(userId);
29
+ }
30
+
31
+ function isUniqueConstraintError(error: unknown): boolean {
32
+ return typeof error === 'object'
33
+ && error !== null
34
+ && 'code' in error
35
+ && error.code === 'SQLITE_CONSTRAINT_UNIQUE';
36
+ }
37
+
38
+ /**
39
+ * Creates the Auth application service around explicit persistence, crypto,
40
+ * transaction, and token dependencies.
41
+ */
42
+ export function createAuthService(dependencies: AuthDependencies) {
43
+ return {
44
+ getStatus() {
45
+ return {
46
+ needsSetup: !dependencies.users.hasUsers(),
47
+ isAuthenticated: false,
48
+ };
49
+ },
50
+
51
+ async register(usernameInput: unknown, passwordInput: unknown) {
52
+ const username = typeof usernameInput === 'string' ? usernameInput : '';
53
+ const password = typeof passwordInput === 'string' ? passwordInput : '';
54
+
55
+ if (!username || !password) {
56
+ throw new AppError('Username and password are required', {
57
+ code: 'AUTH_CREDENTIALS_REQUIRED',
58
+ statusCode: 400,
59
+ });
60
+ }
61
+ if (username.length < 3 || password.length < 6) {
62
+ throw new AppError(
63
+ 'Username must be at least 3 characters, password at least 6 characters',
64
+ { code: 'AUTH_CREDENTIALS_TOO_SHORT', statusCode: 400 },
65
+ );
66
+ }
67
+
68
+ dependencies.transaction.begin();
69
+ try {
70
+ if (dependencies.users.hasUsers()) {
71
+ throw new AppError('User already exists. This is a single-user system.', {
72
+ code: 'AUTH_USER_ALREADY_CONFIGURED',
73
+ statusCode: 403,
74
+ });
75
+ }
76
+
77
+ const passwordHash = await dependencies.hashPassword(password);
78
+ const user = dependencies.users.createUser(username, passwordHash);
79
+ const token = dependencies.generateToken(user);
80
+ dependencies.transaction.commit();
81
+ dependencies.users.updateLastLogin(numericUserId(user.id));
82
+
83
+ return {
84
+ success: true,
85
+ user: { id: user.id, username: user.username },
86
+ token,
87
+ };
88
+ } catch (error) {
89
+ dependencies.transaction.rollback();
90
+ if (isUniqueConstraintError(error)) {
91
+ throw new AppError('Username already exists', {
92
+ code: 'AUTH_USERNAME_CONFLICT',
93
+ statusCode: 409,
94
+ });
95
+ }
96
+ throw error;
97
+ }
98
+ },
99
+
100
+ async login(usernameInput: unknown, passwordInput: unknown) {
101
+ const username = typeof usernameInput === 'string' ? usernameInput : '';
102
+ const password = typeof passwordInput === 'string' ? passwordInput : '';
103
+ if (!username || !password) {
104
+ throw new AppError('Username and password are required', {
105
+ code: 'AUTH_CREDENTIALS_REQUIRED',
106
+ statusCode: 400,
107
+ });
108
+ }
109
+
110
+ const user = dependencies.users.getUserByUsername(username);
111
+ const validPassword = user
112
+ ? await dependencies.comparePassword(password, user.password_hash)
113
+ : false;
114
+ if (!user || !validPassword) {
115
+ throw new AppError('Invalid username or password', {
116
+ code: 'AUTH_INVALID_CREDENTIALS',
117
+ statusCode: 401,
118
+ });
119
+ }
120
+
121
+ dependencies.users.updateLastLogin(numericUserId(user.id));
122
+ return {
123
+ success: true,
124
+ user: { id: user.id, username: user.username },
125
+ token: dependencies.generateToken(user),
126
+ };
127
+ },
128
+
129
+ getCurrentUser(user: unknown) {
130
+ return { user };
131
+ },
132
+
133
+ refreshSession(user: unknown) {
134
+ if (
135
+ typeof user !== 'object'
136
+ || user === null
137
+ || !('id' in user)
138
+ || !('username' in user)
139
+ || (typeof user.id !== 'number' && typeof user.id !== 'bigint')
140
+ || typeof user.username !== 'string'
141
+ ) {
142
+ throw new AppError('Authenticated user is required', {
143
+ code: 'AUTH_USER_REQUIRED',
144
+ statusCode: 401,
145
+ });
146
+ }
147
+
148
+ return { token: dependencies.generateToken(user as AuthUser) };
149
+ },
150
+
151
+ logout() {
152
+ return { success: true, message: 'Logged out successfully' };
153
+ },
154
+ };
155
+ }
@@ -0,0 +1,9 @@
1
+ // authRoutes: used by the server entrypoint to mount public authentication endpoints.
2
+ export { authRoutes } from './auth.module.js';
3
+
4
+ // authenticateToken: used by the server entrypoint to protect authenticated API modules.
5
+ export { authenticateToken } from './auth.middleware.js';
6
+ // authenticateWebSocket: used by WebSocket setup to verify connection tokens.
7
+ export { authenticateWebSocket } from './auth.middleware.js';
8
+ // validateApiKey: used by the server entrypoint for optional API-wide key validation.
9
+ export { validateApiKey } from './auth.middleware.js';
@@ -0,0 +1,95 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+
4
+ import { AppError } from '@/shared/utils.js';
5
+
6
+ import { createAuthService } from '../auth.service.js';
7
+
8
+ type AuthDependencies = Parameters<typeof createAuthService>[0];
9
+
10
+ function createDependencies(overrides: Partial<AuthDependencies> = {}): AuthDependencies {
11
+ return {
12
+ users: {
13
+ hasUsers: () => false,
14
+ createUser: (username, passwordHash) => ({ id: 1, username, password_hash: passwordHash }),
15
+ getUserByUsername: () => undefined,
16
+ updateLastLogin: () => undefined,
17
+ },
18
+ transaction: {
19
+ begin: () => undefined,
20
+ commit: () => undefined,
21
+ rollback: () => undefined,
22
+ },
23
+ hashPassword: async () => 'hashed-password',
24
+ comparePassword: async () => false,
25
+ generateToken: () => 'signed-token',
26
+ ...overrides,
27
+ };
28
+ }
29
+
30
+ test('register hashes credentials and commits through injected dependencies', async () => {
31
+ const operations: string[] = [];
32
+ const service = createAuthService(createDependencies({
33
+ transaction: {
34
+ begin: () => operations.push('begin'),
35
+ commit: () => operations.push('commit'),
36
+ rollback: () => operations.push('rollback'),
37
+ },
38
+ hashPassword: async (password) => {
39
+ operations.push(`hash:${password}`);
40
+ return 'hash';
41
+ },
42
+ users: {
43
+ hasUsers: () => false,
44
+ createUser: (username, passwordHash) => {
45
+ operations.push(`create:${username}:${passwordHash}`);
46
+ return { id: 1, username, password_hash: passwordHash };
47
+ },
48
+ getUserByUsername: () => undefined,
49
+ updateLastLogin: (userId) => operations.push(`login:${userId}`),
50
+ },
51
+ }));
52
+
53
+ const result = await service.register('alice', 'secret12');
54
+
55
+ assert.equal(result.token, 'signed-token');
56
+ assert.deepEqual(operations, ['begin', 'hash:secret12', 'create:alice:hash', 'commit', 'login:1']);
57
+ });
58
+
59
+ test('login rejects an invalid password without issuing a token', async () => {
60
+ let tokenIssued = false;
61
+ const service = createAuthService(createDependencies({
62
+ users: {
63
+ hasUsers: () => true,
64
+ createUser: () => { throw new Error('unused'); },
65
+ getUserByUsername: () => ({ id: 1, username: 'alice', password_hash: 'hash' }),
66
+ updateLastLogin: () => undefined,
67
+ },
68
+ comparePassword: async () => false,
69
+ generateToken: () => {
70
+ tokenIssued = true;
71
+ return 'token';
72
+ },
73
+ }));
74
+
75
+ await assert.rejects(
76
+ service.login('alice', 'wrong-password'),
77
+ (error: unknown) => error instanceof AppError && error.code === 'AUTH_INVALID_CREDENTIALS',
78
+ );
79
+ assert.equal(tokenIssued, false);
80
+ });
81
+
82
+ test('refreshSession issues a replacement token for the authenticated user', () => {
83
+ let tokenUser: { id: number | bigint; username: string } | undefined;
84
+ const service = createAuthService(createDependencies({
85
+ generateToken: (user) => {
86
+ tokenUser = user;
87
+ return 'replacement-token';
88
+ },
89
+ }));
90
+
91
+ const result = service.refreshSession({ id: 7, username: 'alice' });
92
+
93
+ assert.deepEqual(result, { token: 'replacement-token' });
94
+ assert.deepEqual(tokenUser, { id: 7, username: 'alice' });
95
+ });
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import './load-env.js';
2
+ // The MCP executable must load the root environment bootstrap before reading configuration.
3
+ // eslint-disable-next-line boundaries/no-unknown
4
+ import '../../load-env.js';
3
5
 
4
6
  type JsonRpcRequest = {
5
7
  jsonrpc: '2.0';
@@ -9,10 +9,10 @@ import spawn from 'cross-spawn';
9
9
 
10
10
  import { appConfigDb } from '@/modules/database/index.js';
11
11
  import { providerMcpService } from '@/modules/providers/index.js';
12
- import { getModuleDir } from '@/utils/runtime-paths.js';
12
+ import { getModuleDirectory } from '@/shared/utils.js';
13
13
 
14
14
  const require = createRequire(import.meta.url);
15
- const __dirname = getModuleDir(import.meta.url);
15
+ const __dirname = getModuleDirectory(import.meta.url);
16
16
  const IS_PLATFORM = process.env.VITE_IS_PLATFORM === 'true';
17
17
  const MAX_SESSIONS_PER_OWNER = Number.parseInt(process.env.CLOUDCLI_BROWSER_USE_MAX_SESSIONS_PER_OWNER || '3', 10);
18
18
  const SESSION_TTL_MS = Number.parseInt(process.env.CLOUDCLI_BROWSER_USE_SESSION_TTL_MS || String(30 * 60 * 1000), 10);
@@ -150,8 +150,7 @@ function getPlaywright(): any | null {
150
150
  }
151
151
 
152
152
  function getMcpCommand(): { command: string; args: string[] } {
153
- const serverDir = path.resolve(__dirname, '..', '..');
154
- const mcpScriptPath = path.join(serverDir, 'browser-use-mcp.js');
153
+ const mcpScriptPath = path.join(__dirname, 'browser-use-mcp.js');
155
154
  if (fs.existsSync(mcpScriptPath)) {
156
155
  return {
157
156
  command: process.execPath,
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Lazily starts the Browser Use MCP stdio entrypoint. Keeping this import lazy
3
+ * ensures the entrypoint loads environment configuration before its runtime is
4
+ * evaluated.
5
+ */
6
+ export async function startBrowserUseMcp(): Promise<void> {
7
+ await import('./browser-use-mcp.js');
8
+ }
@@ -0,0 +1,96 @@
1
+ import { execFileSync, execSync } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+
6
+ import spawn from 'cross-spawn';
7
+
8
+ import type { CliApplication, CliPackageMetadata } from '@/shared/types.js';
9
+ import { findApplicationRoot, getModuleDirectory } from '@/shared/utils.js';
10
+
11
+ import { createCliService } from './cli.service.js';
12
+ import { createSandboxCommandService } from './sandbox.service.js';
13
+
14
+ /**
15
+ * Creates the production CLI application for the executable entrypoint. This is
16
+ * the CLI module's single composition root: it reads package metadata and wires
17
+ * all concrete Node filesystem, subprocess, environment, clock, and module-start
18
+ * adapters before passing them into otherwise isolated services.
19
+ */
20
+ export function createCliApplication(): CliApplication {
21
+ const applicationRoot = findApplicationRoot(getModuleDirectory(import.meta.url));
22
+ const packageMetadataJson = JSON.parse(
23
+ fs.readFileSync(path.join(applicationRoot, 'package.json'), 'utf8'),
24
+ ) as { version: string; homepage?: string; bugs?: { url?: string } };
25
+ const packageMetadata: CliPackageMetadata = {
26
+ version: packageMetadataJson.version,
27
+ homepage: packageMetadataJson.homepage,
28
+ bugsUrl: packageMetadataJson.bugs?.url,
29
+ };
30
+ const fileSystem = {
31
+ readTextFile: (filePath: string) => fs.readFileSync(filePath, 'utf8'),
32
+ pathExists: (filePath: string) => fs.existsSync(filePath),
33
+ getFileStats: (filePath: string) => {
34
+ const stats = fs.statSync(filePath);
35
+ return { size: stats.size, modifiedAt: stats.mtime };
36
+ },
37
+ };
38
+ const output = {
39
+ log: (message?: string) => console.log(message),
40
+ error: (message?: string) => console.error(message),
41
+ };
42
+ const homeDirectory = os.homedir();
43
+ const sandboxService = createSandboxCommandService({
44
+ homeDirectory,
45
+ fileSystem,
46
+ output,
47
+ runSandboxCommand: (argumentsList, inheritOutput = false) => {
48
+ const result = execFileSync('sbx', argumentsList, {
49
+ encoding: 'utf8',
50
+ stdio: inheritOutput ? 'inherit' : 'pipe',
51
+ });
52
+ return result || '';
53
+ },
54
+ spawnDetachedSandbox: (argumentsList) => {
55
+ const childProcess = spawn('sbx', argumentsList, {
56
+ detached: true,
57
+ stdio: ['ignore', 'ignore', 'ignore'],
58
+ });
59
+ childProcess.unref();
60
+ },
61
+ wait: (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
62
+ });
63
+
64
+ return createCliService({
65
+ applicationRoot,
66
+ defaultDatabasePath: path.join(homeDirectory, '.cloudcli', 'auth.db'),
67
+ homeDirectory,
68
+ packageMetadata,
69
+ environment: process.env,
70
+ fileSystem,
71
+ output,
72
+ sandboxService,
73
+ getLatestPackageVersion: async () => {
74
+ // Yield first so the default `start` command can begin loading the server
75
+ // before this best-effort npm registry check runs.
76
+ await new Promise<void>((resolve) => setImmediate(resolve));
77
+ return execSync(
78
+ 'npm show @cloudcli-ai/cloudcli version',
79
+ { encoding: 'utf8' },
80
+ ).trim();
81
+ },
82
+ updateGlobalPackage: () => {
83
+ execSync('npm update -g @cloudcli-ai/cloudcli', { stdio: 'inherit' });
84
+ },
85
+ startServer: async () => {
86
+ // The server executable is an entrypoint rather than a feature module,
87
+ // so it has no barrel contract to import through.
88
+ // eslint-disable-next-line boundaries/no-unknown
89
+ await import('../../index.js');
90
+ },
91
+ startBrowserUseMcp: async () => {
92
+ const { startBrowserUseMcp } = await import('../browser-use/index.js');
93
+ await startBrowserUseMcp();
94
+ },
95
+ });
96
+ }
@@ -0,0 +1,281 @@
1
+ import path from 'node:path';
2
+
3
+ import type {
4
+ CliApplication,
5
+ CliEnvironment,
6
+ CliFileSystem,
7
+ CliOutput,
8
+ CliPackageMetadata,
9
+ SandboxCommandService,
10
+ } from '@/shared/types.js';
11
+ import { terminalTextStyles } from '@/shared/utils.js';
12
+
13
+ type CliServiceDependencies = {
14
+ applicationRoot: string;
15
+ defaultDatabasePath: string;
16
+ homeDirectory: string;
17
+ packageMetadata: CliPackageMetadata;
18
+ environment: CliEnvironment;
19
+ fileSystem: CliFileSystem;
20
+ output: CliOutput;
21
+ sandboxService: SandboxCommandService;
22
+ getLatestPackageVersion(): Promise<string>;
23
+ updateGlobalPackage(): void;
24
+ startServer(): Promise<void>;
25
+ startBrowserUseMcp(): Promise<void>;
26
+ };
27
+
28
+ type ParsedCliArguments = {
29
+ command: string;
30
+ options: {
31
+ serverPort?: string;
32
+ databasePath?: string;
33
+ };
34
+ remainingArguments: string[];
35
+ };
36
+
37
+ function parseCliArguments(argumentsList: string[]): ParsedCliArguments {
38
+ const parsedArguments: ParsedCliArguments = {
39
+ command: 'start',
40
+ options: {},
41
+ remainingArguments: [],
42
+ };
43
+
44
+ for (let argumentIndex = 0; argumentIndex < argumentsList.length; argumentIndex += 1) {
45
+ const argument = argumentsList[argumentIndex];
46
+ if (argument === '--port' || argument === '-p') {
47
+ parsedArguments.options.serverPort = argumentsList[++argumentIndex];
48
+ } else if (argument.startsWith('--port=')) {
49
+ parsedArguments.options.serverPort = argument.slice('--port='.length);
50
+ } else if (argument === '--database-path') {
51
+ parsedArguments.options.databasePath = argumentsList[++argumentIndex];
52
+ } else if (argument.startsWith('--database-path=')) {
53
+ parsedArguments.options.databasePath = argument.slice('--database-path='.length);
54
+ } else if (argument === '--help' || argument === '-h') {
55
+ parsedArguments.command = 'help';
56
+ } else if (argument === '--version' || argument === '-v') {
57
+ parsedArguments.command = 'version';
58
+ } else if (!argument.startsWith('-')) {
59
+ parsedArguments.command = argument;
60
+ if (argument === 'sandbox') {
61
+ parsedArguments.remainingArguments = argumentsList.slice(argumentIndex + 1);
62
+ break;
63
+ }
64
+ }
65
+ }
66
+
67
+ return parsedArguments;
68
+ }
69
+
70
+ function isNewerVersion(candidateVersion: string, currentVersion: string): boolean {
71
+ const candidateParts = candidateVersion.split('.').map(Number);
72
+ const currentParts = currentVersion.split('.').map(Number);
73
+ for (let partIndex = 0; partIndex < 3; partIndex += 1) {
74
+ if (candidateParts[partIndex] > currentParts[partIndex]) return true;
75
+ if (candidateParts[partIndex] < currentParts[partIndex]) return false;
76
+ }
77
+ return false;
78
+ }
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
+ function showStatus(dependencies: CliServiceDependencies): void {
100
+ loadEnvironmentFile(dependencies);
101
+ const { environment, fileSystem, output } = dependencies;
102
+ const databasePath = environment.DATABASE_PATH || dependencies.defaultDatabasePath;
103
+ const databaseExists = fileSystem.pathExists(databasePath);
104
+ const claudeProjectsPath = path.join(dependencies.homeDirectory, '.claude', 'projects');
105
+ const environmentFilePath = path.join(dependencies.applicationRoot, '.env');
106
+
107
+ output.log(`\n${terminalTextStyles.bright('CloudCLI UI - Status')}\n`);
108
+ output.log(terminalTextStyles.dim('═'.repeat(60)));
109
+ output.log(`\n${terminalTextStyles.info('[INFO]')} Version: ${terminalTextStyles.bright(dependencies.packageMetadata.version)}`);
110
+ output.log(`\n${terminalTextStyles.info('[INFO]')} Installation Directory:`);
111
+ output.log(` ${terminalTextStyles.dim(dependencies.applicationRoot)}`);
112
+ output.log(`\n${terminalTextStyles.info('[INFO]')} Database Location:`);
113
+ output.log(` ${terminalTextStyles.dim(databasePath)}`);
114
+ output.log(` Status: ${databaseExists
115
+ ? terminalTextStyles.ok('[OK] Exists')
116
+ : terminalTextStyles.warn('[WARN] Not created yet (will be created on first run)')}`);
117
+
118
+ if (databaseExists) {
119
+ const databaseStats = fileSystem.getFileStats(databasePath);
120
+ output.log(` Size: ${terminalTextStyles.dim(`${(databaseStats.size / 1024).toFixed(2)} KB`)}`);
121
+ output.log(` Modified: ${terminalTextStyles.dim(databaseStats.modifiedAt.toLocaleString())}`);
122
+ }
123
+
124
+ output.log(`\n${terminalTextStyles.info('[INFO]')} Configuration:`);
125
+ output.log(` SERVER_PORT: ${terminalTextStyles.bright(environment.SERVER_PORT || environment.PORT || '3001')} ${terminalTextStyles.dim(environment.SERVER_PORT || environment.PORT ? '' : '(default)')}`);
126
+ output.log(` DATABASE_PATH: ${terminalTextStyles.dim(environment.DATABASE_PATH || '(using default location)')}`);
127
+ output.log(` CLAUDE_CLI_PATH: ${terminalTextStyles.dim(environment.CLAUDE_CLI_PATH || 'claude (default)')}`);
128
+ output.log(` CONTEXT_WINDOW: ${terminalTextStyles.dim(environment.CONTEXT_WINDOW || '160000 (default)')}`);
129
+ output.log(`\n${terminalTextStyles.info('[INFO]')} Claude Projects Folder:`);
130
+ output.log(` ${terminalTextStyles.dim(claudeProjectsPath)}`);
131
+ output.log(` Status: ${fileSystem.pathExists(claudeProjectsPath)
132
+ ? terminalTextStyles.ok('[OK] Exists')
133
+ : terminalTextStyles.warn('[WARN] Not found')}`);
134
+ output.log(`\n${terminalTextStyles.info('[INFO]')} Configuration File:`);
135
+ output.log(` ${terminalTextStyles.dim(environmentFilePath)}`);
136
+ output.log(` Status: ${fileSystem.pathExists(environmentFilePath)
137
+ ? terminalTextStyles.ok('[OK] Exists')
138
+ : terminalTextStyles.warn('[WARN] Not found (using defaults)')}`);
139
+ output.log(`\n${terminalTextStyles.dim('═'.repeat(60))}`);
140
+ output.log(`\n${terminalTextStyles.tip('[TIP]')} Hints:`);
141
+ output.log(` ${terminalTextStyles.dim('>')} Use ${terminalTextStyles.bright('cloudcli --port 8080')} to run on a custom port`);
142
+ output.log(` ${terminalTextStyles.dim('>')} Use ${terminalTextStyles.bright('cloudcli --database-path /path/to/db')} for custom database`);
143
+ output.log(` ${terminalTextStyles.dim('>')} Run ${terminalTextStyles.bright('cloudcli help')} for all options`);
144
+ output.log(` ${terminalTextStyles.dim('>')} Access the UI at http://localhost:${environment.SERVER_PORT || environment.PORT || '3001'}\n`);
145
+ }
146
+
147
+ function showHelp(dependencies: CliServiceDependencies): void {
148
+ dependencies.output.log(`
149
+ ╔═══════════════════════════════════════════════════════════════╗
150
+ ║ CloudCLI - Command Line Tool ║
151
+ ╚═══════════════════════════════════════════════════════════════╝
152
+
153
+ Usage:
154
+ claude-code-ui [command] [options]
155
+ cloudcli [command] [options]
156
+
157
+ Commands:
158
+ start Start the CloudCLI server (default)
159
+ sandbox Manage Docker sandbox environments
160
+ browser-use-mcp Run Browser MCP stdio server
161
+ status Show configuration and data locations
162
+ update Update to the latest version
163
+ help Show this help information
164
+ version Show version information
165
+
166
+ Options:
167
+ -p, --port <port> Set server port (default: 3001)
168
+ --database-path <path> Set custom database location
169
+ -h, --help Show this help information
170
+ -v, --version Show version information
171
+
172
+ Examples:
173
+ $ cloudcli # Start with defaults
174
+ $ cloudcli --port 8080 # Start on port 8080
175
+ $ cloudcli sandbox ~/my-project # Run in a Docker sandbox
176
+ $ cloudcli status # Show configuration
177
+
178
+ Environment Variables:
179
+ SERVER_PORT Set server port (default: 3001)
180
+ PORT Set server port (default: 3001) (LEGACY)
181
+ DATABASE_PATH Set custom database location
182
+ CLAUDE_CLI_PATH Set custom Claude CLI path
183
+ CONTEXT_WINDOW Set context window size (default: 160000)
184
+
185
+ Documentation:
186
+ ${dependencies.packageMetadata.homepage || 'https://github.com/siteboon/claudecodeui'}
187
+
188
+ Report Issues:
189
+ ${dependencies.packageMetadata.bugsUrl || 'https://github.com/siteboon/claudecodeui/issues'}
190
+ `);
191
+ }
192
+
193
+ /**
194
+ * Creates the top-level CLI command service used by the CLI composition root
195
+ * and unit tests. Every filesystem, subprocess, environment, output, and
196
+ * cross-module startup dependency is explicit and required.
197
+ */
198
+ export function createCliService(dependencies: CliServiceDependencies): CliApplication {
199
+ const checkForUpdates = async (silent = false): Promise<boolean> => {
200
+ try {
201
+ const latestVersion = await dependencies.getLatestPackageVersion();
202
+ const currentVersion = dependencies.packageMetadata.version;
203
+ if (isNewerVersion(latestVersion, currentVersion)) {
204
+ dependencies.output.log(`\n${terminalTextStyles.warn('[UPDATE]')} New version available: ${terminalTextStyles.bright(latestVersion)} (current: ${currentVersion})`);
205
+ dependencies.output.log(` Run ${terminalTextStyles.bright('cloudcli update')} to update\n`);
206
+ return true;
207
+ }
208
+ if (!silent) {
209
+ dependencies.output.log(`${terminalTextStyles.ok('[OK]')} You are on the latest version (${currentVersion})`);
210
+ }
211
+ return false;
212
+ } catch {
213
+ if (!silent) {
214
+ dependencies.output.log(`${terminalTextStyles.warn('[WARN]')} Could not check for updates`);
215
+ }
216
+ return false;
217
+ }
218
+ };
219
+
220
+ const updatePackage = async (): Promise<void> => {
221
+ dependencies.output.log(`${terminalTextStyles.info('[INFO]')} Checking for updates...`);
222
+ const hasUpdate = await checkForUpdates(true);
223
+ if (!hasUpdate) {
224
+ dependencies.output.log(`${terminalTextStyles.ok('[OK]')} Already on the latest version (${dependencies.packageMetadata.version})`);
225
+ return;
226
+ }
227
+
228
+ try {
229
+ dependencies.output.log(`${terminalTextStyles.info('[INFO]')} Updating ${dependencies.packageMetadata.version}...`);
230
+ dependencies.updateGlobalPackage();
231
+ dependencies.output.log(`${terminalTextStyles.ok('[OK]')} Update complete! Restart cloudcli to use the new version.`);
232
+ } catch (error) {
233
+ const message = error instanceof Error ? error.message : String(error);
234
+ dependencies.output.error(`${terminalTextStyles.error('[ERROR]')} Update failed: ${message}`);
235
+ dependencies.output.log(`${terminalTextStyles.tip('[TIP]')} Try running manually: npm update -g @cloudcli-ai/cloudcli`);
236
+ }
237
+ };
238
+
239
+ return {
240
+ async run(argumentsList) {
241
+ const parsedArguments = parseCliArguments(argumentsList);
242
+ if (parsedArguments.options.serverPort) {
243
+ dependencies.environment.SERVER_PORT = parsedArguments.options.serverPort;
244
+ } else if (!dependencies.environment.SERVER_PORT && dependencies.environment.PORT) {
245
+ dependencies.environment.SERVER_PORT = dependencies.environment.PORT;
246
+ }
247
+ if (parsedArguments.options.databasePath) {
248
+ dependencies.environment.DATABASE_PATH = parsedArguments.options.databasePath;
249
+ }
250
+
251
+ switch (parsedArguments.command) {
252
+ case 'start':
253
+ void checkForUpdates(true);
254
+ await dependencies.startServer();
255
+ return 0;
256
+ case 'sandbox':
257
+ return dependencies.sandboxService.execute(parsedArguments.remainingArguments);
258
+ case 'browser-use-mcp':
259
+ await dependencies.startBrowserUseMcp();
260
+ return 0;
261
+ case 'status':
262
+ case 'info':
263
+ showStatus(dependencies);
264
+ return 0;
265
+ case 'help':
266
+ showHelp(dependencies);
267
+ return 0;
268
+ case 'version':
269
+ dependencies.output.log(dependencies.packageMetadata.version);
270
+ return 0;
271
+ case 'update':
272
+ await updatePackage();
273
+ return 0;
274
+ default:
275
+ dependencies.output.error(`\n❌ Unknown command: ${parsedArguments.command}`);
276
+ dependencies.output.log(' Run "cloudcli help" for usage information.\n');
277
+ return 1;
278
+ }
279
+ },
280
+ };
281
+ }