@cloudcli-ai/cloudcli 1.36.3 → 1.37.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (569) hide show
  1. package/dist/assets/index-D3jfzuKN.css +32 -0
  2. package/dist/assets/index-DTMWjJj8.js +1550 -0
  3. package/dist/index.html +2 -2
  4. package/dist-server/server/constants/config.js.map +1 -1
  5. package/dist-server/server/index.js +73 -1224
  6. package/dist-server/server/index.js.map +1 -1
  7. package/dist-server/server/load-env.js +17 -4
  8. package/dist-server/server/load-env.js.map +1 -1
  9. package/dist-server/server/modules/agent/agent.module.js +37 -0
  10. package/dist-server/server/modules/agent/agent.module.js.map +1 -0
  11. package/dist-server/server/modules/agent/agent.routes.js +1161 -0
  12. package/dist-server/server/modules/agent/agent.routes.js.map +1 -0
  13. package/dist-server/server/modules/agent/index.js +3 -0
  14. package/dist-server/server/modules/agent/index.js.map +1 -0
  15. package/dist-server/server/modules/agent/tests/agent.routes.test.js +176 -0
  16. package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -0
  17. package/dist-server/server/modules/assets/assets.routes.js +56 -15
  18. package/dist-server/server/modules/assets/assets.routes.js.map +1 -1
  19. package/dist-server/server/modules/assets/index.js +2 -2
  20. package/dist-server/server/modules/assets/index.js.map +1 -1
  21. package/dist-server/server/modules/assets/services/image-assets.service.js +39 -1
  22. package/dist-server/server/modules/assets/services/image-assets.service.js.map +1 -1
  23. package/dist-server/server/modules/assets/tests/image-assets.service.test.js +21 -1
  24. package/dist-server/server/modules/assets/tests/image-assets.service.test.js.map +1 -1
  25. package/dist-server/server/{middleware/auth.js → modules/auth/auth.middleware.js} +30 -8
  26. package/dist-server/server/modules/auth/auth.middleware.js.map +1 -0
  27. package/dist-server/server/modules/auth/auth.module.js +29 -0
  28. package/dist-server/server/modules/auth/auth.module.js.map +1 -0
  29. package/dist-server/server/modules/auth/auth.routes.js +45 -0
  30. package/dist-server/server/modules/auth/auth.routes.js.map +1 -0
  31. package/dist-server/server/modules/auth/auth.service.js +113 -0
  32. package/dist-server/server/modules/auth/auth.service.js.map +1 -0
  33. package/dist-server/server/modules/auth/index.js +9 -0
  34. package/dist-server/server/modules/auth/index.js.map +1 -0
  35. package/dist-server/server/modules/auth/tests/auth.service.test.js +80 -0
  36. package/dist-server/server/modules/auth/tests/auth.service.test.js.map +1 -0
  37. package/dist-server/server/{browser-use-mcp.js → modules/browser-use/browser-use-mcp.js} +3 -1
  38. package/dist-server/server/modules/browser-use/browser-use-mcp.js.map +1 -0
  39. package/dist-server/server/modules/browser-use/browser-use.service.js +3 -4
  40. package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
  41. package/dist-server/server/modules/browser-use/index.js +9 -0
  42. package/dist-server/server/modules/browser-use/index.js.map +1 -0
  43. package/dist-server/server/modules/cli/cli.js +11 -0
  44. package/dist-server/server/modules/cli/cli.js.map +1 -0
  45. package/dist-server/server/modules/cli/cli.module.js +86 -0
  46. package/dist-server/server/modules/cli/cli.module.js.map +1 -0
  47. package/dist-server/server/modules/cli/cli.service.js +244 -0
  48. package/dist-server/server/modules/cli/cli.service.js.map +1 -0
  49. package/dist-server/server/modules/cli/index.js +3 -0
  50. package/dist-server/server/modules/cli/index.js.map +1 -0
  51. package/dist-server/server/modules/cli/sandbox.service.js +332 -0
  52. package/dist-server/server/modules/cli/sandbox.service.js.map +1 -0
  53. package/dist-server/server/modules/cli/tests/cli.service.test.js +78 -0
  54. package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -0
  55. package/dist-server/server/modules/cli/tests/sandbox.service.test.js +55 -0
  56. package/dist-server/server/modules/cli/tests/sandbox.service.test.js.map +1 -0
  57. package/dist-server/server/modules/commands/commands.module.js +20 -0
  58. package/dist-server/server/modules/commands/commands.module.js.map +1 -0
  59. package/dist-server/server/modules/commands/commands.routes.js +497 -0
  60. package/dist-server/server/modules/commands/commands.routes.js.map +1 -0
  61. package/dist-server/server/modules/commands/index.js +3 -0
  62. package/dist-server/server/modules/commands/index.js.map +1 -0
  63. package/dist-server/server/modules/commands/tests/commands.test.js +91 -0
  64. package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -0
  65. package/dist-server/server/modules/database/index.js +3 -0
  66. package/dist-server/server/modules/database/index.js.map +1 -1
  67. package/dist-server/server/modules/database/migrations.js +31 -1
  68. package/dist-server/server/modules/database/migrations.js.map +1 -1
  69. package/dist-server/server/modules/database/repositories/provider-models.js +112 -0
  70. package/dist-server/server/modules/database/repositories/provider-models.js.map +1 -0
  71. package/dist-server/server/modules/database/repositories/sessions.db.js +76 -7
  72. package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
  73. package/dist-server/server/modules/database/schema.js +29 -0
  74. package/dist-server/server/modules/database/schema.js.map +1 -1
  75. package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js +102 -0
  76. package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js.map +1 -0
  77. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +2 -1
  78. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js.map +1 -1
  79. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js +22 -0
  80. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -1
  81. package/dist-server/server/modules/file-tree/file-tree.module.js +95 -0
  82. package/dist-server/server/modules/file-tree/file-tree.module.js.map +1 -0
  83. package/dist-server/server/modules/file-tree/file-tree.routes.js +208 -0
  84. package/dist-server/server/modules/file-tree/file-tree.routes.js.map +1 -0
  85. package/dist-server/server/modules/file-tree/file-tree.service.js +576 -0
  86. package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -0
  87. package/dist-server/server/modules/file-tree/index.js +3 -0
  88. package/dist-server/server/modules/file-tree/index.js.map +1 -0
  89. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js +123 -0
  90. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js.map +1 -0
  91. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +260 -0
  92. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -0
  93. package/dist-server/server/modules/git/git-parsing.service.js +61 -0
  94. package/dist-server/server/modules/git/git-parsing.service.js.map +1 -0
  95. package/dist-server/server/modules/git/git.module.js +14 -0
  96. package/dist-server/server/modules/git/git.module.js.map +1 -0
  97. package/dist-server/server/modules/git/git.routes.js +1339 -0
  98. package/dist-server/server/modules/git/git.routes.js.map +1 -0
  99. package/dist-server/server/modules/git/index.js +3 -0
  100. package/dist-server/server/modules/git/index.js.map +1 -0
  101. package/dist-server/server/modules/git/tests/git-init.routes.test.js +48 -0
  102. package/dist-server/server/modules/git/tests/git-init.routes.test.js.map +1 -0
  103. package/dist-server/server/{routes → modules/git/tests}/git.test.js +1 -1
  104. package/dist-server/server/modules/git/tests/git.test.js.map +1 -0
  105. package/dist-server/server/modules/notifications/index.js +15 -1
  106. package/dist-server/server/modules/notifications/index.js.map +1 -1
  107. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js +44 -0
  108. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js.map +1 -0
  109. package/dist-server/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.js} +3 -2
  110. package/dist-server/server/modules/notifications/vapid-keys.service.js.map +1 -0
  111. package/dist-server/server/modules/plugins/index.js +9 -0
  112. package/dist-server/server/modules/plugins/index.js.map +1 -0
  113. package/dist-server/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.js} +3 -2
  114. package/dist-server/server/modules/plugins/plugin-process.service.js.map +1 -0
  115. package/dist-server/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.js} +2 -1
  116. package/dist-server/server/modules/plugins/plugin-registry.service.js.map +1 -0
  117. package/dist-server/server/modules/plugins/plugins.module.js +30 -0
  118. package/dist-server/server/modules/plugins/plugins.module.js.map +1 -0
  119. package/dist-server/server/modules/plugins/plugins.routes.js +70 -0
  120. package/dist-server/server/modules/plugins/plugins.routes.js.map +1 -0
  121. package/dist-server/server/modules/plugins/plugins.service.js +123 -0
  122. package/dist-server/server/modules/plugins/plugins.service.js.map +1 -0
  123. package/dist-server/server/modules/plugins/tests/plugins.service.test.js +28 -0
  124. package/dist-server/server/modules/plugins/tests/plugins.service.test.js.map +1 -0
  125. package/dist-server/server/modules/projects/index.js +5 -0
  126. package/dist-server/server/modules/projects/index.js.map +1 -1
  127. package/dist-server/server/modules/providers/index.js +3 -0
  128. package/dist-server/server/modules/providers/index.js.map +1 -1
  129. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +6 -0
  130. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -1
  131. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +47 -18
  132. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
  133. package/dist-server/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +69 -55
  134. package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -0
  135. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +6 -4
  136. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -1
  137. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +23 -4
  138. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
  139. package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
  140. package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
  141. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +59 -75
  142. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
  143. package/dist-server/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +48 -34
  144. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -0
  145. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js +1 -54
  146. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -1
  147. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +290 -6
  148. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
  149. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +5 -0
  150. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -1
  151. package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
  152. package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
  153. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +33 -673
  154. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -1
  155. package/dist-server/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +40 -28
  156. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -0
  157. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +21 -14
  158. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -1
  159. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +2 -0
  160. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -1
  161. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +112 -333
  162. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
  163. package/dist-server/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +38 -25
  164. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js.map +1 -0
  165. package/dist-server/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +27 -4
  166. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js.map +1 -0
  167. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +0 -12
  168. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js.map +1 -1
  169. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +11 -5
  170. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -1
  171. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js +2 -0
  172. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js.map +1 -1
  173. package/dist-server/server/modules/providers/provider.routes.js +169 -37
  174. package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
  175. package/dist-server/server/modules/providers/services/provider-capabilities.service.js +5 -1
  176. package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
  177. package/dist-server/server/modules/providers/services/provider-models.service.js +247 -184
  178. package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
  179. package/dist-server/server/modules/providers/services/provider-runtime.service.js +66 -0
  180. package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -0
  181. package/dist-server/server/modules/providers/services/provider-token-usage.service.js +268 -0
  182. package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -0
  183. package/dist-server/server/modules/providers/services/session-conversations-search.service.js +12 -4
  184. package/dist-server/server/modules/providers/services/session-conversations-search.service.js.map +1 -1
  185. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +2 -0
  186. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
  187. package/dist-server/server/modules/providers/services/sessions.service.js +116 -3
  188. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
  189. package/dist-server/server/modules/providers/shared/base/abstract.provider.js +2 -3
  190. package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -1
  191. package/dist-server/server/modules/providers/tests/claude-auth.test.js +122 -0
  192. package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -0
  193. package/dist-server/server/modules/providers/tests/claude-sessions.test.js +44 -0
  194. package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -0
  195. package/dist-server/server/modules/providers/tests/codex-sessions.test.js +76 -4
  196. package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
  197. package/dist-server/server/modules/providers/tests/opencode-models.test.js +15 -126
  198. package/dist-server/server/modules/providers/tests/opencode-models.test.js.map +1 -1
  199. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +5 -5
  200. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -1
  201. package/dist-server/server/modules/providers/tests/{provider-image-history.test.js → provider-attachment-history.test.js} +60 -2
  202. package/dist-server/server/modules/providers/tests/provider-attachment-history.test.js.map +1 -0
  203. package/dist-server/server/modules/providers/tests/provider-models.service.test.js +241 -271
  204. package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
  205. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +126 -0
  206. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -0
  207. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +166 -0
  208. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -0
  209. package/dist-server/server/modules/providers/tests/provider.routes.test.js +126 -0
  210. package/dist-server/server/modules/providers/tests/provider.routes.test.js.map +1 -0
  211. package/dist-server/server/modules/providers/tests/sessions-details.test.js +62 -0
  212. package/dist-server/server/modules/providers/tests/sessions-details.test.js.map +1 -0
  213. package/dist-server/server/modules/providers/tests/sessions.service.test.js +87 -0
  214. package/dist-server/server/modules/providers/tests/sessions.service.test.js.map +1 -0
  215. package/dist-server/server/modules/providers/tests/skills.test.js +4 -2
  216. package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
  217. package/dist-server/server/modules/settings/index.js +3 -0
  218. package/dist-server/server/modules/settings/index.js.map +1 -0
  219. package/dist-server/server/modules/settings/settings.module.js +35 -0
  220. package/dist-server/server/modules/settings/settings.module.js.map +1 -0
  221. package/dist-server/server/modules/settings/settings.routes.js +34 -0
  222. package/dist-server/server/modules/settings/settings.routes.js.map +1 -0
  223. package/dist-server/server/modules/settings/settings.service.js +116 -0
  224. package/dist-server/server/modules/settings/settings.service.js.map +1 -0
  225. package/dist-server/server/modules/settings/tests/settings.service.test.js +48 -0
  226. package/dist-server/server/modules/settings/tests/settings.service.test.js.map +1 -0
  227. package/dist-server/server/modules/system/index.js +3 -0
  228. package/dist-server/server/modules/system/index.js.map +1 -0
  229. package/dist-server/server/modules/system/system.module.js +44 -0
  230. package/dist-server/server/modules/system/system.module.js.map +1 -0
  231. package/dist-server/server/modules/system/system.routes.js +16 -0
  232. package/dist-server/server/modules/system/system.routes.js.map +1 -0
  233. package/dist-server/server/modules/system/system.service.js +45 -0
  234. package/dist-server/server/modules/system/system.service.js.map +1 -0
  235. package/dist-server/server/modules/system/tests/system.service.test.js +100 -0
  236. package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -0
  237. package/dist-server/server/modules/taskmaster/index.js +3 -0
  238. package/dist-server/server/modules/taskmaster/index.js.map +1 -0
  239. package/dist-server/server/modules/taskmaster/taskmaster.module.js +20 -0
  240. package/dist-server/server/modules/taskmaster/taskmaster.module.js.map +1 -0
  241. package/dist-server/server/modules/taskmaster/taskmaster.routes.js +1372 -0
  242. package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -0
  243. package/dist-server/server/modules/taskmaster/taskmaster.service.js +107 -0
  244. package/dist-server/server/modules/taskmaster/taskmaster.service.js.map +1 -0
  245. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +132 -0
  246. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -0
  247. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js +85 -0
  248. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js.map +1 -0
  249. package/dist-server/server/modules/user/index.js +3 -0
  250. package/dist-server/server/modules/user/index.js.map +1 -0
  251. package/dist-server/server/modules/user/tests/user.service.test.js +53 -0
  252. package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -0
  253. package/dist-server/server/modules/user/user.module.js +47 -0
  254. package/dist-server/server/modules/user/user.module.js.map +1 -0
  255. package/dist-server/server/modules/user/user.routes.js +44 -0
  256. package/dist-server/server/modules/user/user.routes.js.map +1 -0
  257. package/dist-server/server/modules/user/user.service.js +59 -0
  258. package/dist-server/server/modules/user/user.service.js.map +1 -0
  259. package/dist-server/server/modules/voice/index.js +3 -0
  260. package/dist-server/server/modules/voice/index.js.map +1 -0
  261. package/dist-server/server/modules/voice/tests/voice.service.test.js +86 -0
  262. package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -0
  263. package/dist-server/server/modules/voice/voice.module.js +44 -0
  264. package/dist-server/server/modules/voice/voice.module.js.map +1 -0
  265. package/dist-server/server/modules/voice/voice.routes.js +87 -0
  266. package/dist-server/server/modules/voice/voice.routes.js.map +1 -0
  267. package/dist-server/server/modules/voice/voice.service.js +148 -0
  268. package/dist-server/server/modules/voice/voice.service.js.map +1 -0
  269. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +2 -2
  270. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +44 -29
  271. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
  272. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +76 -8
  273. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
  274. package/dist-server/server/modules/websocket/services/websocket-server.service.js +51 -20
  275. package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -1
  276. package/dist-server/server/modules/websocket/tests/{chat-image-filter.test.js → chat-attachment-filter.test.js} +10 -3
  277. package/dist-server/server/modules/websocket/tests/chat-attachment-filter.test.js.map +1 -0
  278. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +97 -0
  279. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -0
  280. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js +61 -0
  281. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js.map +1 -0
  282. package/dist-server/server/modules/worktrees/index.js +3 -0
  283. package/dist-server/server/modules/worktrees/index.js.map +1 -0
  284. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js +37 -0
  285. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js.map +1 -0
  286. package/dist-server/server/modules/worktrees/services/worktree-create.service.js +67 -0
  287. package/dist-server/server/modules/worktrees/services/worktree-create.service.js.map +1 -0
  288. package/dist-server/server/modules/worktrees/services/worktree-git.service.js +172 -0
  289. package/dist-server/server/modules/worktrees/services/worktree-git.service.js.map +1 -0
  290. package/dist-server/server/modules/worktrees/services/worktree-list.service.js +91 -0
  291. package/dist-server/server/modules/worktrees/services/worktree-list.service.js.map +1 -0
  292. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js +118 -0
  293. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js.map +1 -0
  294. package/dist-server/server/modules/worktrees/services/worktree-open.service.js +58 -0
  295. package/dist-server/server/modules/worktrees/services/worktree-open.service.js.map +1 -0
  296. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +65 -0
  297. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js.map +1 -0
  298. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js +58 -0
  299. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js.map +1 -0
  300. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js +85 -0
  301. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js.map +1 -0
  302. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js +58 -0
  303. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js.map +1 -0
  304. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js +34 -0
  305. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js.map +1 -0
  306. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js +137 -0
  307. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js.map +1 -0
  308. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js +99 -0
  309. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js.map +1 -0
  310. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js +157 -0
  311. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js.map +1 -0
  312. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js +167 -0
  313. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js.map +1 -0
  314. package/dist-server/server/modules/worktrees/worktrees.module.js +97 -0
  315. package/dist-server/server/modules/worktrees/worktrees.module.js.map +1 -0
  316. package/dist-server/server/modules/worktrees/worktrees.routes.js +84 -0
  317. package/dist-server/server/modules/worktrees/worktrees.routes.js.map +1 -0
  318. package/dist-server/server/shared/image-attachments.js +90 -17
  319. package/dist-server/server/shared/image-attachments.js.map +1 -1
  320. package/dist-server/server/shared/tests/image-attachments.test.js +43 -1
  321. package/dist-server/server/shared/tests/image-attachments.test.js.map +1 -1
  322. package/dist-server/server/shared/utils.js +66 -142
  323. package/dist-server/server/shared/utils.js.map +1 -1
  324. package/package.json +9 -5
  325. package/server/index.ts +401 -0
  326. package/server/{load-env.js → load-env.ts} +18 -5
  327. package/server/modules/agent/agent.module.ts +51 -0
  328. package/server/modules/agent/agent.routes.ts +1287 -0
  329. package/server/modules/agent/index.ts +2 -0
  330. package/server/modules/agent/tests/agent.routes.test.ts +205 -0
  331. package/server/modules/assets/assets.routes.ts +63 -16
  332. package/server/modules/assets/index.ts +2 -2
  333. package/server/modules/assets/services/image-assets.service.ts +46 -1
  334. package/server/modules/assets/tests/image-assets.service.test.ts +28 -0
  335. package/server/{middleware/auth.js → modules/auth/auth.middleware.ts} +38 -7
  336. package/server/modules/auth/auth.module.ts +38 -0
  337. package/server/modules/auth/auth.routes.ts +57 -0
  338. package/server/modules/auth/auth.service.ts +155 -0
  339. package/server/modules/auth/index.ts +9 -0
  340. package/server/modules/auth/tests/auth.service.test.ts +95 -0
  341. package/server/{browser-use-mcp.ts → modules/browser-use/browser-use-mcp.ts} +3 -1
  342. package/server/modules/browser-use/browser-use.service.ts +3 -4
  343. package/server/modules/browser-use/index.ts +8 -0
  344. package/server/modules/cli/cli.module.ts +96 -0
  345. package/server/modules/cli/cli.service.ts +281 -0
  346. package/server/modules/cli/cli.ts +13 -0
  347. package/server/modules/cli/index.ts +2 -0
  348. package/server/modules/cli/sandbox.service.ts +413 -0
  349. package/server/modules/cli/tests/cli.service.test.ts +91 -0
  350. package/server/modules/cli/tests/sandbox.service.test.ts +61 -0
  351. package/server/modules/commands/commands.module.ts +22 -0
  352. package/server/{routes/commands.js → modules/commands/commands.routes.ts} +46 -38
  353. package/server/modules/commands/index.ts +2 -0
  354. package/server/modules/commands/tests/commands.test.ts +114 -0
  355. package/server/modules/database/index.ts +3 -0
  356. package/server/modules/database/migrations.ts +35 -0
  357. package/server/modules/database/repositories/provider-models.ts +168 -0
  358. package/server/modules/database/repositories/sessions.db.ts +103 -8
  359. package/server/modules/database/schema.ts +30 -0
  360. package/server/modules/database/tests/provider-models.db.integration.test.ts +125 -0
  361. package/server/modules/database/tests/sessions-provider-mapping.test.ts +2 -1
  362. package/server/modules/database/tests/sessions.db.integration.test.ts +32 -0
  363. package/server/modules/file-tree/file-tree.module.ts +116 -0
  364. package/server/modules/file-tree/file-tree.routes.ts +258 -0
  365. package/server/modules/file-tree/file-tree.service.ts +664 -0
  366. package/server/modules/file-tree/index.ts +2 -0
  367. package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -0
  368. package/server/modules/file-tree/tests/file-tree.service.test.ts +317 -0
  369. package/server/modules/git/git-parsing.service.ts +66 -0
  370. package/server/modules/git/git.module.ts +22 -0
  371. package/server/{routes/git.js → modules/git/git.routes.ts} +91 -132
  372. package/server/modules/git/index.ts +2 -0
  373. package/server/modules/git/tests/git-init.routes.test.ts +52 -0
  374. package/server/{routes/git.test.js → modules/git/tests/git.test.ts} +3 -3
  375. package/server/modules/notifications/index.ts +9 -0
  376. package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -0
  377. package/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.ts} +3 -1
  378. package/server/modules/plugins/index.ts +9 -0
  379. package/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.ts} +3 -1
  380. package/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.ts} +1 -0
  381. package/server/modules/plugins/plugins.module.ts +33 -0
  382. package/server/modules/plugins/plugins.routes.ts +66 -0
  383. package/server/modules/plugins/plugins.service.ts +147 -0
  384. package/server/modules/plugins/tests/plugins.service.test.ts +32 -0
  385. package/server/modules/projects/index.ts +5 -0
  386. package/server/modules/providers/README.md +41 -9
  387. package/server/modules/providers/index.ts +4 -0
  388. package/server/modules/providers/list/claude/claude-auth.provider.ts +8 -0
  389. package/server/modules/providers/list/claude/claude-models.provider.ts +47 -26
  390. package/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +73 -59
  391. package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +6 -4
  392. package/server/modules/providers/list/claude/claude-sessions.provider.ts +27 -4
  393. package/server/modules/providers/list/claude/claude.provider.ts +3 -0
  394. package/server/modules/providers/list/codex/codex-models.provider.ts +58 -108
  395. package/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +54 -36
  396. package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +1 -60
  397. package/server/modules/providers/list/codex/codex-sessions.provider.ts +331 -7
  398. package/server/modules/providers/list/codex/codex-skills.provider.ts +5 -0
  399. package/server/modules/providers/list/codex/codex.provider.ts +3 -0
  400. package/server/modules/providers/list/cursor/cursor-models.provider.ts +32 -719
  401. package/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +58 -27
  402. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +26 -15
  403. package/server/modules/providers/list/cursor/cursor.provider.ts +3 -0
  404. package/server/modules/providers/list/opencode/opencode-models.provider.ts +112 -423
  405. package/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +56 -28
  406. package/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +41 -3
  407. package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +0 -13
  408. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +13 -5
  409. package/server/modules/providers/list/opencode/opencode.provider.ts +3 -0
  410. package/server/modules/providers/provider.routes.ts +228 -39
  411. package/server/modules/providers/services/provider-capabilities.service.ts +7 -1
  412. package/server/modules/providers/services/provider-models.service.ts +312 -269
  413. package/server/modules/providers/services/provider-runtime.service.ts +108 -0
  414. package/server/modules/providers/services/provider-token-usage.service.ts +357 -0
  415. package/server/modules/providers/services/session-conversations-search.service.ts +12 -4
  416. package/server/modules/providers/services/sessions-watcher.service.ts +2 -0
  417. package/server/modules/providers/services/sessions.service.ts +166 -3
  418. package/server/modules/providers/shared/base/abstract.provider.ts +4 -3
  419. package/server/modules/providers/tests/claude-auth.test.ts +150 -0
  420. package/server/modules/providers/tests/claude-sessions.test.ts +61 -0
  421. package/server/modules/providers/tests/codex-sessions.test.ts +83 -4
  422. package/server/modules/providers/tests/opencode-models.test.ts +34 -135
  423. package/server/modules/providers/tests/opencode-sessions.test.ts +5 -5
  424. package/server/modules/providers/tests/{provider-image-history.test.ts → provider-attachment-history.test.ts} +68 -1
  425. package/server/modules/providers/tests/provider-models.service.test.ts +300 -296
  426. package/server/modules/providers/tests/provider-runtime.service.test.ts +138 -0
  427. package/server/modules/providers/tests/provider-token-usage.service.test.ts +186 -0
  428. package/server/modules/providers/tests/provider.routes.test.ts +183 -0
  429. package/server/modules/providers/tests/sessions-details.test.ts +73 -0
  430. package/server/modules/providers/tests/sessions.service.test.ts +127 -0
  431. package/server/modules/providers/tests/skills.test.ts +9 -2
  432. package/server/modules/settings/index.ts +2 -0
  433. package/server/modules/settings/settings.module.ts +50 -0
  434. package/server/modules/settings/settings.routes.ts +51 -0
  435. package/server/modules/settings/settings.service.ts +186 -0
  436. package/server/modules/settings/tests/settings.service.test.ts +54 -0
  437. package/server/modules/system/index.ts +2 -0
  438. package/server/modules/system/system.module.ts +62 -0
  439. package/server/modules/system/system.routes.ts +21 -0
  440. package/server/modules/system/system.service.ts +76 -0
  441. package/server/modules/system/tests/system.service.test.ts +118 -0
  442. package/server/modules/taskmaster/index.ts +2 -0
  443. package/server/modules/taskmaster/taskmaster.module.ts +24 -0
  444. package/server/modules/taskmaster/taskmaster.routes.ts +1482 -0
  445. package/server/modules/taskmaster/taskmaster.service.ts +132 -0
  446. package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -0
  447. package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -0
  448. package/server/modules/user/index.ts +2 -0
  449. package/server/modules/user/tests/user.service.test.ts +61 -0
  450. package/server/modules/user/user.module.ts +58 -0
  451. package/server/modules/user/user.routes.ts +50 -0
  452. package/server/modules/user/user.service.ts +85 -0
  453. package/server/modules/voice/index.ts +2 -0
  454. package/server/modules/voice/tests/voice.service.test.ts +98 -0
  455. package/server/modules/voice/voice.module.ts +47 -0
  456. package/server/modules/voice/voice.routes.ts +113 -0
  457. package/server/modules/voice/voice.service.ts +192 -0
  458. package/server/modules/websocket/README.md +7 -7
  459. package/server/modules/websocket/services/chat-session-writer.service.ts +2 -2
  460. package/server/modules/websocket/services/chat-websocket.service.ts +77 -61
  461. package/server/modules/websocket/services/shell-websocket.service.ts +88 -12
  462. package/server/modules/websocket/services/websocket-server.service.ts +63 -19
  463. package/server/modules/websocket/tests/{chat-image-filter.test.ts → chat-attachment-filter.test.ts} +17 -2
  464. package/server/modules/websocket/tests/shell-websocket.service.test.ts +119 -0
  465. package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -0
  466. package/server/modules/worktrees/index.ts +2 -0
  467. package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -0
  468. package/server/modules/worktrees/services/worktree-create.service.ts +104 -0
  469. package/server/modules/worktrees/services/worktree-git.service.ts +207 -0
  470. package/server/modules/worktrees/services/worktree-list.service.ts +143 -0
  471. package/server/modules/worktrees/services/worktree-merge.service.ts +157 -0
  472. package/server/modules/worktrees/services/worktree-open.service.ts +85 -0
  473. package/server/modules/worktrees/services/worktree-remove.service.ts +88 -0
  474. package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -0
  475. package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -0
  476. package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -0
  477. package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -0
  478. package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -0
  479. package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -0
  480. package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -0
  481. package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -0
  482. package/server/modules/worktrees/worktrees.module.ts +113 -0
  483. package/server/modules/worktrees/worktrees.routes.ts +116 -0
  484. package/server/shared/image-attachments.ts +112 -18
  485. package/server/shared/interfaces.ts +33 -25
  486. package/server/shared/tests/image-attachments.test.ts +55 -0
  487. package/server/shared/types.ts +685 -36
  488. package/server/shared/utils.ts +77 -212
  489. package/dist/assets/index-CcCsKitq.js +0 -1423
  490. package/dist/assets/index-DLmhQ15L.css +0 -32
  491. package/dist-server/server/browser-use-mcp.js.map +0 -1
  492. package/dist-server/server/claude-sdk.js.map +0 -1
  493. package/dist-server/server/cli.js +0 -647
  494. package/dist-server/server/cli.js.map +0 -1
  495. package/dist-server/server/cursor-cli.js.map +0 -1
  496. package/dist-server/server/middleware/auth.js.map +0 -1
  497. package/dist-server/server/modules/providers/tests/provider-image-history.test.js.map +0 -1
  498. package/dist-server/server/modules/websocket/tests/chat-image-filter.test.js.map +0 -1
  499. package/dist-server/server/openai-codex.js.map +0 -1
  500. package/dist-server/server/opencode-cli.js.map +0 -1
  501. package/dist-server/server/opencode-cli.test.js.map +0 -1
  502. package/dist-server/server/routes/agent.js +0 -1155
  503. package/dist-server/server/routes/agent.js.map +0 -1
  504. package/dist-server/server/routes/auth.js +0 -119
  505. package/dist-server/server/routes/auth.js.map +0 -1
  506. package/dist-server/server/routes/commands.js +0 -492
  507. package/dist-server/server/routes/commands.js.map +0 -1
  508. package/dist-server/server/routes/cursor.js +0 -49
  509. package/dist-server/server/routes/cursor.js.map +0 -1
  510. package/dist-server/server/routes/git.js +0 -1389
  511. package/dist-server/server/routes/git.js.map +0 -1
  512. package/dist-server/server/routes/git.test.js.map +0 -1
  513. package/dist-server/server/routes/mcp-utils.js +0 -29
  514. package/dist-server/server/routes/mcp-utils.js.map +0 -1
  515. package/dist-server/server/routes/plugins.js +0 -266
  516. package/dist-server/server/routes/plugins.js.map +0 -1
  517. package/dist-server/server/routes/settings.js +0 -249
  518. package/dist-server/server/routes/settings.js.map +0 -1
  519. package/dist-server/server/routes/taskmaster.js +0 -1362
  520. package/dist-server/server/routes/taskmaster.js.map +0 -1
  521. package/dist-server/server/routes/tests/commands.test.js +0 -76
  522. package/dist-server/server/routes/tests/commands.test.js.map +0 -1
  523. package/dist-server/server/routes/user.js +0 -116
  524. package/dist-server/server/routes/user.js.map +0 -1
  525. package/dist-server/server/services/notification-orchestrator.js +0 -2
  526. package/dist-server/server/services/notification-orchestrator.js.map +0 -1
  527. package/dist-server/server/services/tests/notification-orchestrator.test.js +0 -64
  528. package/dist-server/server/services/tests/notification-orchestrator.test.js.map +0 -1
  529. package/dist-server/server/services/vapid-keys.js.map +0 -1
  530. package/dist-server/server/utils/colors.js +0 -20
  531. package/dist-server/server/utils/colors.js.map +0 -1
  532. package/dist-server/server/utils/commandParser.js +0 -255
  533. package/dist-server/server/utils/commandParser.js.map +0 -1
  534. package/dist-server/server/utils/gitConfig.js +0 -37
  535. package/dist-server/server/utils/gitConfig.js.map +0 -1
  536. package/dist-server/server/utils/mcp-detector.js +0 -134
  537. package/dist-server/server/utils/mcp-detector.js.map +0 -1
  538. package/dist-server/server/utils/plugin-loader.js.map +0 -1
  539. package/dist-server/server/utils/plugin-process-manager.js.map +0 -1
  540. package/dist-server/server/utils/runtime-paths.js +0 -30
  541. package/dist-server/server/utils/runtime-paths.js.map +0 -1
  542. package/dist-server/server/utils/taskmaster-websocket.js +0 -124
  543. package/dist-server/server/utils/taskmaster-websocket.js.map +0 -1
  544. package/dist-server/server/utils/url-detection.js +0 -58
  545. package/dist-server/server/utils/url-detection.js.map +0 -1
  546. package/dist-server/server/voice-proxy.js +0 -226
  547. package/dist-server/server/voice-proxy.js.map +0 -1
  548. package/server/cli.js +0 -695
  549. package/server/index.js +0 -1651
  550. package/server/routes/agent.js +0 -1257
  551. package/server/routes/auth.js +0 -137
  552. package/server/routes/cursor.js +0 -52
  553. package/server/routes/mcp-utils.js +0 -31
  554. package/server/routes/plugins.js +0 -307
  555. package/server/routes/settings.js +0 -282
  556. package/server/routes/taskmaster.js +0 -1470
  557. package/server/routes/tests/commands.test.js +0 -82
  558. package/server/routes/user.js +0 -124
  559. package/server/services/notification-orchestrator.js +0 -7
  560. package/server/services/tests/notification-orchestrator.test.js +0 -80
  561. package/server/utils/colors.js +0 -21
  562. package/server/utils/commandParser.js +0 -305
  563. package/server/utils/gitConfig.js +0 -35
  564. package/server/utils/mcp-detector.js +0 -147
  565. package/server/utils/runtime-paths.js +0 -37
  566. package/server/utils/taskmaster-websocket.js +0 -135
  567. package/server/utils/url-detection.js +0 -71
  568. package/server/voice-proxy.js +0 -224
  569. /package/server/constants/{config.js → config.ts} +0 -0
@@ -17,6 +17,7 @@ type CreateAppSessionResult = {
17
17
  sessionId: string;
18
18
  provider: LLMProvider;
19
19
  projectPath: string;
20
+ sessionName: string;
20
21
  };
21
22
 
22
23
  type ArchivedSessionListItem = {
@@ -32,6 +33,43 @@ type ArchivedSessionListItem = {
32
33
  isProjectArchived: boolean;
33
34
  };
34
35
 
36
+ type RecentSessionListItem = Pick<
37
+ ArchivedSessionListItem,
38
+ 'sessionId' | 'provider' | 'projectId' | 'projectDisplayName' | 'sessionTitle' | 'lastActivity'
39
+ >;
40
+
41
+ type RecentSessionsPage = {
42
+ conversations: RecentSessionListItem[];
43
+ total: number;
44
+ hasMore: boolean;
45
+ };
46
+
47
+ type SessionDetails = {
48
+ /** Canonical app-facing session id (may differ from the looked-up id when a provider-native id was given). */
49
+ sessionId: string;
50
+ provider: LLMProvider;
51
+ summary: string;
52
+ createdAt: string | null;
53
+ updatedAt: string | null;
54
+ lastActivity: string | null;
55
+ isArchived: boolean;
56
+ project: {
57
+ projectId: string;
58
+ path: string;
59
+ fullPath: string;
60
+ displayName: string;
61
+ isStarred: boolean;
62
+ isArchived: boolean;
63
+ } | null;
64
+ };
65
+
66
+ const MAX_CLOUDCLI_SESSION_NAME_WORDS = 4;
67
+
68
+ function buildCloudCliSessionName(initialMessage: string): string {
69
+ const words = initialMessage.trim().split(/\s+/).filter(Boolean);
70
+ return words.slice(0, MAX_CLOUDCLI_SESSION_NAME_WORDS).join(' ') || 'Untitled Session';
71
+ }
72
+
35
73
  /**
36
74
  * Removes one file if it exists.
37
75
  */
@@ -100,6 +138,57 @@ export const sessionsService = {
100
138
  return chatRunRegistry.listRunningRuns();
101
139
  },
102
140
 
141
+ /**
142
+ * Returns the active conversation feed in true global activity order.
143
+ */
144
+ listRecentSessions(limit: number, offset: number): RecentSessionsPage {
145
+ const page = sessionsDb.getRecentSessionsPage(limit, offset);
146
+ const projectCache = new Map<string, ReturnType<typeof projectsDb.getProjectPath>>();
147
+ const conversations = page.sessions.map((session) => {
148
+ const projectPath = session.project_path?.trim() ? session.project_path : null;
149
+ let project = null;
150
+
151
+ if (projectPath) {
152
+ if (!projectCache.has(projectPath)) {
153
+ projectCache.set(projectPath, projectsDb.getProjectPath(projectPath));
154
+ }
155
+ project = projectCache.get(projectPath) ?? null;
156
+ }
157
+
158
+ return {
159
+ sessionId: session.session_id,
160
+ provider: session.provider as LLMProvider,
161
+ projectId: project?.project_id ?? null,
162
+ projectDisplayName: resolveProjectDisplayName(projectPath, project?.custom_project_name),
163
+ sessionTitle: session.custom_name?.trim() || session.session_id,
164
+ lastActivity: session.updated_at ?? session.created_at ?? null,
165
+ };
166
+ });
167
+
168
+ return {
169
+ conversations,
170
+ total: page.total,
171
+ hasMore: offset + conversations.length < page.total,
172
+ };
173
+ },
174
+
175
+ /**
176
+ * Resolves the provider-native session id a runtime needs for resume.
177
+ *
178
+ * Callers hand provider runtimes the stable app session id; the provider
179
+ * CLIs/SDKs only understand their own native id, which lives on the session
180
+ * row. Ids without a row are assumed to be provider-native already (direct
181
+ * API callers that reference sessions the watcher has not indexed yet).
182
+ */
183
+ resolveProviderSessionId(sessionId: string | null | undefined): string | null {
184
+ if (!sessionId) {
185
+ return null;
186
+ }
187
+
188
+ const session = sessionsDb.getSessionById(sessionId);
189
+ return session ? session.provider_session_id : sessionId;
190
+ },
191
+
103
192
  /**
104
193
  * Normalizes one provider-native event into frontend session message events.
105
194
  */
@@ -118,9 +207,15 @@ export const sessionsService = {
118
207
  * (via `POST /api/providers/sessions`) when the user starts a brand-new
119
208
  * chat, navigates to the returned id immediately, and the id never changes
120
209
  * for the lifetime of the conversation. The provider-native id is mapped to
121
- * this row later, when the provider runtime announces it mid-run.
210
+ * this row later, when the provider runtime announces it mid-run. Its title
211
+ * comes directly from the first visible CloudCLI message and is limited to
212
+ * four whole words before any provider-owned storage exists.
122
213
  */
123
- createAppSession(provider: LLMProvider, projectPath: string): CreateAppSessionResult {
214
+ createAppSession(
215
+ provider: LLMProvider,
216
+ projectPath: string,
217
+ initialMessage: string,
218
+ ): CreateAppSessionResult {
124
219
  const normalizedProjectPath = projectPath.trim();
125
220
  if (!normalizedProjectPath) {
126
221
  throw new AppError('projectPath is required.', {
@@ -130,15 +225,40 @@ export const sessionsService = {
130
225
  }
131
226
 
132
227
  const sessionId = randomUUID();
133
- sessionsDb.createAppSession(sessionId, provider, normalizedProjectPath);
228
+ const sessionName = buildCloudCliSessionName(initialMessage);
229
+ sessionsDb.createAppSession(sessionId, provider, normalizedProjectPath, sessionName);
134
230
 
135
231
  return {
136
232
  sessionId,
137
233
  provider,
138
234
  projectPath: normalizedProjectPath,
235
+ sessionName,
139
236
  };
140
237
  },
141
238
 
239
+ /**
240
+ * Resolves the provider-native id only for an explicit user copy action.
241
+ * Normal session payloads continue to expose only the stable app id.
242
+ */
243
+ getProviderSessionId(sessionId: string): string {
244
+ const session = sessionsDb.getSessionById(sessionId);
245
+ if (!session) {
246
+ throw new AppError(`Session "${sessionId}" was not found.`, {
247
+ code: 'SESSION_NOT_FOUND',
248
+ statusCode: 404,
249
+ });
250
+ }
251
+
252
+ if (!session.provider_session_id) {
253
+ throw new AppError('This session ID is not available yet.', {
254
+ code: 'PROVIDER_SESSION_ID_NOT_AVAILABLE',
255
+ statusCode: 409,
256
+ });
257
+ }
258
+
259
+ return session.provider_session_id;
260
+ },
261
+
142
262
  /**
143
263
  * Fetches persisted history by app session id.
144
264
  *
@@ -189,6 +309,49 @@ export const sessionsService = {
189
309
  };
190
310
  },
191
311
 
312
+ /**
313
+ * Resolves one session (by app id, falling back to the provider-native id)
314
+ * to its metadata plus the owning project.
315
+ *
316
+ * This backs deep links like `/session/:sessionId`: the frontend's paginated
317
+ * project payloads only carry each project's first session page, so a
318
+ * session opened directly by URL may not be present client-side at all —
319
+ * this lookup is the authoritative way to learn which project owns it.
320
+ */
321
+ getSessionDetailsById(sessionId: string): SessionDetails {
322
+ const session =
323
+ sessionsDb.getSessionById(sessionId) ?? sessionsDb.getSessionByProviderSessionId(sessionId);
324
+ if (!session) {
325
+ throw new AppError(`Session "${sessionId}" was not found.`, {
326
+ code: 'SESSION_NOT_FOUND',
327
+ statusCode: 404,
328
+ });
329
+ }
330
+
331
+ const projectPath = session.project_path?.trim() ? session.project_path : null;
332
+ const project = projectPath ? projectsDb.getProjectPath(projectPath) : null;
333
+
334
+ return {
335
+ sessionId: session.session_id,
336
+ provider: session.provider as LLMProvider,
337
+ summary: session.custom_name?.trim() || '',
338
+ createdAt: session.created_at ?? null,
339
+ updatedAt: session.updated_at ?? null,
340
+ lastActivity: session.updated_at ?? session.created_at ?? null,
341
+ isArchived: Boolean(session.isArchived),
342
+ project: project && projectPath
343
+ ? {
344
+ projectId: project.project_id,
345
+ path: projectPath,
346
+ fullPath: projectPath,
347
+ displayName: resolveProjectDisplayName(projectPath, project.custom_project_name),
348
+ isStarred: Boolean(project.isStarred),
349
+ isArchived: Boolean(project.isArchived),
350
+ }
351
+ : null,
352
+ };
353
+ },
354
+
192
355
  /**
193
356
  * Returns archived sessions with enough project metadata for the sidebar to
194
357
  * group, filter, open, and restore them without a per-row follow-up query.
@@ -3,6 +3,7 @@ import type {
3
3
  IProviderAuth,
4
4
  IProviderMcp,
5
5
  IProviderModels,
6
+ IProviderRuntime,
6
7
  IProviderSessionSynchronizer,
7
8
  IProviderSkills,
8
9
  IProviderSessions,
@@ -12,12 +13,12 @@ import type { LLMProvider } from '@/shared/types.js';
12
13
  /**
13
14
  * Shared provider base.
14
15
  *
15
- * Concrete providers must expose auth/MCP handlers and implement message
16
- * normalization/history loading because those behaviors depend on native
17
- * SDK/CLI formats.
16
+ * Concrete providers expose their live runtime plus model, auth, MCP, skill,
17
+ * session, and synchronization facets behind one registry-owned object.
18
18
  */
19
19
  export abstract class AbstractProvider implements IProvider {
20
20
  readonly id: LLMProvider;
21
+ abstract readonly runtime: IProviderRuntime;
21
22
  abstract readonly models: IProviderModels;
22
23
  abstract readonly mcp: IProviderMcp;
23
24
  abstract readonly auth: IProviderAuth;
@@ -0,0 +1,150 @@
1
+ import assert from 'node:assert/strict';
2
+ import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import test from 'node:test';
6
+
7
+ import { ClaudeProviderAuth } from '@/modules/providers/list/claude/claude-auth.provider.js';
8
+
9
+ // checkCredentials() is private, but unlike getStatus() it never shells out to the
10
+ // `claude` CLI — it only reads env vars and ~/.claude files. Calling it directly
11
+ // (TypeScript's `private` has no runtime effect) tests the priority order without
12
+ // depending on `claude` being installed in the test environment.
13
+ type CheckCredentialsResult = {
14
+ authenticated: boolean;
15
+ email: string | null;
16
+ method: string | null;
17
+ error?: string;
18
+ };
19
+
20
+ const checkCredentials = (auth: ClaudeProviderAuth): Promise<CheckCredentialsResult> =>
21
+ (auth as unknown as { checkCredentials: () => Promise<CheckCredentialsResult> }).checkCredentials();
22
+
23
+ const ENV_KEYS = ['CLAUDE_CODE_OAUTH_TOKEN', 'ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN'] as const;
24
+
25
+ const withEnv = async (
26
+ overrides: Partial<Record<(typeof ENV_KEYS)[number], string>>,
27
+ fn: () => Promise<void>,
28
+ ) => {
29
+ const original: Partial<Record<(typeof ENV_KEYS)[number], string>> = {};
30
+ for (const key of ENV_KEYS) {
31
+ original[key] = process.env[key];
32
+ const value = overrides[key];
33
+ if (value === undefined) {
34
+ delete process.env[key];
35
+ } else {
36
+ process.env[key] = value;
37
+ }
38
+ }
39
+ try {
40
+ await fn();
41
+ } finally {
42
+ for (const key of ENV_KEYS) {
43
+ if (original[key] === undefined) {
44
+ delete process.env[key];
45
+ } else {
46
+ process.env[key] = original[key];
47
+ }
48
+ }
49
+ }
50
+ };
51
+
52
+ const withTempHome = async (fn: (homeDir: string) => Promise<void>) => {
53
+ const homeDir = await mkdtemp(path.join(os.tmpdir(), 'claude-auth-test-'));
54
+ const originalHome = process.env.HOME;
55
+ process.env.HOME = homeDir;
56
+ try {
57
+ await fn(homeDir);
58
+ } finally {
59
+ if (originalHome === undefined) {
60
+ delete process.env.HOME;
61
+ } else {
62
+ process.env.HOME = originalHome;
63
+ }
64
+ await rm(homeDir, { recursive: true, force: true });
65
+ }
66
+ };
67
+
68
+ const writeCredentialsFile = async (homeDir: string, body: unknown) => {
69
+ const claudeDir = path.join(homeDir, '.claude');
70
+ await mkdir(claudeDir, { recursive: true });
71
+ await writeFile(path.join(claudeDir, '.credentials.json'), JSON.stringify(body));
72
+ };
73
+
74
+ const writeSettingsFile = async (homeDir: string, env: Record<string, string>) => {
75
+ const claudeDir = path.join(homeDir, '.claude');
76
+ await mkdir(claudeDir, { recursive: true });
77
+ await writeFile(path.join(claudeDir, 'settings.json'), JSON.stringify({ env }));
78
+ };
79
+
80
+ test('checkCredentials: CLAUDE_CODE_OAUTH_TOKEN set is authenticated via environment, even with a stale credentials file', async () => {
81
+ await withTempHome(async (homeDir) => {
82
+ await writeCredentialsFile(homeDir, {
83
+ claudeAiOauth: { accessToken: 'stale-token', expiresAt: 1_000_000_000_000 }, // long expired
84
+ });
85
+
86
+ await withEnv({ CLAUDE_CODE_OAUTH_TOKEN: 'test-oauth-token' }, async () => {
87
+ const status = await checkCredentials(new ClaudeProviderAuth());
88
+ assert.equal(status.authenticated, true);
89
+ assert.equal(status.method, 'environment');
90
+ });
91
+ });
92
+ });
93
+
94
+ test('checkCredentials: CLAUDE_CODE_OAUTH_TOKEN configured via settings.json env block is authenticated via environment', async () => {
95
+ await withTempHome(async (homeDir) => {
96
+ await writeSettingsFile(homeDir, { CLAUDE_CODE_OAUTH_TOKEN: 'test-oauth-token-from-settings' });
97
+ await writeCredentialsFile(homeDir, {
98
+ claudeAiOauth: { accessToken: 'stale-token', expiresAt: 1_000_000_000_000 }, // long expired
99
+ });
100
+
101
+ await withEnv({}, async () => {
102
+ const status = await checkCredentials(new ClaudeProviderAuth());
103
+ assert.equal(status.authenticated, true);
104
+ assert.equal(status.method, 'environment');
105
+ });
106
+ });
107
+ });
108
+
109
+ test('checkCredentials: no CLAUDE_CODE_OAUTH_TOKEN, valid credentials file falls back to credentials_file', async () => {
110
+ await withTempHome(async (homeDir) => {
111
+ await writeCredentialsFile(homeDir, {
112
+ claudeAiOauth: { accessToken: 'valid-token', expiresAt: Date.now() + 60 * 60 * 1000 },
113
+ email: 'someone@example.com',
114
+ });
115
+
116
+ await withEnv({}, async () => {
117
+ const status = await checkCredentials(new ClaudeProviderAuth());
118
+ assert.equal(status.authenticated, true);
119
+ assert.equal(status.method, 'credentials_file');
120
+ assert.equal(status.email, 'someone@example.com');
121
+ });
122
+ });
123
+ });
124
+
125
+ test('checkCredentials: no CLAUDE_CODE_OAUTH_TOKEN, expired credentials file reports not authenticated', async () => {
126
+ await withTempHome(async (homeDir) => {
127
+ await writeCredentialsFile(homeDir, {
128
+ claudeAiOauth: { accessToken: 'stale-token', expiresAt: 1_000_000_000_000 },
129
+ });
130
+
131
+ await withEnv({}, async () => {
132
+ const status = await checkCredentials(new ClaudeProviderAuth());
133
+ assert.equal(status.authenticated, false);
134
+ assert.match(status.error ?? '', /expired/i);
135
+ });
136
+ });
137
+ });
138
+
139
+ test('checkCredentials: ANTHROPIC_API_KEY takes precedence over CLAUDE_CODE_OAUTH_TOKEN', async () => {
140
+ await withTempHome(async () => {
141
+ await withEnv(
142
+ { ANTHROPIC_API_KEY: 'test-api-key', CLAUDE_CODE_OAUTH_TOKEN: 'test-oauth-token' },
143
+ async () => {
144
+ const status = await checkCredentials(new ClaudeProviderAuth());
145
+ assert.equal(status.authenticated, true);
146
+ assert.equal(status.method, 'api_key');
147
+ },
148
+ );
149
+ });
150
+ });
@@ -0,0 +1,61 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+
4
+ import { ClaudeSessionsProvider } from '@/modules/providers/list/claude/claude-sessions.provider.js';
5
+
6
+ const SESSION_ID = 'session-1';
7
+
8
+ const SKILL_BODY = [
9
+ 'Base directory for this skill: /tmp/claude/bundled-skills/2.1.220/abc123/claude-api',
10
+ '',
11
+ '# Building LLM-Powered Applications with Claude',
12
+ '',
13
+ 'This skill helps you build LLM-powered applications with Claude.',
14
+ ].join('\n');
15
+
16
+ test('claude: injected skill bodies are hidden even without the isMeta flag', () => {
17
+ const provider = new ClaudeSessionsProvider();
18
+
19
+ // The live SDK stream omits `isMeta`, so the payload has to be recognised by
20
+ // its content or it renders as a giant user bubble mid-run.
21
+ const live = provider.normalizeMessage(
22
+ {
23
+ uuid: 'u1',
24
+ timestamp: '2026-07-28T10:00:00.000Z',
25
+ message: { role: 'user', content: [{ type: 'text', text: SKILL_BODY }] },
26
+ },
27
+ SESSION_ID,
28
+ );
29
+ assert.deepEqual(live, []);
30
+
31
+ const persisted = provider.normalizeMessage(
32
+ {
33
+ uuid: 'u2',
34
+ timestamp: '2026-07-28T10:00:00.000Z',
35
+ isMeta: true,
36
+ message: { role: 'user', content: [{ type: 'text', text: SKILL_BODY }] },
37
+ },
38
+ SESSION_ID,
39
+ );
40
+ assert.deepEqual(persisted, []);
41
+ });
42
+
43
+ test('claude: the Skill tool result itself still reaches the UI', () => {
44
+ const provider = new ClaudeSessionsProvider();
45
+
46
+ const messages = provider.normalizeMessage(
47
+ {
48
+ uuid: 'u3',
49
+ timestamp: '2026-07-28T10:00:00.000Z',
50
+ message: {
51
+ role: 'user',
52
+ content: [{ type: 'tool_result', tool_use_id: 'toolu_1', content: 'Launching skill: claude-api' }],
53
+ },
54
+ },
55
+ SESSION_ID,
56
+ );
57
+
58
+ assert.equal(messages.length, 1);
59
+ assert.equal(messages[0].kind, 'tool_result');
60
+ assert.equal(messages[0].toolId, 'toolu_1');
61
+ });
@@ -6,6 +6,7 @@ import test from 'node:test';
6
6
 
7
7
  import { closeConnection, initializeDatabase, sessionsDb } from '@/modules/database/index.js';
8
8
  import { CodexSessionSynchronizer } from '@/modules/providers/list/codex/codex-session-synchronizer.provider.js';
9
+ import { CodexSessionsProvider } from '@/modules/providers/list/codex/codex-sessions.provider.js';
9
10
 
10
11
  const patchHomeDir = (nextHomeDir: string) => {
11
12
  const original = os.homedir;
@@ -63,24 +64,24 @@ const writeCodexTranscript = async (
63
64
  return filePath;
64
65
  };
65
66
 
66
- test('Codex synchronizer titles app-created sessions from the first user message', { concurrency: false }, async () => {
67
+ test('Codex synchronizer preserves the title assigned when CloudCLI creates a session', { concurrency: false }, async () => {
67
68
  const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'codex-session-sync-app-'));
68
69
  const workspacePath = path.join(tempRoot, 'workspace');
69
70
  await mkdir(workspacePath, { recursive: true });
70
71
  const restoreHomeDir = patchHomeDir(tempRoot);
71
72
 
72
73
  try {
73
- await writeCodexTranscript(tempRoot, 'codex-app-1', workspacePath, 'Fix the login redirect bug');
74
+ await writeCodexTranscript(tempRoot, 'codex-app-1', workspacePath, 'Provider transcript title must not win');
74
75
  await withIsolatedDatabase(async () => {
75
76
  // The app allocates its own id and later maps the provider id onto it,
76
77
  // exactly as a message sent from cloudcli does.
77
- sessionsDb.createAppSession('app-1', 'codex', workspacePath);
78
+ sessionsDb.createAppSession('app-1', 'codex', workspacePath, 'Fix the login redirect');
78
79
  sessionsDb.assignProviderSessionId('app-1', 'codex-app-1');
79
80
 
80
81
  const synchronizer = new CodexSessionSynchronizer();
81
82
  await synchronizer.synchronize();
82
83
 
83
- assert.equal(sessionsDb.getSessionById('app-1')?.custom_name, 'Fix the login redirect bug');
84
+ assert.equal(sessionsDb.getSessionById('app-1')?.custom_name, 'Fix the login redirect');
84
85
  });
85
86
  } finally {
86
87
  restoreHomeDir();
@@ -150,3 +151,81 @@ test('Codex synchronizer leaves indexed sessions untitled when no name is availa
150
151
  await rm(tempRoot, { recursive: true, force: true });
151
152
  }
152
153
  });
154
+
155
+ test('Codex history preserves wrapped exec tool calls and results', { concurrency: false }, async () => {
156
+ const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'codex-exec-history-'));
157
+ const workspacePath = path.join(tempRoot, 'workspace');
158
+ await mkdir(workspacePath, { recursive: true });
159
+ const restoreHomeDir = patchHomeDir(tempRoot);
160
+
161
+ try {
162
+ const providerSessionId = 'codex-exec-1';
163
+ const transcriptPath = await writeCodexTranscript(tempRoot, providerSessionId, workspacePath);
164
+ const wrappedCalls = [
165
+ {
166
+ callId: 'shell-command-1',
167
+ input: 'const cmds = ["echo one", "echo two"]; await Promise.all(cmds.map(command => tools.shell_command({ command })));',
168
+ expectedToolName: 'Bash',
169
+ expectedToolInput: JSON.stringify({ command: 'echo one\necho two' }),
170
+ },
171
+ {
172
+ callId: 'json-shell-command-1',
173
+ input: 'const r = await tools.shell_command({"command":"Get-Content -Raw README.md","workdir":"C:\\\\workspace","timeout_ms":10000}); text(r)',
174
+ expectedToolName: 'Bash',
175
+ expectedToolInput: JSON.stringify({ command: 'Get-Content -Raw README.md' }),
176
+ },
177
+ {
178
+ callId: 'exec-command-1',
179
+ input: 'await tools.exec_command({"command":"echo current"});',
180
+ expectedToolName: 'Bash',
181
+ expectedToolInput: JSON.stringify({ command: 'echo current' }),
182
+ },
183
+ { callId: 'apply-patch-1', input: 'await tools.apply_patch("*** Begin Patch\\n*** End Patch");' },
184
+ { callId: 'web-run-1', input: 'await tools.web__run({ search_query: [{ q: "Codex" }] });' },
185
+ { callId: 'update-plan-1', input: 'await tools.update_plan({ plan: [] });' },
186
+ { callId: 'unknown-1', input: 'await tools.unknown_wrapper({ value: true });' },
187
+ ];
188
+ const transcriptLines = [
189
+ JSON.stringify({ type: 'session_meta', payload: { id: providerSessionId, cwd: workspacePath } }),
190
+ ];
191
+ for (const call of wrappedCalls) {
192
+ transcriptLines.push(
193
+ JSON.stringify({
194
+ type: 'response_item',
195
+ payload: { type: 'custom_tool_call', name: 'exec', call_id: call.callId, input: call.input },
196
+ }),
197
+ JSON.stringify({
198
+ type: 'response_item',
199
+ payload: { type: 'custom_tool_call_output', call_id: call.callId, output: `result:${call.callId}` },
200
+ }),
201
+ );
202
+ }
203
+ await writeFile(transcriptPath, `${transcriptLines.join('\n')}\n`, 'utf8');
204
+
205
+ await withIsolatedDatabase(async () => {
206
+ sessionsDb.createAppSession('app-exec-1', 'codex', workspacePath);
207
+ sessionsDb.assignProviderSessionId('app-exec-1', providerSessionId);
208
+ await new CodexSessionSynchronizer().synchronize();
209
+
210
+ const history = await new CodexSessionsProvider().fetchHistory('app-exec-1');
211
+ const toolUses = history.messages.filter((message) => message.kind === 'tool_use');
212
+ const toolResults = history.messages.filter((message) => message.kind === 'tool_result');
213
+ const toolUsesById = new Map(toolUses.map((message) => [message.toolId, message]));
214
+ const toolResultsById = new Map(toolResults.map((message) => [message.toolId, message]));
215
+
216
+ assert.equal(toolUses.length, wrappedCalls.length);
217
+ assert.equal(toolResults.length, wrappedCalls.length);
218
+ for (const call of wrappedCalls) {
219
+ const toolUse = toolUsesById.get(call.callId);
220
+ assert.ok(toolUse);
221
+ assert.equal(toolUse.toolName, call.expectedToolName || 'exec');
222
+ assert.equal(toolUse.toolInput, call.expectedToolInput || call.input);
223
+ assert.equal(toolUse.toolResult?.content, `result:${call.callId}`);
224
+ assert.equal(toolResultsById.get(call.callId)?.content, `result:${call.callId}`);
225
+ }
226
+ });
227
+ } finally {
228
+ restoreHomeDir();
229
+ await rm(tempRoot, { recursive: true, force: true });
230
+ }
231
+ });