@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
@@ -13,15 +13,24 @@ import fs from 'fs';
13
13
  import path from 'path';
14
14
  import { promises as fsPromises } from 'fs';
15
15
  import { spawn } from 'child_process';
16
- import { fileURLToPath } from 'url';
17
- import { dirname } from 'path';
18
- import os from 'os';
19
- import { extractProjectDirectory } from '../projects.js';
16
+ import { projectsDb } from '../modules/database/index.js';
20
17
  import { detectTaskMasterMCPServer } from '../utils/mcp-detector.js';
21
18
  import { broadcastTaskMasterProjectUpdate, broadcastTaskMasterTasksUpdate } from '../utils/taskmaster-websocket.js';
22
19
 
23
- const __filename = fileURLToPath(import.meta.url);
24
- const __dirname = dirname(__filename);
20
+ /**
21
+ * Resolve the absolute project directory from a DB-assigned `projectId`.
22
+ *
23
+ * TaskMaster routes used to accept a Claude-encoded folder name (`projectName`)
24
+ * and derive the path from JSONL history. After the projectId migration the
25
+ * only identifier we accept is the primary key of the `projects` table, so
26
+ * every handler calls this helper and 404s when the id is unknown.
27
+ */
28
+ async function resolveProjectPathFromId(projectId) {
29
+ if (!projectId) {
30
+ return null;
31
+ }
32
+ return projectsDb.getProjectPathById(projectId);
33
+ }
25
34
 
26
35
  const router = express.Router();
27
36
 
@@ -100,140 +109,6 @@ async function checkTaskMasterInstallation() {
100
109
  });
101
110
  }
102
111
 
103
- /**
104
- * Detect .taskmaster folder presence in a given project directory
105
- * @param {string} projectPath - Absolute path to project directory
106
- * @returns {Promise<Object>} Detection result with status and metadata
107
- */
108
- async function detectTaskMasterFolder(projectPath) {
109
- try {
110
- const taskMasterPath = path.join(projectPath, '.taskmaster');
111
-
112
- // Check if .taskmaster directory exists
113
- try {
114
- const stats = await fsPromises.stat(taskMasterPath);
115
- if (!stats.isDirectory()) {
116
- return {
117
- hasTaskmaster: false,
118
- reason: '.taskmaster exists but is not a directory'
119
- };
120
- }
121
- } catch (error) {
122
- if (error.code === 'ENOENT') {
123
- return {
124
- hasTaskmaster: false,
125
- reason: '.taskmaster directory not found'
126
- };
127
- }
128
- throw error;
129
- }
130
-
131
- // Check for key TaskMaster files
132
- const keyFiles = [
133
- 'tasks/tasks.json',
134
- 'config.json'
135
- ];
136
-
137
- const fileStatus = {};
138
- let hasEssentialFiles = true;
139
-
140
- for (const file of keyFiles) {
141
- const filePath = path.join(taskMasterPath, file);
142
- try {
143
- await fsPromises.access(filePath, fs.constants.R_OK);
144
- fileStatus[file] = true;
145
- } catch (error) {
146
- fileStatus[file] = false;
147
- if (file === 'tasks/tasks.json') {
148
- hasEssentialFiles = false;
149
- }
150
- }
151
- }
152
-
153
- // Parse tasks.json if it exists for metadata
154
- let taskMetadata = null;
155
- if (fileStatus['tasks/tasks.json']) {
156
- try {
157
- const tasksPath = path.join(taskMasterPath, 'tasks/tasks.json');
158
- const tasksContent = await fsPromises.readFile(tasksPath, 'utf8');
159
- const tasksData = JSON.parse(tasksContent);
160
-
161
- // Handle both tagged and legacy formats
162
- let tasks = [];
163
- if (tasksData.tasks) {
164
- // Legacy format
165
- tasks = tasksData.tasks;
166
- } else {
167
- // Tagged format - get tasks from all tags
168
- Object.values(tasksData).forEach(tagData => {
169
- if (tagData.tasks) {
170
- tasks = tasks.concat(tagData.tasks);
171
- }
172
- });
173
- }
174
-
175
- // Calculate task statistics
176
- const stats = tasks.reduce((acc, task) => {
177
- acc.total++;
178
- acc[task.status] = (acc[task.status] || 0) + 1;
179
-
180
- // Count subtasks
181
- if (task.subtasks) {
182
- task.subtasks.forEach(subtask => {
183
- acc.subtotalTasks++;
184
- acc.subtasks = acc.subtasks || {};
185
- acc.subtasks[subtask.status] = (acc.subtasks[subtask.status] || 0) + 1;
186
- });
187
- }
188
-
189
- return acc;
190
- }, {
191
- total: 0,
192
- subtotalTasks: 0,
193
- pending: 0,
194
- 'in-progress': 0,
195
- done: 0,
196
- review: 0,
197
- deferred: 0,
198
- cancelled: 0,
199
- subtasks: {}
200
- });
201
-
202
- taskMetadata = {
203
- taskCount: stats.total,
204
- subtaskCount: stats.subtotalTasks,
205
- completed: stats.done || 0,
206
- pending: stats.pending || 0,
207
- inProgress: stats['in-progress'] || 0,
208
- review: stats.review || 0,
209
- completionPercentage: stats.total > 0 ? Math.round((stats.done / stats.total) * 100) : 0,
210
- lastModified: (await fsPromises.stat(tasksPath)).mtime.toISOString()
211
- };
212
- } catch (parseError) {
213
- console.warn('Failed to parse tasks.json:', parseError.message);
214
- taskMetadata = { error: 'Failed to parse tasks.json' };
215
- }
216
- }
217
-
218
- return {
219
- hasTaskmaster: true,
220
- hasEssentialFiles,
221
- files: fileStatus,
222
- metadata: taskMetadata,
223
- path: taskMasterPath
224
- };
225
-
226
- } catch (error) {
227
- console.error('Error detecting TaskMaster folder:', error);
228
- return {
229
- hasTaskmaster: false,
230
- reason: `Error checking directory: ${error.message}`
231
- };
232
- }
233
- }
234
-
235
- // MCP detection is now handled by the centralized utility
236
-
237
112
  // API Routes
238
113
 
239
114
  /**
@@ -272,313 +147,22 @@ router.get('/installation-status', async (req, res) => {
272
147
  });
273
148
 
274
149
  /**
275
- * GET /api/taskmaster/detect/:projectName
276
- * Detect TaskMaster configuration for a specific project
277
- */
278
- router.get('/detect/:projectName', async (req, res) => {
279
- try {
280
- const { projectName } = req.params;
281
-
282
- // Use the existing extractProjectDirectory function to get actual project path
283
- let projectPath;
284
- try {
285
- projectPath = await extractProjectDirectory(projectName);
286
- } catch (error) {
287
- console.error('Error extracting project directory:', error);
288
- return res.status(404).json({
289
- error: 'Project path not found',
290
- projectName,
291
- message: error.message
292
- });
293
- }
294
-
295
- // Verify the project path exists
296
- try {
297
- await fsPromises.access(projectPath, fs.constants.R_OK);
298
- } catch (error) {
299
- return res.status(404).json({
300
- error: 'Project path not accessible',
301
- projectPath,
302
- projectName,
303
- message: error.message
304
- });
305
- }
306
-
307
- // Run detection in parallel
308
- const [taskMasterResult, mcpResult] = await Promise.all([
309
- detectTaskMasterFolder(projectPath),
310
- detectTaskMasterMCPServer()
311
- ]);
312
-
313
- // Determine overall status
314
- let status = 'not-configured';
315
- if (taskMasterResult.hasTaskmaster && taskMasterResult.hasEssentialFiles) {
316
- if (mcpResult.hasMCPServer && mcpResult.isConfigured) {
317
- status = 'fully-configured';
318
- } else {
319
- status = 'taskmaster-only';
320
- }
321
- } else if (mcpResult.hasMCPServer && mcpResult.isConfigured) {
322
- status = 'mcp-only';
323
- }
324
-
325
- const responseData = {
326
- projectName,
327
- projectPath,
328
- status,
329
- taskmaster: taskMasterResult,
330
- mcp: mcpResult,
331
- timestamp: new Date().toISOString()
332
- };
333
-
334
- res.json(responseData);
335
-
336
- } catch (error) {
337
- console.error('TaskMaster detection error:', error);
338
- res.status(500).json({
339
- error: 'Failed to detect TaskMaster configuration',
340
- message: error.message
341
- });
342
- }
343
- });
344
-
345
- /**
346
- * GET /api/taskmaster/detect-all
347
- * Detect TaskMaster configuration for all known projects
348
- * This endpoint works with the existing projects system
349
- */
350
- router.get('/detect-all', async (req, res) => {
351
- try {
352
- // Import getProjects from the projects module
353
- const { getProjects } = await import('../projects.js');
354
- const projects = await getProjects();
355
-
356
- // Run detection for all projects in parallel
357
- const detectionPromises = projects.map(async (project) => {
358
- try {
359
- // Use the project's fullPath if available, otherwise extract the directory
360
- let projectPath;
361
- if (project.fullPath) {
362
- projectPath = project.fullPath;
363
- } else {
364
- try {
365
- projectPath = await extractProjectDirectory(project.name);
366
- } catch (error) {
367
- throw new Error(`Failed to extract project directory: ${error.message}`);
368
- }
369
- }
370
-
371
- const [taskMasterResult, mcpResult] = await Promise.all([
372
- detectTaskMasterFolder(projectPath),
373
- detectTaskMasterMCPServer()
374
- ]);
375
-
376
- // Determine status
377
- let status = 'not-configured';
378
- if (taskMasterResult.hasTaskmaster && taskMasterResult.hasEssentialFiles) {
379
- if (mcpResult.hasMCPServer && mcpResult.isConfigured) {
380
- status = 'fully-configured';
381
- } else {
382
- status = 'taskmaster-only';
383
- }
384
- } else if (mcpResult.hasMCPServer && mcpResult.isConfigured) {
385
- status = 'mcp-only';
386
- }
387
-
388
- return {
389
- projectName: project.name,
390
- displayName: project.displayName,
391
- projectPath,
392
- status,
393
- taskmaster: taskMasterResult,
394
- mcp: mcpResult
395
- };
396
- } catch (error) {
397
- return {
398
- projectName: project.name,
399
- displayName: project.displayName,
400
- status: 'error',
401
- error: error.message
402
- };
403
- }
404
- });
405
-
406
- const results = await Promise.all(detectionPromises);
407
-
408
- res.json({
409
- projects: results,
410
- summary: {
411
- total: results.length,
412
- fullyConfigured: results.filter(p => p.status === 'fully-configured').length,
413
- taskmasterOnly: results.filter(p => p.status === 'taskmaster-only').length,
414
- mcpOnly: results.filter(p => p.status === 'mcp-only').length,
415
- notConfigured: results.filter(p => p.status === 'not-configured').length,
416
- errors: results.filter(p => p.status === 'error').length
417
- },
418
- timestamp: new Date().toISOString()
419
- });
420
-
421
- } catch (error) {
422
- console.error('Bulk TaskMaster detection error:', error);
423
- res.status(500).json({
424
- error: 'Failed to detect TaskMaster configuration for projects',
425
- message: error.message
426
- });
427
- }
428
- });
429
-
430
- /**
431
- * POST /api/taskmaster/initialize/:projectName
432
- * Initialize TaskMaster in a project (placeholder for future CLI integration)
433
- */
434
- router.post('/initialize/:projectName', async (req, res) => {
435
- try {
436
- const { projectName } = req.params;
437
- const { rules } = req.body; // Optional rule profiles
438
-
439
- // This will be implemented in a later subtask with CLI integration
440
- res.status(501).json({
441
- error: 'TaskMaster initialization not yet implemented',
442
- message: 'This endpoint will execute task-master init via CLI in a future update',
443
- projectName,
444
- rules
445
- });
446
-
447
- } catch (error) {
448
- console.error('TaskMaster initialization error:', error);
449
- res.status(500).json({
450
- error: 'Failed to initialize TaskMaster',
451
- message: error.message
452
- });
453
- }
454
- });
455
-
456
- /**
457
- * GET /api/taskmaster/next/:projectName
458
- * Get the next recommended task using task-master CLI
459
- */
460
- router.get('/next/:projectName', async (req, res) => {
461
- try {
462
- const { projectName } = req.params;
463
-
464
- // Get project path
465
- let projectPath;
466
- try {
467
- projectPath = await extractProjectDirectory(projectName);
468
- } catch (error) {
469
- return res.status(404).json({
470
- error: 'Project not found',
471
- message: `Project "${projectName}" does not exist`
472
- });
473
- }
474
-
475
- // Try to execute task-master next command
476
- try {
477
- const { spawn } = await import('child_process');
478
-
479
- const nextTaskCommand = spawn('task-master', ['next'], {
480
- cwd: projectPath,
481
- stdio: ['pipe', 'pipe', 'pipe']
482
- });
483
-
484
- let stdout = '';
485
- let stderr = '';
486
-
487
- nextTaskCommand.stdout.on('data', (data) => {
488
- stdout += data.toString();
489
- });
490
-
491
- nextTaskCommand.stderr.on('data', (data) => {
492
- stderr += data.toString();
493
- });
494
-
495
- await new Promise((resolve, reject) => {
496
- nextTaskCommand.on('close', (code) => {
497
- if (code === 0) {
498
- resolve();
499
- } else {
500
- reject(new Error(`task-master next failed with code ${code}: ${stderr}`));
501
- }
502
- });
503
-
504
- nextTaskCommand.on('error', (error) => {
505
- reject(error);
506
- });
507
- });
508
-
509
- // Parse the output - task-master next usually returns JSON
510
- let nextTaskData = null;
511
- if (stdout.trim()) {
512
- try {
513
- nextTaskData = JSON.parse(stdout);
514
- } catch (parseError) {
515
- // If not JSON, treat as plain text
516
- nextTaskData = { message: stdout.trim() };
517
- }
518
- }
519
-
520
- res.json({
521
- projectName,
522
- projectPath,
523
- nextTask: nextTaskData,
524
- timestamp: new Date().toISOString()
525
- });
526
-
527
- } catch (cliError) {
528
- console.warn('Failed to execute task-master CLI:', cliError.message);
529
-
530
- // Fallback to loading tasks and finding next one locally
531
- // Use localhost to bypass proxy for internal server-to-server calls
532
- const tasksResponse = await fetch(`http://localhost:${process.env.SERVER_PORT || process.env.PORT || '3001'}/api/taskmaster/tasks/${encodeURIComponent(projectName)}`, {
533
- headers: {
534
- 'Authorization': req.headers.authorization
535
- }
536
- });
537
-
538
- if (tasksResponse.ok) {
539
- const tasksData = await tasksResponse.json();
540
- const nextTask = tasksData.tasks?.find(task =>
541
- task.status === 'pending' || task.status === 'in-progress'
542
- ) || null;
543
-
544
- res.json({
545
- projectName,
546
- projectPath,
547
- nextTask,
548
- fallback: true,
549
- message: 'Used fallback method (CLI not available)',
550
- timestamp: new Date().toISOString()
551
- });
552
- } else {
553
- throw new Error('Failed to load tasks via fallback method');
554
- }
555
- }
556
-
557
- } catch (error) {
558
- console.error('TaskMaster next task error:', error);
559
- res.status(500).json({
560
- error: 'Failed to get next task',
561
- message: error.message
562
- });
563
- }
564
- });
565
-
566
- /**
567
- * GET /api/taskmaster/tasks/:projectName
150
+ * GET /api/taskmaster/tasks/:projectId
568
151
  * Load actual tasks from .taskmaster/tasks/tasks.json
152
+ *
153
+ * `projectId` is the DB primary key of the project; the folder is resolved via
154
+ * the projects table rather than extracted from Claude JSONL history.
569
155
  */
570
- router.get('/tasks/:projectName', async (req, res) => {
156
+ router.get('/tasks/:projectId', async (req, res) => {
571
157
  try {
572
- const { projectName } = req.params;
573
-
574
- // Get project path
575
- let projectPath;
576
- try {
577
- projectPath = await extractProjectDirectory(projectName);
578
- } catch (error) {
158
+ const { projectId } = req.params;
159
+
160
+ // Get project path via the DB; the legacy JSONL-based resolver is gone.
161
+ const projectPath = await resolveProjectPathFromId(projectId);
162
+ if (!projectPath) {
579
163
  return res.status(404).json({
580
164
  error: 'Project not found',
581
- message: `Project "${projectName}" does not exist`
165
+ message: `Project "${projectId}" does not exist`
582
166
  });
583
167
  }
584
168
 
@@ -590,7 +174,7 @@ router.get('/tasks/:projectName', async (req, res) => {
590
174
  await fsPromises.access(tasksFilePath);
591
175
  } catch (error) {
592
176
  return res.json({
593
- projectName,
177
+ projectId,
594
178
  tasks: [],
595
179
  message: 'No tasks.json file found'
596
180
  });
@@ -645,7 +229,7 @@ router.get('/tasks/:projectName', async (req, res) => {
645
229
  }));
646
230
 
647
231
  res.json({
648
- projectName,
232
+ projectId,
649
233
  projectPath,
650
234
  tasks: transformedTasks,
651
235
  currentTag,
@@ -679,21 +263,19 @@ router.get('/tasks/:projectName', async (req, res) => {
679
263
  });
680
264
 
681
265
  /**
682
- * GET /api/taskmaster/prd/:projectName
266
+ * GET /api/taskmaster/prd/:projectId
683
267
  * List all PRD files in the project's .taskmaster/docs directory
684
268
  */
685
- router.get('/prd/:projectName', async (req, res) => {
269
+ router.get('/prd/:projectId', async (req, res) => {
686
270
  try {
687
- const { projectName } = req.params;
688
-
689
- // Get project path
690
- let projectPath;
691
- try {
692
- projectPath = await extractProjectDirectory(projectName);
693
- } catch (error) {
271
+ const { projectId } = req.params;
272
+
273
+ // projectId projectPath lookup through the DB (post-migration).
274
+ const projectPath = await resolveProjectPathFromId(projectId);
275
+ if (!projectPath) {
694
276
  return res.status(404).json({
695
277
  error: 'Project not found',
696
- message: `Project "${projectName}" does not exist`
278
+ message: `Project "${projectId}" does not exist`
697
279
  });
698
280
  }
699
281
 
@@ -704,7 +286,7 @@ router.get('/prd/:projectName', async (req, res) => {
704
286
  await fsPromises.access(docsPath, fs.constants.R_OK);
705
287
  } catch (error) {
706
288
  return res.json({
707
- projectName,
289
+ projectId,
708
290
  prdFiles: [],
709
291
  message: 'No .taskmaster/docs directory found'
710
292
  });
@@ -731,7 +313,7 @@ router.get('/prd/:projectName', async (req, res) => {
731
313
  }
732
314
 
733
315
  res.json({
734
- projectName,
316
+ projectId,
735
317
  projectPath,
736
318
  prdFiles: prdFiles.sort((a, b) => new Date(b.modified) - new Date(a.modified)),
737
319
  timestamp: new Date().toISOString()
@@ -755,12 +337,12 @@ router.get('/prd/:projectName', async (req, res) => {
755
337
  });
756
338
 
757
339
  /**
758
- * POST /api/taskmaster/prd/:projectName
340
+ * POST /api/taskmaster/prd/:projectId
759
341
  * Create or update a PRD file in the project's .taskmaster/docs directory
760
342
  */
761
- router.post('/prd/:projectName', async (req, res) => {
343
+ router.post('/prd/:projectId', async (req, res) => {
762
344
  try {
763
- const { projectName } = req.params;
345
+ const { projectId } = req.params;
764
346
  const { fileName, content } = req.body;
765
347
 
766
348
  if (!fileName || !content) {
@@ -778,14 +360,12 @@ router.post('/prd/:projectName', async (req, res) => {
778
360
  });
779
361
  }
780
362
 
781
- // Get project path
782
- let projectPath;
783
- try {
784
- projectPath = await extractProjectDirectory(projectName);
785
- } catch (error) {
363
+ // Resolve the project folder through the DB using the projectId param.
364
+ const projectPath = await resolveProjectPathFromId(projectId);
365
+ if (!projectPath) {
786
366
  return res.status(404).json({
787
367
  error: 'Project not found',
788
- message: `Project "${projectName}" does not exist`
368
+ message: `Project "${projectId}" does not exist`
789
369
  });
790
370
  }
791
371
 
@@ -811,7 +391,7 @@ router.post('/prd/:projectName', async (req, res) => {
811
391
  const stats = await fsPromises.stat(filePath);
812
392
 
813
393
  res.json({
814
- projectName,
394
+ projectId,
815
395
  projectPath,
816
396
  fileName,
817
397
  filePath: path.relative(projectPath, filePath),
@@ -840,21 +420,18 @@ router.post('/prd/:projectName', async (req, res) => {
840
420
  });
841
421
 
842
422
  /**
843
- * GET /api/taskmaster/prd/:projectName/:fileName
423
+ * GET /api/taskmaster/prd/:projectId/:fileName
844
424
  * Get content of a specific PRD file
845
425
  */
846
- router.get('/prd/:projectName/:fileName', async (req, res) => {
426
+ router.get('/prd/:projectId/:fileName', async (req, res) => {
847
427
  try {
848
- const { projectName, fileName } = req.params;
849
-
850
- // Get project path
851
- let projectPath;
852
- try {
853
- projectPath = await extractProjectDirectory(projectName);
854
- } catch (error) {
428
+ const { projectId, fileName } = req.params;
429
+
430
+ const projectPath = await resolveProjectPathFromId(projectId);
431
+ if (!projectPath) {
855
432
  return res.status(404).json({
856
433
  error: 'Project not found',
857
- message: `Project "${projectName}" does not exist`
434
+ message: `Project "${projectId}" does not exist`
858
435
  });
859
436
  }
860
437
 
@@ -876,7 +453,7 @@ router.get('/prd/:projectName/:fileName', async (req, res) => {
876
453
  const stats = await fsPromises.stat(filePath);
877
454
 
878
455
  res.json({
879
- projectName,
456
+ projectId,
880
457
  projectPath,
881
458
  fileName,
882
459
  filePath: path.relative(projectPath, filePath),
@@ -905,81 +482,18 @@ router.get('/prd/:projectName/:fileName', async (req, res) => {
905
482
  });
906
483
 
907
484
  /**
908
- * DELETE /api/taskmaster/prd/:projectName/:fileName
909
- * Delete a specific PRD file
910
- */
911
- router.delete('/prd/:projectName/:fileName', async (req, res) => {
912
- try {
913
- const { projectName, fileName } = req.params;
914
-
915
- // Get project path
916
- let projectPath;
917
- try {
918
- projectPath = await extractProjectDirectory(projectName);
919
- } catch (error) {
920
- return res.status(404).json({
921
- error: 'Project not found',
922
- message: `Project "${projectName}" does not exist`
923
- });
924
- }
925
-
926
- const filePath = path.join(projectPath, '.taskmaster', 'docs', fileName);
927
-
928
- // Check if file exists
929
- try {
930
- await fsPromises.access(filePath, fs.constants.F_OK);
931
- } catch (error) {
932
- return res.status(404).json({
933
- error: 'PRD file not found',
934
- message: `File "${fileName}" does not exist`
935
- });
936
- }
937
-
938
- // Delete the file
939
- try {
940
- await fsPromises.unlink(filePath);
941
-
942
- res.json({
943
- projectName,
944
- projectPath,
945
- fileName,
946
- message: 'PRD file deleted successfully',
947
- timestamp: new Date().toISOString()
948
- });
949
-
950
- } catch (deleteError) {
951
- console.error('Failed to delete PRD file:', deleteError);
952
- return res.status(500).json({
953
- error: 'Failed to delete PRD file',
954
- message: deleteError.message
955
- });
956
- }
957
-
958
- } catch (error) {
959
- console.error('PRD delete error:', error);
960
- res.status(500).json({
961
- error: 'Failed to delete PRD file',
962
- message: error.message
963
- });
964
- }
965
- });
966
-
967
- /**
968
- * POST /api/taskmaster/init/:projectName
485
+ * POST /api/taskmaster/init/:projectId
969
486
  * Initialize TaskMaster in a project
970
487
  */
971
- router.post('/init/:projectName', async (req, res) => {
488
+ router.post('/init/:projectId', async (req, res) => {
972
489
  try {
973
- const { projectName } = req.params;
974
-
975
- // Get project path
976
- let projectPath;
977
- try {
978
- projectPath = await extractProjectDirectory(projectName);
979
- } catch (error) {
490
+ const { projectId } = req.params;
491
+
492
+ const projectPath = await resolveProjectPathFromId(projectId);
493
+ if (!projectPath) {
980
494
  return res.status(404).json({
981
495
  error: 'Project not found',
982
- message: `Project "${projectName}" does not exist`
496
+ message: `Project "${projectId}" does not exist`
983
497
  });
984
498
  }
985
499
 
@@ -1014,17 +528,19 @@ router.post('/init/:projectName', async (req, res) => {
1014
528
 
1015
529
  initProcess.on('close', (code) => {
1016
530
  if (code === 0) {
1017
- // Broadcast TaskMaster project update via WebSocket
531
+ // Broadcast TaskMaster project update via WebSocket. The
532
+ // WebSocket payload keeps using `projectId` so the frontend
533
+ // can match notifications against the current selection.
1018
534
  if (req.app.locals.wss) {
1019
535
  broadcastTaskMasterProjectUpdate(
1020
- req.app.locals.wss,
1021
- projectName,
536
+ req.app.locals.wss,
537
+ projectId,
1022
538
  { hasTaskmaster: true, status: 'initialized' }
1023
539
  );
1024
540
  }
1025
541
 
1026
542
  res.json({
1027
- projectName,
543
+ projectId,
1028
544
  projectPath,
1029
545
  message: 'TaskMaster initialized successfully',
1030
546
  output: stdout,
@@ -1054,12 +570,12 @@ router.post('/init/:projectName', async (req, res) => {
1054
570
  });
1055
571
 
1056
572
  /**
1057
- * POST /api/taskmaster/add-task/:projectName
573
+ * POST /api/taskmaster/add-task/:projectId
1058
574
  * Add a new task to the project
1059
575
  */
1060
- router.post('/add-task/:projectName', async (req, res) => {
576
+ router.post('/add-task/:projectId', async (req, res) => {
1061
577
  try {
1062
- const { projectName } = req.params;
578
+ const { projectId } = req.params;
1063
579
  const { prompt, title, description, priority = 'medium', dependencies } = req.body;
1064
580
 
1065
581
  if (!prompt && (!title || !description)) {
@@ -1068,15 +584,12 @@ router.post('/add-task/:projectName', async (req, res) => {
1068
584
  message: 'Either "prompt" or both "title" and "description" are required'
1069
585
  });
1070
586
  }
1071
-
1072
- // Get project path
1073
- let projectPath;
1074
- try {
1075
- projectPath = await extractProjectDirectory(projectName);
1076
- } catch (error) {
587
+
588
+ const projectPath = await resolveProjectPathFromId(projectId);
589
+ if (!projectPath) {
1077
590
  return res.status(404).json({
1078
591
  error: 'Project not found',
1079
- message: `Project "${projectName}" does not exist`
592
+ message: `Project "${projectId}" does not exist`
1080
593
  });
1081
594
  }
1082
595
 
@@ -1121,16 +634,17 @@ router.post('/add-task/:projectName', async (req, res) => {
1121
634
  console.log('Stderr:', stderr);
1122
635
 
1123
636
  if (code === 0) {
1124
- // Broadcast task update via WebSocket
637
+ // Broadcast task update via WebSocket using the projectId so
638
+ // clients subscribed to this project get notified immediately.
1125
639
  if (req.app.locals.wss) {
1126
640
  broadcastTaskMasterTasksUpdate(
1127
- req.app.locals.wss,
1128
- projectName
641
+ req.app.locals.wss,
642
+ projectId
1129
643
  );
1130
644
  }
1131
645
 
1132
646
  res.json({
1133
- projectName,
647
+ projectId,
1134
648
  projectPath,
1135
649
  message: 'Task added successfully',
1136
650
  output: stdout,
@@ -1158,22 +672,19 @@ router.post('/add-task/:projectName', async (req, res) => {
1158
672
  });
1159
673
 
1160
674
  /**
1161
- * PUT /api/taskmaster/update-task/:projectName/:taskId
675
+ * PUT /api/taskmaster/update-task/:projectId/:taskId
1162
676
  * Update a specific task using TaskMaster CLI
1163
677
  */
1164
- router.put('/update-task/:projectName/:taskId', async (req, res) => {
678
+ router.put('/update-task/:projectId/:taskId', async (req, res) => {
1165
679
  try {
1166
- const { projectName, taskId } = req.params;
680
+ const { projectId, taskId } = req.params;
1167
681
  const { title, description, status, priority, details } = req.body;
1168
-
1169
- // Get project path
1170
- let projectPath;
1171
- try {
1172
- projectPath = await extractProjectDirectory(projectName);
1173
- } catch (error) {
682
+
683
+ const projectPath = await resolveProjectPathFromId(projectId);
684
+ if (!projectPath) {
1174
685
  return res.status(404).json({
1175
686
  error: 'Project not found',
1176
- message: `Project "${projectName}" does not exist`
687
+ message: `Project "${projectId}" does not exist`
1177
688
  });
1178
689
  }
1179
690
 
@@ -1199,11 +710,11 @@ router.put('/update-task/:projectName/:taskId', async (req, res) => {
1199
710
  if (code === 0) {
1200
711
  // Broadcast task update via WebSocket
1201
712
  if (req.app.locals.wss) {
1202
- broadcastTaskMasterTasksUpdate(req.app.locals.wss, projectName);
713
+ broadcastTaskMasterTasksUpdate(req.app.locals.wss, projectId);
1203
714
  }
1204
715
 
1205
716
  res.json({
1206
- projectName,
717
+ projectId,
1207
718
  projectPath,
1208
719
  taskId,
1209
720
  message: 'Task status updated successfully',
@@ -1251,11 +762,11 @@ router.put('/update-task/:projectName/:taskId', async (req, res) => {
1251
762
  if (code === 0) {
1252
763
  // Broadcast task update via WebSocket
1253
764
  if (req.app.locals.wss) {
1254
- broadcastTaskMasterTasksUpdate(req.app.locals.wss, projectName);
765
+ broadcastTaskMasterTasksUpdate(req.app.locals.wss, projectId);
1255
766
  }
1256
767
 
1257
768
  res.json({
1258
- projectName,
769
+ projectId,
1259
770
  projectPath,
1260
771
  taskId,
1261
772
  message: 'Task updated successfully',
@@ -1285,22 +796,19 @@ router.put('/update-task/:projectName/:taskId', async (req, res) => {
1285
796
  });
1286
797
 
1287
798
  /**
1288
- * POST /api/taskmaster/parse-prd/:projectName
799
+ * POST /api/taskmaster/parse-prd/:projectId
1289
800
  * Parse a PRD file to generate tasks
1290
801
  */
1291
- router.post('/parse-prd/:projectName', async (req, res) => {
802
+ router.post('/parse-prd/:projectId', async (req, res) => {
1292
803
  try {
1293
- const { projectName } = req.params;
804
+ const { projectId } = req.params;
1294
805
  const { fileName = 'prd.txt', numTasks, append = false } = req.body;
1295
-
1296
- // Get project path
1297
- let projectPath;
1298
- try {
1299
- projectPath = await extractProjectDirectory(projectName);
1300
- } catch (error) {
806
+
807
+ const projectPath = await resolveProjectPathFromId(projectId);
808
+ if (!projectPath) {
1301
809
  return res.status(404).json({
1302
810
  error: 'Project not found',
1303
- message: `Project "${projectName}" does not exist`
811
+ message: `Project "${projectId}" does not exist`
1304
812
  });
1305
813
  }
1306
814
 
@@ -1351,13 +859,13 @@ router.post('/parse-prd/:projectName', async (req, res) => {
1351
859
  // Broadcast task update via WebSocket
1352
860
  if (req.app.locals.wss) {
1353
861
  broadcastTaskMasterTasksUpdate(
1354
- req.app.locals.wss,
1355
- projectName
862
+ req.app.locals.wss,
863
+ projectId
1356
864
  );
1357
865
  }
1358
866
 
1359
867
  res.json({
1360
- projectName,
868
+ projectId,
1361
869
  projectPath,
1362
870
  prdFile: fileName,
1363
871
  message: 'PRD parsed and tasks generated successfully',
@@ -1832,12 +1340,12 @@ Description of the business problem, data sources, and expected insights.
1832
1340
  });
1833
1341
 
1834
1342
  /**
1835
- * POST /api/taskmaster/apply-template/:projectName
1343
+ * POST /api/taskmaster/apply-template/:projectId
1836
1344
  * Apply a PRD template to create a new PRD file
1837
1345
  */
1838
- router.post('/apply-template/:projectName', async (req, res) => {
1346
+ router.post('/apply-template/:projectId', async (req, res) => {
1839
1347
  try {
1840
- const { projectName } = req.params;
1348
+ const { projectId } = req.params;
1841
1349
  const { templateId, fileName = 'prd.txt', customizations = {} } = req.body;
1842
1350
 
1843
1351
  if (!templateId) {
@@ -1847,14 +1355,11 @@ router.post('/apply-template/:projectName', async (req, res) => {
1847
1355
  });
1848
1356
  }
1849
1357
 
1850
- // Get project path
1851
- let projectPath;
1852
- try {
1853
- projectPath = await extractProjectDirectory(projectName);
1854
- } catch (error) {
1358
+ const projectPath = await resolveProjectPathFromId(projectId);
1359
+ if (!projectPath) {
1855
1360
  return res.status(404).json({
1856
1361
  error: 'Project not found',
1857
- message: `Project "${projectName}" does not exist`
1362
+ message: `Project "${projectId}" does not exist`
1858
1363
  });
1859
1364
  }
1860
1365
 
@@ -1893,7 +1398,7 @@ router.post('/apply-template/:projectName', async (req, res) => {
1893
1398
  await fsPromises.writeFile(filePath, content, 'utf8');
1894
1399
 
1895
1400
  res.json({
1896
- projectName,
1401
+ projectId,
1897
1402
  projectPath,
1898
1403
  templateId,
1899
1404
  templateName: template.name,