@cloudcli-ai/cloudcli 1.36.3 → 1.37.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 (535) hide show
  1. package/dist/assets/index-DSlds633.css +32 -0
  2. package/dist/assets/{index-CcCsKitq.js → index-eGqPeIEu.js} +375 -267
  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 +96 -0
  64. package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -0
  65. package/dist-server/server/modules/database/index.js +1 -0
  66. package/dist-server/server/modules/database/index.js.map +1 -1
  67. package/dist-server/server/modules/database/migrations.js +13 -0
  68. package/dist-server/server/modules/database/migrations.js.map +1 -1
  69. package/dist-server/server/modules/database/repositories/sessions.db.js +14 -1
  70. package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
  71. package/dist-server/server/modules/database/schema.js +4 -0
  72. package/dist-server/server/modules/database/schema.js.map +1 -1
  73. package/dist-server/server/modules/file-tree/file-tree.module.js +91 -0
  74. package/dist-server/server/modules/file-tree/file-tree.module.js.map +1 -0
  75. package/dist-server/server/modules/file-tree/file-tree.routes.js +208 -0
  76. package/dist-server/server/modules/file-tree/file-tree.routes.js.map +1 -0
  77. package/dist-server/server/modules/file-tree/file-tree.service.js +544 -0
  78. package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -0
  79. package/dist-server/server/modules/file-tree/index.js +3 -0
  80. package/dist-server/server/modules/file-tree/index.js.map +1 -0
  81. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js +123 -0
  82. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js.map +1 -0
  83. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +184 -0
  84. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -0
  85. package/dist-server/server/modules/git/git-parsing.service.js +61 -0
  86. package/dist-server/server/modules/git/git-parsing.service.js.map +1 -0
  87. package/dist-server/server/modules/git/git.module.js +14 -0
  88. package/dist-server/server/modules/git/git.module.js.map +1 -0
  89. package/dist-server/server/modules/git/git.routes.js +1339 -0
  90. package/dist-server/server/modules/git/git.routes.js.map +1 -0
  91. package/dist-server/server/modules/git/index.js +3 -0
  92. package/dist-server/server/modules/git/index.js.map +1 -0
  93. package/dist-server/server/modules/git/tests/git-init.routes.test.js +48 -0
  94. package/dist-server/server/modules/git/tests/git-init.routes.test.js.map +1 -0
  95. package/dist-server/server/{routes → modules/git/tests}/git.test.js +1 -1
  96. package/dist-server/server/modules/git/tests/git.test.js.map +1 -0
  97. package/dist-server/server/modules/notifications/index.js +15 -1
  98. package/dist-server/server/modules/notifications/index.js.map +1 -1
  99. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js +44 -0
  100. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js.map +1 -0
  101. package/dist-server/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.js} +3 -2
  102. package/dist-server/server/modules/notifications/vapid-keys.service.js.map +1 -0
  103. package/dist-server/server/modules/plugins/index.js +9 -0
  104. package/dist-server/server/modules/plugins/index.js.map +1 -0
  105. package/dist-server/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.js} +3 -2
  106. package/dist-server/server/modules/plugins/plugin-process.service.js.map +1 -0
  107. package/dist-server/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.js} +2 -1
  108. package/dist-server/server/modules/plugins/plugin-registry.service.js.map +1 -0
  109. package/dist-server/server/modules/plugins/plugins.module.js +30 -0
  110. package/dist-server/server/modules/plugins/plugins.module.js.map +1 -0
  111. package/dist-server/server/modules/plugins/plugins.routes.js +70 -0
  112. package/dist-server/server/modules/plugins/plugins.routes.js.map +1 -0
  113. package/dist-server/server/modules/plugins/plugins.service.js +123 -0
  114. package/dist-server/server/modules/plugins/plugins.service.js.map +1 -0
  115. package/dist-server/server/modules/plugins/tests/plugins.service.test.js +28 -0
  116. package/dist-server/server/modules/plugins/tests/plugins.service.test.js.map +1 -0
  117. package/dist-server/server/modules/projects/index.js +5 -0
  118. package/dist-server/server/modules/projects/index.js.map +1 -1
  119. package/dist-server/server/modules/providers/index.js +3 -0
  120. package/dist-server/server/modules/providers/index.js.map +1 -1
  121. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +6 -0
  122. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -1
  123. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +1 -4
  124. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
  125. package/dist-server/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +62 -41
  126. package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -0
  127. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +6 -4
  128. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -1
  129. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +23 -4
  130. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
  131. package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
  132. package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
  133. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +1 -4
  134. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
  135. package/dist-server/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +48 -34
  136. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -0
  137. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +290 -6
  138. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
  139. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +5 -0
  140. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -1
  141. package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
  142. package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
  143. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +1 -4
  144. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -1
  145. package/dist-server/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +40 -28
  146. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -0
  147. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +21 -14
  148. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -1
  149. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +2 -0
  150. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -1
  151. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +7 -5
  152. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
  153. package/dist-server/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +38 -25
  154. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js.map +1 -0
  155. package/dist-server/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +27 -4
  156. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js.map +1 -0
  157. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +11 -5
  158. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -1
  159. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js +2 -0
  160. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js.map +1 -1
  161. package/dist-server/server/modules/providers/provider.routes.js +33 -9
  162. package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
  163. package/dist-server/server/modules/providers/services/provider-capabilities.service.js +5 -1
  164. package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
  165. package/dist-server/server/modules/providers/services/provider-models.service.js +110 -15
  166. package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
  167. package/dist-server/server/modules/providers/services/provider-runtime.service.js +66 -0
  168. package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -0
  169. package/dist-server/server/modules/providers/services/provider-token-usage.service.js +268 -0
  170. package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -0
  171. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +2 -0
  172. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
  173. package/dist-server/server/modules/providers/services/sessions.service.js +54 -0
  174. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
  175. package/dist-server/server/modules/providers/shared/base/abstract.provider.js +2 -3
  176. package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -1
  177. package/dist-server/server/modules/providers/tests/claude-auth.test.js +122 -0
  178. package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -0
  179. package/dist-server/server/modules/providers/tests/claude-sessions.test.js +44 -0
  180. package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -0
  181. package/dist-server/server/modules/providers/tests/codex-sessions.test.js +36 -0
  182. package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
  183. package/dist-server/server/modules/providers/tests/{provider-image-history.test.js → provider-attachment-history.test.js} +60 -2
  184. package/dist-server/server/modules/providers/tests/provider-attachment-history.test.js.map +1 -0
  185. package/dist-server/server/modules/providers/tests/provider-models.service.test.js +148 -61
  186. package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
  187. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +130 -0
  188. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -0
  189. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +165 -0
  190. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -0
  191. package/dist-server/server/modules/providers/tests/sessions-details.test.js +62 -0
  192. package/dist-server/server/modules/providers/tests/sessions-details.test.js.map +1 -0
  193. package/dist-server/server/modules/providers/tests/skills.test.js +4 -2
  194. package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
  195. package/dist-server/server/modules/settings/index.js +3 -0
  196. package/dist-server/server/modules/settings/index.js.map +1 -0
  197. package/dist-server/server/modules/settings/settings.module.js +35 -0
  198. package/dist-server/server/modules/settings/settings.module.js.map +1 -0
  199. package/dist-server/server/modules/settings/settings.routes.js +34 -0
  200. package/dist-server/server/modules/settings/settings.routes.js.map +1 -0
  201. package/dist-server/server/modules/settings/settings.service.js +116 -0
  202. package/dist-server/server/modules/settings/settings.service.js.map +1 -0
  203. package/dist-server/server/modules/settings/tests/settings.service.test.js +48 -0
  204. package/dist-server/server/modules/settings/tests/settings.service.test.js.map +1 -0
  205. package/dist-server/server/modules/system/index.js +3 -0
  206. package/dist-server/server/modules/system/index.js.map +1 -0
  207. package/dist-server/server/modules/system/system.module.js +44 -0
  208. package/dist-server/server/modules/system/system.module.js.map +1 -0
  209. package/dist-server/server/modules/system/system.routes.js +16 -0
  210. package/dist-server/server/modules/system/system.routes.js.map +1 -0
  211. package/dist-server/server/modules/system/system.service.js +45 -0
  212. package/dist-server/server/modules/system/system.service.js.map +1 -0
  213. package/dist-server/server/modules/system/tests/system.service.test.js +100 -0
  214. package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -0
  215. package/dist-server/server/modules/taskmaster/index.js +3 -0
  216. package/dist-server/server/modules/taskmaster/index.js.map +1 -0
  217. package/dist-server/server/modules/taskmaster/taskmaster.module.js +20 -0
  218. package/dist-server/server/modules/taskmaster/taskmaster.module.js.map +1 -0
  219. package/dist-server/server/modules/taskmaster/taskmaster.routes.js +1372 -0
  220. package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -0
  221. package/dist-server/server/modules/taskmaster/taskmaster.service.js +107 -0
  222. package/dist-server/server/modules/taskmaster/taskmaster.service.js.map +1 -0
  223. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +132 -0
  224. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -0
  225. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js +85 -0
  226. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js.map +1 -0
  227. package/dist-server/server/modules/user/index.js +3 -0
  228. package/dist-server/server/modules/user/index.js.map +1 -0
  229. package/dist-server/server/modules/user/tests/user.service.test.js +53 -0
  230. package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -0
  231. package/dist-server/server/modules/user/user.module.js +47 -0
  232. package/dist-server/server/modules/user/user.module.js.map +1 -0
  233. package/dist-server/server/modules/user/user.routes.js +44 -0
  234. package/dist-server/server/modules/user/user.routes.js.map +1 -0
  235. package/dist-server/server/modules/user/user.service.js +59 -0
  236. package/dist-server/server/modules/user/user.service.js.map +1 -0
  237. package/dist-server/server/modules/voice/index.js +3 -0
  238. package/dist-server/server/modules/voice/index.js.map +1 -0
  239. package/dist-server/server/modules/voice/tests/voice.service.test.js +86 -0
  240. package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -0
  241. package/dist-server/server/modules/voice/voice.module.js +44 -0
  242. package/dist-server/server/modules/voice/voice.module.js.map +1 -0
  243. package/dist-server/server/modules/voice/voice.routes.js +87 -0
  244. package/dist-server/server/modules/voice/voice.routes.js.map +1 -0
  245. package/dist-server/server/modules/voice/voice.service.js +148 -0
  246. package/dist-server/server/modules/voice/voice.service.js.map +1 -0
  247. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +2 -2
  248. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +40 -29
  249. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
  250. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +76 -8
  251. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
  252. package/dist-server/server/modules/websocket/services/websocket-server.service.js +51 -20
  253. package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -1
  254. package/dist-server/server/modules/websocket/tests/{chat-image-filter.test.js → chat-attachment-filter.test.js} +10 -3
  255. package/dist-server/server/modules/websocket/tests/chat-attachment-filter.test.js.map +1 -0
  256. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +97 -0
  257. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -0
  258. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js +61 -0
  259. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js.map +1 -0
  260. package/dist-server/server/modules/worktrees/index.js +3 -0
  261. package/dist-server/server/modules/worktrees/index.js.map +1 -0
  262. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js +37 -0
  263. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js.map +1 -0
  264. package/dist-server/server/modules/worktrees/services/worktree-create.service.js +67 -0
  265. package/dist-server/server/modules/worktrees/services/worktree-create.service.js.map +1 -0
  266. package/dist-server/server/modules/worktrees/services/worktree-git.service.js +172 -0
  267. package/dist-server/server/modules/worktrees/services/worktree-git.service.js.map +1 -0
  268. package/dist-server/server/modules/worktrees/services/worktree-list.service.js +91 -0
  269. package/dist-server/server/modules/worktrees/services/worktree-list.service.js.map +1 -0
  270. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js +118 -0
  271. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js.map +1 -0
  272. package/dist-server/server/modules/worktrees/services/worktree-open.service.js +58 -0
  273. package/dist-server/server/modules/worktrees/services/worktree-open.service.js.map +1 -0
  274. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +65 -0
  275. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js.map +1 -0
  276. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js +58 -0
  277. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js.map +1 -0
  278. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js +85 -0
  279. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js.map +1 -0
  280. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js +58 -0
  281. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js.map +1 -0
  282. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js +34 -0
  283. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js.map +1 -0
  284. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js +137 -0
  285. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js.map +1 -0
  286. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js +99 -0
  287. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js.map +1 -0
  288. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js +157 -0
  289. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js.map +1 -0
  290. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js +167 -0
  291. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js.map +1 -0
  292. package/dist-server/server/modules/worktrees/worktrees.module.js +97 -0
  293. package/dist-server/server/modules/worktrees/worktrees.module.js.map +1 -0
  294. package/dist-server/server/modules/worktrees/worktrees.routes.js +84 -0
  295. package/dist-server/server/modules/worktrees/worktrees.routes.js.map +1 -0
  296. package/dist-server/server/shared/image-attachments.js +90 -17
  297. package/dist-server/server/shared/image-attachments.js.map +1 -1
  298. package/dist-server/server/shared/tests/image-attachments.test.js +43 -1
  299. package/dist-server/server/shared/tests/image-attachments.test.js.map +1 -1
  300. package/dist-server/server/shared/utils.js +66 -142
  301. package/dist-server/server/shared/utils.js.map +1 -1
  302. package/package.json +8 -4
  303. package/server/index.ts +401 -0
  304. package/server/{load-env.js → load-env.ts} +18 -5
  305. package/server/modules/agent/agent.module.ts +51 -0
  306. package/server/modules/agent/agent.routes.ts +1287 -0
  307. package/server/modules/agent/index.ts +2 -0
  308. package/server/modules/agent/tests/agent.routes.test.ts +205 -0
  309. package/server/modules/assets/assets.routes.ts +63 -16
  310. package/server/modules/assets/index.ts +2 -2
  311. package/server/modules/assets/services/image-assets.service.ts +46 -1
  312. package/server/modules/assets/tests/image-assets.service.test.ts +28 -0
  313. package/server/{middleware/auth.js → modules/auth/auth.middleware.ts} +38 -7
  314. package/server/modules/auth/auth.module.ts +38 -0
  315. package/server/modules/auth/auth.routes.ts +57 -0
  316. package/server/modules/auth/auth.service.ts +155 -0
  317. package/server/modules/auth/index.ts +9 -0
  318. package/server/modules/auth/tests/auth.service.test.ts +95 -0
  319. package/server/{browser-use-mcp.ts → modules/browser-use/browser-use-mcp.ts} +3 -1
  320. package/server/modules/browser-use/browser-use.service.ts +3 -4
  321. package/server/modules/browser-use/index.ts +8 -0
  322. package/server/modules/cli/cli.module.ts +96 -0
  323. package/server/modules/cli/cli.service.ts +281 -0
  324. package/server/modules/cli/cli.ts +13 -0
  325. package/server/modules/cli/index.ts +2 -0
  326. package/server/modules/cli/sandbox.service.ts +413 -0
  327. package/server/modules/cli/tests/cli.service.test.ts +91 -0
  328. package/server/modules/cli/tests/sandbox.service.test.ts +61 -0
  329. package/server/modules/commands/commands.module.ts +22 -0
  330. package/server/{routes/commands.js → modules/commands/commands.routes.ts} +44 -36
  331. package/server/modules/commands/index.ts +2 -0
  332. package/server/modules/commands/tests/commands.test.ts +119 -0
  333. package/server/modules/database/index.ts +1 -0
  334. package/server/modules/database/migrations.ts +15 -0
  335. package/server/modules/database/repositories/sessions.db.ts +19 -1
  336. package/server/modules/database/schema.ts +4 -0
  337. package/server/modules/file-tree/file-tree.module.ts +112 -0
  338. package/server/modules/file-tree/file-tree.routes.ts +258 -0
  339. package/server/modules/file-tree/file-tree.service.ts +616 -0
  340. package/server/modules/file-tree/index.ts +2 -0
  341. package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -0
  342. package/server/modules/file-tree/tests/file-tree.service.test.ts +220 -0
  343. package/server/modules/git/git-parsing.service.ts +66 -0
  344. package/server/modules/git/git.module.ts +22 -0
  345. package/server/{routes/git.js → modules/git/git.routes.ts} +91 -132
  346. package/server/modules/git/index.ts +2 -0
  347. package/server/modules/git/tests/git-init.routes.test.ts +52 -0
  348. package/server/{routes/git.test.js → modules/git/tests/git.test.ts} +3 -3
  349. package/server/modules/notifications/index.ts +9 -0
  350. package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -0
  351. package/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.ts} +3 -1
  352. package/server/modules/plugins/index.ts +9 -0
  353. package/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.ts} +3 -1
  354. package/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.ts} +1 -0
  355. package/server/modules/plugins/plugins.module.ts +33 -0
  356. package/server/modules/plugins/plugins.routes.ts +66 -0
  357. package/server/modules/plugins/plugins.service.ts +147 -0
  358. package/server/modules/plugins/tests/plugins.service.test.ts +32 -0
  359. package/server/modules/projects/index.ts +5 -0
  360. package/server/modules/providers/README.md +41 -9
  361. package/server/modules/providers/index.ts +4 -0
  362. package/server/modules/providers/list/claude/claude-auth.provider.ts +8 -0
  363. package/server/modules/providers/list/claude/claude-models.provider.ts +1 -12
  364. package/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +66 -44
  365. package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +6 -4
  366. package/server/modules/providers/list/claude/claude-sessions.provider.ts +27 -4
  367. package/server/modules/providers/list/claude/claude.provider.ts +3 -0
  368. package/server/modules/providers/list/codex/codex-models.provider.ts +0 -9
  369. package/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +54 -36
  370. package/server/modules/providers/list/codex/codex-sessions.provider.ts +331 -7
  371. package/server/modules/providers/list/codex/codex-skills.provider.ts +5 -0
  372. package/server/modules/providers/list/codex/codex.provider.ts +3 -0
  373. package/server/modules/providers/list/cursor/cursor-models.provider.ts +0 -9
  374. package/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +58 -27
  375. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +26 -15
  376. package/server/modules/providers/list/cursor/cursor.provider.ts +3 -0
  377. package/server/modules/providers/list/opencode/opencode-models.provider.ts +7 -10
  378. package/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +56 -28
  379. package/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +41 -3
  380. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +13 -5
  381. package/server/modules/providers/list/opencode/opencode.provider.ts +3 -0
  382. package/server/modules/providers/provider.routes.ts +47 -10
  383. package/server/modules/providers/services/provider-capabilities.service.ts +7 -1
  384. package/server/modules/providers/services/provider-models.service.ts +131 -23
  385. package/server/modules/providers/services/provider-runtime.service.ts +109 -0
  386. package/server/modules/providers/services/provider-token-usage.service.ts +357 -0
  387. package/server/modules/providers/services/sessions-watcher.service.ts +2 -0
  388. package/server/modules/providers/services/sessions.service.ts +79 -0
  389. package/server/modules/providers/shared/base/abstract.provider.ts +4 -3
  390. package/server/modules/providers/tests/claude-auth.test.ts +150 -0
  391. package/server/modules/providers/tests/claude-sessions.test.ts +61 -0
  392. package/server/modules/providers/tests/codex-sessions.test.ts +40 -0
  393. package/server/modules/providers/tests/{provider-image-history.test.ts → provider-attachment-history.test.ts} +68 -1
  394. package/server/modules/providers/tests/provider-models.service.test.ts +450 -349
  395. package/server/modules/providers/tests/provider-runtime.service.test.ts +142 -0
  396. package/server/modules/providers/tests/provider-token-usage.service.test.ts +185 -0
  397. package/server/modules/providers/tests/sessions-details.test.ts +73 -0
  398. package/server/modules/providers/tests/skills.test.ts +9 -2
  399. package/server/modules/settings/index.ts +2 -0
  400. package/server/modules/settings/settings.module.ts +50 -0
  401. package/server/modules/settings/settings.routes.ts +51 -0
  402. package/server/modules/settings/settings.service.ts +186 -0
  403. package/server/modules/settings/tests/settings.service.test.ts +54 -0
  404. package/server/modules/system/index.ts +2 -0
  405. package/server/modules/system/system.module.ts +62 -0
  406. package/server/modules/system/system.routes.ts +21 -0
  407. package/server/modules/system/system.service.ts +76 -0
  408. package/server/modules/system/tests/system.service.test.ts +118 -0
  409. package/server/modules/taskmaster/index.ts +2 -0
  410. package/server/modules/taskmaster/taskmaster.module.ts +24 -0
  411. package/server/modules/taskmaster/taskmaster.routes.ts +1482 -0
  412. package/server/modules/taskmaster/taskmaster.service.ts +132 -0
  413. package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -0
  414. package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -0
  415. package/server/modules/user/index.ts +2 -0
  416. package/server/modules/user/tests/user.service.test.ts +61 -0
  417. package/server/modules/user/user.module.ts +58 -0
  418. package/server/modules/user/user.routes.ts +50 -0
  419. package/server/modules/user/user.service.ts +85 -0
  420. package/server/modules/voice/index.ts +2 -0
  421. package/server/modules/voice/tests/voice.service.test.ts +98 -0
  422. package/server/modules/voice/voice.module.ts +47 -0
  423. package/server/modules/voice/voice.routes.ts +113 -0
  424. package/server/modules/voice/voice.service.ts +192 -0
  425. package/server/modules/websocket/README.md +7 -7
  426. package/server/modules/websocket/services/chat-session-writer.service.ts +2 -2
  427. package/server/modules/websocket/services/chat-websocket.service.ts +73 -61
  428. package/server/modules/websocket/services/shell-websocket.service.ts +88 -12
  429. package/server/modules/websocket/services/websocket-server.service.ts +63 -19
  430. package/server/modules/websocket/tests/{chat-image-filter.test.ts → chat-attachment-filter.test.ts} +17 -2
  431. package/server/modules/websocket/tests/shell-websocket.service.test.ts +119 -0
  432. package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -0
  433. package/server/modules/worktrees/index.ts +2 -0
  434. package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -0
  435. package/server/modules/worktrees/services/worktree-create.service.ts +104 -0
  436. package/server/modules/worktrees/services/worktree-git.service.ts +207 -0
  437. package/server/modules/worktrees/services/worktree-list.service.ts +143 -0
  438. package/server/modules/worktrees/services/worktree-merge.service.ts +157 -0
  439. package/server/modules/worktrees/services/worktree-open.service.ts +85 -0
  440. package/server/modules/worktrees/services/worktree-remove.service.ts +88 -0
  441. package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -0
  442. package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -0
  443. package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -0
  444. package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -0
  445. package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -0
  446. package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -0
  447. package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -0
  448. package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -0
  449. package/server/modules/worktrees/worktrees.module.ts +113 -0
  450. package/server/modules/worktrees/worktrees.routes.ts +116 -0
  451. package/server/shared/image-attachments.ts +112 -18
  452. package/server/shared/interfaces.ts +29 -19
  453. package/server/shared/tests/image-attachments.test.ts +55 -0
  454. package/server/shared/types.ts +658 -21
  455. package/server/shared/utils.ts +77 -212
  456. package/dist/assets/index-DLmhQ15L.css +0 -32
  457. package/dist-server/server/browser-use-mcp.js.map +0 -1
  458. package/dist-server/server/claude-sdk.js.map +0 -1
  459. package/dist-server/server/cli.js +0 -647
  460. package/dist-server/server/cli.js.map +0 -1
  461. package/dist-server/server/cursor-cli.js.map +0 -1
  462. package/dist-server/server/middleware/auth.js.map +0 -1
  463. package/dist-server/server/modules/providers/tests/provider-image-history.test.js.map +0 -1
  464. package/dist-server/server/modules/websocket/tests/chat-image-filter.test.js.map +0 -1
  465. package/dist-server/server/openai-codex.js.map +0 -1
  466. package/dist-server/server/opencode-cli.js.map +0 -1
  467. package/dist-server/server/opencode-cli.test.js.map +0 -1
  468. package/dist-server/server/routes/agent.js +0 -1155
  469. package/dist-server/server/routes/agent.js.map +0 -1
  470. package/dist-server/server/routes/auth.js +0 -119
  471. package/dist-server/server/routes/auth.js.map +0 -1
  472. package/dist-server/server/routes/commands.js +0 -492
  473. package/dist-server/server/routes/commands.js.map +0 -1
  474. package/dist-server/server/routes/cursor.js +0 -49
  475. package/dist-server/server/routes/cursor.js.map +0 -1
  476. package/dist-server/server/routes/git.js +0 -1389
  477. package/dist-server/server/routes/git.js.map +0 -1
  478. package/dist-server/server/routes/git.test.js.map +0 -1
  479. package/dist-server/server/routes/mcp-utils.js +0 -29
  480. package/dist-server/server/routes/mcp-utils.js.map +0 -1
  481. package/dist-server/server/routes/plugins.js +0 -266
  482. package/dist-server/server/routes/plugins.js.map +0 -1
  483. package/dist-server/server/routes/settings.js +0 -249
  484. package/dist-server/server/routes/settings.js.map +0 -1
  485. package/dist-server/server/routes/taskmaster.js +0 -1362
  486. package/dist-server/server/routes/taskmaster.js.map +0 -1
  487. package/dist-server/server/routes/tests/commands.test.js +0 -76
  488. package/dist-server/server/routes/tests/commands.test.js.map +0 -1
  489. package/dist-server/server/routes/user.js +0 -116
  490. package/dist-server/server/routes/user.js.map +0 -1
  491. package/dist-server/server/services/notification-orchestrator.js +0 -2
  492. package/dist-server/server/services/notification-orchestrator.js.map +0 -1
  493. package/dist-server/server/services/tests/notification-orchestrator.test.js +0 -64
  494. package/dist-server/server/services/tests/notification-orchestrator.test.js.map +0 -1
  495. package/dist-server/server/services/vapid-keys.js.map +0 -1
  496. package/dist-server/server/utils/colors.js +0 -20
  497. package/dist-server/server/utils/colors.js.map +0 -1
  498. package/dist-server/server/utils/commandParser.js +0 -255
  499. package/dist-server/server/utils/commandParser.js.map +0 -1
  500. package/dist-server/server/utils/gitConfig.js +0 -37
  501. package/dist-server/server/utils/gitConfig.js.map +0 -1
  502. package/dist-server/server/utils/mcp-detector.js +0 -134
  503. package/dist-server/server/utils/mcp-detector.js.map +0 -1
  504. package/dist-server/server/utils/plugin-loader.js.map +0 -1
  505. package/dist-server/server/utils/plugin-process-manager.js.map +0 -1
  506. package/dist-server/server/utils/runtime-paths.js +0 -30
  507. package/dist-server/server/utils/runtime-paths.js.map +0 -1
  508. package/dist-server/server/utils/taskmaster-websocket.js +0 -124
  509. package/dist-server/server/utils/taskmaster-websocket.js.map +0 -1
  510. package/dist-server/server/utils/url-detection.js +0 -58
  511. package/dist-server/server/utils/url-detection.js.map +0 -1
  512. package/dist-server/server/voice-proxy.js +0 -226
  513. package/dist-server/server/voice-proxy.js.map +0 -1
  514. package/server/cli.js +0 -695
  515. package/server/index.js +0 -1651
  516. package/server/routes/agent.js +0 -1257
  517. package/server/routes/auth.js +0 -137
  518. package/server/routes/cursor.js +0 -52
  519. package/server/routes/mcp-utils.js +0 -31
  520. package/server/routes/plugins.js +0 -307
  521. package/server/routes/settings.js +0 -282
  522. package/server/routes/taskmaster.js +0 -1470
  523. package/server/routes/tests/commands.test.js +0 -82
  524. package/server/routes/user.js +0 -124
  525. package/server/services/notification-orchestrator.js +0 -7
  526. package/server/services/tests/notification-orchestrator.test.js +0 -80
  527. package/server/utils/colors.js +0 -21
  528. package/server/utils/commandParser.js +0 -305
  529. package/server/utils/gitConfig.js +0 -35
  530. package/server/utils/mcp-detector.js +0 -147
  531. package/server/utils/runtime-paths.js +0 -37
  532. package/server/utils/taskmaster-websocket.js +0 -135
  533. package/server/utils/url-detection.js +0 -71
  534. package/server/voice-proxy.js +0 -224
  535. /package/server/constants/{config.js → config.ts} +0 -0
@@ -1,6 +1,7 @@
1
1
  import { AbstractProvider } from '@/modules/providers/shared/base/abstract.provider.js';
2
2
  import { CodexProviderAuth } from '@/modules/providers/list/codex/codex-auth.provider.js';
3
3
  import { CodexProviderModels } from '@/modules/providers/list/codex/codex-models.provider.js';
4
+ import { codexRuntime } from '@/modules/providers/list/codex/codex-runtime.provider.js';
4
5
  import { CodexMcpProvider } from '@/modules/providers/list/codex/codex-mcp.provider.js';
5
6
  import { CodexSessionSynchronizer } from '@/modules/providers/list/codex/codex-session-synchronizer.provider.js';
6
7
  import { CodexSessionsProvider } from '@/modules/providers/list/codex/codex-sessions.provider.js';
@@ -8,12 +9,14 @@ import { CodexSkillsProvider } from '@/modules/providers/list/codex/codex-skills
8
9
  import type {
9
10
  IProviderAuth,
10
11
  IProviderModels,
12
+ IProviderRuntime,
11
13
  IProviderSessionSynchronizer,
12
14
  IProviderSkills,
13
15
  IProviderSessions,
14
16
  } from '@/shared/interfaces.js';
15
17
 
16
18
  export class CodexProvider extends AbstractProvider {
19
+ readonly runtime: IProviderRuntime = codexRuntime;
17
20
  readonly models: IProviderModels = new CodexProviderModels();
18
21
  readonly mcp = new CodexMcpProvider();
19
22
  readonly auth: IProviderAuth = new CodexProviderAuth();
@@ -6,16 +6,13 @@ import crossSpawn from 'cross-spawn';
6
6
 
7
7
  import type { IProviderModels } from '@/shared/interfaces.js';
8
8
  import type {
9
- ProviderChangeActiveModelInput,
10
9
  ProviderCurrentActiveModel,
11
10
  ProviderModelOption,
12
11
  ProviderModelsDefinition,
13
- ProviderSessionActiveModelChange,
14
12
  } from '@/shared/types.js';
15
13
  import {
16
14
  buildDefaultProviderCurrentActiveModel,
17
15
  sanitizeLeafDirectoryName,
18
- writeProviderSessionActiveModelChange,
19
16
  } from '@/shared/utils.js';
20
17
 
21
18
  export const CURSOR_FALLBACK_MODELS: ProviderModelsDefinition = {
@@ -796,11 +793,5 @@ export class CursorProviderModels implements IProviderModels {
796
793
 
797
794
  return buildDefaultProviderCurrentActiveModel(await this.getSupportedModels());
798
795
  }
799
-
800
- async changeActiveModel(
801
- input: ProviderChangeActiveModelInput,
802
- ): Promise<ProviderSessionActiveModelChange> {
803
- return writeProviderSessionActiveModelChange('cursor', input);
804
- }
805
796
  }
806
797
 
@@ -1,11 +1,12 @@
1
1
  import crossSpawn from 'cross-spawn';
2
2
 
3
- import { appendImagesInputTag } from './shared/image-attachments.js';
4
- import { notifyRunFailed, notifyRunStopped } from './services/notification-orchestrator.js';
5
- import { sessionsService } from './modules/providers/services/sessions.service.js';
6
- import { providerAuthService } from './modules/providers/services/provider-auth.service.js';
7
- import { providerModelsService } from './modules/providers/services/provider-models.service.js';
8
- import { createCompleteMessage, createNormalizedMessage, flattenPromptForWindowsShell } from './shared/utils.js';
3
+ import {
4
+ appendFilesInputTag,
5
+ appendImagesInputTag,
6
+ normalizeAttachmentDescriptors
7
+ } from '@/shared/image-attachments.js';
8
+ import { notifyRunFailed, notifyRunStopped } from '@/modules/notifications/index.js';
9
+ import { createCompleteMessage, createNormalizedMessage, flattenPromptForWindowsShell } from '@/shared/utils.js';
9
10
 
10
11
  // cross-spawn resolves .cmd shims/PATHEXT on Windows and delegates to
11
12
  // child_process.spawn everywhere else.
@@ -28,11 +29,24 @@ function isWorkspaceTrustPrompt(text = '') {
28
29
  return WORKSPACE_TRUST_PATTERNS.some((pattern) => pattern.test(text));
29
30
  }
30
31
 
31
- async function spawnCursor(command, options = {}, ws) {
32
+ async function spawnCursor(command, options = {}, ws, context) {
32
33
  return new Promise(async (resolve, reject) => {
33
- const { sessionId, projectPath, cwd, toolsSettings, skipPermissions, model, sessionSummary, images } = options;
34
- const resolvedModel = await providerModelsService.resolveResumeModel('cursor', sessionId, model);
35
- let capturedSessionId = sessionId; // Track session ID throughout the process
34
+ const {
35
+ sessionId,
36
+ projectPath,
37
+ cwd,
38
+ toolsSettings,
39
+ skipPermissions,
40
+ model,
41
+ sessionSummary,
42
+ images,
43
+ files
44
+ } = options;
45
+ // Callers pass the stable app session id; the CLI resumes with the
46
+ // provider-native id recorded on the session row.
47
+ const providerSessionId = context.resolveProviderSessionId(sessionId);
48
+ const resolvedModel = await context.resolveResumeModel(sessionId, model);
49
+ let capturedSessionId = providerSessionId; // Track the provider-native session id throughout the process
36
50
  let sessionCreatedSent = false; // Track if we've already sent session-created event
37
51
  let hasRetriedWithTrust = false;
38
52
  let settled = false;
@@ -51,18 +65,25 @@ async function spawnCursor(command, options = {}, ws) {
51
65
  const baseArgs = [];
52
66
 
53
67
  // Build flags allowing both resume and prompt together (reply in existing session)
54
- // Treat presence of sessionId as intention to resume, regardless of resume flag
55
- if (sessionId) {
56
- baseArgs.push('--resume=' + sessionId);
68
+ // Treat a known provider-native id as intention to resume
69
+ if (providerSessionId) {
70
+ baseArgs.push('--resume=' + providerSessionId);
57
71
  }
58
72
 
59
- if (command && command.trim()) {
73
+ const hasAttachments =
74
+ normalizeAttachmentDescriptors(images).length > 0
75
+ || normalizeAttachmentDescriptors(files).length > 0;
76
+ if ((command && command.trim()) || hasAttachments) {
60
77
  // Provide a prompt (works for both new and resumed sessions). Image
61
78
  // attachments ride along as an <images_input> path list appended to the
62
79
  // prompt; the session history reader strips the tag back out for display.
63
80
  // cursor-agent is a .cmd shim on Windows, so the whole argument must be
64
81
  // newline-free or cmd.exe silently truncates it at the first newline.
65
- baseArgs.push('-p', flattenPromptForWindowsShell(appendImagesInputTag(command, images)));
82
+ const promptWithAttachments = appendFilesInputTag(
83
+ appendImagesInputTag(command || '', images),
84
+ files
85
+ );
86
+ baseArgs.push('-p', flattenPromptForWindowsShell(promptWithAttachments));
66
87
 
67
88
  // Model overrides are applied to both new and resumed sessions so a
68
89
  // session-scoped change request can take effect on the next turn.
@@ -82,8 +103,9 @@ async function spawnCursor(command, options = {}, ws) {
82
103
  // Use cwd (actual project directory) instead of projectPath
83
104
  const workingDir = cwd || projectPath || process.cwd();
84
105
 
85
- // Store process reference for potential abort
86
- const processKey = capturedSessionId || Date.now().toString();
106
+ // Store process reference for potential abort — keyed by the app session
107
+ // id when the caller supplied one, so abort-by-app-id always works.
108
+ const processKey = sessionId || Date.now().toString();
87
109
 
88
110
  const settleOnce = (callback) => {
89
111
  if (settled) {
@@ -106,7 +128,8 @@ async function spawnCursor(command, options = {}, ws) {
106
128
 
107
129
  terminalNotificationSent = true;
108
130
 
109
- const finalSessionId = capturedSessionId || sessionId || processKey;
131
+ // Notifications are app-facing, so they carry the app session id.
132
+ const finalSessionId = sessionId || capturedSessionId || processKey;
110
133
  if (code === 0 && !error) {
111
134
  notifyRunStopped({
112
135
  userId: ws?.userId || null,
@@ -167,8 +190,9 @@ async function spawnCursor(command, options = {}, ws) {
167
190
  if (response.session_id && !capturedSessionId) {
168
191
  capturedSessionId = response.session_id;
169
192
 
170
- // Update process key with captured session ID
171
- if (processKey !== capturedSessionId) {
193
+ // Legacy/direct callers without an app session id re-key the
194
+ // process under the provider-native id once it is known.
195
+ if (!sessionId && processKey !== capturedSessionId) {
172
196
  activeCursorProcesses.delete(processKey);
173
197
  activeCursorProcesses.set(capturedSessionId, cursorProcess);
174
198
  }
@@ -178,8 +202,8 @@ async function spawnCursor(command, options = {}, ws) {
178
202
  ws.setSessionId(capturedSessionId);
179
203
  }
180
204
 
181
- // Send session-created event only once for new sessions
182
- if (!sessionId && !sessionCreatedSent) {
205
+ // Send session-created event only once for sessions with nothing to resume
206
+ if (!providerSessionId && !sessionCreatedSent) {
183
207
  sessionCreatedSent = true;
184
208
  ws.send(createNormalizedMessage({ kind: 'session_created', newSessionId: capturedSessionId, model: response.model, cwd: response.cwd, sessionId: capturedSessionId, provider: 'cursor' }));
185
209
  }
@@ -196,7 +220,7 @@ async function spawnCursor(command, options = {}, ws) {
196
220
  case 'assistant':
197
221
  // Accumulate assistant message chunks
198
222
  if (response.message && response.message.content && response.message.content.length > 0) {
199
- const normalized = sessionsService.normalizeMessage('cursor', response, capturedSessionId || sessionId || null);
223
+ const normalized = context.normalizeMessage(response, capturedSessionId || sessionId || null);
200
224
  for (const msg of normalized) ws.send(msg);
201
225
  }
202
226
  break;
@@ -223,7 +247,7 @@ async function spawnCursor(command, options = {}, ws) {
223
247
  }
224
248
 
225
249
  // If not JSON, send as stream delta via adapter
226
- const normalized = sessionsService.normalizeMessage('cursor', line, capturedSessionId || sessionId || null);
250
+ const normalized = context.normalizeMessage(line, capturedSessionId || sessionId || null);
227
251
  for (const msg of normalized) ws.send(msg);
228
252
  }
229
253
  };
@@ -256,7 +280,9 @@ async function spawnCursor(command, options = {}, ws) {
256
280
 
257
281
  // Handle process completion
258
282
  cursorProcess.on('close', async (code) => {
259
- const finalSessionId = capturedSessionId || sessionId || processKey;
283
+ // The process map is keyed by the app session id when one was given,
284
+ // otherwise by the captured provider id (or the timestamp fallback).
285
+ const finalSessionId = sessionId || capturedSessionId || processKey;
260
286
  activeCursorProcesses.delete(finalSessionId);
261
287
 
262
288
  // Flush any final unterminated stdout line before completion handling.
@@ -297,11 +323,11 @@ async function spawnCursor(command, options = {}, ws) {
297
323
  console.error('Cursor CLI process error:', error);
298
324
 
299
325
  // Clean up process reference on error
300
- const finalSessionId = capturedSessionId || sessionId || processKey;
326
+ const finalSessionId = sessionId || capturedSessionId || processKey;
301
327
  activeCursorProcesses.delete(finalSessionId);
302
328
 
303
329
  // Check if Cursor CLI is installed for a clearer error message
304
- const installed = await providerAuthService.isProviderInstalled('cursor');
330
+ const installed = await context.isProviderInstalled();
305
331
  const errorContent = !installed
306
332
  ? 'Cursor CLI is not installed. Please install it from https://cursor.com'
307
333
  : error.message;
@@ -346,6 +372,11 @@ function getActiveCursorSessions() {
346
372
  return Array.from(activeCursorProcesses.keys());
347
373
  }
348
374
 
375
+ export const cursorRuntime = {
376
+ run: spawnCursor,
377
+ abort: abortCursorSession,
378
+ };
379
+
349
380
  export {
350
381
  spawnCursor,
351
382
  abortCursorSession,
@@ -2,7 +2,7 @@ import crypto from 'node:crypto';
2
2
  import os from 'node:os';
3
3
  import path from 'node:path';
4
4
 
5
- import { parseImagesInputTag } from '@/shared/image-attachments.js';
5
+ import { parseFilesInputTag, parseImagesInputTag } from '@/shared/image-attachments.js';
6
6
  import type { IProviderSessions } from '@/shared/interfaces.js';
7
7
  import type { AnyRecord, FetchHistoryOptions, FetchHistoryResult, NormalizedMessage } from '@/shared/types.js';
8
8
  import {
@@ -85,16 +85,22 @@ function unwrapUserQueryText(value: string, role: 'user' | 'assistant'): string
85
85
  function extractUserTextAndImages(
86
86
  value: string,
87
87
  role: 'user' | 'assistant',
88
- ): { text: string; images?: Array<{ path: string; name?: string }> } {
88
+ ): {
89
+ text: string;
90
+ images?: Array<{ path: string; name?: string }>;
91
+ files?: Array<{ path: string; name?: string }>;
92
+ } {
89
93
  const unwrapped = unwrapUserQueryText(value, role);
90
94
  if (role !== 'user') {
91
95
  return { text: unwrapped };
92
96
  }
93
97
 
94
- const { text, attachments } = parseImagesInputTag(unwrapped);
98
+ const parsedImages = parseImagesInputTag(unwrapped);
99
+ const parsedFiles = parseFilesInputTag(parsedImages.text);
95
100
  return {
96
- text,
97
- images: attachments.length > 0 ? attachments : undefined,
101
+ text: parsedFiles.text,
102
+ images: parsedImages.attachments.length > 0 ? parsedImages.attachments : undefined,
103
+ files: parsedFiles.attachments.length > 0 ? parsedFiles.attachments : undefined,
98
104
  };
99
105
  }
100
106
 
@@ -471,16 +477,18 @@ export class CursorSessionsProvider implements IProviderSessions {
471
477
  text = unwrapUserQueryText(content.message.content, role);
472
478
  }
473
479
  }
474
- const { text: cleanText, images } = role === 'user'
480
+ const { text: cleanText, images, files } = role === 'user'
475
481
  ? (() => {
476
- const parsed = parseImagesInputTag(text);
482
+ const parsedImages = parseImagesInputTag(text);
483
+ const parsedFiles = parseFilesInputTag(parsedImages.text);
477
484
  return {
478
- text: parsed.text,
479
- images: parsed.attachments.length > 0 ? parsed.attachments : undefined,
485
+ text: parsedFiles.text,
486
+ images: parsedImages.attachments.length > 0 ? parsedImages.attachments : undefined,
487
+ files: parsedFiles.attachments.length > 0 ? parsedFiles.attachments : undefined,
480
488
  };
481
489
  })()
482
- : { text, images: undefined };
483
- if (cleanText?.trim() || images) {
490
+ : { text, images: undefined, files: undefined };
491
+ if (cleanText?.trim() || images || files) {
484
492
  messages.push(createNormalizedMessage({
485
493
  id: baseId,
486
494
  sessionId,
@@ -490,6 +498,7 @@ export class CursorSessionsProvider implements IProviderSessions {
490
498
  role,
491
499
  content: cleanText,
492
500
  images,
501
+ files,
493
502
  sequence: blob.sequence,
494
503
  rowid: blob.rowid,
495
504
  }));
@@ -541,8 +550,8 @@ export class CursorSessionsProvider implements IProviderSessions {
541
550
  }
542
551
 
543
552
  if (part?.type === 'text' && part?.text) {
544
- const { text: normalizedPartText, images } = extractUserTextAndImages(part.text, role);
545
- if (!normalizedPartText && !images) {
553
+ const { text: normalizedPartText, images, files } = extractUserTextAndImages(part.text, role);
554
+ if (!normalizedPartText && !images && !files) {
546
555
  continue;
547
556
  }
548
557
  messages.push(createNormalizedMessage({
@@ -554,6 +563,7 @@ export class CursorSessionsProvider implements IProviderSessions {
554
563
  role,
555
564
  content: normalizedPartText,
556
565
  images,
566
+ files,
557
567
  sequence: blob.sequence,
558
568
  rowid: blob.rowid,
559
569
  }));
@@ -593,8 +603,8 @@ export class CursorSessionsProvider implements IProviderSessions {
593
603
  && content.content.trim()
594
604
  && !isInternalCursorText(content.content)
595
605
  ) {
596
- const { text: normalizedText, images } = extractUserTextAndImages(content.content, role);
597
- if (!normalizedText && !images) {
606
+ const { text: normalizedText, images, files } = extractUserTextAndImages(content.content, role);
607
+ if (!normalizedText && !images && !files) {
598
608
  continue;
599
609
  }
600
610
  messages.push(createNormalizedMessage({
@@ -606,6 +616,7 @@ export class CursorSessionsProvider implements IProviderSessions {
606
616
  role,
607
617
  content: normalizedText,
608
618
  images,
619
+ files,
609
620
  sequence: blob.sequence,
610
621
  rowid: blob.rowid,
611
622
  }));
@@ -1,6 +1,7 @@
1
1
  import { AbstractProvider } from '@/modules/providers/shared/base/abstract.provider.js';
2
2
  import { CursorProviderAuth } from '@/modules/providers/list/cursor/cursor-auth.provider.js';
3
3
  import { CursorProviderModels } from '@/modules/providers/list/cursor/cursor-models.provider.js';
4
+ import { cursorRuntime } from '@/modules/providers/list/cursor/cursor-runtime.provider.js';
4
5
  import { CursorMcpProvider } from '@/modules/providers/list/cursor/cursor-mcp.provider.js';
5
6
  import { CursorSessionSynchronizer } from '@/modules/providers/list/cursor/cursor-session-synchronizer.provider.js';
6
7
  import { CursorSessionsProvider } from '@/modules/providers/list/cursor/cursor-sessions.provider.js';
@@ -8,12 +9,14 @@ import { CursorSkillsProvider } from '@/modules/providers/list/cursor/cursor-ski
8
9
  import type {
9
10
  IProviderAuth,
10
11
  IProviderModels,
12
+ IProviderRuntime,
11
13
  IProviderSessionSynchronizer,
12
14
  IProviderSkills,
13
15
  IProviderSessions,
14
16
  } from '@/shared/interfaces.js';
15
17
 
16
18
  export class CursorProvider extends AbstractProvider {
19
+ readonly runtime: IProviderRuntime = cursorRuntime;
17
20
  readonly models: IProviderModels = new CursorProviderModels();
18
21
  readonly mcp = new CursorMcpProvider();
19
22
  readonly auth: IProviderAuth = new CursorProviderAuth();
@@ -1,20 +1,18 @@
1
1
  import Database from 'better-sqlite3';
2
2
  import crossSpawn from 'cross-spawn';
3
3
 
4
+ import { sessionsDb } from '@/modules/database/index.js';
4
5
  import type { IProviderModels } from '@/shared/interfaces.js';
5
6
  import type {
6
- ProviderChangeActiveModelInput,
7
7
  ProviderCurrentActiveModel,
8
8
  ProviderModelOption,
9
9
  ProviderModelsDefinition,
10
- ProviderSessionActiveModelChange,
11
10
  } from '@/shared/types.js';
12
11
  import {
13
12
  buildDefaultProviderCurrentActiveModel,
14
13
  getOpenCodeDatabasePath,
15
14
  readObjectRecord,
16
15
  readOptionalString,
17
- writeProviderSessionActiveModelChange,
18
16
  } from '@/shared/utils.js';
19
17
 
20
18
  export const OPENCODE_FALLBACK_MODELS: ProviderModelsDefinition = {
@@ -464,6 +462,11 @@ export class OpenCodeProviderModels implements IProviderModels {
464
462
  return buildDefaultProviderCurrentActiveModel(await this.getSupportedModels());
465
463
  }
466
464
 
465
+ // OpenCode's `session` table is keyed by its own session id, so the stable
466
+ // app id has to be translated first; sessions discovered on disk store the
467
+ // provider id in both columns and resolve to themselves.
468
+ const providerSessionId = sessionsDb.getSessionById(sessionId)?.provider_session_id ?? sessionId;
469
+
467
470
  try {
468
471
  const dbPath = getOpenCodeDatabasePath();
469
472
  const db = new Database(dbPath, { readonly: true, fileMustExist: true });
@@ -481,7 +484,7 @@ export class OpenCodeProviderModels implements IProviderModels {
481
484
  WHERE s.id = ?
482
485
  ORDER BY COALESCE(s.time_updated, s.time_created, 0) DESC
483
486
  LIMIT 1
484
- `).get(sessionId) as {
487
+ `).get(providerSessionId) as {
485
488
  sessionId?: string;
486
489
  model?: unknown;
487
490
  agent?: string | null;
@@ -505,10 +508,4 @@ export class OpenCodeProviderModels implements IProviderModels {
505
508
 
506
509
  return buildDefaultProviderCurrentActiveModel(await this.getSupportedModels());
507
510
  }
508
-
509
- async changeActiveModel(
510
- input: ProviderChangeActiveModelInput,
511
- ): Promise<ProviderSessionActiveModelChange> {
512
- return writeProviderSessionActiveModelChange('opencode', input);
513
- }
514
511
  }
@@ -3,12 +3,13 @@ import fsSync from 'node:fs';
3
3
  import crossSpawn from 'cross-spawn';
4
4
  import Database from 'better-sqlite3';
5
5
 
6
- import { appendImagesInputTag } from './shared/image-attachments.js';
7
- import { sessionsService } from './modules/providers/services/sessions.service.js';
8
- import { providerAuthService } from './modules/providers/services/provider-auth.service.js';
9
- import { providerModelsService } from './modules/providers/services/provider-models.service.js';
10
- import { notifyRunFailed, notifyRunStopped } from './services/notification-orchestrator.js';
11
- import { createCompleteMessage, createNormalizedMessage, flattenPromptForWindowsShell, getOpenCodeDatabasePath } from './shared/utils.js';
6
+ import {
7
+ appendFilesInputTag,
8
+ appendImagesInputTag,
9
+ normalizeAttachmentDescriptors
10
+ } from '@/shared/image-attachments.js';
11
+ import { notifyRunFailed, notifyRunStopped } from '@/modules/notifications/index.js';
12
+ import { createCompleteMessage, createNormalizedMessage, flattenPromptForWindowsShell, getOpenCodeDatabasePath } from '@/shared/utils.js';
12
13
 
13
14
  // cross-spawn resolves .cmd shims/PATHEXT on Windows and delegates to
14
15
  // child_process.spawn everywhere else.
@@ -122,12 +123,27 @@ function readOpenCodeTokenUsage(sessionId) {
122
123
  }
123
124
  }
124
125
 
125
- async function spawnOpenCode(command, options = {}, ws) {
126
+ async function spawnOpenCode(command, options = {}, ws, context) {
126
127
  return new Promise((resolve, reject) => {
127
- const { sessionId, projectPath, cwd, model, effort, sessionSummary, images, permissionMode } = options;
128
+ const {
129
+ sessionId,
130
+ projectPath,
131
+ cwd,
132
+ model,
133
+ effort,
134
+ sessionSummary,
135
+ images,
136
+ files,
137
+ permissionMode
138
+ } = options;
139
+ // Callers pass the stable app session id; the CLI resumes with the
140
+ // provider-native id recorded on the session row.
141
+ const providerSessionId = context.resolveProviderSessionId(sessionId);
128
142
  const workingDir = cwd || projectPath || process.cwd();
143
+ // Process-map key: the app session id when the caller supplied one, so
144
+ // abort-by-app-id always works.
129
145
  const processKey = sessionId || Date.now().toString();
130
- let capturedSessionId = sessionId || null;
146
+ let capturedSessionId = providerSessionId;
131
147
  let sessionCreatedSent = false;
132
148
  let stdoutLineBuffer = '';
133
149
  let terminalNotificationSent = false;
@@ -142,7 +158,8 @@ async function spawnOpenCode(command, options = {}, ws) {
142
158
  }
143
159
 
144
160
  terminalNotificationSent = true;
145
- const finalSessionId = capturedSessionId || sessionId || processKey;
161
+ // Notifications are app-facing, so they carry the app session id.
162
+ const finalSessionId = sessionId || capturedSessionId || processKey;
146
163
  if (code === 0 && !error) {
147
164
  notifyRunStopped({
148
165
  userId: ws?.userId || null,
@@ -169,7 +186,9 @@ async function spawnOpenCode(command, options = {}, ws) {
169
186
  }
170
187
 
171
188
  capturedSessionId = nextSessionId;
172
- if (processKey !== capturedSessionId && opencodeProcess) {
189
+ // Legacy/direct callers without an app session id re-key the process
190
+ // under the provider-native id once it is known.
191
+ if (!sessionId && processKey !== capturedSessionId && opencodeProcess) {
173
192
  activeOpenCodeProcesses.delete(processKey);
174
193
  activeOpenCodeProcesses.set(capturedSessionId, opencodeProcess);
175
194
  }
@@ -181,7 +200,7 @@ async function spawnOpenCode(command, options = {}, ws) {
181
200
  ws.setSessionId(capturedSessionId);
182
201
  }
183
202
 
184
- if (!sessionId && !sessionCreatedSent) {
203
+ if (!providerSessionId && !sessionCreatedSent) {
185
204
  sessionCreatedSent = true;
186
205
  ws.send(createNormalizedMessage({
187
206
  kind: 'session_created',
@@ -212,11 +231,7 @@ async function spawnOpenCode(command, options = {}, ws) {
212
231
 
213
232
  try {
214
233
  registerSession(readOpenCodeSessionId(response));
215
- const normalized = sessionsService.normalizeMessage(
216
- 'opencode',
217
- response,
218
- capturedSessionId || sessionId || null,
219
- );
234
+ const normalized = context.normalizeMessage(response, capturedSessionId || sessionId || null);
220
235
  for (const msg of normalized) {
221
236
  ws.send(msg);
222
237
  }
@@ -232,10 +247,10 @@ async function spawnOpenCode(command, options = {}, ws) {
232
247
  }
233
248
  };
234
249
 
235
- void providerModelsService.resolveResumeModel('opencode', sessionId, model).then(async (resolvedModel) => {
250
+ void context.resolveResumeModel(sessionId, model).then(async (resolvedModel) => {
236
251
  let effortModels = null;
237
252
  try {
238
- effortModels = (await providerModelsService.getProviderModels('opencode')).models;
253
+ effortModels = await context.getProviderModels();
239
254
  } catch (error) {
240
255
  console.warn('[OpenCode] Unable to load provider models for effort validation:', error);
241
256
  }
@@ -246,8 +261,8 @@ async function spawnOpenCode(command, options = {}, ws) {
246
261
  // Relying on the child-process cwd alone is not enough on Linux, where
247
262
  // the CLI can still resolve the session under the server install dir.
248
263
  args.push('--dir', workingDir);
249
- if (sessionId) {
250
- args.push('--session', sessionId);
264
+ if (providerSessionId) {
265
+ args.push('--session', providerSessionId);
251
266
  }
252
267
  if (resolvedModel) {
253
268
  args.push('--model', resolvedModel);
@@ -257,12 +272,19 @@ async function spawnOpenCode(command, options = {}, ws) {
257
272
  }
258
273
  const permissionOptions = resolveOpenCodePermissionOptions(permissionMode);
259
274
  args.push(...permissionOptions.args);
260
- if (command && command.trim()) {
275
+ const hasAttachments =
276
+ normalizeAttachmentDescriptors(images).length > 0
277
+ || normalizeAttachmentDescriptors(files).length > 0;
278
+ if ((command && command.trim()) || hasAttachments) {
261
279
  // Image attachments ride along as an <images_input> path list appended
262
280
  // to the prompt; the session history reader strips the tag back out.
263
281
  // opencode is a .cmd shim on Windows, so the whole argument must be
264
282
  // newline-free or cmd.exe silently truncates it at the first newline.
265
- args.push(flattenPromptForWindowsShell(appendImagesInputTag(command.trim(), images)));
283
+ const promptWithAttachments = appendFilesInputTag(
284
+ appendImagesInputTag(command?.trim() || '', images),
285
+ files
286
+ );
287
+ args.push(flattenPromptForWindowsShell(promptWithAttachments));
266
288
  }
267
289
 
268
290
  opencodeProcess = spawnFunction('opencode', args, {
@@ -300,7 +322,7 @@ async function spawnOpenCode(command, options = {}, ws) {
300
322
  });
301
323
 
302
324
  opencodeProcess.on('close', async (code) => {
303
- const finalSessionId = capturedSessionId || sessionId || processKey;
325
+ const finalSessionId = sessionId || capturedSessionId || processKey;
304
326
  activeOpenCodeProcesses.delete(finalSessionId);
305
327
  activeOpenCodeProcesses.delete(processKey);
306
328
 
@@ -309,7 +331,8 @@ async function spawnOpenCode(command, options = {}, ws) {
309
331
  stdoutLineBuffer = '';
310
332
  }
311
333
 
312
- const tokenBudget = readOpenCodeTokenUsage(finalSessionId);
334
+ // OpenCode's own database is keyed by the provider-native id.
335
+ const tokenBudget = readOpenCodeTokenUsage(capturedSessionId);
313
336
  if (tokenBudget) {
314
337
  ws.send(createNormalizedMessage({
315
338
  kind: 'status',
@@ -334,7 +357,7 @@ async function spawnOpenCode(command, options = {}, ws) {
334
357
  }
335
358
 
336
359
  if (code === 127 || code === null) {
337
- const installed = await providerAuthService.isProviderInstalled('opencode');
360
+ const installed = await context.isProviderInstalled();
338
361
  if (!installed) {
339
362
  ws.send(createNormalizedMessage({
340
363
  kind: 'error',
@@ -350,11 +373,11 @@ async function spawnOpenCode(command, options = {}, ws) {
350
373
  });
351
374
 
352
375
  opencodeProcess.on('error', async (error) => {
353
- const finalSessionId = capturedSessionId || sessionId || processKey;
376
+ const finalSessionId = sessionId || capturedSessionId || processKey;
354
377
  activeOpenCodeProcesses.delete(finalSessionId);
355
378
  activeOpenCodeProcesses.delete(processKey);
356
379
 
357
- const installed = await providerAuthService.isProviderInstalled('opencode');
380
+ const installed = await context.isProviderInstalled();
358
381
  const errorContent = !installed
359
382
  ? 'OpenCode CLI is not installed. Install it from https://opencode.ai/docs/'
360
383
  : error.message;
@@ -398,6 +421,11 @@ function getActiveOpenCodeSessions() {
398
421
  return Array.from(activeOpenCodeProcesses.keys());
399
422
  }
400
423
 
424
+ export const opencodeRuntime = {
425
+ run: spawnOpenCode,
426
+ abort: abortOpenCodeSession,
427
+ };
428
+
401
429
  export {
402
430
  spawnOpenCode,
403
431
  abortOpenCodeSession,