@cloudcli-ai/cloudcli 1.36.3 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (535) hide show
  1. package/dist/assets/index-DSlds633.css +32 -0
  2. package/dist/assets/{index-CcCsKitq.js → index-eGqPeIEu.js} +375 -267
  3. package/dist/index.html +2 -2
  4. package/dist-server/server/constants/config.js.map +1 -1
  5. package/dist-server/server/index.js +73 -1224
  6. package/dist-server/server/index.js.map +1 -1
  7. package/dist-server/server/load-env.js +17 -4
  8. package/dist-server/server/load-env.js.map +1 -1
  9. package/dist-server/server/modules/agent/agent.module.js +37 -0
  10. package/dist-server/server/modules/agent/agent.module.js.map +1 -0
  11. package/dist-server/server/modules/agent/agent.routes.js +1161 -0
  12. package/dist-server/server/modules/agent/agent.routes.js.map +1 -0
  13. package/dist-server/server/modules/agent/index.js +3 -0
  14. package/dist-server/server/modules/agent/index.js.map +1 -0
  15. package/dist-server/server/modules/agent/tests/agent.routes.test.js +176 -0
  16. package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -0
  17. package/dist-server/server/modules/assets/assets.routes.js +56 -15
  18. package/dist-server/server/modules/assets/assets.routes.js.map +1 -1
  19. package/dist-server/server/modules/assets/index.js +2 -2
  20. package/dist-server/server/modules/assets/index.js.map +1 -1
  21. package/dist-server/server/modules/assets/services/image-assets.service.js +39 -1
  22. package/dist-server/server/modules/assets/services/image-assets.service.js.map +1 -1
  23. package/dist-server/server/modules/assets/tests/image-assets.service.test.js +21 -1
  24. package/dist-server/server/modules/assets/tests/image-assets.service.test.js.map +1 -1
  25. package/dist-server/server/{middleware/auth.js → modules/auth/auth.middleware.js} +30 -8
  26. package/dist-server/server/modules/auth/auth.middleware.js.map +1 -0
  27. package/dist-server/server/modules/auth/auth.module.js +29 -0
  28. package/dist-server/server/modules/auth/auth.module.js.map +1 -0
  29. package/dist-server/server/modules/auth/auth.routes.js +45 -0
  30. package/dist-server/server/modules/auth/auth.routes.js.map +1 -0
  31. package/dist-server/server/modules/auth/auth.service.js +113 -0
  32. package/dist-server/server/modules/auth/auth.service.js.map +1 -0
  33. package/dist-server/server/modules/auth/index.js +9 -0
  34. package/dist-server/server/modules/auth/index.js.map +1 -0
  35. package/dist-server/server/modules/auth/tests/auth.service.test.js +80 -0
  36. package/dist-server/server/modules/auth/tests/auth.service.test.js.map +1 -0
  37. package/dist-server/server/{browser-use-mcp.js → modules/browser-use/browser-use-mcp.js} +3 -1
  38. package/dist-server/server/modules/browser-use/browser-use-mcp.js.map +1 -0
  39. package/dist-server/server/modules/browser-use/browser-use.service.js +3 -4
  40. package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
  41. package/dist-server/server/modules/browser-use/index.js +9 -0
  42. package/dist-server/server/modules/browser-use/index.js.map +1 -0
  43. package/dist-server/server/modules/cli/cli.js +11 -0
  44. package/dist-server/server/modules/cli/cli.js.map +1 -0
  45. package/dist-server/server/modules/cli/cli.module.js +86 -0
  46. package/dist-server/server/modules/cli/cli.module.js.map +1 -0
  47. package/dist-server/server/modules/cli/cli.service.js +244 -0
  48. package/dist-server/server/modules/cli/cli.service.js.map +1 -0
  49. package/dist-server/server/modules/cli/index.js +3 -0
  50. package/dist-server/server/modules/cli/index.js.map +1 -0
  51. package/dist-server/server/modules/cli/sandbox.service.js +332 -0
  52. package/dist-server/server/modules/cli/sandbox.service.js.map +1 -0
  53. package/dist-server/server/modules/cli/tests/cli.service.test.js +78 -0
  54. package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -0
  55. package/dist-server/server/modules/cli/tests/sandbox.service.test.js +55 -0
  56. package/dist-server/server/modules/cli/tests/sandbox.service.test.js.map +1 -0
  57. package/dist-server/server/modules/commands/commands.module.js +20 -0
  58. package/dist-server/server/modules/commands/commands.module.js.map +1 -0
  59. package/dist-server/server/modules/commands/commands.routes.js +497 -0
  60. package/dist-server/server/modules/commands/commands.routes.js.map +1 -0
  61. package/dist-server/server/modules/commands/index.js +3 -0
  62. package/dist-server/server/modules/commands/index.js.map +1 -0
  63. package/dist-server/server/modules/commands/tests/commands.test.js +96 -0
  64. package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -0
  65. package/dist-server/server/modules/database/index.js +1 -0
  66. package/dist-server/server/modules/database/index.js.map +1 -1
  67. package/dist-server/server/modules/database/migrations.js +13 -0
  68. package/dist-server/server/modules/database/migrations.js.map +1 -1
  69. package/dist-server/server/modules/database/repositories/sessions.db.js +14 -1
  70. package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
  71. package/dist-server/server/modules/database/schema.js +4 -0
  72. package/dist-server/server/modules/database/schema.js.map +1 -1
  73. package/dist-server/server/modules/file-tree/file-tree.module.js +91 -0
  74. package/dist-server/server/modules/file-tree/file-tree.module.js.map +1 -0
  75. package/dist-server/server/modules/file-tree/file-tree.routes.js +208 -0
  76. package/dist-server/server/modules/file-tree/file-tree.routes.js.map +1 -0
  77. package/dist-server/server/modules/file-tree/file-tree.service.js +544 -0
  78. package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -0
  79. package/dist-server/server/modules/file-tree/index.js +3 -0
  80. package/dist-server/server/modules/file-tree/index.js.map +1 -0
  81. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js +123 -0
  82. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js.map +1 -0
  83. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +184 -0
  84. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -0
  85. package/dist-server/server/modules/git/git-parsing.service.js +61 -0
  86. package/dist-server/server/modules/git/git-parsing.service.js.map +1 -0
  87. package/dist-server/server/modules/git/git.module.js +14 -0
  88. package/dist-server/server/modules/git/git.module.js.map +1 -0
  89. package/dist-server/server/modules/git/git.routes.js +1339 -0
  90. package/dist-server/server/modules/git/git.routes.js.map +1 -0
  91. package/dist-server/server/modules/git/index.js +3 -0
  92. package/dist-server/server/modules/git/index.js.map +1 -0
  93. package/dist-server/server/modules/git/tests/git-init.routes.test.js +48 -0
  94. package/dist-server/server/modules/git/tests/git-init.routes.test.js.map +1 -0
  95. package/dist-server/server/{routes → modules/git/tests}/git.test.js +1 -1
  96. package/dist-server/server/modules/git/tests/git.test.js.map +1 -0
  97. package/dist-server/server/modules/notifications/index.js +15 -1
  98. package/dist-server/server/modules/notifications/index.js.map +1 -1
  99. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js +44 -0
  100. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js.map +1 -0
  101. package/dist-server/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.js} +3 -2
  102. package/dist-server/server/modules/notifications/vapid-keys.service.js.map +1 -0
  103. package/dist-server/server/modules/plugins/index.js +9 -0
  104. package/dist-server/server/modules/plugins/index.js.map +1 -0
  105. package/dist-server/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.js} +3 -2
  106. package/dist-server/server/modules/plugins/plugin-process.service.js.map +1 -0
  107. package/dist-server/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.js} +2 -1
  108. package/dist-server/server/modules/plugins/plugin-registry.service.js.map +1 -0
  109. package/dist-server/server/modules/plugins/plugins.module.js +30 -0
  110. package/dist-server/server/modules/plugins/plugins.module.js.map +1 -0
  111. package/dist-server/server/modules/plugins/plugins.routes.js +70 -0
  112. package/dist-server/server/modules/plugins/plugins.routes.js.map +1 -0
  113. package/dist-server/server/modules/plugins/plugins.service.js +123 -0
  114. package/dist-server/server/modules/plugins/plugins.service.js.map +1 -0
  115. package/dist-server/server/modules/plugins/tests/plugins.service.test.js +28 -0
  116. package/dist-server/server/modules/plugins/tests/plugins.service.test.js.map +1 -0
  117. package/dist-server/server/modules/projects/index.js +5 -0
  118. package/dist-server/server/modules/projects/index.js.map +1 -1
  119. package/dist-server/server/modules/providers/index.js +3 -0
  120. package/dist-server/server/modules/providers/index.js.map +1 -1
  121. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +6 -0
  122. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -1
  123. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +1 -4
  124. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
  125. package/dist-server/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +62 -41
  126. package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -0
  127. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +6 -4
  128. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -1
  129. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +23 -4
  130. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
  131. package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
  132. package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
  133. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +1 -4
  134. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
  135. package/dist-server/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +48 -34
  136. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -0
  137. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +290 -6
  138. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
  139. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +5 -0
  140. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -1
  141. package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
  142. package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
  143. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +1 -4
  144. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -1
  145. package/dist-server/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +40 -28
  146. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -0
  147. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +21 -14
  148. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -1
  149. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +2 -0
  150. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -1
  151. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +7 -5
  152. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
  153. package/dist-server/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +38 -25
  154. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js.map +1 -0
  155. package/dist-server/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +27 -4
  156. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js.map +1 -0
  157. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +11 -5
  158. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -1
  159. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js +2 -0
  160. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js.map +1 -1
  161. package/dist-server/server/modules/providers/provider.routes.js +33 -9
  162. package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
  163. package/dist-server/server/modules/providers/services/provider-capabilities.service.js +5 -1
  164. package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
  165. package/dist-server/server/modules/providers/services/provider-models.service.js +110 -15
  166. package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
  167. package/dist-server/server/modules/providers/services/provider-runtime.service.js +66 -0
  168. package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -0
  169. package/dist-server/server/modules/providers/services/provider-token-usage.service.js +268 -0
  170. package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -0
  171. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +2 -0
  172. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
  173. package/dist-server/server/modules/providers/services/sessions.service.js +54 -0
  174. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
  175. package/dist-server/server/modules/providers/shared/base/abstract.provider.js +2 -3
  176. package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -1
  177. package/dist-server/server/modules/providers/tests/claude-auth.test.js +122 -0
  178. package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -0
  179. package/dist-server/server/modules/providers/tests/claude-sessions.test.js +44 -0
  180. package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -0
  181. package/dist-server/server/modules/providers/tests/codex-sessions.test.js +36 -0
  182. package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
  183. package/dist-server/server/modules/providers/tests/{provider-image-history.test.js → provider-attachment-history.test.js} +60 -2
  184. package/dist-server/server/modules/providers/tests/provider-attachment-history.test.js.map +1 -0
  185. package/dist-server/server/modules/providers/tests/provider-models.service.test.js +148 -61
  186. package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
  187. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +130 -0
  188. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -0
  189. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +165 -0
  190. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -0
  191. package/dist-server/server/modules/providers/tests/sessions-details.test.js +62 -0
  192. package/dist-server/server/modules/providers/tests/sessions-details.test.js.map +1 -0
  193. package/dist-server/server/modules/providers/tests/skills.test.js +4 -2
  194. package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
  195. package/dist-server/server/modules/settings/index.js +3 -0
  196. package/dist-server/server/modules/settings/index.js.map +1 -0
  197. package/dist-server/server/modules/settings/settings.module.js +35 -0
  198. package/dist-server/server/modules/settings/settings.module.js.map +1 -0
  199. package/dist-server/server/modules/settings/settings.routes.js +34 -0
  200. package/dist-server/server/modules/settings/settings.routes.js.map +1 -0
  201. package/dist-server/server/modules/settings/settings.service.js +116 -0
  202. package/dist-server/server/modules/settings/settings.service.js.map +1 -0
  203. package/dist-server/server/modules/settings/tests/settings.service.test.js +48 -0
  204. package/dist-server/server/modules/settings/tests/settings.service.test.js.map +1 -0
  205. package/dist-server/server/modules/system/index.js +3 -0
  206. package/dist-server/server/modules/system/index.js.map +1 -0
  207. package/dist-server/server/modules/system/system.module.js +44 -0
  208. package/dist-server/server/modules/system/system.module.js.map +1 -0
  209. package/dist-server/server/modules/system/system.routes.js +16 -0
  210. package/dist-server/server/modules/system/system.routes.js.map +1 -0
  211. package/dist-server/server/modules/system/system.service.js +45 -0
  212. package/dist-server/server/modules/system/system.service.js.map +1 -0
  213. package/dist-server/server/modules/system/tests/system.service.test.js +100 -0
  214. package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -0
  215. package/dist-server/server/modules/taskmaster/index.js +3 -0
  216. package/dist-server/server/modules/taskmaster/index.js.map +1 -0
  217. package/dist-server/server/modules/taskmaster/taskmaster.module.js +20 -0
  218. package/dist-server/server/modules/taskmaster/taskmaster.module.js.map +1 -0
  219. package/dist-server/server/modules/taskmaster/taskmaster.routes.js +1372 -0
  220. package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -0
  221. package/dist-server/server/modules/taskmaster/taskmaster.service.js +107 -0
  222. package/dist-server/server/modules/taskmaster/taskmaster.service.js.map +1 -0
  223. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +132 -0
  224. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -0
  225. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js +85 -0
  226. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js.map +1 -0
  227. package/dist-server/server/modules/user/index.js +3 -0
  228. package/dist-server/server/modules/user/index.js.map +1 -0
  229. package/dist-server/server/modules/user/tests/user.service.test.js +53 -0
  230. package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -0
  231. package/dist-server/server/modules/user/user.module.js +47 -0
  232. package/dist-server/server/modules/user/user.module.js.map +1 -0
  233. package/dist-server/server/modules/user/user.routes.js +44 -0
  234. package/dist-server/server/modules/user/user.routes.js.map +1 -0
  235. package/dist-server/server/modules/user/user.service.js +59 -0
  236. package/dist-server/server/modules/user/user.service.js.map +1 -0
  237. package/dist-server/server/modules/voice/index.js +3 -0
  238. package/dist-server/server/modules/voice/index.js.map +1 -0
  239. package/dist-server/server/modules/voice/tests/voice.service.test.js +86 -0
  240. package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -0
  241. package/dist-server/server/modules/voice/voice.module.js +44 -0
  242. package/dist-server/server/modules/voice/voice.module.js.map +1 -0
  243. package/dist-server/server/modules/voice/voice.routes.js +87 -0
  244. package/dist-server/server/modules/voice/voice.routes.js.map +1 -0
  245. package/dist-server/server/modules/voice/voice.service.js +148 -0
  246. package/dist-server/server/modules/voice/voice.service.js.map +1 -0
  247. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +2 -2
  248. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +40 -29
  249. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
  250. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +76 -8
  251. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
  252. package/dist-server/server/modules/websocket/services/websocket-server.service.js +51 -20
  253. package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -1
  254. package/dist-server/server/modules/websocket/tests/{chat-image-filter.test.js → chat-attachment-filter.test.js} +10 -3
  255. package/dist-server/server/modules/websocket/tests/chat-attachment-filter.test.js.map +1 -0
  256. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +97 -0
  257. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -0
  258. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js +61 -0
  259. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js.map +1 -0
  260. package/dist-server/server/modules/worktrees/index.js +3 -0
  261. package/dist-server/server/modules/worktrees/index.js.map +1 -0
  262. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js +37 -0
  263. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js.map +1 -0
  264. package/dist-server/server/modules/worktrees/services/worktree-create.service.js +67 -0
  265. package/dist-server/server/modules/worktrees/services/worktree-create.service.js.map +1 -0
  266. package/dist-server/server/modules/worktrees/services/worktree-git.service.js +172 -0
  267. package/dist-server/server/modules/worktrees/services/worktree-git.service.js.map +1 -0
  268. package/dist-server/server/modules/worktrees/services/worktree-list.service.js +91 -0
  269. package/dist-server/server/modules/worktrees/services/worktree-list.service.js.map +1 -0
  270. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js +118 -0
  271. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js.map +1 -0
  272. package/dist-server/server/modules/worktrees/services/worktree-open.service.js +58 -0
  273. package/dist-server/server/modules/worktrees/services/worktree-open.service.js.map +1 -0
  274. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +65 -0
  275. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js.map +1 -0
  276. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js +58 -0
  277. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js.map +1 -0
  278. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js +85 -0
  279. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js.map +1 -0
  280. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js +58 -0
  281. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js.map +1 -0
  282. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js +34 -0
  283. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js.map +1 -0
  284. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js +137 -0
  285. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js.map +1 -0
  286. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js +99 -0
  287. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js.map +1 -0
  288. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js +157 -0
  289. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js.map +1 -0
  290. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js +167 -0
  291. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js.map +1 -0
  292. package/dist-server/server/modules/worktrees/worktrees.module.js +97 -0
  293. package/dist-server/server/modules/worktrees/worktrees.module.js.map +1 -0
  294. package/dist-server/server/modules/worktrees/worktrees.routes.js +84 -0
  295. package/dist-server/server/modules/worktrees/worktrees.routes.js.map +1 -0
  296. package/dist-server/server/shared/image-attachments.js +90 -17
  297. package/dist-server/server/shared/image-attachments.js.map +1 -1
  298. package/dist-server/server/shared/tests/image-attachments.test.js +43 -1
  299. package/dist-server/server/shared/tests/image-attachments.test.js.map +1 -1
  300. package/dist-server/server/shared/utils.js +66 -142
  301. package/dist-server/server/shared/utils.js.map +1 -1
  302. package/package.json +8 -4
  303. package/server/index.ts +401 -0
  304. package/server/{load-env.js → load-env.ts} +18 -5
  305. package/server/modules/agent/agent.module.ts +51 -0
  306. package/server/modules/agent/agent.routes.ts +1287 -0
  307. package/server/modules/agent/index.ts +2 -0
  308. package/server/modules/agent/tests/agent.routes.test.ts +205 -0
  309. package/server/modules/assets/assets.routes.ts +63 -16
  310. package/server/modules/assets/index.ts +2 -2
  311. package/server/modules/assets/services/image-assets.service.ts +46 -1
  312. package/server/modules/assets/tests/image-assets.service.test.ts +28 -0
  313. package/server/{middleware/auth.js → modules/auth/auth.middleware.ts} +38 -7
  314. package/server/modules/auth/auth.module.ts +38 -0
  315. package/server/modules/auth/auth.routes.ts +57 -0
  316. package/server/modules/auth/auth.service.ts +155 -0
  317. package/server/modules/auth/index.ts +9 -0
  318. package/server/modules/auth/tests/auth.service.test.ts +95 -0
  319. package/server/{browser-use-mcp.ts → modules/browser-use/browser-use-mcp.ts} +3 -1
  320. package/server/modules/browser-use/browser-use.service.ts +3 -4
  321. package/server/modules/browser-use/index.ts +8 -0
  322. package/server/modules/cli/cli.module.ts +96 -0
  323. package/server/modules/cli/cli.service.ts +281 -0
  324. package/server/modules/cli/cli.ts +13 -0
  325. package/server/modules/cli/index.ts +2 -0
  326. package/server/modules/cli/sandbox.service.ts +413 -0
  327. package/server/modules/cli/tests/cli.service.test.ts +91 -0
  328. package/server/modules/cli/tests/sandbox.service.test.ts +61 -0
  329. package/server/modules/commands/commands.module.ts +22 -0
  330. package/server/{routes/commands.js → modules/commands/commands.routes.ts} +44 -36
  331. package/server/modules/commands/index.ts +2 -0
  332. package/server/modules/commands/tests/commands.test.ts +119 -0
  333. package/server/modules/database/index.ts +1 -0
  334. package/server/modules/database/migrations.ts +15 -0
  335. package/server/modules/database/repositories/sessions.db.ts +19 -1
  336. package/server/modules/database/schema.ts +4 -0
  337. package/server/modules/file-tree/file-tree.module.ts +112 -0
  338. package/server/modules/file-tree/file-tree.routes.ts +258 -0
  339. package/server/modules/file-tree/file-tree.service.ts +616 -0
  340. package/server/modules/file-tree/index.ts +2 -0
  341. package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -0
  342. package/server/modules/file-tree/tests/file-tree.service.test.ts +220 -0
  343. package/server/modules/git/git-parsing.service.ts +66 -0
  344. package/server/modules/git/git.module.ts +22 -0
  345. package/server/{routes/git.js → modules/git/git.routes.ts} +91 -132
  346. package/server/modules/git/index.ts +2 -0
  347. package/server/modules/git/tests/git-init.routes.test.ts +52 -0
  348. package/server/{routes/git.test.js → modules/git/tests/git.test.ts} +3 -3
  349. package/server/modules/notifications/index.ts +9 -0
  350. package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -0
  351. package/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.ts} +3 -1
  352. package/server/modules/plugins/index.ts +9 -0
  353. package/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.ts} +3 -1
  354. package/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.ts} +1 -0
  355. package/server/modules/plugins/plugins.module.ts +33 -0
  356. package/server/modules/plugins/plugins.routes.ts +66 -0
  357. package/server/modules/plugins/plugins.service.ts +147 -0
  358. package/server/modules/plugins/tests/plugins.service.test.ts +32 -0
  359. package/server/modules/projects/index.ts +5 -0
  360. package/server/modules/providers/README.md +41 -9
  361. package/server/modules/providers/index.ts +4 -0
  362. package/server/modules/providers/list/claude/claude-auth.provider.ts +8 -0
  363. package/server/modules/providers/list/claude/claude-models.provider.ts +1 -12
  364. package/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +66 -44
  365. package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +6 -4
  366. package/server/modules/providers/list/claude/claude-sessions.provider.ts +27 -4
  367. package/server/modules/providers/list/claude/claude.provider.ts +3 -0
  368. package/server/modules/providers/list/codex/codex-models.provider.ts +0 -9
  369. package/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +54 -36
  370. package/server/modules/providers/list/codex/codex-sessions.provider.ts +331 -7
  371. package/server/modules/providers/list/codex/codex-skills.provider.ts +5 -0
  372. package/server/modules/providers/list/codex/codex.provider.ts +3 -0
  373. package/server/modules/providers/list/cursor/cursor-models.provider.ts +0 -9
  374. package/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +58 -27
  375. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +26 -15
  376. package/server/modules/providers/list/cursor/cursor.provider.ts +3 -0
  377. package/server/modules/providers/list/opencode/opencode-models.provider.ts +7 -10
  378. package/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +56 -28
  379. package/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +41 -3
  380. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +13 -5
  381. package/server/modules/providers/list/opencode/opencode.provider.ts +3 -0
  382. package/server/modules/providers/provider.routes.ts +47 -10
  383. package/server/modules/providers/services/provider-capabilities.service.ts +7 -1
  384. package/server/modules/providers/services/provider-models.service.ts +131 -23
  385. package/server/modules/providers/services/provider-runtime.service.ts +109 -0
  386. package/server/modules/providers/services/provider-token-usage.service.ts +357 -0
  387. package/server/modules/providers/services/sessions-watcher.service.ts +2 -0
  388. package/server/modules/providers/services/sessions.service.ts +79 -0
  389. package/server/modules/providers/shared/base/abstract.provider.ts +4 -3
  390. package/server/modules/providers/tests/claude-auth.test.ts +150 -0
  391. package/server/modules/providers/tests/claude-sessions.test.ts +61 -0
  392. package/server/modules/providers/tests/codex-sessions.test.ts +40 -0
  393. package/server/modules/providers/tests/{provider-image-history.test.ts → provider-attachment-history.test.ts} +68 -1
  394. package/server/modules/providers/tests/provider-models.service.test.ts +450 -349
  395. package/server/modules/providers/tests/provider-runtime.service.test.ts +142 -0
  396. package/server/modules/providers/tests/provider-token-usage.service.test.ts +185 -0
  397. package/server/modules/providers/tests/sessions-details.test.ts +73 -0
  398. package/server/modules/providers/tests/skills.test.ts +9 -2
  399. package/server/modules/settings/index.ts +2 -0
  400. package/server/modules/settings/settings.module.ts +50 -0
  401. package/server/modules/settings/settings.routes.ts +51 -0
  402. package/server/modules/settings/settings.service.ts +186 -0
  403. package/server/modules/settings/tests/settings.service.test.ts +54 -0
  404. package/server/modules/system/index.ts +2 -0
  405. package/server/modules/system/system.module.ts +62 -0
  406. package/server/modules/system/system.routes.ts +21 -0
  407. package/server/modules/system/system.service.ts +76 -0
  408. package/server/modules/system/tests/system.service.test.ts +118 -0
  409. package/server/modules/taskmaster/index.ts +2 -0
  410. package/server/modules/taskmaster/taskmaster.module.ts +24 -0
  411. package/server/modules/taskmaster/taskmaster.routes.ts +1482 -0
  412. package/server/modules/taskmaster/taskmaster.service.ts +132 -0
  413. package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -0
  414. package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -0
  415. package/server/modules/user/index.ts +2 -0
  416. package/server/modules/user/tests/user.service.test.ts +61 -0
  417. package/server/modules/user/user.module.ts +58 -0
  418. package/server/modules/user/user.routes.ts +50 -0
  419. package/server/modules/user/user.service.ts +85 -0
  420. package/server/modules/voice/index.ts +2 -0
  421. package/server/modules/voice/tests/voice.service.test.ts +98 -0
  422. package/server/modules/voice/voice.module.ts +47 -0
  423. package/server/modules/voice/voice.routes.ts +113 -0
  424. package/server/modules/voice/voice.service.ts +192 -0
  425. package/server/modules/websocket/README.md +7 -7
  426. package/server/modules/websocket/services/chat-session-writer.service.ts +2 -2
  427. package/server/modules/websocket/services/chat-websocket.service.ts +73 -61
  428. package/server/modules/websocket/services/shell-websocket.service.ts +88 -12
  429. package/server/modules/websocket/services/websocket-server.service.ts +63 -19
  430. package/server/modules/websocket/tests/{chat-image-filter.test.ts → chat-attachment-filter.test.ts} +17 -2
  431. package/server/modules/websocket/tests/shell-websocket.service.test.ts +119 -0
  432. package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -0
  433. package/server/modules/worktrees/index.ts +2 -0
  434. package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -0
  435. package/server/modules/worktrees/services/worktree-create.service.ts +104 -0
  436. package/server/modules/worktrees/services/worktree-git.service.ts +207 -0
  437. package/server/modules/worktrees/services/worktree-list.service.ts +143 -0
  438. package/server/modules/worktrees/services/worktree-merge.service.ts +157 -0
  439. package/server/modules/worktrees/services/worktree-open.service.ts +85 -0
  440. package/server/modules/worktrees/services/worktree-remove.service.ts +88 -0
  441. package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -0
  442. package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -0
  443. package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -0
  444. package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -0
  445. package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -0
  446. package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -0
  447. package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -0
  448. package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -0
  449. package/server/modules/worktrees/worktrees.module.ts +113 -0
  450. package/server/modules/worktrees/worktrees.routes.ts +116 -0
  451. package/server/shared/image-attachments.ts +112 -18
  452. package/server/shared/interfaces.ts +29 -19
  453. package/server/shared/tests/image-attachments.test.ts +55 -0
  454. package/server/shared/types.ts +658 -21
  455. package/server/shared/utils.ts +77 -212
  456. package/dist/assets/index-DLmhQ15L.css +0 -32
  457. package/dist-server/server/browser-use-mcp.js.map +0 -1
  458. package/dist-server/server/claude-sdk.js.map +0 -1
  459. package/dist-server/server/cli.js +0 -647
  460. package/dist-server/server/cli.js.map +0 -1
  461. package/dist-server/server/cursor-cli.js.map +0 -1
  462. package/dist-server/server/middleware/auth.js.map +0 -1
  463. package/dist-server/server/modules/providers/tests/provider-image-history.test.js.map +0 -1
  464. package/dist-server/server/modules/websocket/tests/chat-image-filter.test.js.map +0 -1
  465. package/dist-server/server/openai-codex.js.map +0 -1
  466. package/dist-server/server/opencode-cli.js.map +0 -1
  467. package/dist-server/server/opencode-cli.test.js.map +0 -1
  468. package/dist-server/server/routes/agent.js +0 -1155
  469. package/dist-server/server/routes/agent.js.map +0 -1
  470. package/dist-server/server/routes/auth.js +0 -119
  471. package/dist-server/server/routes/auth.js.map +0 -1
  472. package/dist-server/server/routes/commands.js +0 -492
  473. package/dist-server/server/routes/commands.js.map +0 -1
  474. package/dist-server/server/routes/cursor.js +0 -49
  475. package/dist-server/server/routes/cursor.js.map +0 -1
  476. package/dist-server/server/routes/git.js +0 -1389
  477. package/dist-server/server/routes/git.js.map +0 -1
  478. package/dist-server/server/routes/git.test.js.map +0 -1
  479. package/dist-server/server/routes/mcp-utils.js +0 -29
  480. package/dist-server/server/routes/mcp-utils.js.map +0 -1
  481. package/dist-server/server/routes/plugins.js +0 -266
  482. package/dist-server/server/routes/plugins.js.map +0 -1
  483. package/dist-server/server/routes/settings.js +0 -249
  484. package/dist-server/server/routes/settings.js.map +0 -1
  485. package/dist-server/server/routes/taskmaster.js +0 -1362
  486. package/dist-server/server/routes/taskmaster.js.map +0 -1
  487. package/dist-server/server/routes/tests/commands.test.js +0 -76
  488. package/dist-server/server/routes/tests/commands.test.js.map +0 -1
  489. package/dist-server/server/routes/user.js +0 -116
  490. package/dist-server/server/routes/user.js.map +0 -1
  491. package/dist-server/server/services/notification-orchestrator.js +0 -2
  492. package/dist-server/server/services/notification-orchestrator.js.map +0 -1
  493. package/dist-server/server/services/tests/notification-orchestrator.test.js +0 -64
  494. package/dist-server/server/services/tests/notification-orchestrator.test.js.map +0 -1
  495. package/dist-server/server/services/vapid-keys.js.map +0 -1
  496. package/dist-server/server/utils/colors.js +0 -20
  497. package/dist-server/server/utils/colors.js.map +0 -1
  498. package/dist-server/server/utils/commandParser.js +0 -255
  499. package/dist-server/server/utils/commandParser.js.map +0 -1
  500. package/dist-server/server/utils/gitConfig.js +0 -37
  501. package/dist-server/server/utils/gitConfig.js.map +0 -1
  502. package/dist-server/server/utils/mcp-detector.js +0 -134
  503. package/dist-server/server/utils/mcp-detector.js.map +0 -1
  504. package/dist-server/server/utils/plugin-loader.js.map +0 -1
  505. package/dist-server/server/utils/plugin-process-manager.js.map +0 -1
  506. package/dist-server/server/utils/runtime-paths.js +0 -30
  507. package/dist-server/server/utils/runtime-paths.js.map +0 -1
  508. package/dist-server/server/utils/taskmaster-websocket.js +0 -124
  509. package/dist-server/server/utils/taskmaster-websocket.js.map +0 -1
  510. package/dist-server/server/utils/url-detection.js +0 -58
  511. package/dist-server/server/utils/url-detection.js.map +0 -1
  512. package/dist-server/server/voice-proxy.js +0 -226
  513. package/dist-server/server/voice-proxy.js.map +0 -1
  514. package/server/cli.js +0 -695
  515. package/server/index.js +0 -1651
  516. package/server/routes/agent.js +0 -1257
  517. package/server/routes/auth.js +0 -137
  518. package/server/routes/cursor.js +0 -52
  519. package/server/routes/mcp-utils.js +0 -31
  520. package/server/routes/plugins.js +0 -307
  521. package/server/routes/settings.js +0 -282
  522. package/server/routes/taskmaster.js +0 -1470
  523. package/server/routes/tests/commands.test.js +0 -82
  524. package/server/routes/user.js +0 -124
  525. package/server/services/notification-orchestrator.js +0 -7
  526. package/server/services/tests/notification-orchestrator.test.js +0 -80
  527. package/server/utils/colors.js +0 -21
  528. package/server/utils/commandParser.js +0 -305
  529. package/server/utils/gitConfig.js +0 -35
  530. package/server/utils/mcp-detector.js +0 -147
  531. package/server/utils/runtime-paths.js +0 -37
  532. package/server/utils/taskmaster-websocket.js +0 -135
  533. package/server/utils/url-detection.js +0 -71
  534. package/server/voice-proxy.js +0 -224
  535. /package/server/constants/{config.js → config.ts} +0 -0
@@ -3,11 +3,11 @@
3
3
  * =============================
4
4
  *
5
5
  * This module provides integration with the OpenAI Codex SDK for non-interactive
6
- * chat sessions. It mirrors the pattern used in claude-sdk.js for consistency.
6
+ * chat sessions. It mirrors the Claude runtime adapter for consistency.
7
7
  *
8
8
  * ## Usage
9
9
  *
10
- * - queryCodex(command, options, ws) - Execute a prompt with streaming via WebSocket
10
+ * - codexRuntime.run(command, options, writer, context) - Execute a streamed prompt
11
11
  * - abortCodexSession(sessionId) - Cancel an active session
12
12
  * - isCodexSessionActive(sessionId) - Check if a session is running
13
13
  * - getActiveCodexSessions() - List all active sessions
@@ -15,12 +15,13 @@
15
15
 
16
16
  import { Codex } from '@openai/codex-sdk';
17
17
 
18
- import { buildCodexInputItems, normalizeImageDescriptors } from './shared/image-attachments.js';
19
- import { notifyRunFailed, notifyRunStopped } from './services/notification-orchestrator.js';
20
- import { sessionsService } from './modules/providers/services/sessions.service.js';
21
- import { providerAuthService } from './modules/providers/services/provider-auth.service.js';
22
- import { providerModelsService } from './modules/providers/services/provider-models.service.js';
23
- import { createCompleteMessage, createNormalizedMessage } from './shared/utils.js';
18
+ import {
19
+ appendFilesInputTag,
20
+ buildCodexInputItems,
21
+ normalizeImageDescriptors
22
+ } from '@/shared/image-attachments.js';
23
+ import { notifyRunFailed, notifyRunStopped } from '@/modules/notifications/index.js';
24
+ import { createCompleteMessage, createNormalizedMessage } from '@/shared/utils.js';
24
25
 
25
26
  const activeCodexSessions = new Map();
26
27
 
@@ -222,7 +223,7 @@ function mapPermissionModeToCodexOptions(permissionMode) {
222
223
  * @param {object} options - Options including cwd, sessionId, model, permissionMode
223
224
  * @param {WebSocket|object} ws - WebSocket connection or response writer
224
225
  */
225
- export async function queryCodex(command, options = {}, ws) {
226
+ export async function queryCodex(command, options = {}, ws, context) {
226
227
  const {
227
228
  sessionId,
228
229
  sessionSummary,
@@ -231,18 +232,19 @@ export async function queryCodex(command, options = {}, ws) {
231
232
  model,
232
233
  effort,
233
234
  images,
235
+ files,
234
236
  permissionMode = 'default'
235
237
  } = options;
236
238
 
237
- const resolvedModel = await providerModelsService.resolveResumeModel(
238
- 'codex',
239
- sessionId,
240
- model,
241
- );
239
+ // Callers pass the stable app session id; the SDK resumes threads with the
240
+ // provider-native id recorded on the session row.
241
+ const providerSessionId = context.resolveProviderSessionId(sessionId);
242
+
243
+ const resolvedModel = await context.resolveResumeModel(sessionId, model);
242
244
 
243
245
  const workingDirectory = cwd || projectPath || process.cwd();
244
246
  const { sandboxMode, approvalPolicy } = mapPermissionModeToCodexOptions(permissionMode);
245
- const catalog = (await providerModelsService.getProviderModels('codex')).models;
247
+ const catalog = await context.getProviderModels();
246
248
  const selectedModel = catalog.OPTIONS.find((option) => option.value === resolvedModel) || null;
247
249
  const allowedEfforts = selectedModel?.effort?.values?.map((value) => value.value) || [];
248
250
  const resolvedEffort = typeof effort === 'string' && effort !== 'default' && allowedEfforts.includes(effort)
@@ -251,10 +253,15 @@ export async function queryCodex(command, options = {}, ws) {
251
253
 
252
254
  let codex;
253
255
  let thread;
254
- let capturedSessionId = sessionId;
256
+ // Provider-native thread id (starts as the resume id, or is captured from
257
+ // the stream for brand-new sessions).
258
+ let capturedSessionId = providerSessionId;
255
259
  let sessionCreatedSent = false;
256
260
  let terminalFailure = null;
257
261
  const abortController = new AbortController();
262
+ // Session-map key: the app session id when the caller supplied one, else
263
+ // the provider-native thread id once captured (legacy/direct API callers).
264
+ const sessionKey = () => sessionId || capturedSessionId || null;
258
265
 
259
266
  try {
260
267
  codex = new Codex();
@@ -268,8 +275,8 @@ export async function queryCodex(command, options = {}, ws) {
268
275
  modelReasoningEffort: resolvedEffort,
269
276
  };
270
277
 
271
- if (sessionId) {
272
- thread = codex.resumeThread(sessionId, threadOptions);
278
+ if (providerSessionId) {
279
+ thread = codex.resumeThread(providerSessionId, threadOptions);
273
280
  } else {
274
281
  thread = codex.startThread(threadOptions);
275
282
  }
@@ -287,15 +294,16 @@ export async function queryCodex(command, options = {}, ws) {
287
294
  });
288
295
  };
289
296
 
290
- if (capturedSessionId) {
291
- registerSession(capturedSessionId);
297
+ if (sessionKey()) {
298
+ registerSession(sessionKey());
292
299
  }
293
300
 
294
301
  // Execute with streaming. Turns with image attachments send structured
295
302
  // input items so Codex reads the images from their local asset paths.
303
+ const promptWithFiles = appendFilesInputTag(command, files);
296
304
  const turnInput = normalizeImageDescriptors(images).length > 0
297
- ? buildCodexInputItems(command, images, workingDirectory)
298
- : command;
305
+ ? buildCodexInputItems(promptWithFiles, images, workingDirectory)
306
+ : promptWithFiles;
299
307
  const streamedTurn = await thread.runStreamed(turnInput, {
300
308
  signal: abortController.signal
301
309
  });
@@ -306,13 +314,13 @@ export async function queryCodex(command, options = {}, ws) {
306
314
  const discoveredSessionId = event.thread_id || event.id || null;
307
315
  if (discoveredSessionId && !capturedSessionId) {
308
316
  capturedSessionId = discoveredSessionId;
309
- registerSession(capturedSessionId);
317
+ registerSession(sessionKey());
310
318
 
311
319
  if (ws.setSessionId && typeof ws.setSessionId === 'function') {
312
320
  ws.setSessionId(capturedSessionId);
313
321
  }
314
322
 
315
- if (!sessionId && !sessionCreatedSent) {
323
+ if (!providerSessionId && !sessionCreatedSent) {
316
324
  sessionCreatedSent = true;
317
325
  sendMessage(ws, createNormalizedMessage({ kind: 'session_created', newSessionId: capturedSessionId, sessionId: capturedSessionId, provider: 'codex' }));
318
326
  }
@@ -323,8 +331,8 @@ export async function queryCodex(command, options = {}, ws) {
323
331
  if (abortController.signal.aborted) {
324
332
  break;
325
333
  }
326
- if (capturedSessionId) {
327
- const session = activeCodexSessions.get(capturedSessionId);
334
+ if (sessionKey()) {
335
+ const session = activeCodexSessions.get(sessionKey());
328
336
  if (session?.status === 'aborted') {
329
337
  break;
330
338
  }
@@ -337,17 +345,18 @@ export async function queryCodex(command, options = {}, ws) {
337
345
  const transformed = transformCodexEvent(event);
338
346
 
339
347
  // Normalize the transformed event into NormalizedMessage(s) via adapter
340
- const normalizedMsgs = sessionsService.normalizeMessage('codex', transformed, capturedSessionId || sessionId || null);
348
+ const normalizedMsgs = context.normalizeMessage(transformed, capturedSessionId || sessionId || null);
341
349
  for (const msg of normalizedMsgs) {
342
350
  sendMessage(ws, msg);
343
351
  }
344
352
 
345
353
  if (event.type === 'turn.failed' && !terminalFailure) {
346
354
  terminalFailure = event.error || new Error('Turn failed');
355
+ // Notifications are app-facing, so they carry the app session id.
347
356
  notifyRunFailed({
348
357
  userId: ws?.userId || null,
349
358
  provider: 'codex',
350
- sessionId: capturedSessionId || sessionId || null,
359
+ sessionId: sessionId || capturedSessionId || null,
351
360
  sessionName: sessionSummary,
352
361
  error: terminalFailure
353
362
  });
@@ -364,7 +373,7 @@ export async function queryCodex(command, options = {}, ws) {
364
373
 
365
374
  // Send the terminal completion event — skipped for aborted runs, whose
366
375
  // terminal `complete` (aborted: true) was already sent by abort-session.
367
- const runSession = capturedSessionId ? activeCodexSessions.get(capturedSessionId) : null;
376
+ const runSession = sessionKey() ? activeCodexSessions.get(sessionKey()) : null;
368
377
  const runAborted = runSession?.status === 'aborted' || abortController.signal.aborted;
369
378
  if (!runAborted) {
370
379
  sendMessage(ws, createCompleteMessage({
@@ -377,7 +386,7 @@ export async function queryCodex(command, options = {}, ws) {
377
386
  notifyRunStopped({
378
387
  userId: ws?.userId || null,
379
388
  provider: 'codex',
380
- sessionId: capturedSessionId || sessionId || null,
389
+ sessionId: sessionId || capturedSessionId || null,
381
390
  sessionName: sessionSummary,
382
391
  stopReason: 'completed'
383
392
  });
@@ -385,7 +394,7 @@ export async function queryCodex(command, options = {}, ws) {
385
394
  }
386
395
 
387
396
  } catch (error) {
388
- const session = capturedSessionId ? activeCodexSessions.get(capturedSessionId) : null;
397
+ const session = sessionKey() ? activeCodexSessions.get(sessionKey()) : null;
389
398
  const wasAborted =
390
399
  session?.status === 'aborted' ||
391
400
  error?.name === 'AbortError' ||
@@ -395,7 +404,7 @@ export async function queryCodex(command, options = {}, ws) {
395
404
  console.error('[Codex] Error:', error);
396
405
 
397
406
  // Check if Codex SDK is available for a clearer error message
398
- const installed = await providerAuthService.isProviderInstalled('codex');
407
+ const installed = await context.isProviderInstalled();
399
408
  const errorContent = !installed
400
409
  ? 'Codex CLI is not configured. Please set up authentication first.'
401
410
  : error.message;
@@ -410,7 +419,7 @@ export async function queryCodex(command, options = {}, ws) {
410
419
  notifyRunFailed({
411
420
  userId: ws?.userId || null,
412
421
  provider: 'codex',
413
- sessionId: capturedSessionId || sessionId || null,
422
+ sessionId: sessionId || capturedSessionId || null,
414
423
  sessionName: sessionSummary,
415
424
  error
416
425
  });
@@ -419,8 +428,8 @@ export async function queryCodex(command, options = {}, ws) {
419
428
 
420
429
  } finally {
421
430
  // Update session status
422
- if (capturedSessionId) {
423
- const session = activeCodexSessions.get(capturedSessionId);
431
+ if (sessionKey()) {
432
+ const session = activeCodexSessions.get(sessionKey());
424
433
  if (session) {
425
434
  session.status = session.status === 'aborted' ? 'aborted' : 'completed';
426
435
  }
@@ -480,6 +489,11 @@ export function getActiveCodexSessions() {
480
489
  return sessions;
481
490
  }
482
491
 
492
+ export const codexRuntime = {
493
+ run: queryCodex,
494
+ abort: abortCodexSession,
495
+ };
496
+
483
497
  /**
484
498
  * Helper to send message via WebSocket or writer
485
499
  * @param {WebSocket|object} ws - WebSocket or response writer
@@ -500,7 +514,7 @@ function sendMessage(ws, data) {
500
514
  }
501
515
 
502
516
  // Clean up old completed sessions periodically
503
- setInterval(() => {
517
+ const completedSessionCleanupTimer = setInterval(() => {
504
518
  const now = Date.now();
505
519
  const maxAge = 30 * 60 * 1000; // 30 minutes
506
520
 
@@ -513,3 +527,7 @@ setInterval(() => {
513
527
  }
514
528
  }
515
529
  }, 5 * 60 * 1000); // Every 5 minutes
530
+
531
+ // Runtime cleanup should not keep focused tests or one-off scripts alive after
532
+ // their provider work has completed.
533
+ completedSessionCleanupTimer.unref?.();
@@ -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'),