@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,117 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+
4
+ import { createProject } from '@/modules/projects/services/project-management.service.js';
5
+ import { AppError } from '@/shared/utils.js';
6
+
7
+ const projectRow = {
8
+ project_id: 'project-1',
9
+ project_path: '/workspace/my-project',
10
+ custom_project_name: 'my-project',
11
+ isStarred: 0,
12
+ isArchived: 0,
13
+ };
14
+
15
+ test('createProject throws when project path is missing', async () => {
16
+ await assert.rejects(
17
+ async () => createProject({ projectPath: '' }),
18
+ (error: unknown) => {
19
+ assert.ok(error instanceof AppError);
20
+ assert.equal(error.code, 'PROJECT_PATH_REQUIRED');
21
+ assert.equal(error.statusCode, 400);
22
+ return true;
23
+ },
24
+ );
25
+ });
26
+
27
+ test('createProject throws when path validation fails', async () => {
28
+ await assert.rejects(
29
+ async () =>
30
+ createProject(
31
+ { projectPath: '/invalid/path' },
32
+ {
33
+ validatePath: async () => ({ valid: false, error: 'blocked path' }),
34
+ ensureWorkspaceDirectory: async () => undefined,
35
+ persistProjectPath: () => ({ outcome: 'created', project: projectRow }),
36
+ getProjectByPath: () => projectRow,
37
+ },
38
+ ),
39
+ (error: unknown) => {
40
+ assert.ok(error instanceof AppError);
41
+ assert.equal(error.code, 'INVALID_PROJECT_PATH');
42
+ assert.equal(error.statusCode, 400);
43
+ assert.equal(error.details, 'blocked path');
44
+ return true;
45
+ },
46
+ );
47
+ });
48
+
49
+ test('createProject throws conflict when active project path already exists', async () => {
50
+ await assert.rejects(
51
+ async () =>
52
+ createProject(
53
+ { projectPath: '/workspace/my-project' },
54
+ {
55
+ validatePath: async () => ({ valid: true, resolvedPath: '/workspace/my-project' }),
56
+ ensureWorkspaceDirectory: async () => undefined,
57
+ persistProjectPath: () => ({ outcome: 'active_conflict', project: projectRow }),
58
+ getProjectByPath: () => projectRow,
59
+ },
60
+ ),
61
+ (error: unknown) => {
62
+ assert.ok(error instanceof AppError);
63
+ assert.equal(error.code, 'PROJECT_ALREADY_EXISTS');
64
+ assert.equal(error.statusCode, 409);
65
+ assert.equal(error.details, 'Project path already exists: /workspace/my-project');
66
+ return true;
67
+ },
68
+ );
69
+ });
70
+
71
+ test('createProject falls back to directory name when custom name is not provided', async () => {
72
+ let capturedCustomName: string | null = null;
73
+
74
+ const result = await createProject(
75
+ { projectPath: '/workspace/my-project', customName: '' },
76
+ {
77
+ validatePath: async () => ({ valid: true, resolvedPath: '/workspace/my-project' }),
78
+ ensureWorkspaceDirectory: async () => undefined,
79
+ persistProjectPath: (_projectPath, customName) => {
80
+ capturedCustomName = customName;
81
+ return {
82
+ outcome: 'created',
83
+ project: {
84
+ ...projectRow,
85
+ custom_project_name: customName,
86
+ },
87
+ };
88
+ },
89
+ getProjectByPath: () => projectRow,
90
+ },
91
+ );
92
+
93
+ assert.equal(capturedCustomName, 'my-project');
94
+ assert.equal(result.outcome, 'created');
95
+ assert.equal(result.project.displayName, 'my-project');
96
+ });
97
+
98
+ test('createProject returns archived reuse outcome when archived row is reused', async () => {
99
+ const result = await createProject(
100
+ { projectPath: '/workspace/my-project' },
101
+ {
102
+ validatePath: async () => ({ valid: true, resolvedPath: '/workspace/my-project' }),
103
+ ensureWorkspaceDirectory: async () => undefined,
104
+ persistProjectPath: () => ({
105
+ outcome: 'reactivated_archived',
106
+ project: {
107
+ ...projectRow,
108
+ isArchived: 1,
109
+ },
110
+ }),
111
+ getProjectByPath: () => projectRow,
112
+ },
113
+ );
114
+
115
+ assert.equal(result.outcome, 'reactivated_archived');
116
+ assert.equal(result.project.isArchived, true);
117
+ });
@@ -0,0 +1,123 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+
4
+ import { projectsDb } from '@/modules/database/index.js';
5
+ import { applyLegacyStarredProjectIds, toggleProjectStar } from '@/modules/projects/services/project-star.service.js';
6
+ import { AppError } from '@/shared/utils.js';
7
+
8
+ type ProjectRow = {
9
+ project_id: string;
10
+ project_path: string;
11
+ custom_project_name: string | null;
12
+ isStarred: number;
13
+ isArchived: number;
14
+ };
15
+
16
+ test('toggleProjectStar throws when projectId is missing', () => {
17
+ assert.throws(
18
+ () => toggleProjectStar(' '),
19
+ (error: unknown) =>
20
+ error instanceof AppError
21
+ && error.code === 'PROJECT_ID_REQUIRED'
22
+ && error.statusCode === 400,
23
+ );
24
+ });
25
+
26
+ test('toggleProjectStar throws when project does not exist', () => {
27
+ const originalGetProjectById = projectsDb.getProjectById;
28
+ try {
29
+ projectsDb.getProjectById = () => null;
30
+ assert.throws(
31
+ () => toggleProjectStar('project-1'),
32
+ (error: unknown) =>
33
+ error instanceof AppError
34
+ && error.code === 'PROJECT_NOT_FOUND'
35
+ && error.statusCode === 404,
36
+ );
37
+ } finally {
38
+ projectsDb.getProjectById = originalGetProjectById;
39
+ }
40
+ });
41
+
42
+ test('toggleProjectStar flips star state and persists it', () => {
43
+ const originalGetProjectById = projectsDb.getProjectById;
44
+ const originalUpdateProjectIsStarredById = projectsDb.updateProjectIsStarredById;
45
+
46
+ let capturedProjectId = '';
47
+ let capturedState = false;
48
+
49
+ try {
50
+ projectsDb.getProjectById = () =>
51
+ ({
52
+ project_id: 'project-1',
53
+ project_path: '/workspace/project-1',
54
+ custom_project_name: 'project-1',
55
+ isStarred: 0,
56
+ isArchived: 0,
57
+ }) as ProjectRow;
58
+ projectsDb.updateProjectIsStarredById = (projectId: string, isStarred: boolean) => {
59
+ capturedProjectId = projectId;
60
+ capturedState = isStarred;
61
+ };
62
+
63
+ const result = toggleProjectStar('project-1');
64
+
65
+ assert.equal(result.isStarred, true);
66
+ assert.equal(capturedProjectId, 'project-1');
67
+ assert.equal(capturedState, true);
68
+ } finally {
69
+ projectsDb.getProjectById = originalGetProjectById;
70
+ projectsDb.updateProjectIsStarredById = originalUpdateProjectIsStarredById;
71
+ }
72
+ });
73
+
74
+ test('applyLegacyStarredProjectIds stars only valid, unstarred projects', () => {
75
+ const originalGetProjectById = projectsDb.getProjectById;
76
+ const originalUpdateProjectIsStarredById = projectsDb.updateProjectIsStarredById;
77
+
78
+ const updatedProjectIds: string[] = [];
79
+
80
+ try {
81
+ projectsDb.getProjectById = (projectId: string) => {
82
+ if (projectId === 'project-a') {
83
+ return {
84
+ project_id: 'project-a',
85
+ project_path: '/workspace/project-a',
86
+ custom_project_name: 'A',
87
+ isStarred: 0,
88
+ isArchived: 0,
89
+ } as ProjectRow;
90
+ }
91
+
92
+ if (projectId === 'project-b') {
93
+ return {
94
+ project_id: 'project-b',
95
+ project_path: '/workspace/project-b',
96
+ custom_project_name: 'B',
97
+ isStarred: 1,
98
+ isArchived: 0,
99
+ } as ProjectRow;
100
+ }
101
+
102
+ return null;
103
+ };
104
+ projectsDb.updateProjectIsStarredById = (projectId: string) => {
105
+ updatedProjectIds.push(projectId);
106
+ };
107
+
108
+ const result = applyLegacyStarredProjectIds([
109
+ 'project-a',
110
+ 'project-b',
111
+ 'missing-project',
112
+ 'project-a',
113
+ '',
114
+ ' ',
115
+ ]);
116
+
117
+ assert.equal(result.updated, 1);
118
+ assert.deepEqual(updatedProjectIds, ['project-a']);
119
+ } finally {
120
+ projectsDb.getProjectById = originalGetProjectById;
121
+ projectsDb.updateProjectIsStarredById = originalUpdateProjectIsStarredById;
122
+ }
123
+ });
@@ -0,0 +1,105 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+
4
+ import {
5
+ getProjectTaskMaster,
6
+ getProjectTaskMasterById,
7
+ } from '@/modules/projects/services/projects-has-taskmaster.service.js';
8
+ import { AppError } from '@/shared/utils.js';
9
+
10
+ test('getProjectTaskMasterById returns null when project path is missing', async () => {
11
+ const result = await getProjectTaskMasterById('project-1', {
12
+ resolveProjectPathById: () => null,
13
+ detectTaskMasterFolder: async () => {
14
+ throw new Error('detectTaskMasterFolder should not be called when path is missing');
15
+ },
16
+ });
17
+
18
+ assert.equal(result, null);
19
+ });
20
+
21
+ test('getProjectTaskMasterById returns configured status when taskmaster exists with essential files', async () => {
22
+ const result = await getProjectTaskMasterById('project-1', {
23
+ resolveProjectPathById: () => '/workspace/project-1',
24
+ detectTaskMasterFolder: async () => ({
25
+ hasTaskmaster: true,
26
+ hasEssentialFiles: true,
27
+ metadata: {
28
+ taskCount: 3,
29
+ subtaskCount: 0,
30
+ completed: 1,
31
+ pending: 2,
32
+ inProgress: 0,
33
+ review: 0,
34
+ completionPercentage: 33,
35
+ lastModified: '2026-01-01T00:00:00.000Z',
36
+ },
37
+ }),
38
+ });
39
+
40
+ assert.ok(result);
41
+ assert.equal(result.projectId, 'project-1');
42
+ assert.equal(result.projectPath, '/workspace/project-1');
43
+ assert.equal(result.taskmaster.hasTaskmaster, true);
44
+ assert.equal(result.taskmaster.hasEssentialFiles, true);
45
+ assert.equal(result.taskmaster.status, 'configured');
46
+ assert.deepEqual(result.taskmaster.metadata, {
47
+ taskCount: 3,
48
+ subtaskCount: 0,
49
+ completed: 1,
50
+ pending: 2,
51
+ inProgress: 0,
52
+ review: 0,
53
+ completionPercentage: 33,
54
+ lastModified: '2026-01-01T00:00:00.000Z',
55
+ });
56
+ });
57
+
58
+ test('getProjectTaskMasterById returns not-configured status when taskmaster is missing', async () => {
59
+ const result = await getProjectTaskMasterById('project-1', {
60
+ resolveProjectPathById: () => '/workspace/project-1',
61
+ detectTaskMasterFolder: async () => ({
62
+ hasTaskmaster: false,
63
+ }),
64
+ });
65
+
66
+ assert.ok(result);
67
+ assert.equal(result.taskmaster.hasTaskmaster, false);
68
+ assert.equal(result.taskmaster.hasEssentialFiles, false);
69
+ assert.equal(result.taskmaster.status, 'not-configured');
70
+ assert.equal(result.taskmaster.metadata, null);
71
+ });
72
+
73
+ test('getProjectTaskMaster throws when project id is missing', async () => {
74
+ await assert.rejects(
75
+ async () =>
76
+ getProjectTaskMaster('', async () => ({
77
+ projectId: 'project-1',
78
+ projectPath: '/workspace/project-1',
79
+ taskmaster: {
80
+ hasTaskmaster: true,
81
+ hasEssentialFiles: true,
82
+ metadata: null,
83
+ status: 'configured',
84
+ },
85
+ })),
86
+ (error: unknown) => {
87
+ assert.ok(error instanceof AppError);
88
+ assert.equal(error.code, 'PROJECT_ID_REQUIRED');
89
+ assert.equal(error.statusCode, 400);
90
+ return true;
91
+ },
92
+ );
93
+ });
94
+
95
+ test('getProjectTaskMaster throws when project does not exist', async () => {
96
+ await assert.rejects(
97
+ async () => getProjectTaskMaster('project-that-does-not-exist', async () => null),
98
+ (error: unknown) => {
99
+ assert.ok(error instanceof AppError);
100
+ assert.equal(error.code, 'PROJECT_NOT_FOUND');
101
+ assert.equal(error.statusCode, 404);
102
+ return true;
103
+ },
104
+ );
105
+ });
@@ -0,0 +1,4 @@
1
+ export { sessionSynchronizerService } from './services/session-synchronizer.service.js';
2
+
3
+ export { initializeSessionsWatcher } from './services/sessions-watcher.service.js';
4
+ export { closeSessionsWatcher } from './services/sessions-watcher.service.js';
@@ -0,0 +1,123 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+
5
+ import spawn from 'cross-spawn';
6
+
7
+ import type { IProviderAuth } from '@/shared/interfaces.js';
8
+ import type { ProviderAuthStatus } from '@/shared/types.js';
9
+ import { readObjectRecord, readOptionalString } from '@/shared/utils.js';
10
+
11
+ type ClaudeCredentialsStatus = {
12
+ authenticated: boolean;
13
+ email: string | null;
14
+ method: string | null;
15
+ error?: string;
16
+ };
17
+
18
+ export class ClaudeProviderAuth implements IProviderAuth {
19
+ /**
20
+ * Checks whether the Claude Code CLI is available on this host.
21
+ */
22
+ private checkInstalled(): boolean {
23
+ const cliPath = process.env.CLAUDE_CLI_PATH || 'claude';
24
+ try {
25
+ spawn.sync(cliPath, ['--version'], { stdio: 'ignore', timeout: 5000 });
26
+ return true;
27
+ } catch {
28
+ return false;
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Returns Claude installation and credential status using Claude Code's auth priority.
34
+ */
35
+ async getStatus(): Promise<ProviderAuthStatus> {
36
+ const installed = this.checkInstalled();
37
+
38
+ if (!installed) {
39
+ return {
40
+ installed,
41
+ provider: 'claude',
42
+ authenticated: false,
43
+ email: null,
44
+ method: null,
45
+ error: 'Claude Code CLI is not installed',
46
+ };
47
+ }
48
+
49
+ const credentials = await this.checkCredentials();
50
+
51
+ return {
52
+ installed,
53
+ provider: 'claude',
54
+ authenticated: credentials.authenticated,
55
+ email: credentials.authenticated ? credentials.email || 'Authenticated' : credentials.email,
56
+ method: credentials.method,
57
+ error: credentials.authenticated ? undefined : credentials.error || 'Not authenticated',
58
+ };
59
+ }
60
+
61
+ /**
62
+ * Reads Claude settings env values that the CLI can use even when the server process env is empty.
63
+ */
64
+ private async loadSettingsEnv(): Promise<Record<string, unknown>> {
65
+ try {
66
+ const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
67
+ const content = await readFile(settingsPath, 'utf8');
68
+ const settings = readObjectRecord(JSON.parse(content));
69
+ return readObjectRecord(settings?.env) ?? {};
70
+ } catch {
71
+ return {};
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Checks Claude credentials in the same priority order used by Claude Code.
77
+ */
78
+ private async checkCredentials(): Promise<ClaudeCredentialsStatus> {
79
+ if (process.env.ANTHROPIC_API_KEY?.trim()) {
80
+ return { authenticated: true, email: 'API Key Auth', method: 'api_key' };
81
+ }
82
+
83
+ const settingsEnv = await this.loadSettingsEnv();
84
+ if (readOptionalString(settingsEnv.ANTHROPIC_API_KEY)) {
85
+ return { authenticated: true, email: 'API Key Auth', method: 'api_key' };
86
+ }
87
+
88
+ if (readOptionalString(settingsEnv.ANTHROPIC_AUTH_TOKEN)) {
89
+ return { authenticated: true, email: 'Configured via settings.json', method: 'api_key' };
90
+ }
91
+
92
+ try {
93
+ const credPath = path.join(os.homedir(), '.claude', '.credentials.json');
94
+ const content = await readFile(credPath, 'utf8');
95
+ const creds = readObjectRecord(JSON.parse(content)) ?? {};
96
+ const oauth = readObjectRecord(creds.claudeAiOauth);
97
+ const accessToken = readOptionalString(oauth?.accessToken);
98
+
99
+ if (accessToken) {
100
+ const expiresAt = typeof oauth?.expiresAt === 'number' ? oauth.expiresAt : undefined;
101
+ const email = readOptionalString(creds.email) ?? readOptionalString(creds.user) ?? null;
102
+ if (!expiresAt || Date.now() < expiresAt) {
103
+ return {
104
+ authenticated: true,
105
+ email,
106
+ method: 'credentials_file',
107
+ };
108
+ }
109
+
110
+ return {
111
+ authenticated: false,
112
+ email,
113
+ method: 'credentials_file',
114
+ error: 'OAuth token has expired. Please re-authenticate with claude login',
115
+ };
116
+ }
117
+
118
+ return { authenticated: false, email: null, method: null };
119
+ } catch {
120
+ return { authenticated: false, email: null, method: null };
121
+ }
122
+ }
123
+ }
@@ -0,0 +1,135 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+
4
+ import { McpProvider } from '@/modules/providers/shared/mcp/mcp.provider.js';
5
+ import type { McpScope, ProviderMcpServer, UpsertProviderMcpServerInput } from '@/shared/types.js';
6
+ import {
7
+ AppError,
8
+ readJsonConfig,
9
+ readObjectRecord,
10
+ readOptionalString,
11
+ readStringArray,
12
+ readStringRecord,
13
+ writeJsonConfig,
14
+ } from '@/shared/utils.js';
15
+
16
+ export class ClaudeMcpProvider extends McpProvider {
17
+ constructor() {
18
+ super('claude', ['user', 'local', 'project'], ['stdio', 'http', 'sse']);
19
+ }
20
+
21
+ protected async readScopedServers(scope: McpScope, workspacePath: string): Promise<Record<string, unknown>> {
22
+ if (scope === 'project') {
23
+ const filePath = path.join(workspacePath, '.mcp.json');
24
+ const config = await readJsonConfig(filePath);
25
+ return readObjectRecord(config.mcpServers) ?? {};
26
+ }
27
+
28
+ const filePath = path.join(os.homedir(), '.claude.json');
29
+ const config = await readJsonConfig(filePath);
30
+ if (scope === 'user') {
31
+ return readObjectRecord(config.mcpServers) ?? {};
32
+ }
33
+
34
+ const projects = readObjectRecord(config.projects) ?? {};
35
+ const projectConfig = readObjectRecord(projects[workspacePath]) ?? {};
36
+ return readObjectRecord(projectConfig.mcpServers) ?? {};
37
+ }
38
+
39
+ protected async writeScopedServers(
40
+ scope: McpScope,
41
+ workspacePath: string,
42
+ servers: Record<string, unknown>,
43
+ ): Promise<void> {
44
+ if (scope === 'project') {
45
+ const filePath = path.join(workspacePath, '.mcp.json');
46
+ const config = await readJsonConfig(filePath);
47
+ config.mcpServers = servers;
48
+ await writeJsonConfig(filePath, config);
49
+ return;
50
+ }
51
+
52
+ const filePath = path.join(os.homedir(), '.claude.json');
53
+ const config = await readJsonConfig(filePath);
54
+ if (scope === 'user') {
55
+ config.mcpServers = servers;
56
+ await writeJsonConfig(filePath, config);
57
+ return;
58
+ }
59
+
60
+ const projects = readObjectRecord(config.projects) ?? {};
61
+ const projectConfig = readObjectRecord(projects[workspacePath]) ?? {};
62
+ projectConfig.mcpServers = servers;
63
+ projects[workspacePath] = projectConfig;
64
+ config.projects = projects;
65
+ await writeJsonConfig(filePath, config);
66
+ }
67
+
68
+ protected buildServerConfig(input: UpsertProviderMcpServerInput): Record<string, unknown> {
69
+ if (input.transport === 'stdio') {
70
+ if (!input.command?.trim()) {
71
+ throw new AppError('command is required for stdio MCP servers.', {
72
+ code: 'MCP_COMMAND_REQUIRED',
73
+ statusCode: 400,
74
+ });
75
+ }
76
+
77
+ return {
78
+ type: 'stdio',
79
+ command: input.command,
80
+ args: input.args ?? [],
81
+ env: input.env ?? {},
82
+ };
83
+ }
84
+
85
+ if (!input.url?.trim()) {
86
+ throw new AppError('url is required for http/sse MCP servers.', {
87
+ code: 'MCP_URL_REQUIRED',
88
+ statusCode: 400,
89
+ });
90
+ }
91
+
92
+ return {
93
+ type: input.transport,
94
+ url: input.url,
95
+ headers: input.headers ?? {},
96
+ };
97
+ }
98
+
99
+ protected normalizeServerConfig(
100
+ scope: McpScope,
101
+ name: string,
102
+ rawConfig: unknown,
103
+ ): ProviderMcpServer | null {
104
+ if (!rawConfig || typeof rawConfig !== 'object') {
105
+ return null;
106
+ }
107
+
108
+ const config = rawConfig as Record<string, unknown>;
109
+ if (typeof config.command === 'string') {
110
+ return {
111
+ provider: 'claude',
112
+ name,
113
+ scope,
114
+ transport: 'stdio',
115
+ command: config.command,
116
+ args: readStringArray(config.args),
117
+ env: readStringRecord(config.env),
118
+ };
119
+ }
120
+
121
+ if (typeof config.url === 'string') {
122
+ const transport = readOptionalString(config.type) === 'sse' ? 'sse' : 'http';
123
+ return {
124
+ provider: 'claude',
125
+ name,
126
+ scope,
127
+ transport,
128
+ url: config.url,
129
+ headers: readStringRecord(config.headers),
130
+ };
131
+ }
132
+
133
+ return null;
134
+ }
135
+ }