@cloudcli-ai/cloudcli 1.36.2 → 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 (539) hide show
  1. package/dist/assets/index-DSlds633.css +32 -0
  2. package/dist/assets/{index-CDGzV0LN.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-session-synchronizer.provider.js +19 -1
  138. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -1
  139. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +290 -6
  140. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
  141. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +5 -0
  142. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -1
  143. package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
  144. package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
  145. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +1 -4
  146. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -1
  147. package/dist-server/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +40 -28
  148. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -0
  149. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +21 -14
  150. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -1
  151. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +2 -0
  152. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -1
  153. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +7 -5
  154. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
  155. package/dist-server/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +38 -25
  156. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js.map +1 -0
  157. package/dist-server/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +27 -4
  158. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js.map +1 -0
  159. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +11 -5
  160. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -1
  161. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js +2 -0
  162. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js.map +1 -1
  163. package/dist-server/server/modules/providers/provider.routes.js +33 -9
  164. package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
  165. package/dist-server/server/modules/providers/services/provider-capabilities.service.js +5 -1
  166. package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
  167. package/dist-server/server/modules/providers/services/provider-models.service.js +110 -15
  168. package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
  169. package/dist-server/server/modules/providers/services/provider-runtime.service.js +66 -0
  170. package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -0
  171. package/dist-server/server/modules/providers/services/provider-token-usage.service.js +268 -0
  172. package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -0
  173. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +2 -0
  174. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
  175. package/dist-server/server/modules/providers/services/sessions.service.js +54 -0
  176. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
  177. package/dist-server/server/modules/providers/shared/base/abstract.provider.js +2 -3
  178. package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -1
  179. package/dist-server/server/modules/providers/tests/claude-auth.test.js +122 -0
  180. package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -0
  181. package/dist-server/server/modules/providers/tests/claude-sessions.test.js +44 -0
  182. package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -0
  183. package/dist-server/server/modules/providers/tests/codex-sessions.test.js +70 -0
  184. package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
  185. package/dist-server/server/modules/providers/tests/{provider-image-history.test.js → provider-attachment-history.test.js} +60 -2
  186. package/dist-server/server/modules/providers/tests/provider-attachment-history.test.js.map +1 -0
  187. package/dist-server/server/modules/providers/tests/provider-models.service.test.js +148 -61
  188. package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
  189. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +130 -0
  190. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -0
  191. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +165 -0
  192. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -0
  193. package/dist-server/server/modules/providers/tests/sessions-details.test.js +62 -0
  194. package/dist-server/server/modules/providers/tests/sessions-details.test.js.map +1 -0
  195. package/dist-server/server/modules/providers/tests/skills.test.js +4 -2
  196. package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
  197. package/dist-server/server/modules/settings/index.js +3 -0
  198. package/dist-server/server/modules/settings/index.js.map +1 -0
  199. package/dist-server/server/modules/settings/settings.module.js +35 -0
  200. package/dist-server/server/modules/settings/settings.module.js.map +1 -0
  201. package/dist-server/server/modules/settings/settings.routes.js +34 -0
  202. package/dist-server/server/modules/settings/settings.routes.js.map +1 -0
  203. package/dist-server/server/modules/settings/settings.service.js +116 -0
  204. package/dist-server/server/modules/settings/settings.service.js.map +1 -0
  205. package/dist-server/server/modules/settings/tests/settings.service.test.js +48 -0
  206. package/dist-server/server/modules/settings/tests/settings.service.test.js.map +1 -0
  207. package/dist-server/server/modules/system/index.js +3 -0
  208. package/dist-server/server/modules/system/index.js.map +1 -0
  209. package/dist-server/server/modules/system/system.module.js +44 -0
  210. package/dist-server/server/modules/system/system.module.js.map +1 -0
  211. package/dist-server/server/modules/system/system.routes.js +16 -0
  212. package/dist-server/server/modules/system/system.routes.js.map +1 -0
  213. package/dist-server/server/modules/system/system.service.js +45 -0
  214. package/dist-server/server/modules/system/system.service.js.map +1 -0
  215. package/dist-server/server/modules/system/tests/system.service.test.js +100 -0
  216. package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -0
  217. package/dist-server/server/modules/taskmaster/index.js +3 -0
  218. package/dist-server/server/modules/taskmaster/index.js.map +1 -0
  219. package/dist-server/server/modules/taskmaster/taskmaster.module.js +20 -0
  220. package/dist-server/server/modules/taskmaster/taskmaster.module.js.map +1 -0
  221. package/dist-server/server/modules/taskmaster/taskmaster.routes.js +1372 -0
  222. package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -0
  223. package/dist-server/server/modules/taskmaster/taskmaster.service.js +107 -0
  224. package/dist-server/server/modules/taskmaster/taskmaster.service.js.map +1 -0
  225. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +132 -0
  226. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -0
  227. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js +85 -0
  228. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js.map +1 -0
  229. package/dist-server/server/modules/user/index.js +3 -0
  230. package/dist-server/server/modules/user/index.js.map +1 -0
  231. package/dist-server/server/modules/user/tests/user.service.test.js +53 -0
  232. package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -0
  233. package/dist-server/server/modules/user/user.module.js +47 -0
  234. package/dist-server/server/modules/user/user.module.js.map +1 -0
  235. package/dist-server/server/modules/user/user.routes.js +44 -0
  236. package/dist-server/server/modules/user/user.routes.js.map +1 -0
  237. package/dist-server/server/modules/user/user.service.js +59 -0
  238. package/dist-server/server/modules/user/user.service.js.map +1 -0
  239. package/dist-server/server/modules/voice/index.js +3 -0
  240. package/dist-server/server/modules/voice/index.js.map +1 -0
  241. package/dist-server/server/modules/voice/tests/voice.service.test.js +86 -0
  242. package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -0
  243. package/dist-server/server/modules/voice/voice.module.js +44 -0
  244. package/dist-server/server/modules/voice/voice.module.js.map +1 -0
  245. package/dist-server/server/modules/voice/voice.routes.js +87 -0
  246. package/dist-server/server/modules/voice/voice.routes.js.map +1 -0
  247. package/dist-server/server/modules/voice/voice.service.js +148 -0
  248. package/dist-server/server/modules/voice/voice.service.js.map +1 -0
  249. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +2 -2
  250. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +40 -29
  251. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
  252. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +76 -8
  253. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
  254. package/dist-server/server/modules/websocket/services/websocket-server.service.js +51 -20
  255. package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -1
  256. package/dist-server/server/modules/websocket/tests/{chat-image-filter.test.js → chat-attachment-filter.test.js} +10 -3
  257. package/dist-server/server/modules/websocket/tests/chat-attachment-filter.test.js.map +1 -0
  258. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +97 -0
  259. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -0
  260. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js +61 -0
  261. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js.map +1 -0
  262. package/dist-server/server/modules/worktrees/index.js +3 -0
  263. package/dist-server/server/modules/worktrees/index.js.map +1 -0
  264. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js +37 -0
  265. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js.map +1 -0
  266. package/dist-server/server/modules/worktrees/services/worktree-create.service.js +67 -0
  267. package/dist-server/server/modules/worktrees/services/worktree-create.service.js.map +1 -0
  268. package/dist-server/server/modules/worktrees/services/worktree-git.service.js +172 -0
  269. package/dist-server/server/modules/worktrees/services/worktree-git.service.js.map +1 -0
  270. package/dist-server/server/modules/worktrees/services/worktree-list.service.js +91 -0
  271. package/dist-server/server/modules/worktrees/services/worktree-list.service.js.map +1 -0
  272. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js +118 -0
  273. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js.map +1 -0
  274. package/dist-server/server/modules/worktrees/services/worktree-open.service.js +58 -0
  275. package/dist-server/server/modules/worktrees/services/worktree-open.service.js.map +1 -0
  276. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +65 -0
  277. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js.map +1 -0
  278. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js +58 -0
  279. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js.map +1 -0
  280. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js +85 -0
  281. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js.map +1 -0
  282. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js +58 -0
  283. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js.map +1 -0
  284. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js +34 -0
  285. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js.map +1 -0
  286. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js +137 -0
  287. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js.map +1 -0
  288. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js +99 -0
  289. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js.map +1 -0
  290. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js +157 -0
  291. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js.map +1 -0
  292. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js +167 -0
  293. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js.map +1 -0
  294. package/dist-server/server/modules/worktrees/worktrees.module.js +97 -0
  295. package/dist-server/server/modules/worktrees/worktrees.module.js.map +1 -0
  296. package/dist-server/server/modules/worktrees/worktrees.routes.js +84 -0
  297. package/dist-server/server/modules/worktrees/worktrees.routes.js.map +1 -0
  298. package/dist-server/server/shared/image-attachments.js +90 -17
  299. package/dist-server/server/shared/image-attachments.js.map +1 -1
  300. package/dist-server/server/shared/tests/image-attachments.test.js +43 -1
  301. package/dist-server/server/shared/tests/image-attachments.test.js.map +1 -1
  302. package/dist-server/server/shared/utils.js +66 -142
  303. package/dist-server/server/shared/utils.js.map +1 -1
  304. package/electron/localServer.js +1 -2
  305. package/package.json +8 -4
  306. package/server/index.ts +401 -0
  307. package/server/{load-env.js → load-env.ts} +18 -5
  308. package/server/modules/agent/agent.module.ts +51 -0
  309. package/server/modules/agent/agent.routes.ts +1287 -0
  310. package/server/modules/agent/index.ts +2 -0
  311. package/server/modules/agent/tests/agent.routes.test.ts +205 -0
  312. package/server/modules/assets/assets.routes.ts +63 -16
  313. package/server/modules/assets/index.ts +2 -2
  314. package/server/modules/assets/services/image-assets.service.ts +46 -1
  315. package/server/modules/assets/tests/image-assets.service.test.ts +28 -0
  316. package/server/{middleware/auth.js → modules/auth/auth.middleware.ts} +38 -7
  317. package/server/modules/auth/auth.module.ts +38 -0
  318. package/server/modules/auth/auth.routes.ts +57 -0
  319. package/server/modules/auth/auth.service.ts +155 -0
  320. package/server/modules/auth/index.ts +9 -0
  321. package/server/modules/auth/tests/auth.service.test.ts +95 -0
  322. package/server/{browser-use-mcp.ts → modules/browser-use/browser-use-mcp.ts} +3 -1
  323. package/server/modules/browser-use/browser-use.service.ts +3 -4
  324. package/server/modules/browser-use/index.ts +8 -0
  325. package/server/modules/cli/cli.module.ts +96 -0
  326. package/server/modules/cli/cli.service.ts +281 -0
  327. package/server/modules/cli/cli.ts +13 -0
  328. package/server/modules/cli/index.ts +2 -0
  329. package/server/modules/cli/sandbox.service.ts +413 -0
  330. package/server/modules/cli/tests/cli.service.test.ts +91 -0
  331. package/server/modules/cli/tests/sandbox.service.test.ts +61 -0
  332. package/server/modules/commands/commands.module.ts +22 -0
  333. package/server/{routes/commands.js → modules/commands/commands.routes.ts} +44 -36
  334. package/server/modules/commands/index.ts +2 -0
  335. package/server/modules/commands/tests/commands.test.ts +119 -0
  336. package/server/modules/database/index.ts +1 -0
  337. package/server/modules/database/migrations.ts +15 -0
  338. package/server/modules/database/repositories/sessions.db.ts +19 -1
  339. package/server/modules/database/schema.ts +4 -0
  340. package/server/modules/file-tree/file-tree.module.ts +112 -0
  341. package/server/modules/file-tree/file-tree.routes.ts +258 -0
  342. package/server/modules/file-tree/file-tree.service.ts +616 -0
  343. package/server/modules/file-tree/index.ts +2 -0
  344. package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -0
  345. package/server/modules/file-tree/tests/file-tree.service.test.ts +220 -0
  346. package/server/modules/git/git-parsing.service.ts +66 -0
  347. package/server/modules/git/git.module.ts +22 -0
  348. package/server/{routes/git.js → modules/git/git.routes.ts} +91 -132
  349. package/server/modules/git/index.ts +2 -0
  350. package/server/modules/git/tests/git-init.routes.test.ts +52 -0
  351. package/server/{routes/git.test.js → modules/git/tests/git.test.ts} +3 -3
  352. package/server/modules/notifications/index.ts +9 -0
  353. package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -0
  354. package/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.ts} +3 -1
  355. package/server/modules/plugins/index.ts +9 -0
  356. package/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.ts} +3 -1
  357. package/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.ts} +1 -0
  358. package/server/modules/plugins/plugins.module.ts +33 -0
  359. package/server/modules/plugins/plugins.routes.ts +66 -0
  360. package/server/modules/plugins/plugins.service.ts +147 -0
  361. package/server/modules/plugins/tests/plugins.service.test.ts +32 -0
  362. package/server/modules/projects/index.ts +5 -0
  363. package/server/modules/providers/README.md +41 -9
  364. package/server/modules/providers/index.ts +4 -0
  365. package/server/modules/providers/list/claude/claude-auth.provider.ts +8 -0
  366. package/server/modules/providers/list/claude/claude-models.provider.ts +1 -12
  367. package/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +66 -44
  368. package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +6 -4
  369. package/server/modules/providers/list/claude/claude-sessions.provider.ts +27 -4
  370. package/server/modules/providers/list/claude/claude.provider.ts +3 -0
  371. package/server/modules/providers/list/codex/codex-models.provider.ts +0 -9
  372. package/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +54 -36
  373. package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +21 -1
  374. package/server/modules/providers/list/codex/codex-sessions.provider.ts +331 -7
  375. package/server/modules/providers/list/codex/codex-skills.provider.ts +5 -0
  376. package/server/modules/providers/list/codex/codex.provider.ts +3 -0
  377. package/server/modules/providers/list/cursor/cursor-models.provider.ts +0 -9
  378. package/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +58 -27
  379. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +26 -15
  380. package/server/modules/providers/list/cursor/cursor.provider.ts +3 -0
  381. package/server/modules/providers/list/opencode/opencode-models.provider.ts +7 -10
  382. package/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +56 -28
  383. package/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +41 -3
  384. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +13 -5
  385. package/server/modules/providers/list/opencode/opencode.provider.ts +3 -0
  386. package/server/modules/providers/provider.routes.ts +47 -10
  387. package/server/modules/providers/services/provider-capabilities.service.ts +7 -1
  388. package/server/modules/providers/services/provider-models.service.ts +131 -23
  389. package/server/modules/providers/services/provider-runtime.service.ts +109 -0
  390. package/server/modules/providers/services/provider-token-usage.service.ts +357 -0
  391. package/server/modules/providers/services/sessions-watcher.service.ts +2 -0
  392. package/server/modules/providers/services/sessions.service.ts +79 -0
  393. package/server/modules/providers/shared/base/abstract.provider.ts +4 -3
  394. package/server/modules/providers/tests/claude-auth.test.ts +150 -0
  395. package/server/modules/providers/tests/claude-sessions.test.ts +61 -0
  396. package/server/modules/providers/tests/codex-sessions.test.ts +81 -0
  397. package/server/modules/providers/tests/{provider-image-history.test.ts → provider-attachment-history.test.ts} +68 -1
  398. package/server/modules/providers/tests/provider-models.service.test.ts +450 -349
  399. package/server/modules/providers/tests/provider-runtime.service.test.ts +142 -0
  400. package/server/modules/providers/tests/provider-token-usage.service.test.ts +185 -0
  401. package/server/modules/providers/tests/sessions-details.test.ts +73 -0
  402. package/server/modules/providers/tests/skills.test.ts +9 -2
  403. package/server/modules/settings/index.ts +2 -0
  404. package/server/modules/settings/settings.module.ts +50 -0
  405. package/server/modules/settings/settings.routes.ts +51 -0
  406. package/server/modules/settings/settings.service.ts +186 -0
  407. package/server/modules/settings/tests/settings.service.test.ts +54 -0
  408. package/server/modules/system/index.ts +2 -0
  409. package/server/modules/system/system.module.ts +62 -0
  410. package/server/modules/system/system.routes.ts +21 -0
  411. package/server/modules/system/system.service.ts +76 -0
  412. package/server/modules/system/tests/system.service.test.ts +118 -0
  413. package/server/modules/taskmaster/index.ts +2 -0
  414. package/server/modules/taskmaster/taskmaster.module.ts +24 -0
  415. package/server/modules/taskmaster/taskmaster.routes.ts +1482 -0
  416. package/server/modules/taskmaster/taskmaster.service.ts +132 -0
  417. package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -0
  418. package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -0
  419. package/server/modules/user/index.ts +2 -0
  420. package/server/modules/user/tests/user.service.test.ts +61 -0
  421. package/server/modules/user/user.module.ts +58 -0
  422. package/server/modules/user/user.routes.ts +50 -0
  423. package/server/modules/user/user.service.ts +85 -0
  424. package/server/modules/voice/index.ts +2 -0
  425. package/server/modules/voice/tests/voice.service.test.ts +98 -0
  426. package/server/modules/voice/voice.module.ts +47 -0
  427. package/server/modules/voice/voice.routes.ts +113 -0
  428. package/server/modules/voice/voice.service.ts +192 -0
  429. package/server/modules/websocket/README.md +7 -7
  430. package/server/modules/websocket/services/chat-session-writer.service.ts +2 -2
  431. package/server/modules/websocket/services/chat-websocket.service.ts +73 -61
  432. package/server/modules/websocket/services/shell-websocket.service.ts +88 -12
  433. package/server/modules/websocket/services/websocket-server.service.ts +63 -19
  434. package/server/modules/websocket/tests/{chat-image-filter.test.ts → chat-attachment-filter.test.ts} +17 -2
  435. package/server/modules/websocket/tests/shell-websocket.service.test.ts +119 -0
  436. package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -0
  437. package/server/modules/worktrees/index.ts +2 -0
  438. package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -0
  439. package/server/modules/worktrees/services/worktree-create.service.ts +104 -0
  440. package/server/modules/worktrees/services/worktree-git.service.ts +207 -0
  441. package/server/modules/worktrees/services/worktree-list.service.ts +143 -0
  442. package/server/modules/worktrees/services/worktree-merge.service.ts +157 -0
  443. package/server/modules/worktrees/services/worktree-open.service.ts +85 -0
  444. package/server/modules/worktrees/services/worktree-remove.service.ts +88 -0
  445. package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -0
  446. package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -0
  447. package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -0
  448. package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -0
  449. package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -0
  450. package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -0
  451. package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -0
  452. package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -0
  453. package/server/modules/worktrees/worktrees.module.ts +113 -0
  454. package/server/modules/worktrees/worktrees.routes.ts +116 -0
  455. package/server/shared/image-attachments.ts +112 -18
  456. package/server/shared/interfaces.ts +29 -19
  457. package/server/shared/tests/image-attachments.test.ts +55 -0
  458. package/server/shared/types.ts +658 -21
  459. package/server/shared/utils.ts +77 -212
  460. package/dist/assets/index-DLmhQ15L.css +0 -32
  461. package/dist-server/server/browser-use-mcp.js.map +0 -1
  462. package/dist-server/server/claude-sdk.js.map +0 -1
  463. package/dist-server/server/cli.js +0 -647
  464. package/dist-server/server/cli.js.map +0 -1
  465. package/dist-server/server/cursor-cli.js.map +0 -1
  466. package/dist-server/server/middleware/auth.js.map +0 -1
  467. package/dist-server/server/modules/providers/tests/provider-image-history.test.js.map +0 -1
  468. package/dist-server/server/modules/websocket/tests/chat-image-filter.test.js.map +0 -1
  469. package/dist-server/server/openai-codex.js.map +0 -1
  470. package/dist-server/server/opencode-cli.js.map +0 -1
  471. package/dist-server/server/opencode-cli.test.js.map +0 -1
  472. package/dist-server/server/routes/agent.js +0 -1155
  473. package/dist-server/server/routes/agent.js.map +0 -1
  474. package/dist-server/server/routes/auth.js +0 -119
  475. package/dist-server/server/routes/auth.js.map +0 -1
  476. package/dist-server/server/routes/commands.js +0 -492
  477. package/dist-server/server/routes/commands.js.map +0 -1
  478. package/dist-server/server/routes/cursor.js +0 -49
  479. package/dist-server/server/routes/cursor.js.map +0 -1
  480. package/dist-server/server/routes/git.js +0 -1389
  481. package/dist-server/server/routes/git.js.map +0 -1
  482. package/dist-server/server/routes/git.test.js.map +0 -1
  483. package/dist-server/server/routes/mcp-utils.js +0 -29
  484. package/dist-server/server/routes/mcp-utils.js.map +0 -1
  485. package/dist-server/server/routes/plugins.js +0 -266
  486. package/dist-server/server/routes/plugins.js.map +0 -1
  487. package/dist-server/server/routes/settings.js +0 -249
  488. package/dist-server/server/routes/settings.js.map +0 -1
  489. package/dist-server/server/routes/taskmaster.js +0 -1362
  490. package/dist-server/server/routes/taskmaster.js.map +0 -1
  491. package/dist-server/server/routes/tests/commands.test.js +0 -76
  492. package/dist-server/server/routes/tests/commands.test.js.map +0 -1
  493. package/dist-server/server/routes/user.js +0 -116
  494. package/dist-server/server/routes/user.js.map +0 -1
  495. package/dist-server/server/services/notification-orchestrator.js +0 -2
  496. package/dist-server/server/services/notification-orchestrator.js.map +0 -1
  497. package/dist-server/server/services/tests/notification-orchestrator.test.js +0 -64
  498. package/dist-server/server/services/tests/notification-orchestrator.test.js.map +0 -1
  499. package/dist-server/server/services/vapid-keys.js.map +0 -1
  500. package/dist-server/server/utils/colors.js +0 -20
  501. package/dist-server/server/utils/colors.js.map +0 -1
  502. package/dist-server/server/utils/commandParser.js +0 -255
  503. package/dist-server/server/utils/commandParser.js.map +0 -1
  504. package/dist-server/server/utils/gitConfig.js +0 -37
  505. package/dist-server/server/utils/gitConfig.js.map +0 -1
  506. package/dist-server/server/utils/mcp-detector.js +0 -134
  507. package/dist-server/server/utils/mcp-detector.js.map +0 -1
  508. package/dist-server/server/utils/plugin-loader.js.map +0 -1
  509. package/dist-server/server/utils/plugin-process-manager.js.map +0 -1
  510. package/dist-server/server/utils/runtime-paths.js +0 -30
  511. package/dist-server/server/utils/runtime-paths.js.map +0 -1
  512. package/dist-server/server/utils/taskmaster-websocket.js +0 -124
  513. package/dist-server/server/utils/taskmaster-websocket.js.map +0 -1
  514. package/dist-server/server/utils/url-detection.js +0 -58
  515. package/dist-server/server/utils/url-detection.js.map +0 -1
  516. package/dist-server/server/voice-proxy.js +0 -226
  517. package/dist-server/server/voice-proxy.js.map +0 -1
  518. package/server/cli.js +0 -695
  519. package/server/index.js +0 -1651
  520. package/server/routes/agent.js +0 -1257
  521. package/server/routes/auth.js +0 -137
  522. package/server/routes/cursor.js +0 -52
  523. package/server/routes/mcp-utils.js +0 -31
  524. package/server/routes/plugins.js +0 -307
  525. package/server/routes/settings.js +0 -282
  526. package/server/routes/taskmaster.js +0 -1470
  527. package/server/routes/tests/commands.test.js +0 -82
  528. package/server/routes/user.js +0 -124
  529. package/server/services/notification-orchestrator.js +0 -7
  530. package/server/services/tests/notification-orchestrator.test.js +0 -80
  531. package/server/utils/colors.js +0 -21
  532. package/server/utils/commandParser.js +0 -305
  533. package/server/utils/gitConfig.js +0 -35
  534. package/server/utils/mcp-detector.js +0 -147
  535. package/server/utils/runtime-paths.js +0 -37
  536. package/server/utils/taskmaster-websocket.js +0 -135
  537. package/server/utils/url-detection.js +0 -71
  538. package/server/voice-proxy.js +0 -224
  539. /package/server/constants/{config.js → config.ts} +0 -0
@@ -2,7 +2,7 @@ import fsSync from 'node:fs';
2
2
  import readline from 'node:readline';
3
3
 
4
4
  import { sessionsDb } from '@/modules/database/index.js';
5
- import { toImageAttachments } from '@/shared/image-attachments.js';
5
+ import { parseFilesInputTag, toImageAttachments } 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 { createNormalizedMessage, generateMessageId, readObjectRecord, sliceTailPage } from '@/shared/utils.js';
@@ -93,6 +93,144 @@ function extractCodexTextContent(content: unknown): string {
93
93
  .join('\n');
94
94
  }
95
95
 
96
+ function extractCodexToolOutput(output: unknown): string {
97
+ if (typeof output === 'string') {
98
+ return output;
99
+ }
100
+
101
+ if (!Array.isArray(output)) {
102
+ return output == null ? '' : JSON.stringify(output);
103
+ }
104
+
105
+ return output
106
+ .map((item) => {
107
+ const record = readObjectRecord(item);
108
+ return typeof record?.text === 'string' ? record.text : '';
109
+ })
110
+ .filter(Boolean)
111
+ .join('');
112
+ }
113
+
114
+ function readRunningExecOutput(output: string): { cellId: string; content: string } | null {
115
+ const runningCell = /Script running with cell ID\s+(\S+)/i.exec(output);
116
+ if (!runningCell) {
117
+ return null;
118
+ }
119
+
120
+ const outputMarker = /\r?\nOutput:\r?\n/i.exec(output);
121
+ return {
122
+ cellId: runningCell[1],
123
+ content: outputMarker ? output.slice((outputMarker.index || 0) + outputMarker[0].length) : '',
124
+ };
125
+ }
126
+
127
+ function decodeJavaScriptStringLiteral(literal: string): string {
128
+ if (literal.startsWith('"')) {
129
+ try {
130
+ return JSON.parse(literal) as string;
131
+ } catch {
132
+ return literal.slice(1, -1);
133
+ }
134
+ }
135
+
136
+ return literal
137
+ .slice(1, -1)
138
+ .replace(/\\n/g, '\n')
139
+ .replace(/\\r/g, '\r')
140
+ .replace(/\\t/g, '\t')
141
+ .replace(/\\([\\'`])/g, '$1');
142
+ }
143
+
144
+ function extractNestedCodexCommands(source: string): string[] {
145
+ const commands: string[] = [];
146
+ const commandPattern = /\bcommand\s*:\s*("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)/gs;
147
+ for (const match of source.matchAll(commandPattern)) {
148
+ commands.push(decodeJavaScriptStringLiteral(match[1]));
149
+ }
150
+
151
+ if (commands.length === 0) {
152
+ const arrayPattern = /\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*\[([\s\S]*?)\]\s*;/g;
153
+ const stringPattern = /("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)/g;
154
+
155
+ for (const arrayMatch of source.matchAll(arrayPattern)) {
156
+ const arrayName = arrayMatch[1];
157
+ if (!new RegExp(`\\b${arrayName}\\.map\\s*\\(`).test(source)) {
158
+ continue;
159
+ }
160
+ for (const stringMatch of arrayMatch[2].matchAll(stringPattern)) {
161
+ commands.push(decodeJavaScriptStringLiteral(stringMatch[1]));
162
+ }
163
+ }
164
+ }
165
+
166
+ return commands;
167
+ }
168
+
169
+ /**
170
+ * Newer Codex rollouts persist the orchestration wrapper (`exec`) instead of
171
+ * the nested tool name. Recover the useful UI-level operation so history does
172
+ * not degrade into rows labelled only "exec / Parameters".
173
+ */
174
+ function translateCodexExecInput(input: unknown): { toolName: string; toolInput: string } | null {
175
+ const source = typeof input === 'string' ? input : String(input || '');
176
+ if (/\btools\.shell_command\s*\(/.test(source)) {
177
+ const commands = extractNestedCodexCommands(source);
178
+ if (commands.length > 0) {
179
+ return {
180
+ toolName: 'Bash',
181
+ toolInput: JSON.stringify({ command: commands.join('\n') }),
182
+ };
183
+ }
184
+ }
185
+
186
+ return null;
187
+ }
188
+
189
+ function humanizeCodexToolName(toolName: string): string {
190
+ return toolName
191
+ .replace(/__/g, ' ')
192
+ .replace(/_/g, ' ')
193
+ .replace(/\b\w/g, (character) => character.toUpperCase());
194
+ }
195
+
196
+ type CodexSubagentRecord = {
197
+ toolCallId: string;
198
+ message: AnyRecord;
199
+ agentPath?: string;
200
+ isComplete: boolean;
201
+ };
202
+
203
+ function parseCodexSubagentMessage(payload: AnyRecord): {
204
+ author: string;
205
+ messageType: string;
206
+ result: string;
207
+ } | null {
208
+ const text = extractCodexTextContent(payload.content);
209
+ const header = /Message Type:\s*([^\r\n]+)[\s\S]*?Sender:\s*([^\r\n]+)[\s\S]*?Payload:\s*\r?\n([\s\S]*)/i.exec(text);
210
+ const author = readNonEmptyString(payload.author) || header?.[2]?.trim();
211
+ if (!author) {
212
+ return null;
213
+ }
214
+
215
+ return {
216
+ author,
217
+ messageType: header?.[1]?.trim().toUpperCase() || 'MESSAGE',
218
+ result: header?.[3]?.trim() || '',
219
+ };
220
+ }
221
+
222
+ const CODEX_COLLABORATION_CONTROL_TOOLS = new Set([
223
+ 'followup_task',
224
+ 'interrupt_agent',
225
+ 'list_agents',
226
+ 'send_message',
227
+ 'wait_agent',
228
+ ]);
229
+
230
+ function readNonEmptyString(value: unknown): string | undefined {
231
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
232
+ }
233
+
96
234
  async function getCodexSessionMessages(
97
235
  sessionId: string,
98
236
  limit: number | null = null,
@@ -108,6 +246,14 @@ async function getCodexSessionMessages(
108
246
 
109
247
  const messages: AnyRecord[] = [];
110
248
  let tokenUsage: AnyRecord | null = null;
249
+ const ignoredToolCallIds = new Set<string>();
250
+ const execToolCallIds = new Set<string>();
251
+ const execCallByCellId = new Map<string, string>();
252
+ const waitCallToExecCall = new Map<string, string>();
253
+ const pendingExecOutput = new Map<string, string>();
254
+ const completedExecCalls = new Set<string>();
255
+ const subagentsByCallId = new Map<string, CodexSubagentRecord>();
256
+ const subagentsByPath = new Map<string, CodexSubagentRecord>();
111
257
  const fileStream = fsSync.createReadStream(sessionFilePath);
112
258
  const rl = readline.createInterface({
113
259
  input: fileStream,
@@ -121,7 +267,6 @@ async function getCodexSessionMessages(
121
267
 
122
268
  try {
123
269
  const entry = JSON.parse(line) as AnyRecord;
124
-
125
270
  if (entry.type === 'event_msg' && entry.payload?.type === 'token_count' && entry.payload?.info) {
126
271
  const info = entry.payload.info as AnyRecord;
127
272
  if (info.total_token_usage) {
@@ -133,6 +278,20 @@ async function getCodexSessionMessages(
133
278
  }
134
279
  }
135
280
 
281
+ if (
282
+ entry.type === 'event_msg'
283
+ && entry.payload?.type === 'sub_agent_activity'
284
+ && entry.payload.kind === 'started'
285
+ ) {
286
+ const eventId = readNonEmptyString(entry.payload.event_id);
287
+ const agentPath = readNonEmptyString(entry.payload.agent_path);
288
+ const subagent = eventId ? subagentsByCallId.get(eventId) : undefined;
289
+ if (subagent && agentPath) {
290
+ subagent.agentPath = agentPath;
291
+ subagentsByPath.set(agentPath, subagent);
292
+ }
293
+ }
294
+
136
295
  if (entry.type === 'event_msg' && isVisibleCodexUserMessage(entry.payload as AnyRecord)) {
137
296
  messages.push({
138
297
  type: 'user',
@@ -183,10 +342,101 @@ async function getCodexSessionMessages(
183
342
  }
184
343
  }
185
344
 
345
+ if (entry.type === 'response_item' && entry.payload?.type === 'agent_message') {
346
+ const agentMessage = parseCodexSubagentMessage(entry.payload as AnyRecord);
347
+ if (agentMessage && agentMessage.messageType === 'FINAL_ANSWER' && agentMessage.result) {
348
+ let subagent = subagentsByPath.get(agentMessage.author);
349
+ if (!subagent) {
350
+ const fallbackCallId = entry.payload.id || generateMessageId('codex-subagent');
351
+ const taskName = agentMessage.author.split('/').filter(Boolean).pop() || 'agent';
352
+ const taskMessage: AnyRecord = {
353
+ uuid: fallbackCallId,
354
+ type: 'tool_use',
355
+ timestamp: entry.timestamp,
356
+ toolName: 'Task',
357
+ toolInput: JSON.stringify({
358
+ subagent_type: 'Codex',
359
+ description: humanizeCodexToolName(taskName),
360
+ }),
361
+ toolCallId: fallbackCallId,
362
+ };
363
+ messages.push(taskMessage);
364
+ subagent = {
365
+ toolCallId: fallbackCallId,
366
+ message: taskMessage,
367
+ agentPath: agentMessage.author,
368
+ isComplete: false,
369
+ };
370
+ subagentsByCallId.set(fallbackCallId, subagent);
371
+ subagentsByPath.set(agentMessage.author, subagent);
372
+ }
373
+
374
+ if (!subagent.isComplete) {
375
+ messages.push({
376
+ type: 'tool_result',
377
+ timestamp: entry.timestamp,
378
+ toolCallId: subagent.toolCallId,
379
+ output: agentMessage.result,
380
+ });
381
+ subagent.isComplete = true;
382
+ }
383
+ }
384
+ }
385
+
186
386
  if (entry.type === 'response_item' && entry.payload?.type === 'function_call') {
187
387
  let toolName = entry.payload.name;
188
388
  let toolInput = entry.payload.arguments;
189
389
 
390
+ if (toolName === 'spawn_agent') {
391
+ let taskName = 'agent';
392
+ try {
393
+ const args = JSON.parse(String(entry.payload.arguments || '{}')) as AnyRecord;
394
+ taskName = readNonEmptyString(args.task_name) || taskName;
395
+ } catch {
396
+ // The activity event can still provide the canonical agent path.
397
+ }
398
+
399
+ const taskMessage: AnyRecord = {
400
+ uuid: entry.payload.call_id,
401
+ type: 'tool_use',
402
+ timestamp: entry.timestamp,
403
+ toolName: 'Task',
404
+ toolInput: JSON.stringify({
405
+ subagent_type: 'Codex',
406
+ description: humanizeCodexToolName(taskName),
407
+ }),
408
+ toolCallId: entry.payload.call_id,
409
+ };
410
+ messages.push(taskMessage);
411
+ subagentsByCallId.set(entry.payload.call_id, {
412
+ toolCallId: entry.payload.call_id,
413
+ message: taskMessage,
414
+ isComplete: false,
415
+ });
416
+ ignoredToolCallIds.add(entry.payload.call_id);
417
+ continue;
418
+ }
419
+
420
+ if (toolName === 'wait') {
421
+ try {
422
+ const args = JSON.parse(String(entry.payload.arguments || '{}')) as AnyRecord;
423
+ const cellId = String(args.cell_id || '');
424
+ const execCallId = execCallByCellId.get(cellId);
425
+ if (execCallId) {
426
+ waitCallToExecCall.set(entry.payload.call_id, execCallId);
427
+ }
428
+ } catch {
429
+ // Suppress the orchestration wait even when its payload is malformed.
430
+ }
431
+ ignoredToolCallIds.add(entry.payload.call_id);
432
+ continue;
433
+ }
434
+
435
+ if (CODEX_COLLABORATION_CONTROL_TOOLS.has(toolName)) {
436
+ ignoredToolCallIds.add(entry.payload.call_id);
437
+ continue;
438
+ }
439
+
190
440
  if (toolName === 'shell_command') {
191
441
  toolName = 'Bash';
192
442
  try {
@@ -207,18 +457,74 @@ async function getCodexSessionMessages(
207
457
  }
208
458
 
209
459
  if (entry.type === 'response_item' && entry.payload?.type === 'function_call_output') {
460
+ const waitExecCallId = waitCallToExecCall.get(entry.payload.call_id);
461
+ if (waitExecCallId) {
462
+ const output = extractCodexToolOutput(entry.payload.output);
463
+ const runningOutput = readRunningExecOutput(output);
464
+ const accumulatedOutput = `${pendingExecOutput.get(waitExecCallId) || ''}${runningOutput?.content ?? output}`;
465
+ pendingExecOutput.set(waitExecCallId, accumulatedOutput);
466
+
467
+ if (!runningOutput && !completedExecCalls.has(waitExecCallId)) {
468
+ messages.push({
469
+ type: 'tool_result',
470
+ timestamp: entry.timestamp,
471
+ toolCallId: waitExecCallId,
472
+ output: accumulatedOutput,
473
+ });
474
+ completedExecCalls.add(waitExecCallId);
475
+ }
476
+ continue;
477
+ }
478
+
479
+ const subagent = subagentsByCallId.get(entry.payload.call_id);
480
+ if (subagent) {
481
+ const output = extractCodexToolOutput(entry.payload.output);
482
+ try {
483
+ const taskPath = readNonEmptyString((JSON.parse(output) as AnyRecord).task_name);
484
+ if (taskPath) {
485
+ subagent.agentPath = taskPath;
486
+ subagentsByPath.set(taskPath, subagent);
487
+ }
488
+ } catch {
489
+ // The sub_agent_activity event normally supplies the path.
490
+ }
491
+ continue;
492
+ }
493
+
494
+ if (ignoredToolCallIds.has(entry.payload.call_id)) {
495
+ continue;
496
+ }
497
+
210
498
  messages.push({
211
499
  type: 'tool_result',
212
500
  timestamp: entry.timestamp,
213
501
  toolCallId: entry.payload.call_id,
214
- output: entry.payload.output,
502
+ output: extractCodexToolOutput(entry.payload.output),
215
503
  });
216
504
  }
217
505
 
218
506
  if (entry.type === 'response_item' && entry.payload?.type === 'custom_tool_call') {
219
- const toolName = entry.payload.name || 'custom_tool';
507
+ let toolName = entry.payload.name || 'custom_tool';
220
508
  const input = entry.payload.input || '';
221
509
 
510
+ if (toolName === 'exec') {
511
+ const translated = translateCodexExecInput(input);
512
+ if (!translated) {
513
+ ignoredToolCallIds.add(entry.payload.call_id);
514
+ continue;
515
+ }
516
+ toolName = translated.toolName;
517
+ messages.push({
518
+ type: 'tool_use',
519
+ timestamp: entry.timestamp,
520
+ toolName,
521
+ toolInput: translated.toolInput,
522
+ toolCallId: entry.payload.call_id,
523
+ });
524
+ execToolCallIds.add(entry.payload.call_id);
525
+ continue;
526
+ }
527
+
222
528
  if (toolName === 'apply_patch') {
223
529
  const fileMatch = String(input).match(/\*\*\* Update File: (.+)/);
224
530
  const filePath = fileMatch ? fileMatch[1].trim() : 'unknown';
@@ -257,11 +563,26 @@ async function getCodexSessionMessages(
257
563
  }
258
564
 
259
565
  if (entry.type === 'response_item' && entry.payload?.type === 'custom_tool_call_output') {
566
+ if (ignoredToolCallIds.has(entry.payload.call_id)) {
567
+ continue;
568
+ }
569
+
570
+ const output = extractCodexToolOutput(entry.payload.output);
571
+ if (execToolCallIds.has(entry.payload.call_id)) {
572
+ const runningOutput = readRunningExecOutput(output);
573
+ if (runningOutput) {
574
+ execCallByCellId.set(runningOutput.cellId, entry.payload.call_id);
575
+ pendingExecOutput.set(entry.payload.call_id, runningOutput.content);
576
+ continue;
577
+ }
578
+ completedExecCalls.add(entry.payload.call_id);
579
+ }
580
+
260
581
  messages.push({
261
582
  type: 'tool_result',
262
583
  timestamp: entry.timestamp,
263
584
  toolCallId: entry.payload.call_id,
264
- output: entry.payload.output || '',
585
+ output,
265
586
  });
266
587
  }
267
588
  } catch {
@@ -334,8 +655,10 @@ export class CodexSessionsProvider implements IProviderSessions {
334
655
  .filter(Boolean)
335
656
  .join('\n')
336
657
  : String(raw.message.content || '');
658
+ const parsedFiles = parseFilesInputTag(content);
337
659
  const rawImages = Array.isArray(raw.images) && raw.images.length > 0 ? raw.images : undefined;
338
- if (!content.trim() && !rawImages) {
660
+ const files = parsedFiles.attachments.length > 0 ? parsedFiles.attachments : undefined;
661
+ if (!parsedFiles.text.trim() && !rawImages && !files) {
339
662
  return [];
340
663
  }
341
664
  return [createNormalizedMessage({
@@ -345,8 +668,9 @@ export class CodexSessionsProvider implements IProviderSessions {
345
668
  provider: PROVIDER,
346
669
  kind: 'text',
347
670
  role: 'user',
348
- content,
671
+ content: parsedFiles.text,
349
672
  images: rawImages,
673
+ files,
350
674
  })];
351
675
  }
352
676
 
@@ -44,6 +44,11 @@ export class CodexSkillsProvider extends SkillsProvider {
44
44
  rootDir: path.join(os.homedir(), '.agents', 'skills'),
45
45
  commandPrefix: '$',
46
46
  });
47
+ addUniqueProviderSkillSource(sources, seenRootDirs, {
48
+ scope: 'user',
49
+ rootDir: path.join(os.homedir(), '.codex', 'skills'),
50
+ commandPrefix: '$',
51
+ });
47
52
  addUniqueProviderSkillSource(sources, seenRootDirs, {
48
53
  scope: 'admin',
49
54
  rootDir: path.join('/etc', 'codex', 'skills'),
@@ -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,