@cloudcli-ai/cloudcli 1.29.5 → 1.31.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 (354) hide show
  1. package/README.de.md +1 -1
  2. package/README.ja.md +1 -1
  3. package/README.ko.md +1 -1
  4. package/README.md +1 -1
  5. package/README.ru.md +1 -1
  6. package/README.tr.md +252 -0
  7. package/README.zh-CN.md +1 -1
  8. package/dist/assets/index-DF8TTVHl.css +32 -0
  9. package/dist/assets/index-DbZAcc9z.js +1262 -0
  10. package/dist/index.html +2 -2
  11. package/dist-server/server/claude-sdk.js +13 -8
  12. package/dist-server/server/claude-sdk.js.map +1 -1
  13. package/dist-server/server/cursor-cli.js +7 -7
  14. package/dist-server/server/cursor-cli.js.map +1 -1
  15. package/dist-server/server/gemini-cli.js +5 -5
  16. package/dist-server/server/gemini-cli.js.map +1 -1
  17. package/dist-server/server/gemini-response-handler.js +2 -2
  18. package/dist-server/server/gemini-response-handler.js.map +1 -1
  19. package/dist-server/server/index.js +139 -977
  20. package/dist-server/server/index.js.map +1 -1
  21. package/dist-server/server/middleware/auth.js +1 -1
  22. package/dist-server/server/middleware/auth.js.map +1 -1
  23. package/dist-server/server/modules/database/connection.js +125 -0
  24. package/dist-server/server/modules/database/connection.js.map +1 -0
  25. package/dist-server/server/modules/database/index.js +13 -0
  26. package/dist-server/server/modules/database/index.js.map +1 -0
  27. package/dist-server/server/modules/database/init-db.js +18 -0
  28. package/dist-server/server/modules/database/init-db.js.map +1 -0
  29. package/dist-server/server/modules/database/migrations.js +370 -0
  30. package/dist-server/server/modules/database/migrations.js.map +1 -0
  31. package/dist-server/server/modules/database/repositories/api-keys.js +72 -0
  32. package/dist-server/server/modules/database/repositories/api-keys.js.map +1 -0
  33. package/dist-server/server/modules/database/repositories/app-config.js +47 -0
  34. package/dist-server/server/modules/database/repositories/app-config.js.map +1 -0
  35. package/dist-server/server/modules/database/repositories/credentials.js +68 -0
  36. package/dist-server/server/modules/database/repositories/credentials.js.map +1 -0
  37. package/dist-server/server/modules/database/repositories/github-tokens.js +54 -0
  38. package/dist-server/server/modules/database/repositories/github-tokens.js.map +1 -0
  39. package/dist-server/server/modules/database/repositories/notification-preferences.js +72 -0
  40. package/dist-server/server/modules/database/repositories/notification-preferences.js.map +1 -0
  41. package/dist-server/server/modules/database/repositories/projects.db.integration.test.js +64 -0
  42. package/dist-server/server/modules/database/repositories/projects.db.integration.test.js.map +1 -0
  43. package/dist-server/server/modules/database/repositories/projects.db.js +160 -0
  44. package/dist-server/server/modules/database/repositories/projects.db.js.map +1 -0
  45. package/dist-server/server/modules/database/repositories/push-subscriptions.js +49 -0
  46. package/dist-server/server/modules/database/repositories/push-subscriptions.js.map +1 -0
  47. package/dist-server/server/modules/database/repositories/scan-state.db.js +31 -0
  48. package/dist-server/server/modules/database/repositories/scan-state.db.js.map +1 -0
  49. package/dist-server/server/modules/database/repositories/sessions.db.js +109 -0
  50. package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -0
  51. package/dist-server/server/modules/database/repositories/users.js +88 -0
  52. package/dist-server/server/modules/database/repositories/users.js.map +1 -0
  53. package/dist-server/server/modules/database/repositories/vapid-keys.js +38 -0
  54. package/dist-server/server/modules/database/repositories/vapid-keys.js.map +1 -0
  55. package/dist-server/server/modules/database/schema.js +143 -0
  56. package/dist-server/server/modules/database/schema.js.map +1 -0
  57. package/dist-server/server/modules/projects/index.js +4 -0
  58. package/dist-server/server/modules/projects/index.js.map +1 -0
  59. package/dist-server/server/modules/projects/projects.routes.js +188 -0
  60. package/dist-server/server/modules/projects/projects.routes.js.map +1 -0
  61. package/dist-server/server/modules/projects/services/project-clone.service.js +219 -0
  62. package/dist-server/server/modules/projects/services/project-clone.service.js.map +1 -0
  63. package/dist-server/server/modules/projects/services/project-delete.service.js +65 -0
  64. package/dist-server/server/modules/projects/services/project-delete.service.js.map +1 -0
  65. package/dist-server/server/modules/projects/services/project-management.service.js +93 -0
  66. package/dist-server/server/modules/projects/services/project-management.service.js.map +1 -0
  67. package/dist-server/server/modules/projects/services/project-star.service.js +60 -0
  68. package/dist-server/server/modules/projects/services/project-star.service.js.map +1 -0
  69. package/dist-server/server/modules/projects/services/projects-has-taskmaster.service.js +167 -0
  70. package/dist-server/server/modules/projects/services/projects-has-taskmaster.service.js.map +1 -0
  71. package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js +169 -0
  72. package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js.map +1 -0
  73. package/dist-server/server/modules/projects/tests/project-clone.service.test.js +126 -0
  74. package/dist-server/server/modules/projects/tests/project-clone.service.test.js.map +1 -0
  75. package/dist-server/server/modules/projects/tests/project-management.service.test.js +85 -0
  76. package/dist-server/server/modules/projects/tests/project-management.service.test.js.map +1 -0
  77. package/dist-server/server/modules/projects/tests/project-star.service.test.js +95 -0
  78. package/dist-server/server/modules/projects/tests/project-star.service.test.js.map +1 -0
  79. package/dist-server/server/modules/projects/tests/projects-has-taskmaster.service.test.js +87 -0
  80. package/dist-server/server/modules/projects/tests/projects-has-taskmaster.service.test.js.map +1 -0
  81. package/dist-server/server/modules/providers/index.js +4 -0
  82. package/dist-server/server/modules/providers/index.js.map +1 -0
  83. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +103 -0
  84. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -0
  85. package/dist-server/server/modules/providers/list/claude/claude-mcp.provider.js +103 -0
  86. package/dist-server/server/modules/providers/list/claude/claude-mcp.provider.js.map +1 -0
  87. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +63 -0
  88. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -0
  89. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +403 -0
  90. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -0
  91. package/dist-server/server/modules/providers/list/claude/claude.provider.js +15 -0
  92. package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -0
  93. package/dist-server/server/modules/providers/list/codex/codex-auth.provider.js +84 -0
  94. package/dist-server/server/modules/providers/list/codex/codex-auth.provider.js.map +1 -0
  95. package/dist-server/server/modules/providers/list/codex/codex-mcp.provider.js +107 -0
  96. package/dist-server/server/modules/providers/list/codex/codex-mcp.provider.js.map +1 -0
  97. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js +71 -0
  98. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -0
  99. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +494 -0
  100. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -0
  101. package/dist-server/server/modules/providers/list/codex/codex.provider.js +15 -0
  102. package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -0
  103. package/dist-server/server/modules/providers/list/cursor/cursor-auth.provider.js +118 -0
  104. package/dist-server/server/modules/providers/list/cursor/cursor-auth.provider.js.map +1 -0
  105. package/dist-server/server/modules/providers/list/cursor/cursor-mcp.provider.js +80 -0
  106. package/dist-server/server/modules/providers/list/cursor/cursor-mcp.provider.js.map +1 -0
  107. package/dist-server/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.js +127 -0
  108. package/dist-server/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.js.map +1 -0
  109. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +369 -0
  110. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -0
  111. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +15 -0
  112. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -0
  113. package/dist-server/server/modules/providers/list/gemini/gemini-auth.provider.js +131 -0
  114. package/dist-server/server/modules/providers/list/gemini/gemini-auth.provider.js.map +1 -0
  115. package/dist-server/server/modules/providers/list/gemini/gemini-mcp.provider.js +82 -0
  116. package/dist-server/server/modules/providers/list/gemini/gemini-mcp.provider.js.map +1 -0
  117. package/dist-server/server/modules/providers/list/gemini/gemini-session-synchronizer.provider.js +296 -0
  118. package/dist-server/server/modules/providers/list/gemini/gemini-session-synchronizer.provider.js.map +1 -0
  119. package/dist-server/server/modules/providers/list/gemini/gemini-sessions.provider.js +474 -0
  120. package/dist-server/server/modules/providers/list/gemini/gemini-sessions.provider.js.map +1 -0
  121. package/dist-server/server/modules/providers/list/gemini/gemini.provider.js +15 -0
  122. package/dist-server/server/modules/providers/list/gemini/gemini.provider.js.map +1 -0
  123. package/dist-server/server/modules/providers/provider.registry.js +31 -0
  124. package/dist-server/server/modules/providers/provider.registry.js.map +1 -0
  125. package/dist-server/server/modules/providers/provider.routes.js +331 -0
  126. package/dist-server/server/modules/providers/provider.routes.js.map +1 -0
  127. package/dist-server/server/modules/providers/services/mcp.service.js +69 -0
  128. package/dist-server/server/modules/providers/services/mcp.service.js.map +1 -0
  129. package/dist-server/server/modules/providers/services/provider-auth.service.js +25 -0
  130. package/dist-server/server/modules/providers/services/provider-auth.service.js.map +1 -0
  131. package/dist-server/server/modules/providers/services/session-conversations-search.service.js +868 -0
  132. package/dist-server/server/modules/providers/services/session-conversations-search.service.js.map +1 -0
  133. package/dist-server/server/modules/providers/services/session-synchronizer.service.js +56 -0
  134. package/dist-server/server/modules/providers/services/session-synchronizer.service.js.map +1 -0
  135. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +234 -0
  136. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -0
  137. package/dist-server/server/modules/providers/services/sessions.service.js +104 -0
  138. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -0
  139. package/dist-server/server/modules/providers/shared/base/abstract.provider.js +14 -0
  140. package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -0
  141. package/dist-server/server/modules/providers/shared/mcp/mcp.provider.js +102 -0
  142. package/dist-server/server/modules/providers/shared/mcp/mcp.provider.js.map +1 -0
  143. package/dist-server/server/modules/providers/tests/mcp.test.js +250 -0
  144. package/dist-server/server/modules/providers/tests/mcp.test.js.map +1 -0
  145. package/dist-server/server/modules/websocket/index.js +3 -0
  146. package/dist-server/server/modules/websocket/index.js.map +1 -0
  147. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +188 -0
  148. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -0
  149. package/dist-server/server/modules/websocket/services/plugin-websocket-proxy.service.js +52 -0
  150. package/dist-server/server/modules/websocket/services/plugin-websocket-proxy.service.js.map +1 -0
  151. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +334 -0
  152. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -0
  153. package/dist-server/server/modules/websocket/services/websocket-auth.service.js +32 -0
  154. package/dist-server/server/modules/websocket/services/websocket-auth.service.js.map +1 -0
  155. package/dist-server/server/modules/websocket/services/websocket-server.service.js +36 -0
  156. package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -0
  157. package/dist-server/server/modules/websocket/services/websocket-state.service.js +14 -0
  158. package/dist-server/server/modules/websocket/services/websocket-state.service.js.map +1 -0
  159. package/dist-server/server/modules/websocket/services/websocket-writer.service.js +32 -0
  160. package/dist-server/server/modules/websocket/services/websocket-writer.service.js.map +1 -0
  161. package/dist-server/server/openai-codex.js +5 -5
  162. package/dist-server/server/openai-codex.js.map +1 -1
  163. package/dist-server/server/routes/agent.js +10 -17
  164. package/dist-server/server/routes/agent.js.map +1 -1
  165. package/dist-server/server/routes/auth.js +3 -1
  166. package/dist-server/server/routes/auth.js.map +1 -1
  167. package/dist-server/server/routes/commands.js +1 -45
  168. package/dist-server/server/routes/commands.js.map +1 -1
  169. package/dist-server/server/routes/cursor.js +9 -489
  170. package/dist-server/server/routes/cursor.js.map +1 -1
  171. package/dist-server/server/routes/gemini.js +2 -2
  172. package/dist-server/server/routes/gemini.js.map +1 -1
  173. package/dist-server/server/routes/git.js +33 -29
  174. package/dist-server/server/routes/git.js.map +1 -1
  175. package/dist-server/server/routes/mcp-utils.js +1 -18
  176. package/dist-server/server/routes/mcp-utils.js.map +1 -1
  177. package/dist-server/server/routes/settings.js +11 -1
  178. package/dist-server/server/routes/settings.js.map +1 -1
  179. package/dist-server/server/routes/taskmaster.js +97 -569
  180. package/dist-server/server/routes/taskmaster.js.map +1 -1
  181. package/dist-server/server/routes/user.js +1 -1
  182. package/dist-server/server/routes/user.js.map +1 -1
  183. package/dist-server/server/services/notification-orchestrator.js +2 -2
  184. package/dist-server/server/services/notification-orchestrator.js.map +1 -1
  185. package/dist-server/server/services/vapid-keys.js +2 -1
  186. package/dist-server/server/services/vapid-keys.js.map +1 -1
  187. package/dist-server/server/shared/interfaces.js +2 -0
  188. package/dist-server/server/shared/interfaces.js.map +1 -0
  189. package/dist-server/server/shared/types.js +2 -0
  190. package/dist-server/server/shared/types.js.map +1 -0
  191. package/dist-server/server/shared/utils.js +551 -0
  192. package/dist-server/server/shared/utils.js.map +1 -0
  193. package/dist-server/server/utils/mcp-detector.js +0 -49
  194. package/dist-server/server/utils/mcp-detector.js.map +1 -1
  195. package/dist-server/server/utils/taskmaster-websocket.js +18 -12
  196. package/dist-server/server/utils/taskmaster-websocket.js.map +1 -1
  197. package/dist-server/shared/modelConstants.js +3 -1
  198. package/dist-server/shared/modelConstants.js.map +1 -1
  199. package/package.json +7 -2
  200. package/server/claude-sdk.js +14 -8
  201. package/server/cursor-cli.js +7 -7
  202. package/server/gemini-cli.js +5 -5
  203. package/server/gemini-response-handler.js +2 -2
  204. package/server/index.js +173 -1035
  205. package/server/middleware/auth.js +1 -1
  206. package/server/modules/database/connection.ts +143 -0
  207. package/server/modules/database/index.ts +12 -0
  208. package/server/modules/database/init-db.ts +17 -0
  209. package/server/modules/database/migrations.ts +442 -0
  210. package/server/modules/database/repositories/api-keys.ts +119 -0
  211. package/server/modules/database/repositories/app-config.ts +53 -0
  212. package/server/modules/database/repositories/credentials.ts +106 -0
  213. package/server/modules/database/repositories/github-tokens.ts +100 -0
  214. package/server/modules/database/repositories/notification-preferences.ts +103 -0
  215. package/server/modules/database/repositories/projects.db.integration.test.ts +72 -0
  216. package/server/modules/database/repositories/projects.db.ts +183 -0
  217. package/server/modules/database/repositories/push-subscriptions.ts +80 -0
  218. package/server/modules/database/repositories/scan-state.db.ts +42 -0
  219. package/server/modules/database/repositories/sessions.db.ts +174 -0
  220. package/server/modules/database/repositories/users.ts +140 -0
  221. package/server/modules/database/repositories/vapid-keys.ts +57 -0
  222. package/server/modules/database/schema.ts +152 -0
  223. package/server/modules/projects/index.ts +6 -0
  224. package/server/modules/projects/projects.routes.ts +247 -0
  225. package/server/modules/projects/services/project-clone.service.ts +321 -0
  226. package/server/modules/projects/services/project-delete.service.ts +75 -0
  227. package/server/modules/projects/services/project-management.service.ts +150 -0
  228. package/server/modules/projects/services/project-star.service.ts +78 -0
  229. package/server/modules/projects/services/projects-has-taskmaster.service.ts +248 -0
  230. package/server/modules/projects/services/projects-with-sessions-fetch.service.ts +285 -0
  231. package/server/modules/projects/tests/project-clone.service.test.ts +183 -0
  232. package/server/modules/projects/tests/project-management.service.test.ts +117 -0
  233. package/server/modules/projects/tests/project-star.service.test.ts +123 -0
  234. package/server/modules/projects/tests/projects-has-taskmaster.service.test.ts +105 -0
  235. package/server/modules/providers/index.ts +4 -0
  236. package/server/modules/providers/list/claude/claude-auth.provider.ts +123 -0
  237. package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -0
  238. package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +110 -0
  239. package/server/modules/providers/list/claude/claude-sessions.provider.ts +475 -0
  240. package/server/modules/providers/list/claude/claude.provider.ts +17 -0
  241. package/server/modules/providers/list/codex/codex-auth.provider.ts +100 -0
  242. package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -0
  243. package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +119 -0
  244. package/server/modules/providers/list/codex/codex-sessions.provider.ts +564 -0
  245. package/server/modules/providers/list/codex/codex.provider.ts +17 -0
  246. package/server/modules/providers/list/cursor/cursor-auth.provider.ts +143 -0
  247. package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -0
  248. package/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.ts +176 -0
  249. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +421 -0
  250. package/server/modules/providers/list/cursor/cursor.provider.ts +17 -0
  251. package/server/modules/providers/list/gemini/gemini-auth.provider.ts +151 -0
  252. package/server/modules/providers/list/gemini/gemini-mcp.provider.ts +110 -0
  253. package/server/modules/providers/list/gemini/gemini-session-synchronizer.provider.ts +401 -0
  254. package/server/modules/providers/list/gemini/gemini-sessions.provider.ts +541 -0
  255. package/server/modules/providers/list/gemini/gemini.provider.ts +17 -0
  256. package/server/modules/providers/provider.registry.ts +36 -0
  257. package/server/modules/providers/provider.routes.ts +425 -0
  258. package/server/modules/providers/services/mcp.service.ts +94 -0
  259. package/server/modules/providers/services/provider-auth.service.ts +26 -0
  260. package/server/modules/providers/services/session-conversations-search.service.ts +1167 -0
  261. package/server/modules/providers/services/session-synchronizer.service.ts +74 -0
  262. package/server/modules/providers/services/sessions-watcher.service.ts +283 -0
  263. package/server/modules/providers/services/sessions.service.ts +130 -0
  264. package/server/modules/providers/shared/base/abstract.provider.ts +27 -0
  265. package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -0
  266. package/server/modules/providers/tests/mcp.test.ts +293 -0
  267. package/server/modules/websocket/README.md +267 -0
  268. package/server/modules/websocket/index.ts +2 -0
  269. package/server/modules/websocket/services/chat-websocket.service.ts +271 -0
  270. package/server/modules/websocket/services/plugin-websocket-proxy.service.ts +65 -0
  271. package/server/modules/websocket/services/shell-websocket.service.ts +453 -0
  272. package/server/modules/websocket/services/websocket-auth.service.ts +54 -0
  273. package/server/modules/websocket/services/websocket-server.service.ts +58 -0
  274. package/server/modules/websocket/services/websocket-state.service.ts +16 -0
  275. package/server/modules/websocket/services/websocket-writer.service.ts +38 -0
  276. package/server/openai-codex.js +5 -5
  277. package/server/routes/agent.js +11 -16
  278. package/server/routes/auth.js +4 -2
  279. package/server/routes/commands.js +1 -50
  280. package/server/routes/cursor.js +15 -527
  281. package/server/routes/gemini.js +3 -2
  282. package/server/routes/git.js +33 -28
  283. package/server/routes/mcp-utils.js +2 -19
  284. package/server/routes/settings.js +11 -1
  285. package/server/routes/taskmaster.js +107 -602
  286. package/server/routes/user.js +1 -1
  287. package/server/services/notification-orchestrator.js +3 -2
  288. package/server/services/vapid-keys.js +2 -1
  289. package/server/shared/interfaces.ts +92 -0
  290. package/server/shared/types.ts +327 -0
  291. package/server/shared/utils.ts +669 -0
  292. package/server/tsconfig.json +6 -3
  293. package/server/utils/mcp-detector.js +0 -51
  294. package/server/utils/taskmaster-websocket.js +19 -13
  295. package/shared/modelConstants.js +3 -1
  296. package/dist/assets/index-BBAE1OJ_.css +0 -32
  297. package/dist/assets/index-Ci1GOyV7.js +0 -1262
  298. package/dist-server/server/database/db.js +0 -535
  299. package/dist-server/server/database/db.js.map +0 -1
  300. package/dist-server/server/database/schema.js +0 -97
  301. package/dist-server/server/database/schema.js.map +0 -1
  302. package/dist-server/server/projects.js +0 -2325
  303. package/dist-server/server/projects.js.map +0 -1
  304. package/dist-server/server/providers/claude/adapter.js +0 -266
  305. package/dist-server/server/providers/claude/adapter.js.map +0 -1
  306. package/dist-server/server/providers/claude/status.js +0 -121
  307. package/dist-server/server/providers/claude/status.js.map +0 -1
  308. package/dist-server/server/providers/codex/adapter.js +0 -232
  309. package/dist-server/server/providers/codex/adapter.js.map +0 -1
  310. package/dist-server/server/providers/codex/status.js +0 -70
  311. package/dist-server/server/providers/codex/status.js.map +0 -1
  312. package/dist-server/server/providers/cursor/adapter.js +0 -342
  313. package/dist-server/server/providers/cursor/adapter.js.map +0 -1
  314. package/dist-server/server/providers/cursor/status.js +0 -118
  315. package/dist-server/server/providers/cursor/status.js.map +0 -1
  316. package/dist-server/server/providers/gemini/adapter.js +0 -174
  317. package/dist-server/server/providers/gemini/adapter.js.map +0 -1
  318. package/dist-server/server/providers/gemini/status.js +0 -104
  319. package/dist-server/server/providers/gemini/status.js.map +0 -1
  320. package/dist-server/server/providers/registry.js +0 -58
  321. package/dist-server/server/providers/registry.js.map +0 -1
  322. package/dist-server/server/providers/types.js +0 -117
  323. package/dist-server/server/providers/types.js.map +0 -1
  324. package/dist-server/server/providers/utils.js +0 -28
  325. package/dist-server/server/providers/utils.js.map +0 -1
  326. package/dist-server/server/routes/cli-auth.js +0 -25
  327. package/dist-server/server/routes/cli-auth.js.map +0 -1
  328. package/dist-server/server/routes/codex.js +0 -294
  329. package/dist-server/server/routes/codex.js.map +0 -1
  330. package/dist-server/server/routes/mcp.js +0 -480
  331. package/dist-server/server/routes/mcp.js.map +0 -1
  332. package/dist-server/server/routes/messages.js +0 -56
  333. package/dist-server/server/routes/messages.js.map +0 -1
  334. package/dist-server/server/routes/projects.js +0 -505
  335. package/dist-server/server/routes/projects.js.map +0 -1
  336. package/server/database/db.js +0 -593
  337. package/server/database/schema.js +0 -102
  338. package/server/projects.js +0 -2555
  339. package/server/providers/claude/adapter.js +0 -278
  340. package/server/providers/claude/status.js +0 -136
  341. package/server/providers/codex/adapter.js +0 -248
  342. package/server/providers/codex/status.js +0 -78
  343. package/server/providers/cursor/adapter.js +0 -348
  344. package/server/providers/cursor/status.js +0 -128
  345. package/server/providers/gemini/adapter.js +0 -186
  346. package/server/providers/gemini/status.js +0 -111
  347. package/server/providers/registry.js +0 -67
  348. package/server/providers/types.js +0 -132
  349. package/server/providers/utils.js +0 -29
  350. package/server/routes/cli-auth.js +0 -27
  351. package/server/routes/codex.js +0 -329
  352. package/server/routes/mcp.js +0 -552
  353. package/server/routes/messages.js +0 -61
  354. package/server/routes/projects.js +0 -548
@@ -0,0 +1,453 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+
5
+ import pty, { type IPty } from 'node-pty';
6
+ import { WebSocket, type RawData } from 'ws';
7
+
8
+ import { parseIncomingJsonObject } from '@/shared/utils.js';
9
+
10
+ type ShellIncomingMessage = {
11
+ type?: string;
12
+ data?: string;
13
+ cols?: number;
14
+ rows?: number;
15
+ projectPath?: string;
16
+ sessionId?: string;
17
+ hasSession?: boolean;
18
+ provider?: string;
19
+ initialCommand?: string;
20
+ isPlainShell?: boolean;
21
+ };
22
+
23
+ type PtySessionEntry = {
24
+ pty: IPty;
25
+ ws: WebSocket | null;
26
+ buffer: string[];
27
+ timeoutId: NodeJS.Timeout | null;
28
+ projectPath: string;
29
+ sessionId: string | null;
30
+ };
31
+
32
+ const ptySessionsMap = new Map<string, PtySessionEntry>();
33
+ const PTY_SESSION_TIMEOUT = 30 * 60 * 1000;
34
+ const SHELL_URL_PARSE_BUFFER_LIMIT = 32768;
35
+
36
+ type ShellWebSocketDependencies = {
37
+ getSessionById: (sessionId: string) => { cliSessionId?: string } | null | undefined;
38
+ stripAnsiSequences: (content: string) => string;
39
+ normalizeDetectedUrl: (url: string) => string | null;
40
+ extractUrlsFromText: (content: string) => string[];
41
+ shouldAutoOpenUrlFromOutput: (content: string) => boolean;
42
+ };
43
+
44
+ /**
45
+ * Reads a string field from untyped payloads and falls back when absent.
46
+ */
47
+ function readString(value: unknown, fallback = ''): string {
48
+ return typeof value === 'string' ? value : fallback;
49
+ }
50
+
51
+ /**
52
+ * Reads a boolean field from untyped payloads and falls back when absent.
53
+ */
54
+ function readBoolean(value: unknown, fallback = false): boolean {
55
+ return typeof value === 'boolean' ? value : fallback;
56
+ }
57
+
58
+ /**
59
+ * Reads a finite number field from untyped payloads and falls back when absent.
60
+ */
61
+ function readNumber(value: unknown, fallback: number): number {
62
+ return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
63
+ }
64
+
65
+ /**
66
+ * Parses incoming websocket shell messages and keeps processing safe when
67
+ * malformed payloads are received.
68
+ */
69
+ function parseShellMessage(rawMessage: RawData): ShellIncomingMessage | null {
70
+ const payload = parseIncomingJsonObject(rawMessage);
71
+ if (!payload) {
72
+ return null;
73
+ }
74
+
75
+ return payload as ShellIncomingMessage;
76
+ }
77
+
78
+ /**
79
+ * Resolves provider command line for plain shell and agent-backed shell modes.
80
+ */
81
+ function buildShellCommand(
82
+ message: ShellIncomingMessage,
83
+ dependencies: ShellWebSocketDependencies
84
+ ): string {
85
+ const hasSession = readBoolean(message.hasSession);
86
+ const sessionId = readString(message.sessionId);
87
+ const initialCommand = readString(message.initialCommand);
88
+ const provider = readString(message.provider, 'claude');
89
+ const safeSessionIdPattern = /^[a-zA-Z0-9_.\-:]+$/;
90
+ const isPlainShell =
91
+ readBoolean(message.isPlainShell) ||
92
+ (!!initialCommand && !hasSession) ||
93
+ provider === 'plain-shell';
94
+
95
+ if (isPlainShell) {
96
+ return initialCommand;
97
+ }
98
+
99
+ if (provider === 'cursor') {
100
+ if (hasSession && sessionId) {
101
+ return `cursor-agent --resume="${sessionId}"`;
102
+ }
103
+ return 'cursor-agent';
104
+ }
105
+
106
+ if (provider === 'codex') {
107
+ if (hasSession && sessionId) {
108
+ if (os.platform() === 'win32') {
109
+ return `codex resume "${sessionId}"; if ($LASTEXITCODE -ne 0) { codex }`;
110
+ }
111
+ return `codex resume "${sessionId}" || codex`;
112
+ }
113
+ return 'codex';
114
+ }
115
+
116
+ if (provider === 'gemini') {
117
+ const command = initialCommand || 'gemini';
118
+ let resumeId = sessionId;
119
+ if (hasSession && sessionId) {
120
+ try {
121
+ const existingSession = dependencies.getSessionById(sessionId);
122
+ if (existingSession && existingSession.cliSessionId) {
123
+ resumeId = existingSession.cliSessionId;
124
+ if (!safeSessionIdPattern.test(resumeId)) {
125
+ resumeId = '';
126
+ }
127
+ }
128
+ } catch (error) {
129
+ console.error('Failed to get Gemini CLI session ID:', error);
130
+ }
131
+ }
132
+
133
+ if (hasSession && resumeId) {
134
+ return `${command} --resume "${resumeId}"`;
135
+ }
136
+ return command;
137
+ }
138
+
139
+ const command = initialCommand || 'claude';
140
+ if (hasSession && sessionId) {
141
+ if (os.platform() === 'win32') {
142
+ return `claude --resume "${sessionId}"; if ($LASTEXITCODE -ne 0) { claude }`;
143
+ }
144
+ return `claude --resume "${sessionId}" || claude`;
145
+ }
146
+ return command;
147
+ }
148
+
149
+ /**
150
+ * Handles websocket connections used by the standalone shell terminal UI.
151
+ */
152
+ export function handleShellConnection(
153
+ ws: WebSocket,
154
+ dependencies: ShellWebSocketDependencies
155
+ ): void {
156
+ console.log('[INFO] Shell websocket connected');
157
+
158
+ let shellProcess: IPty | null = null;
159
+ let ptySessionKey: string | null = null;
160
+ let urlDetectionBuffer = '';
161
+ const announcedAuthUrls = new Set<string>();
162
+
163
+ ws.on('message', async (rawMessage) => {
164
+ try {
165
+ const data = parseShellMessage(rawMessage);
166
+ if (!data?.type) {
167
+ throw new Error('Invalid websocket payload');
168
+ }
169
+
170
+ if (data.type === 'init') {
171
+ const projectPath = readString(data.projectPath, process.cwd());
172
+ const sessionId = readString(data.sessionId) || null;
173
+ const hasSession = readBoolean(data.hasSession);
174
+ const provider = readString(data.provider, 'claude');
175
+ const initialCommand = readString(data.initialCommand);
176
+ const isPlainShell =
177
+ readBoolean(data.isPlainShell) ||
178
+ (!!initialCommand && !hasSession) ||
179
+ provider === 'plain-shell';
180
+
181
+ urlDetectionBuffer = '';
182
+ announcedAuthUrls.clear();
183
+
184
+ const isLoginCommand =
185
+ !!initialCommand &&
186
+ (initialCommand.includes('setup-token') ||
187
+ initialCommand.includes('cursor-agent login') ||
188
+ initialCommand.includes('auth login'));
189
+
190
+ const commandSuffix =
191
+ isPlainShell && initialCommand
192
+ ? `_cmd_${Buffer.from(initialCommand).toString('base64').slice(0, 16)}`
193
+ : '';
194
+ ptySessionKey = `${projectPath}_${sessionId ?? 'default'}${commandSuffix}`;
195
+
196
+ if (isLoginCommand) {
197
+ const oldSession = ptySessionsMap.get(ptySessionKey);
198
+ if (oldSession) {
199
+ if (oldSession.timeoutId) {
200
+ clearTimeout(oldSession.timeoutId);
201
+ }
202
+ oldSession.pty.kill();
203
+ ptySessionsMap.delete(ptySessionKey);
204
+ }
205
+ }
206
+
207
+ const existingSession = isLoginCommand ? null : ptySessionsMap.get(ptySessionKey);
208
+ if (existingSession) {
209
+ shellProcess = existingSession.pty;
210
+ if (existingSession.timeoutId) {
211
+ clearTimeout(existingSession.timeoutId);
212
+ }
213
+
214
+ ws.send(
215
+ JSON.stringify({
216
+ type: 'output',
217
+ data: '\x1b[36m[Reconnected to existing session]\x1b[0m\r\n',
218
+ })
219
+ );
220
+
221
+ if (existingSession.buffer.length > 0) {
222
+ existingSession.buffer.forEach((bufferedData) => {
223
+ ws.send(
224
+ JSON.stringify({
225
+ type: 'output',
226
+ data: bufferedData,
227
+ })
228
+ );
229
+ });
230
+ }
231
+
232
+ existingSession.ws = ws;
233
+ return;
234
+ }
235
+
236
+ const resolvedProjectPath = path.resolve(projectPath);
237
+ try {
238
+ const stats = fs.statSync(resolvedProjectPath);
239
+ if (!stats.isDirectory()) {
240
+ throw new Error('Not a directory');
241
+ }
242
+ } catch {
243
+ ws.send(JSON.stringify({ type: 'error', message: 'Invalid project path' }));
244
+ return;
245
+ }
246
+
247
+ const safeSessionIdPattern = /^[a-zA-Z0-9_.\-:]+$/;
248
+ if (sessionId && !safeSessionIdPattern.test(sessionId)) {
249
+ ws.send(JSON.stringify({ type: 'error', message: 'Invalid session ID' }));
250
+ return;
251
+ }
252
+
253
+ const shellCommand = buildShellCommand(data, dependencies);
254
+ const shell = os.platform() === 'win32' ? 'powershell.exe' : 'bash';
255
+ const shellArgs =
256
+ os.platform() === 'win32' ? ['-Command', shellCommand] : ['-c', shellCommand];
257
+ const termCols = readNumber(data.cols, 80);
258
+ const termRows = readNumber(data.rows, 24);
259
+
260
+ shellProcess = pty.spawn(shell, shellArgs, {
261
+ name: 'xterm-256color',
262
+ cols: termCols,
263
+ rows: termRows,
264
+ cwd: resolvedProjectPath,
265
+ env: {
266
+ ...process.env,
267
+ TERM: 'xterm-256color',
268
+ COLORTERM: 'truecolor',
269
+ FORCE_COLOR: '3',
270
+ },
271
+ });
272
+
273
+ ptySessionsMap.set(ptySessionKey, {
274
+ pty: shellProcess,
275
+ ws,
276
+ buffer: [],
277
+ timeoutId: null,
278
+ projectPath,
279
+ sessionId,
280
+ });
281
+
282
+ shellProcess.onData((chunk) => {
283
+ if (!ptySessionKey) {
284
+ return;
285
+ }
286
+
287
+ const session = ptySessionsMap.get(ptySessionKey);
288
+ if (!session) {
289
+ return;
290
+ }
291
+
292
+ if (session.buffer.length < 5000) {
293
+ session.buffer.push(chunk);
294
+ } else {
295
+ session.buffer.shift();
296
+ session.buffer.push(chunk);
297
+ }
298
+
299
+ if (session.ws && session.ws.readyState === WebSocket.OPEN) {
300
+ let outputData = chunk;
301
+ const cleanChunk = dependencies.stripAnsiSequences(chunk);
302
+ urlDetectionBuffer = `${urlDetectionBuffer}${cleanChunk}`.slice(-SHELL_URL_PARSE_BUFFER_LIMIT);
303
+
304
+ outputData = outputData.replace(
305
+ /OPEN_URL:\s*(https?:\/\/[^\s\x1b\x07]+)/g,
306
+ '[INFO] Opening in browser: $1'
307
+ );
308
+
309
+ const emitAuthUrl = (detectedUrl: string, autoOpen = false) => {
310
+ const normalizedUrl = dependencies.normalizeDetectedUrl(detectedUrl);
311
+ if (!normalizedUrl) {
312
+ return;
313
+ }
314
+
315
+ const isNewUrl = !announcedAuthUrls.has(normalizedUrl);
316
+ if (isNewUrl) {
317
+ announcedAuthUrls.add(normalizedUrl);
318
+ session.ws?.send(
319
+ JSON.stringify({
320
+ type: 'auth_url',
321
+ url: normalizedUrl,
322
+ autoOpen,
323
+ })
324
+ );
325
+ }
326
+ };
327
+
328
+ const normalizedDetectedUrls = dependencies.extractUrlsFromText(urlDetectionBuffer)
329
+ .map((url) => dependencies.normalizeDetectedUrl(url))
330
+ .filter((url): url is string => Boolean(url));
331
+
332
+ const dedupedDetectedUrls = Array.from(new Set(normalizedDetectedUrls)).filter(
333
+ (url, _, urls) =>
334
+ !urls.some((otherUrl) => otherUrl !== url && otherUrl.startsWith(url))
335
+ );
336
+
337
+ dedupedDetectedUrls.forEach((url) => emitAuthUrl(url, false));
338
+
339
+ if (
340
+ dependencies.shouldAutoOpenUrlFromOutput(cleanChunk) &&
341
+ dedupedDetectedUrls.length > 0
342
+ ) {
343
+ const bestUrl = dedupedDetectedUrls.reduce((longest, current) =>
344
+ current.length > longest.length ? current : longest
345
+ );
346
+ emitAuthUrl(bestUrl, true);
347
+ }
348
+
349
+ session.ws.send(
350
+ JSON.stringify({
351
+ type: 'output',
352
+ data: outputData,
353
+ })
354
+ );
355
+ }
356
+ });
357
+
358
+ shellProcess.onExit((exitCode) => {
359
+ if (!ptySessionKey) {
360
+ return;
361
+ }
362
+
363
+ const session = ptySessionsMap.get(ptySessionKey);
364
+ if (session && session.ws && session.ws.readyState === WebSocket.OPEN) {
365
+ session.ws.send(
366
+ JSON.stringify({
367
+ type: 'output',
368
+ data: `\r\n\x1b[33mProcess exited with code ${exitCode.exitCode}${
369
+ exitCode.signal != null ? ` (${exitCode.signal})` : ''
370
+ }\x1b[0m\r\n`,
371
+ })
372
+ );
373
+ }
374
+
375
+ if (session?.timeoutId) {
376
+ clearTimeout(session.timeoutId);
377
+ }
378
+
379
+ ptySessionsMap.delete(ptySessionKey);
380
+ shellProcess = null;
381
+ });
382
+
383
+ let welcomeMsg = `\x1b[36mStarting terminal in: ${projectPath}\x1b[0m\r\n`;
384
+ if (!isPlainShell) {
385
+ const providerName =
386
+ provider === 'cursor'
387
+ ? 'Cursor'
388
+ : provider === 'codex'
389
+ ? 'Codex'
390
+ : provider === 'gemini'
391
+ ? 'Gemini'
392
+ : 'Claude';
393
+ welcomeMsg = hasSession
394
+ ? `\x1b[36mResuming ${providerName} session ${sessionId} in: ${projectPath}\x1b[0m\r\n`
395
+ : `\x1b[36mStarting new ${providerName} session in: ${projectPath}\x1b[0m\r\n`;
396
+ }
397
+
398
+ ws.send(
399
+ JSON.stringify({
400
+ type: 'output',
401
+ data: welcomeMsg,
402
+ })
403
+ );
404
+ return;
405
+ }
406
+
407
+ if (data.type === 'input') {
408
+ if (shellProcess) {
409
+ shellProcess.write(readString(data.data));
410
+ }
411
+ return;
412
+ }
413
+
414
+ if (data.type === 'resize') {
415
+ if (shellProcess) {
416
+ shellProcess.resize(readNumber(data.cols, 80), readNumber(data.rows, 24));
417
+ }
418
+ }
419
+ } catch (error) {
420
+ const message = error instanceof Error ? error.message : String(error);
421
+ console.error('[ERROR] Shell WebSocket error:', message);
422
+ if (ws.readyState === WebSocket.OPEN) {
423
+ ws.send(
424
+ JSON.stringify({
425
+ type: 'output',
426
+ data: `\r\n\x1b[31mError: ${message}\x1b[0m\r\n`,
427
+ })
428
+ );
429
+ }
430
+ }
431
+ });
432
+
433
+ ws.on('close', () => {
434
+ if (!ptySessionKey) {
435
+ return;
436
+ }
437
+
438
+ const session = ptySessionsMap.get(ptySessionKey);
439
+ if (!session) {
440
+ return;
441
+ }
442
+
443
+ session.ws = null;
444
+ session.timeoutId = setTimeout(() => {
445
+ session.pty.kill();
446
+ ptySessionsMap.delete(ptySessionKey as string);
447
+ }, PTY_SESSION_TIMEOUT);
448
+ });
449
+
450
+ ws.on('error', (error) => {
451
+ console.error('[ERROR] Shell WebSocket error:', error);
452
+ });
453
+ }
@@ -0,0 +1,54 @@
1
+ import type { VerifyClientCallbackSync } from 'ws';
2
+
3
+ import type { AuthenticatedWebSocketRequest } from '@/shared/types.js';
4
+
5
+ type WebSocketAuthDependencies = {
6
+ isPlatform: boolean;
7
+ authenticateWebSocket: (token: string | null) => {
8
+ id?: string | number;
9
+ userId?: string | number;
10
+ username?: string;
11
+ [key: string]: unknown;
12
+ } | null;
13
+ };
14
+
15
+ /**
16
+ * Authenticates websocket upgrade requests before the `connection` handler runs.
17
+ */
18
+ export function verifyWebSocketClient(
19
+ info: Parameters<VerifyClientCallbackSync<AuthenticatedWebSocketRequest>>[0],
20
+ dependencies: WebSocketAuthDependencies
21
+ ): boolean {
22
+ const request = info.req as AuthenticatedWebSocketRequest;
23
+ console.log('WebSocket connection attempt to:', request.url);
24
+
25
+ // Platform mode: use the first DB user and skip token checks.
26
+ if (dependencies.isPlatform) {
27
+ const user = dependencies.authenticateWebSocket(null);
28
+ if (!user) {
29
+ console.log('[WARN] Platform mode: No user found in database');
30
+ return false;
31
+ }
32
+
33
+ request.user = user;
34
+ console.log('[OK] Platform mode WebSocket authenticated for user:', user.username);
35
+ return true;
36
+ }
37
+
38
+ // OSS mode: read JWT from query string first, then Authorization header.
39
+ const upgradeUrl = new URL(request.url ?? '/', 'http://localhost');
40
+ const token =
41
+ upgradeUrl.searchParams.get('token') ??
42
+ request.headers.authorization?.split(' ')[1] ??
43
+ null;
44
+
45
+ const user = dependencies.authenticateWebSocket(token);
46
+ if (!user) {
47
+ console.log('[WARN] WebSocket authentication failed');
48
+ return false;
49
+ }
50
+
51
+ request.user = user;
52
+ console.log('[OK] WebSocket authenticated for user:', user.username);
53
+ return true;
54
+ }
@@ -0,0 +1,58 @@
1
+ import type { Server as HttpServer } from 'node:http';
2
+
3
+ import { WebSocketServer, type VerifyClientCallbackSync } from 'ws';
4
+
5
+ import { handleChatConnection } from '@/modules/websocket/services/chat-websocket.service.js';
6
+ import { verifyWebSocketClient } from '@/modules/websocket/services/websocket-auth.service.js';
7
+ import { handlePluginWsProxy } from '@/modules/websocket/services/plugin-websocket-proxy.service.js';
8
+ import { handleShellConnection } from '@/modules/websocket/services/shell-websocket.service.js';
9
+ import type { AuthenticatedWebSocketRequest } from '@/shared/types.js';
10
+
11
+ type WebSocketServerDependencies = {
12
+ verifyClient: Parameters<typeof verifyWebSocketClient>[1];
13
+ chat: Parameters<typeof handleChatConnection>[2];
14
+ shell: Parameters<typeof handleShellConnection>[1];
15
+ getPluginPort: Parameters<typeof handlePluginWsProxy>[2];
16
+ };
17
+
18
+ /**
19
+ * Creates and wires the server-wide websocket gateway used for chat, shell, and
20
+ * plugin proxy routes.
21
+ */
22
+ export function createWebSocketServer(
23
+ server: HttpServer,
24
+ dependencies: WebSocketServerDependencies
25
+ ): WebSocketServer {
26
+ const wss = new WebSocketServer({
27
+ server,
28
+ verifyClient: ((
29
+ info: Parameters<VerifyClientCallbackSync<AuthenticatedWebSocketRequest>>[0]
30
+ ) => verifyWebSocketClient(info, dependencies.verifyClient)),
31
+ });
32
+
33
+ wss.on('connection', (ws, request) => {
34
+ const incomingRequest = request as AuthenticatedWebSocketRequest;
35
+ const url = incomingRequest.url ?? '/';
36
+ const pathname = new URL(url, 'http://localhost').pathname;
37
+
38
+ if (pathname === '/shell') {
39
+ handleShellConnection(ws, dependencies.shell);
40
+ return;
41
+ }
42
+
43
+ if (pathname === '/ws') {
44
+ handleChatConnection(ws, incomingRequest, dependencies.chat);
45
+ return;
46
+ }
47
+
48
+ if (pathname.startsWith('/plugin-ws/')) {
49
+ handlePluginWsProxy(ws, pathname, dependencies.getPluginPort);
50
+ return;
51
+ }
52
+
53
+ console.log('[WARN] Unknown WebSocket path:', pathname);
54
+ ws.close();
55
+ });
56
+
57
+ return wss;
58
+ }
@@ -0,0 +1,16 @@
1
+ import type { RealtimeClientConnection } from '@/shared/types.js';
2
+
3
+ /**
4
+ * Numeric readyState for an open WebSocket connection.
5
+ *
6
+ * We keep this in module state so services that broadcast updates do not need
7
+ * to import `ws` directly just to compare open/closed state.
8
+ */
9
+ export const WS_OPEN_STATE = 1;
10
+
11
+ /**
12
+ * Shared registry of active chat WebSocket connections.
13
+ *
14
+ * Project/session services publish realtime updates by iterating this set.
15
+ */
16
+ export const connectedClients = new Set<RealtimeClientConnection>();
@@ -0,0 +1,38 @@
1
+ import { WS_OPEN_STATE } from '@/modules/websocket/services/websocket-state.service.js';
2
+ import type { RealtimeClientConnection } from '@/shared/types.js';
3
+
4
+ /**
5
+ * Thin transport adapter that gives WebSocket connections the same interface as
6
+ * SSE writers used by API routes (`send`, `setSessionId`, `getSessionId`).
7
+ */
8
+ export class WebSocketWriter {
9
+ ws: RealtimeClientConnection;
10
+ sessionId: string | null;
11
+ userId: string | number | null;
12
+ isWebSocketWriter: boolean;
13
+
14
+ constructor(ws: RealtimeClientConnection, userId: string | number | null = null) {
15
+ this.ws = ws;
16
+ this.sessionId = null;
17
+ this.userId = userId;
18
+ this.isWebSocketWriter = true;
19
+ }
20
+
21
+ send(data: unknown): void {
22
+ if (this.ws.readyState === WS_OPEN_STATE) {
23
+ this.ws.send(JSON.stringify(data));
24
+ }
25
+ }
26
+
27
+ updateWebSocket(newRawWs: RealtimeClientConnection): void {
28
+ this.ws = newRawWs;
29
+ }
30
+
31
+ setSessionId(sessionId: string): void {
32
+ this.sessionId = sessionId;
33
+ }
34
+
35
+ getSessionId(): string | null {
36
+ return this.sessionId;
37
+ }
38
+ }
@@ -15,9 +15,9 @@
15
15
 
16
16
  import { Codex } from '@openai/codex-sdk';
17
17
  import { notifyRunFailed, notifyRunStopped } from './services/notification-orchestrator.js';
18
- import { codexAdapter } from './providers/codex/adapter.js';
19
- import { createNormalizedMessage } from './providers/types.js';
20
- import { getStatusChecker } from './providers/registry.js';
18
+ import { sessionsService } from './modules/providers/services/sessions.service.js';
19
+ import { providerAuthService } from './modules/providers/services/provider-auth.service.js';
20
+ import { createNormalizedMessage } from './shared/utils.js';
21
21
 
22
22
  // Track active sessions
23
23
  const activeCodexSessions = new Map();
@@ -265,7 +265,7 @@ export async function queryCodex(command, options = {}, ws) {
265
265
  const transformed = transformCodexEvent(event);
266
266
 
267
267
  // Normalize the transformed event into NormalizedMessage(s) via adapter
268
- const normalizedMsgs = codexAdapter.normalizeMessage(transformed, currentSessionId);
268
+ const normalizedMsgs = sessionsService.normalizeMessage('codex', transformed, currentSessionId);
269
269
  for (const msg of normalizedMsgs) {
270
270
  sendMessage(ws, msg);
271
271
  }
@@ -311,7 +311,7 @@ export async function queryCodex(command, options = {}, ws) {
311
311
  console.error('[Codex] Error:', error);
312
312
 
313
313
  // Check if Codex SDK is available for a clearer error message
314
- const installed = getStatusChecker('codex')?.checkInstalled() ?? true;
314
+ const installed = await providerAuthService.isProviderInstalled('codex');
315
315
  const errorContent = !installed
316
316
  ? 'Codex CLI is not configured. Please set up authentication first.'
317
317
  : error.message;