@cloudcli-ai/cloudcli 1.34.0 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/README.de.md +9 -1
  2. package/README.ja.md +8 -0
  3. package/README.ko.md +9 -1
  4. package/README.md +16 -3
  5. package/README.ru.md +9 -1
  6. package/README.tr.md +8 -1
  7. package/README.zh-CN.md +9 -1
  8. package/README.zh-TW.md +9 -1
  9. package/dist/api-docs.html +36 -18
  10. package/dist/assets/index-CtwxqzGG.js +1407 -0
  11. package/dist/assets/index-DlvtxFyt.css +32 -0
  12. package/dist/index.html +2 -2
  13. package/dist-server/server/browser-use-mcp.js +350 -0
  14. package/dist-server/server/browser-use-mcp.js.map +1 -0
  15. package/dist-server/server/claude-sdk.js +25 -5
  16. package/dist-server/server/claude-sdk.js.map +1 -1
  17. package/dist-server/server/cli.js +14 -6
  18. package/dist-server/server/cli.js.map +1 -1
  19. package/dist-server/server/computer-use-agent.js +242 -0
  20. package/dist-server/server/computer-use-agent.js.map +1 -0
  21. package/dist-server/server/computer-use-mcp.js +519 -0
  22. package/dist-server/server/computer-use-mcp.js.map +1 -0
  23. package/dist-server/server/cursor-cli.js +27 -11
  24. package/dist-server/server/cursor-cli.js.map +1 -1
  25. package/dist-server/server/gemini-cli.js +17 -2
  26. package/dist-server/server/gemini-cli.js.map +1 -1
  27. package/dist-server/server/index.js +149 -40
  28. package/dist-server/server/index.js.map +1 -1
  29. package/dist-server/server/load-env.js +1 -1
  30. package/dist-server/server/load-env.js.map +1 -1
  31. package/dist-server/server/modules/browser-use/browser-use-mcp.routes.js +107 -0
  32. package/dist-server/server/modules/browser-use/browser-use-mcp.routes.js.map +1 -0
  33. package/dist-server/server/modules/browser-use/browser-use.routes.js +93 -0
  34. package/dist-server/server/modules/browser-use/browser-use.routes.js.map +1 -0
  35. package/dist-server/server/modules/browser-use/browser-use.service.js +688 -0
  36. package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -0
  37. package/dist-server/server/modules/browser-use/tests/browser-use.service.test.js +8 -0
  38. package/dist-server/server/modules/browser-use/tests/browser-use.service.test.js.map +1 -0
  39. package/dist-server/server/modules/computer-use/actions/raw-action-dispatcher.js +55 -0
  40. package/dist-server/server/modules/computer-use/actions/raw-action-dispatcher.js.map +1 -0
  41. package/dist-server/server/modules/computer-use/actions/raw-action-types.js +2 -0
  42. package/dist-server/server/modules/computer-use/actions/raw-action-types.js.map +1 -0
  43. package/dist-server/server/modules/computer-use/computer-executor.js +212 -0
  44. package/dist-server/server/modules/computer-use/computer-executor.js.map +1 -0
  45. package/dist-server/server/modules/computer-use/computer-semantics.service.js +422 -0
  46. package/dist-server/server/modules/computer-use/computer-semantics.service.js.map +1 -0
  47. package/dist-server/server/modules/computer-use/computer-use-mcp.routes.js +126 -0
  48. package/dist-server/server/modules/computer-use/computer-use-mcp.routes.js.map +1 -0
  49. package/dist-server/server/modules/computer-use/computer-use.routes.js +196 -0
  50. package/dist-server/server/modules/computer-use/computer-use.routes.js.map +1 -0
  51. package/dist-server/server/modules/computer-use/computer-use.service.js +759 -0
  52. package/dist-server/server/modules/computer-use/computer-use.service.js.map +1 -0
  53. package/dist-server/server/modules/computer-use/desktop-agent-relay.service.js +126 -0
  54. package/dist-server/server/modules/computer-use/desktop-agent-relay.service.js.map +1 -0
  55. package/dist-server/server/modules/computer-use/index.js +3 -0
  56. package/dist-server/server/modules/computer-use/index.js.map +1 -0
  57. package/dist-server/server/modules/computer-use/semantics/adapters/helper-semantic-adapter.js +59 -0
  58. package/dist-server/server/modules/computer-use/semantics/adapters/helper-semantic-adapter.js.map +1 -0
  59. package/dist-server/server/modules/computer-use/semantics/adapters/macos/macos-semantic-adapter.js +5 -0
  60. package/dist-server/server/modules/computer-use/semantics/adapters/macos/macos-semantic-adapter.js.map +1 -0
  61. package/dist-server/server/modules/computer-use/semantics/adapters/semantic-adapter.js +2 -0
  62. package/dist-server/server/modules/computer-use/semantics/adapters/semantic-adapter.js.map +1 -0
  63. package/dist-server/server/modules/computer-use/semantics/adapters/windows/windows-semantic-adapter.js +5 -0
  64. package/dist-server/server/modules/computer-use/semantics/adapters/windows/windows-semantic-adapter.js.map +1 -0
  65. package/dist-server/server/modules/computer-use/semantics/bin/darwin-arm64/CloudCLISemantics +0 -0
  66. package/dist-server/server/modules/computer-use/semantics/bin/darwin-x64/CloudCLISemantics +0 -0
  67. package/dist-server/server/modules/computer-use/semantics/bin/win32-arm64/CloudCLISemantics.exe +0 -0
  68. package/dist-server/server/modules/computer-use/semantics/bin/win32-x64/CloudCLISemantics.exe +0 -0
  69. package/dist-server/server/modules/computer-use/semantics/helpers/semantic-helper-process.js +106 -0
  70. package/dist-server/server/modules/computer-use/semantics/helpers/semantic-helper-process.js.map +1 -0
  71. package/dist-server/server/modules/computer-use/semantics/helpers/semantic-helper-resolver.js +78 -0
  72. package/dist-server/server/modules/computer-use/semantics/helpers/semantic-helper-resolver.js.map +1 -0
  73. package/dist-server/server/modules/computer-use/semantics/semantic-session-store.js +68 -0
  74. package/dist-server/server/modules/computer-use/semantics/semantic-session-store.js.map +1 -0
  75. package/dist-server/server/modules/computer-use/semantics/semantic-tool-dispatcher.js +16 -0
  76. package/dist-server/server/modules/computer-use/semantics/semantic-tool-dispatcher.js.map +1 -0
  77. package/dist-server/server/modules/computer-use/semantics/semantic-types.js +2 -0
  78. package/dist-server/server/modules/computer-use/semantics/semantic-types.js.map +1 -0
  79. package/dist-server/server/modules/database/index.js +1 -0
  80. package/dist-server/server/modules/database/index.js.map +1 -1
  81. package/dist-server/server/modules/database/migrations.js +23 -1
  82. package/dist-server/server/modules/database/migrations.js.map +1 -1
  83. package/dist-server/server/modules/database/repositories/notification-channel-endpoints.js +100 -0
  84. package/dist-server/server/modules/database/repositories/notification-channel-endpoints.js.map +1 -0
  85. package/dist-server/server/modules/database/repositories/notification-preferences.js +8 -0
  86. package/dist-server/server/modules/database/repositories/notification-preferences.js.map +1 -1
  87. package/dist-server/server/modules/database/repositories/sessions.db.js +173 -17
  88. package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
  89. package/dist-server/server/modules/database/schema.js +26 -0
  90. package/dist-server/server/modules/database/schema.js.map +1 -1
  91. package/dist-server/server/modules/database/tests/projects.db.integration.test.js.map +1 -0
  92. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +78 -0
  93. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js.map +1 -0
  94. package/dist-server/server/modules/database/{repositories → tests}/sessions.db.integration.test.js +10 -0
  95. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -0
  96. package/dist-server/server/modules/notifications/index.js +4 -0
  97. package/dist-server/server/modules/notifications/index.js.map +1 -0
  98. package/dist-server/server/modules/notifications/notifications.routes.js +115 -0
  99. package/dist-server/server/modules/notifications/notifications.routes.js.map +1 -0
  100. package/dist-server/server/modules/notifications/services/desktop-notification-clients.service.js +97 -0
  101. package/dist-server/server/modules/notifications/services/desktop-notification-clients.service.js.map +1 -0
  102. package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js +229 -0
  103. package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js.map +1 -0
  104. package/dist-server/server/modules/notifications/websocket/desktop-notifications-websocket.service.js +79 -0
  105. package/dist-server/server/modules/notifications/websocket/desktop-notifications-websocket.service.js.map +1 -0
  106. package/dist-server/server/modules/projects/services/project-management.service.js +0 -4
  107. package/dist-server/server/modules/projects/services/project-management.service.js.map +1 -1
  108. package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js +10 -38
  109. package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js.map +1 -1
  110. package/dist-server/server/modules/providers/index.js +1 -0
  111. package/dist-server/server/modules/providers/index.js.map +1 -1
  112. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +24 -1
  113. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -1
  114. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +9 -12
  115. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
  116. package/dist-server/server/modules/providers/list/claude/claude-skills.provider.js +7 -0
  117. package/dist-server/server/modules/providers/list/claude/claude-skills.provider.js.map +1 -1
  118. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js +7 -3
  119. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -1
  120. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +3 -9
  121. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
  122. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +7 -0
  123. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -1
  124. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +13 -22
  125. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -1
  126. package/dist-server/server/modules/providers/list/cursor/cursor-skills.provider.js +7 -0
  127. package/dist-server/server/modules/providers/list/cursor/cursor-skills.provider.js.map +1 -1
  128. package/dist-server/server/modules/providers/list/gemini/gemini-models.provider.js +5 -8
  129. package/dist-server/server/modules/providers/list/gemini/gemini-models.provider.js.map +1 -1
  130. package/dist-server/server/modules/providers/list/gemini/gemini-sessions.provider.js +6 -6
  131. package/dist-server/server/modules/providers/list/gemini/gemini-sessions.provider.js.map +1 -1
  132. package/dist-server/server/modules/providers/list/gemini/gemini-skills.provider.js +7 -0
  133. package/dist-server/server/modules/providers/list/gemini/gemini-skills.provider.js.map +1 -1
  134. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +17 -3
  135. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js.map +1 -1
  136. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +9 -10
  137. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -1
  138. package/dist-server/server/modules/providers/provider.routes.js +123 -1
  139. package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
  140. package/dist-server/server/modules/providers/services/mcp.service.js +23 -0
  141. package/dist-server/server/modules/providers/services/mcp.service.js.map +1 -1
  142. package/dist-server/server/modules/providers/services/provider-capabilities.service.js +65 -0
  143. package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -0
  144. package/dist-server/server/modules/providers/services/provider-models.service.js +1 -1
  145. package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
  146. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +62 -23
  147. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
  148. package/dist-server/server/modules/providers/services/sessions.service.js +62 -4
  149. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
  150. package/dist-server/server/modules/providers/services/skills.service.js +11 -0
  151. package/dist-server/server/modules/providers/services/skills.service.js.map +1 -1
  152. package/dist-server/server/modules/providers/shared/skills/skills.provider.js +163 -1
  153. package/dist-server/server/modules/providers/shared/skills/skills.provider.js.map +1 -1
  154. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +45 -0
  155. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -1
  156. package/dist-server/server/modules/providers/tests/skills.test.js +160 -0
  157. package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
  158. package/dist-server/server/modules/websocket/index.js +1 -0
  159. package/dist-server/server/modules/websocket/index.js.map +1 -1
  160. package/dist-server/server/modules/websocket/services/chat-run-registry.service.js +252 -0
  161. package/dist-server/server/modules/websocket/services/chat-run-registry.service.js.map +1 -0
  162. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +105 -0
  163. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js.map +1 -0
  164. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +218 -156
  165. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
  166. package/dist-server/server/modules/websocket/services/desktop-agent-websocket.service.js +39 -0
  167. package/dist-server/server/modules/websocket/services/desktop-agent-websocket.service.js.map +1 -0
  168. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +83 -31
  169. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
  170. package/dist-server/server/modules/websocket/services/websocket-server.service.js +10 -0
  171. package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -1
  172. package/dist-server/server/modules/websocket/tests/chat-run-registry.test.js +216 -0
  173. package/dist-server/server/modules/websocket/tests/chat-run-registry.test.js.map +1 -0
  174. package/dist-server/server/openai-codex.js +24 -14
  175. package/dist-server/server/openai-codex.js.map +1 -1
  176. package/dist-server/server/opencode-cli.js +21 -8
  177. package/dist-server/server/opencode-cli.js.map +1 -1
  178. package/dist-server/server/opencode-cli.test.js +19 -1
  179. package/dist-server/server/opencode-cli.test.js.map +1 -1
  180. package/dist-server/server/routes/settings.js +1 -1
  181. package/dist-server/server/routes/settings.js.map +1 -1
  182. package/dist-server/server/services/notification-orchestrator.js +1 -176
  183. package/dist-server/server/services/notification-orchestrator.js.map +1 -1
  184. package/dist-server/server/services/tests/notification-orchestrator.test.js +64 -0
  185. package/dist-server/server/services/tests/notification-orchestrator.test.js.map +1 -0
  186. package/dist-server/server/shared/{claude-cli-path.test.js → tests/claude-cli-path.test.js} +1 -1
  187. package/dist-server/server/shared/tests/claude-cli-path.test.js.map +1 -0
  188. package/dist-server/server/shared/tests/slice-tail-page.test.js +35 -0
  189. package/dist-server/server/shared/tests/slice-tail-page.test.js.map +1 -0
  190. package/dist-server/server/shared/utils.js +73 -1
  191. package/dist-server/server/shared/utils.js.map +1 -1
  192. package/dist-server/server/voice-proxy.js +226 -0
  193. package/dist-server/server/voice-proxy.js.map +1 -0
  194. package/electron/assets/logo-macos.icns +0 -0
  195. package/electron/assets/logo-macos.png +0 -0
  196. package/electron/assets/logo-windows.ico +0 -0
  197. package/electron/cloud.js +260 -0
  198. package/electron/computerAgent.js +290 -0
  199. package/electron/desktopNotifications.js +378 -0
  200. package/electron/desktopWindow.js +781 -0
  201. package/electron/launcher/index.html +14 -0
  202. package/electron/launcher/launcher.css +801 -0
  203. package/electron/launcher/launcher.js +829 -0
  204. package/electron/localServer.js +550 -0
  205. package/electron/main.js +1060 -0
  206. package/electron/preload.cjs +63 -0
  207. package/electron/scripts/generate-macos-icon.js +62 -0
  208. package/electron/serverInstaller.js +277 -0
  209. package/electron/tabs.js +87 -0
  210. package/electron/viewHost.js +331 -0
  211. package/package.json +86 -5
  212. package/public/api-docs.html +36 -18
  213. package/scripts/build-computer-semantics.mjs +133 -0
  214. package/scripts/copy-computer-semantics-bin.mjs +24 -0
  215. package/scripts/release/build-server-bundle.js +176 -0
  216. package/scripts/release/prepare-desktop-app.js +158 -0
  217. package/server/browser-use-mcp.ts +384 -0
  218. package/server/claude-sdk.js +27 -5
  219. package/server/cli.js +15 -6
  220. package/server/computer-use-agent.ts +279 -0
  221. package/server/computer-use-mcp.ts +574 -0
  222. package/server/cursor-cli.js +27 -11
  223. package/server/gemini-cli.js +17 -2
  224. package/server/index.js +151 -47
  225. package/server/load-env.js +1 -1
  226. package/server/modules/browser-use/browser-use-mcp.routes.ts +120 -0
  227. package/server/modules/browser-use/browser-use.routes.ts +96 -0
  228. package/server/modules/browser-use/browser-use.service.ts +836 -0
  229. package/server/modules/browser-use/tests/browser-use.service.test.ts +10 -0
  230. package/server/modules/computer-use/actions/raw-action-dispatcher.ts +67 -0
  231. package/server/modules/computer-use/actions/raw-action-types.ts +28 -0
  232. package/server/modules/computer-use/computer-executor.ts +242 -0
  233. package/server/modules/computer-use/computer-semantics.service.ts +460 -0
  234. package/server/modules/computer-use/computer-use-mcp.routes.ts +141 -0
  235. package/server/modules/computer-use/computer-use.routes.ts +211 -0
  236. package/server/modules/computer-use/computer-use.service.ts +920 -0
  237. package/server/modules/computer-use/desktop-agent-relay.service.ts +158 -0
  238. package/server/modules/computer-use/index.ts +2 -0
  239. package/server/modules/computer-use/semantics/adapters/helper-semantic-adapter.ts +82 -0
  240. package/server/modules/computer-use/semantics/adapters/macos/macos-semantic-adapter.ts +5 -0
  241. package/server/modules/computer-use/semantics/adapters/semantic-adapter.ts +23 -0
  242. package/server/modules/computer-use/semantics/adapters/windows/windows-semantic-adapter.ts +5 -0
  243. package/server/modules/computer-use/semantics/bin/darwin-arm64/CloudCLISemantics +0 -0
  244. package/server/modules/computer-use/semantics/bin/darwin-x64/CloudCLISemantics +0 -0
  245. package/server/modules/computer-use/semantics/bin/win32-arm64/CloudCLISemantics.exe +0 -0
  246. package/server/modules/computer-use/semantics/bin/win32-x64/CloudCLISemantics.exe +0 -0
  247. package/server/modules/computer-use/semantics/helpers/macos/CloudCLISemantics.swift +467 -0
  248. package/server/modules/computer-use/semantics/helpers/semantic-helper-process.ts +124 -0
  249. package/server/modules/computer-use/semantics/helpers/semantic-helper-resolver.ts +97 -0
  250. package/server/modules/computer-use/semantics/helpers/windows/CloudCLISemantics.csproj +11 -0
  251. package/server/modules/computer-use/semantics/helpers/windows/Program.cs +534 -0
  252. package/server/modules/computer-use/semantics/semantic-session-store.ts +87 -0
  253. package/server/modules/computer-use/semantics/semantic-tool-dispatcher.ts +17 -0
  254. package/server/modules/computer-use/semantics/semantic-types.ts +58 -0
  255. package/server/modules/database/index.ts +1 -0
  256. package/server/modules/database/migrations.ts +25 -0
  257. package/server/modules/database/repositories/notification-channel-endpoints.ts +153 -0
  258. package/server/modules/database/repositories/notification-preferences.ts +12 -1
  259. package/server/modules/database/repositories/sessions.db.ts +227 -23
  260. package/server/modules/database/schema.ts +27 -0
  261. package/server/modules/database/tests/sessions-provider-mapping.test.ts +108 -0
  262. package/server/modules/database/{repositories → tests}/sessions.db.integration.test.ts +12 -0
  263. package/server/modules/notifications/index.ts +13 -0
  264. package/server/modules/notifications/notifications.routes.ts +127 -0
  265. package/server/modules/notifications/services/desktop-notification-clients.service.ts +124 -0
  266. package/server/modules/notifications/services/notification-orchestrator.service.js +288 -0
  267. package/server/modules/notifications/websocket/desktop-notifications-websocket.service.ts +109 -0
  268. package/server/modules/projects/services/project-management.service.ts +0 -8
  269. package/server/modules/projects/services/projects-with-sessions-fetch.service.ts +12 -53
  270. package/server/modules/providers/README.md +1 -1
  271. package/server/modules/providers/index.ts +1 -0
  272. package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +26 -1
  273. package/server/modules/providers/list/claude/claude-sessions.provider.ts +9 -14
  274. package/server/modules/providers/list/claude/claude-skills.provider.ts +8 -0
  275. package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +7 -3
  276. package/server/modules/providers/list/codex/codex-sessions.provider.ts +3 -12
  277. package/server/modules/providers/list/codex/codex-skills.provider.ts +8 -0
  278. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +13 -22
  279. package/server/modules/providers/list/cursor/cursor-skills.provider.ts +8 -0
  280. package/server/modules/providers/list/gemini/gemini-models.provider.ts +5 -8
  281. package/server/modules/providers/list/gemini/gemini-sessions.provider.ts +6 -6
  282. package/server/modules/providers/list/gemini/gemini-skills.provider.ts +8 -0
  283. package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +18 -4
  284. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +9 -12
  285. package/server/modules/providers/provider.routes.ts +167 -1
  286. package/server/modules/providers/services/mcp.service.ts +26 -0
  287. package/server/modules/providers/services/provider-capabilities.service.ts +91 -0
  288. package/server/modules/providers/services/provider-models.service.ts +1 -1
  289. package/server/modules/providers/services/sessions-watcher.service.ts +71 -25
  290. package/server/modules/providers/services/sessions.service.ts +79 -4
  291. package/server/modules/providers/services/skills.service.ts +25 -1
  292. package/server/modules/providers/shared/skills/skills.provider.ts +223 -0
  293. package/server/modules/providers/tests/opencode-sessions.test.ts +49 -0
  294. package/server/modules/providers/tests/skills.test.ts +212 -0
  295. package/server/modules/websocket/README.md +33 -27
  296. package/server/modules/websocket/index.ts +1 -0
  297. package/server/modules/websocket/services/chat-run-registry.service.ts +327 -0
  298. package/server/modules/websocket/services/chat-session-writer.service.ts +145 -0
  299. package/server/modules/websocket/services/chat-websocket.service.ts +292 -207
  300. package/server/modules/websocket/services/desktop-agent-websocket.service.ts +51 -0
  301. package/server/modules/websocket/services/shell-websocket.service.ts +108 -32
  302. package/server/modules/websocket/services/websocket-server.service.ts +12 -0
  303. package/server/modules/websocket/tests/chat-run-registry.test.ts +244 -0
  304. package/server/openai-codex.js +24 -14
  305. package/server/opencode-cli.js +21 -8
  306. package/server/opencode-cli.test.js +20 -1
  307. package/server/routes/settings.js +6 -1
  308. package/server/services/notification-orchestrator.js +3 -224
  309. package/server/services/tests/notification-orchestrator.test.js +80 -0
  310. package/server/shared/interfaces.ts +15 -0
  311. package/server/shared/tests/slice-tail-page.test.ts +42 -0
  312. package/server/shared/types.ts +84 -1
  313. package/server/shared/utils.ts +95 -1
  314. package/server/voice-proxy.js +224 -0
  315. package/dist/assets/index-73Xw3i9v.css +0 -32
  316. package/dist/assets/index-BIHaviaA.js +0 -1361
  317. package/dist/modelConstants.js +0 -854
  318. package/dist-server/server/modules/database/repositories/projects.db.integration.test.js.map +0 -1
  319. package/dist-server/server/modules/database/repositories/sessions.db.integration.test.js.map +0 -1
  320. package/dist-server/server/shared/claude-cli-path.test.js.map +0 -1
  321. package/public/modelConstants.js +0 -854
  322. /package/dist-server/server/modules/database/{repositories → tests}/projects.db.integration.test.js +0 -0
  323. /package/server/modules/database/{repositories → tests}/projects.db.integration.test.ts +0 -0
  324. /package/server/shared/{claude-cli-path.test.ts → tests/claude-cli-path.test.ts} +0 -0
@@ -0,0 +1,384 @@
1
+ #!/usr/bin/env node
2
+ import './load-env.js';
3
+
4
+ type JsonRpcRequest = {
5
+ jsonrpc: '2.0';
6
+ id?: string | number | null;
7
+ method: string;
8
+ params?: Record<string, unknown>;
9
+ };
10
+
11
+ type ToolDefinition = {
12
+ name: string;
13
+ description: string;
14
+ inputSchema: Record<string, unknown>;
15
+ };
16
+
17
+ const textResponse = (text: string) => ({
18
+ content: [{ type: 'text', text }],
19
+ });
20
+
21
+ const jsonResponse = (value: unknown) => textResponse(JSON.stringify(value, null, 2));
22
+
23
+ const readString = (value: unknown, name: string): string => {
24
+ if (typeof value !== 'string' || value.trim() === '') {
25
+ throw new Error(`${name} is required.`);
26
+ }
27
+ return value.trim();
28
+ };
29
+
30
+ const readOptionalString = (value: unknown): string | undefined =>
31
+ typeof value === 'string' && value.trim() ? value.trim() : undefined;
32
+
33
+ const readNumber = (value: unknown): number | undefined =>
34
+ typeof value === 'number' && Number.isFinite(value) ? value : undefined;
35
+
36
+ const apiUrl = (process.env.CLOUDCLI_BROWSER_USE_API_URL || 'http://127.0.0.1:3001/api/browser-use-mcp').replace(/\/$/, '');
37
+ const apiToken = process.env.CLOUDCLI_BROWSER_USE_MCP_TOKEN || '';
38
+ const API_TIMEOUT_MS = Number.parseInt(process.env.CLOUDCLI_BROWSER_USE_API_TIMEOUT_MS || '60000', 10);
39
+
40
+ async function callBrowserUseApi(toolName: string, input: Record<string, unknown>) {
41
+ if (!apiToken) {
42
+ throw new Error('CLOUDCLI_BROWSER_USE_MCP_TOKEN is not configured.');
43
+ }
44
+
45
+ const response = await fetch(`${apiUrl}/tools/${encodeURIComponent(toolName)}`, {
46
+ method: 'POST',
47
+ headers: {
48
+ Authorization: `Bearer ${apiToken}`,
49
+ 'Content-Type': 'application/json',
50
+ },
51
+ body: JSON.stringify(input),
52
+ signal: AbortSignal.timeout(API_TIMEOUT_MS),
53
+ });
54
+ const data = await response.json() as { success?: boolean; data?: unknown; error?: string };
55
+ if (!response.ok || data.success === false) {
56
+ throw new Error(data.error || `Browser API request failed (${response.status})`);
57
+ }
58
+ return data.data;
59
+ }
60
+
61
+ const sessionIdSchema = {
62
+ type: 'object',
63
+ properties: {
64
+ sessionId: { type: 'string', description: 'Browser session id.' },
65
+ },
66
+ required: ['sessionId'],
67
+ };
68
+
69
+ const tools: ToolDefinition[] = [
70
+ {
71
+ name: 'browser_create_session',
72
+ description: 'Create a temporary Browser session that the agent can control. Optionally provide a background profileName to reuse cookies and storage.',
73
+ inputSchema: {
74
+ type: 'object',
75
+ properties: {
76
+ profileName: { type: 'string', description: 'Optional background profile name for persistent browser storage.' },
77
+ },
78
+ },
79
+ },
80
+ {
81
+ name: 'browser_list_sessions',
82
+ description: 'List Browser sessions currently available to agents.',
83
+ inputSchema: { type: 'object', properties: {} },
84
+ },
85
+ {
86
+ name: 'browser_snapshot',
87
+ description: 'Capture current page metadata, screenshot data URL, and visible body text for a Browser session.',
88
+ inputSchema: sessionIdSchema,
89
+ },
90
+ {
91
+ name: 'browser_take_screenshot',
92
+ description: 'Capture the latest screenshot for a Browser session.',
93
+ inputSchema: sessionIdSchema,
94
+ },
95
+ {
96
+ name: 'browser_navigate',
97
+ description: 'Navigate a Browser session to an HTTP or HTTPS URL.',
98
+ inputSchema: {
99
+ type: 'object',
100
+ properties: {
101
+ sessionId: { type: 'string' },
102
+ url: { type: 'string' },
103
+ },
104
+ required: ['sessionId', 'url'],
105
+ },
106
+ },
107
+ {
108
+ name: 'browser_click',
109
+ description: 'Click an element by CSS selector, visible text, or x/y coordinates.',
110
+ inputSchema: {
111
+ type: 'object',
112
+ properties: {
113
+ sessionId: { type: 'string' },
114
+ selector: { type: 'string' },
115
+ text: { type: 'string' },
116
+ x: { type: 'number' },
117
+ y: { type: 'number' },
118
+ },
119
+ required: ['sessionId'],
120
+ },
121
+ },
122
+ {
123
+ name: 'browser_type',
124
+ description: 'Type text into the focused page or fill a CSS selector. Set submit to press Enter after typing.',
125
+ inputSchema: {
126
+ type: 'object',
127
+ properties: {
128
+ sessionId: { type: 'string' },
129
+ selector: { type: 'string' },
130
+ text: { type: 'string' },
131
+ submit: { type: 'boolean' },
132
+ },
133
+ required: ['sessionId', 'text'],
134
+ },
135
+ },
136
+ {
137
+ name: 'browser_fill_form',
138
+ description: 'Fill multiple form fields using CSS selectors.',
139
+ inputSchema: {
140
+ type: 'object',
141
+ properties: {
142
+ sessionId: { type: 'string' },
143
+ fields: {
144
+ type: 'array',
145
+ items: {
146
+ type: 'object',
147
+ properties: {
148
+ selector: { type: 'string' },
149
+ value: { type: 'string' },
150
+ },
151
+ required: ['selector', 'value'],
152
+ },
153
+ },
154
+ },
155
+ required: ['sessionId', 'fields'],
156
+ },
157
+ },
158
+ {
159
+ name: 'browser_press_key',
160
+ description: 'Press a keyboard key, for example Enter, Escape, Tab, or Control+A.',
161
+ inputSchema: {
162
+ type: 'object',
163
+ properties: {
164
+ sessionId: { type: 'string' },
165
+ key: { type: 'string' },
166
+ },
167
+ required: ['sessionId', 'key'],
168
+ },
169
+ },
170
+ {
171
+ name: 'browser_select_option',
172
+ description: 'Select option values in a select element found by CSS selector.',
173
+ inputSchema: {
174
+ type: 'object',
175
+ properties: {
176
+ sessionId: { type: 'string' },
177
+ selector: { type: 'string' },
178
+ values: { type: 'array', items: { type: 'string' } },
179
+ },
180
+ required: ['sessionId', 'selector', 'values'],
181
+ },
182
+ },
183
+ {
184
+ name: 'browser_wait_for',
185
+ description: 'Wait for visible text, a URL pattern, or a short timeout.',
186
+ inputSchema: {
187
+ type: 'object',
188
+ properties: {
189
+ sessionId: { type: 'string' },
190
+ text: { type: 'string' },
191
+ url: { type: 'string' },
192
+ timeoutMs: { type: 'number' },
193
+ },
194
+ required: ['sessionId'],
195
+ },
196
+ },
197
+ {
198
+ name: 'browser_tabs',
199
+ description: 'List, open, select, or close tabs in a Browser session.',
200
+ inputSchema: {
201
+ type: 'object',
202
+ properties: {
203
+ sessionId: { type: 'string' },
204
+ action: { type: 'string', enum: ['list', 'new', 'select', 'close'] },
205
+ index: { type: 'number' },
206
+ url: { type: 'string' },
207
+ },
208
+ required: ['sessionId'],
209
+ },
210
+ },
211
+ {
212
+ name: 'browser_close_session',
213
+ description: 'Stop a Browser session controlled by agents.',
214
+ inputSchema: sessionIdSchema,
215
+ },
216
+ ];
217
+
218
+ async function callTool(name: string, args: Record<string, unknown>) {
219
+ switch (name) {
220
+ case 'browser_create_session':
221
+ return jsonResponse(await callBrowserUseApi(name, {
222
+ profileName: readOptionalString(args.profileName),
223
+ }));
224
+ case 'browser_list_sessions':
225
+ return jsonResponse(await callBrowserUseApi(name, {}));
226
+ case 'browser_snapshot':
227
+ return jsonResponse(await callBrowserUseApi(name, { sessionId: readString(args.sessionId, 'sessionId') }));
228
+ case 'browser_take_screenshot': {
229
+ return jsonResponse(await callBrowserUseApi(name, { sessionId: readString(args.sessionId, 'sessionId') }));
230
+ }
231
+ case 'browser_navigate':
232
+ return jsonResponse(await callBrowserUseApi(name, {
233
+ sessionId: readString(args.sessionId, 'sessionId'),
234
+ url: readString(args.url, 'url'),
235
+ }));
236
+ case 'browser_click':
237
+ return jsonResponse(await callBrowserUseApi(name, {
238
+ sessionId: readString(args.sessionId, 'sessionId'),
239
+ selector: readOptionalString(args.selector),
240
+ text: readOptionalString(args.text),
241
+ x: readNumber(args.x),
242
+ y: readNumber(args.y),
243
+ }));
244
+ case 'browser_type':
245
+ return jsonResponse(await callBrowserUseApi(name, {
246
+ sessionId: readString(args.sessionId, 'sessionId'),
247
+ selector: readOptionalString(args.selector),
248
+ text: readString(args.text, 'text'),
249
+ submit: args.submit === true,
250
+ }));
251
+ case 'browser_fill_form': {
252
+ const fields = Array.isArray(args.fields)
253
+ ? args.fields.map((field) => {
254
+ const record = field as Record<string, unknown>;
255
+ return {
256
+ selector: readString(record.selector, 'field.selector'),
257
+ value: readString(record.value, 'field.value'),
258
+ };
259
+ })
260
+ : [];
261
+ return jsonResponse(await callBrowserUseApi(name, {
262
+ sessionId: readString(args.sessionId, 'sessionId'),
263
+ fields,
264
+ }));
265
+ }
266
+ case 'browser_press_key':
267
+ return jsonResponse(await callBrowserUseApi(name, {
268
+ sessionId: readString(args.sessionId, 'sessionId'),
269
+ key: readString(args.key, 'key'),
270
+ }));
271
+ case 'browser_select_option':
272
+ return jsonResponse(await callBrowserUseApi(name, {
273
+ sessionId: readString(args.sessionId, 'sessionId'),
274
+ selector: readString(args.selector, 'selector'),
275
+ values: Array.isArray(args.values) ? args.values.filter((value): value is string => typeof value === 'string') : [],
276
+ }));
277
+ case 'browser_wait_for':
278
+ return jsonResponse(await callBrowserUseApi(name, {
279
+ sessionId: readString(args.sessionId, 'sessionId'),
280
+ text: readOptionalString(args.text),
281
+ url: readOptionalString(args.url),
282
+ timeoutMs: readNumber(args.timeoutMs),
283
+ }));
284
+ case 'browser_tabs':
285
+ return jsonResponse(await callBrowserUseApi(name, {
286
+ sessionId: readString(args.sessionId, 'sessionId'),
287
+ action: args.action === 'new' || args.action === 'select' || args.action === 'close' || args.action === 'list'
288
+ ? args.action
289
+ : undefined,
290
+ index: readNumber(args.index),
291
+ url: readOptionalString(args.url),
292
+ }));
293
+ case 'browser_close_session':
294
+ return jsonResponse(await callBrowserUseApi(name, { sessionId: readString(args.sessionId, 'sessionId') }));
295
+ default:
296
+ throw new Error(`Unknown tool: ${name}`);
297
+ }
298
+ }
299
+
300
+ async function handleMessage(message: JsonRpcRequest) {
301
+ if (message.method === 'initialize') {
302
+ return {
303
+ protocolVersion: '2024-11-05',
304
+ capabilities: { tools: {} },
305
+ serverInfo: { name: 'cloudcli-browser', version: '1.0.0' },
306
+ };
307
+ }
308
+
309
+ if (message.method === 'tools/list') {
310
+ return { tools };
311
+ }
312
+
313
+ if (message.method === 'tools/call') {
314
+ const params = message.params || {};
315
+ const name = readString(params.name, 'name');
316
+ const args = (params.arguments && typeof params.arguments === 'object'
317
+ ? params.arguments
318
+ : {}) as Record<string, unknown>;
319
+ return callTool(name, args);
320
+ }
321
+
322
+ if (message.method.startsWith('notifications/')) {
323
+ return undefined;
324
+ }
325
+
326
+ throw new Error(`Unsupported method: ${message.method}`);
327
+ }
328
+
329
+ function writeMessage(message: Record<string, unknown>) {
330
+ // MCP stdio transport uses newline-delimited JSON (one JSON-RPC message per line,
331
+ // no embedded newlines). This is NOT the LSP Content-Length framing.
332
+ process.stdout.write(`${JSON.stringify(message)}\n`);
333
+ }
334
+
335
+ function sendResult(id: string | number | null | undefined, result: unknown) {
336
+ if (id === undefined) {
337
+ return;
338
+ }
339
+ writeMessage({ jsonrpc: '2.0', id, result });
340
+ }
341
+
342
+ function sendError(id: string | number | null | undefined, error: unknown) {
343
+ if (id === undefined) {
344
+ return;
345
+ }
346
+ writeMessage({
347
+ jsonrpc: '2.0',
348
+ id,
349
+ error: {
350
+ code: -32000,
351
+ message: error instanceof Error ? error.message : String(error),
352
+ },
353
+ });
354
+ }
355
+
356
+ let buffer = '';
357
+
358
+ process.stdin.on('data', (chunk) => {
359
+ buffer += chunk.toString('utf8');
360
+ let newlineIndex: number;
361
+ while ((newlineIndex = buffer.indexOf('\n')) !== -1) {
362
+ const rawMessage = buffer.slice(0, newlineIndex).trim();
363
+ buffer = buffer.slice(newlineIndex + 1);
364
+ if (!rawMessage) {
365
+ continue;
366
+ }
367
+
368
+ void (async () => {
369
+ let request: JsonRpcRequest;
370
+ try {
371
+ request = JSON.parse(rawMessage) as JsonRpcRequest;
372
+ } catch (error) {
373
+ sendError(null, error);
374
+ return;
375
+ }
376
+ try {
377
+ const result = await handleMessage(request);
378
+ sendResult(request.id, result);
379
+ } catch (error) {
380
+ sendError(request.id, error);
381
+ }
382
+ })();
383
+ }
384
+ });
@@ -28,10 +28,14 @@ import {
28
28
  } from './services/notification-orchestrator.js';
29
29
  import { sessionsService } from './modules/providers/services/sessions.service.js';
30
30
  import { providerAuthService } from './modules/providers/services/provider-auth.service.js';
31
- import { createNormalizedMessage } from './shared/utils.js';
31
+ import { createCompleteMessage, createNormalizedMessage } from './shared/utils.js';
32
32
 
33
33
  const activeSessions = new Map();
34
34
  const pendingToolApprovals = new Map();
35
+ // Sessions cancelled via abort-session. The abort handler already sent the
36
+ // terminal `complete` (aborted: true) to the client, so the run loop must not
37
+ // emit a second one when its generator winds down.
38
+ const abortedSessionIds = new Set();
35
39
 
36
40
  const TOOL_APPROVAL_TIMEOUT_MS = parseInt(process.env.CLAUDE_TOOL_APPROVAL_TIMEOUT_MS, 10) || 55000;
37
41
 
@@ -731,14 +735,18 @@ async function queryClaudeSDK(command, options = {}, ws) {
731
735
  // Clean up temporary image files
732
736
  await cleanupTempFiles(tempImagePaths, tempDir);
733
737
 
734
- // Send completion event
735
- ws.send(createNormalizedMessage({ kind: 'complete', exitCode: 0, isNewSession: !sessionId && !!command, sessionId: capturedSessionId, provider: 'claude' }));
738
+ // Send the terminal completion event — skipped for aborted runs, whose
739
+ // terminal `complete` (aborted: true) was already sent by abort-session.
740
+ const wasAborted = capturedSessionId ? abortedSessionIds.delete(capturedSessionId) : false;
741
+ if (!wasAborted) {
742
+ ws.send(createCompleteMessage({ provider: 'claude', sessionId: capturedSessionId || sessionId || null, exitCode: 0 }));
743
+ }
736
744
  notifyRunStopped({
737
745
  userId: ws?.userId || null,
738
746
  provider: 'claude',
739
747
  sessionId: capturedSessionId || sessionId || null,
740
748
  sessionName: sessionSummary,
741
- stopReason: 'completed'
749
+ stopReason: wasAborted ? 'aborted' : 'completed'
742
750
  });
743
751
  // Complete
744
752
 
@@ -753,14 +761,22 @@ async function queryClaudeSDK(command, options = {}, ws) {
753
761
  // Clean up temporary image files on error
754
762
  await cleanupTempFiles(tempImagePaths, tempDir);
755
763
 
764
+ const wasAborted = capturedSessionId ? abortedSessionIds.delete(capturedSessionId) : false;
765
+ if (wasAborted) {
766
+ // The abort already produced the terminal complete; a generator throw
767
+ // caused by interrupt() is expected noise, not a user-facing error.
768
+ return;
769
+ }
770
+
756
771
  // Check if Claude CLI is installed for a clearer error message
757
772
  const installed = await providerAuthService.isProviderInstalled('claude');
758
773
  const errorContent = !installed
759
774
  ? 'Claude Code is not installed. Please install it first: https://docs.anthropic.com/en/docs/claude-code'
760
775
  : error.message;
761
776
 
762
- // Send error to WebSocket
777
+ // Send error to WebSocket, then the terminal complete
763
778
  ws.send(createNormalizedMessage({ kind: 'error', content: errorContent, sessionId: capturedSessionId || sessionId || null, provider: 'claude' }));
779
+ ws.send(createCompleteMessage({ provider: 'claude', sessionId: capturedSessionId || sessionId || null, exitCode: 1 }));
764
780
  notifyRunFailed({
765
781
  userId: ws?.userId || null,
766
782
  provider: 'claude',
@@ -787,6 +803,10 @@ async function abortClaudeSDKSession(sessionId) {
787
803
  try {
788
804
  console.log(`Aborting SDK session: ${sessionId}`);
789
805
 
806
+ // Mark before interrupting so the run loop knows not to emit its own
807
+ // terminal complete (the abort handler sends the aborted one).
808
+ abortedSessionIds.add(sessionId);
809
+
790
810
  // Call interrupt() on the query instance
791
811
  await session.instance.interrupt();
792
812
 
@@ -802,6 +822,8 @@ async function abortClaudeSDKSession(sessionId) {
802
822
  return true;
803
823
  } catch (error) {
804
824
  console.error(`Error aborting session ${sessionId}:`, error);
825
+ // The run keeps going; let it emit its own terminal complete.
826
+ abortedSessionIds.delete(sessionId);
805
827
  return false;
806
828
  }
807
829
  }
package/server/cli.js CHANGED
@@ -8,6 +8,7 @@
8
8
  * (no args) - Start the server (default)
9
9
  * start - Start the server
10
10
  * sandbox - Manage Docker sandbox environments
11
+ * browser-use-mcp - Run Browser MCP stdio server
11
12
  * status - Show configuration and data locations
12
13
  * help - Show help information
13
14
  * version - Show version information
@@ -154,12 +155,13 @@ Usage:
154
155
  cloudcli [command] [options]
155
156
 
156
157
  Commands:
157
- start Start the CloudCLI server (default)
158
- sandbox Manage Docker sandbox environments
159
- status Show configuration and data locations
160
- update Update to the latest version
161
- help Show this help information
162
- version Show version information
158
+ start Start the CloudCLI server (default)
159
+ sandbox Manage Docker sandbox environments
160
+ browser-use-mcp Run the 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
163
165
 
164
166
  Options:
165
167
  -p, --port <port> Set server port (default: 3001)
@@ -605,6 +607,10 @@ async function startServer() {
605
607
  await import('./index.js');
606
608
  }
607
609
 
610
+ async function startBrowserUseMcp() {
611
+ await import('./browser-use-mcp.js');
612
+ }
613
+
608
614
  // Parse CLI arguments
609
615
  function parseArgs(args) {
610
616
  const parsed = { command: 'start', options: {} };
@@ -658,6 +664,9 @@ async function main() {
658
664
  case 'sandbox':
659
665
  await sandboxCommand(remainingArgs || []);
660
666
  break;
667
+ case 'browser-use-mcp':
668
+ await startBrowserUseMcp();
669
+ break;
661
670
  case 'status':
662
671
  case 'info':
663
672
  showStatus();