@cloudcli-ai/cloudcli 1.36.3 → 1.37.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (569) hide show
  1. package/dist/assets/index-D3jfzuKN.css +32 -0
  2. package/dist/assets/index-DTMWjJj8.js +1550 -0
  3. package/dist/index.html +2 -2
  4. package/dist-server/server/constants/config.js.map +1 -1
  5. package/dist-server/server/index.js +73 -1224
  6. package/dist-server/server/index.js.map +1 -1
  7. package/dist-server/server/load-env.js +17 -4
  8. package/dist-server/server/load-env.js.map +1 -1
  9. package/dist-server/server/modules/agent/agent.module.js +37 -0
  10. package/dist-server/server/modules/agent/agent.module.js.map +1 -0
  11. package/dist-server/server/modules/agent/agent.routes.js +1161 -0
  12. package/dist-server/server/modules/agent/agent.routes.js.map +1 -0
  13. package/dist-server/server/modules/agent/index.js +3 -0
  14. package/dist-server/server/modules/agent/index.js.map +1 -0
  15. package/dist-server/server/modules/agent/tests/agent.routes.test.js +176 -0
  16. package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -0
  17. package/dist-server/server/modules/assets/assets.routes.js +56 -15
  18. package/dist-server/server/modules/assets/assets.routes.js.map +1 -1
  19. package/dist-server/server/modules/assets/index.js +2 -2
  20. package/dist-server/server/modules/assets/index.js.map +1 -1
  21. package/dist-server/server/modules/assets/services/image-assets.service.js +39 -1
  22. package/dist-server/server/modules/assets/services/image-assets.service.js.map +1 -1
  23. package/dist-server/server/modules/assets/tests/image-assets.service.test.js +21 -1
  24. package/dist-server/server/modules/assets/tests/image-assets.service.test.js.map +1 -1
  25. package/dist-server/server/{middleware/auth.js → modules/auth/auth.middleware.js} +30 -8
  26. package/dist-server/server/modules/auth/auth.middleware.js.map +1 -0
  27. package/dist-server/server/modules/auth/auth.module.js +29 -0
  28. package/dist-server/server/modules/auth/auth.module.js.map +1 -0
  29. package/dist-server/server/modules/auth/auth.routes.js +45 -0
  30. package/dist-server/server/modules/auth/auth.routes.js.map +1 -0
  31. package/dist-server/server/modules/auth/auth.service.js +113 -0
  32. package/dist-server/server/modules/auth/auth.service.js.map +1 -0
  33. package/dist-server/server/modules/auth/index.js +9 -0
  34. package/dist-server/server/modules/auth/index.js.map +1 -0
  35. package/dist-server/server/modules/auth/tests/auth.service.test.js +80 -0
  36. package/dist-server/server/modules/auth/tests/auth.service.test.js.map +1 -0
  37. package/dist-server/server/{browser-use-mcp.js → modules/browser-use/browser-use-mcp.js} +3 -1
  38. package/dist-server/server/modules/browser-use/browser-use-mcp.js.map +1 -0
  39. package/dist-server/server/modules/browser-use/browser-use.service.js +3 -4
  40. package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
  41. package/dist-server/server/modules/browser-use/index.js +9 -0
  42. package/dist-server/server/modules/browser-use/index.js.map +1 -0
  43. package/dist-server/server/modules/cli/cli.js +11 -0
  44. package/dist-server/server/modules/cli/cli.js.map +1 -0
  45. package/dist-server/server/modules/cli/cli.module.js +86 -0
  46. package/dist-server/server/modules/cli/cli.module.js.map +1 -0
  47. package/dist-server/server/modules/cli/cli.service.js +244 -0
  48. package/dist-server/server/modules/cli/cli.service.js.map +1 -0
  49. package/dist-server/server/modules/cli/index.js +3 -0
  50. package/dist-server/server/modules/cli/index.js.map +1 -0
  51. package/dist-server/server/modules/cli/sandbox.service.js +332 -0
  52. package/dist-server/server/modules/cli/sandbox.service.js.map +1 -0
  53. package/dist-server/server/modules/cli/tests/cli.service.test.js +78 -0
  54. package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -0
  55. package/dist-server/server/modules/cli/tests/sandbox.service.test.js +55 -0
  56. package/dist-server/server/modules/cli/tests/sandbox.service.test.js.map +1 -0
  57. package/dist-server/server/modules/commands/commands.module.js +20 -0
  58. package/dist-server/server/modules/commands/commands.module.js.map +1 -0
  59. package/dist-server/server/modules/commands/commands.routes.js +497 -0
  60. package/dist-server/server/modules/commands/commands.routes.js.map +1 -0
  61. package/dist-server/server/modules/commands/index.js +3 -0
  62. package/dist-server/server/modules/commands/index.js.map +1 -0
  63. package/dist-server/server/modules/commands/tests/commands.test.js +91 -0
  64. package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -0
  65. package/dist-server/server/modules/database/index.js +3 -0
  66. package/dist-server/server/modules/database/index.js.map +1 -1
  67. package/dist-server/server/modules/database/migrations.js +31 -1
  68. package/dist-server/server/modules/database/migrations.js.map +1 -1
  69. package/dist-server/server/modules/database/repositories/provider-models.js +112 -0
  70. package/dist-server/server/modules/database/repositories/provider-models.js.map +1 -0
  71. package/dist-server/server/modules/database/repositories/sessions.db.js +76 -7
  72. package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
  73. package/dist-server/server/modules/database/schema.js +29 -0
  74. package/dist-server/server/modules/database/schema.js.map +1 -1
  75. package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js +102 -0
  76. package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js.map +1 -0
  77. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +2 -1
  78. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js.map +1 -1
  79. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js +22 -0
  80. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -1
  81. package/dist-server/server/modules/file-tree/file-tree.module.js +95 -0
  82. package/dist-server/server/modules/file-tree/file-tree.module.js.map +1 -0
  83. package/dist-server/server/modules/file-tree/file-tree.routes.js +208 -0
  84. package/dist-server/server/modules/file-tree/file-tree.routes.js.map +1 -0
  85. package/dist-server/server/modules/file-tree/file-tree.service.js +576 -0
  86. package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -0
  87. package/dist-server/server/modules/file-tree/index.js +3 -0
  88. package/dist-server/server/modules/file-tree/index.js.map +1 -0
  89. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js +123 -0
  90. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js.map +1 -0
  91. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +260 -0
  92. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -0
  93. package/dist-server/server/modules/git/git-parsing.service.js +61 -0
  94. package/dist-server/server/modules/git/git-parsing.service.js.map +1 -0
  95. package/dist-server/server/modules/git/git.module.js +14 -0
  96. package/dist-server/server/modules/git/git.module.js.map +1 -0
  97. package/dist-server/server/modules/git/git.routes.js +1339 -0
  98. package/dist-server/server/modules/git/git.routes.js.map +1 -0
  99. package/dist-server/server/modules/git/index.js +3 -0
  100. package/dist-server/server/modules/git/index.js.map +1 -0
  101. package/dist-server/server/modules/git/tests/git-init.routes.test.js +48 -0
  102. package/dist-server/server/modules/git/tests/git-init.routes.test.js.map +1 -0
  103. package/dist-server/server/{routes → modules/git/tests}/git.test.js +1 -1
  104. package/dist-server/server/modules/git/tests/git.test.js.map +1 -0
  105. package/dist-server/server/modules/notifications/index.js +15 -1
  106. package/dist-server/server/modules/notifications/index.js.map +1 -1
  107. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js +44 -0
  108. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js.map +1 -0
  109. package/dist-server/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.js} +3 -2
  110. package/dist-server/server/modules/notifications/vapid-keys.service.js.map +1 -0
  111. package/dist-server/server/modules/plugins/index.js +9 -0
  112. package/dist-server/server/modules/plugins/index.js.map +1 -0
  113. package/dist-server/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.js} +3 -2
  114. package/dist-server/server/modules/plugins/plugin-process.service.js.map +1 -0
  115. package/dist-server/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.js} +2 -1
  116. package/dist-server/server/modules/plugins/plugin-registry.service.js.map +1 -0
  117. package/dist-server/server/modules/plugins/plugins.module.js +30 -0
  118. package/dist-server/server/modules/plugins/plugins.module.js.map +1 -0
  119. package/dist-server/server/modules/plugins/plugins.routes.js +70 -0
  120. package/dist-server/server/modules/plugins/plugins.routes.js.map +1 -0
  121. package/dist-server/server/modules/plugins/plugins.service.js +123 -0
  122. package/dist-server/server/modules/plugins/plugins.service.js.map +1 -0
  123. package/dist-server/server/modules/plugins/tests/plugins.service.test.js +28 -0
  124. package/dist-server/server/modules/plugins/tests/plugins.service.test.js.map +1 -0
  125. package/dist-server/server/modules/projects/index.js +5 -0
  126. package/dist-server/server/modules/projects/index.js.map +1 -1
  127. package/dist-server/server/modules/providers/index.js +3 -0
  128. package/dist-server/server/modules/providers/index.js.map +1 -1
  129. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +6 -0
  130. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -1
  131. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +47 -18
  132. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
  133. package/dist-server/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +69 -55
  134. package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -0
  135. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +6 -4
  136. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -1
  137. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +23 -4
  138. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
  139. package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
  140. package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
  141. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +59 -75
  142. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
  143. package/dist-server/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +48 -34
  144. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -0
  145. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js +1 -54
  146. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -1
  147. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +290 -6
  148. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
  149. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +5 -0
  150. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -1
  151. package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
  152. package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
  153. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +33 -673
  154. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -1
  155. package/dist-server/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +40 -28
  156. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -0
  157. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +21 -14
  158. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -1
  159. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +2 -0
  160. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -1
  161. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +112 -333
  162. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
  163. package/dist-server/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +38 -25
  164. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js.map +1 -0
  165. package/dist-server/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +27 -4
  166. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js.map +1 -0
  167. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +0 -12
  168. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js.map +1 -1
  169. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +11 -5
  170. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -1
  171. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js +2 -0
  172. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js.map +1 -1
  173. package/dist-server/server/modules/providers/provider.routes.js +169 -37
  174. package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
  175. package/dist-server/server/modules/providers/services/provider-capabilities.service.js +5 -1
  176. package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
  177. package/dist-server/server/modules/providers/services/provider-models.service.js +247 -184
  178. package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
  179. package/dist-server/server/modules/providers/services/provider-runtime.service.js +66 -0
  180. package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -0
  181. package/dist-server/server/modules/providers/services/provider-token-usage.service.js +268 -0
  182. package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -0
  183. package/dist-server/server/modules/providers/services/session-conversations-search.service.js +12 -4
  184. package/dist-server/server/modules/providers/services/session-conversations-search.service.js.map +1 -1
  185. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +2 -0
  186. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
  187. package/dist-server/server/modules/providers/services/sessions.service.js +116 -3
  188. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
  189. package/dist-server/server/modules/providers/shared/base/abstract.provider.js +2 -3
  190. package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -1
  191. package/dist-server/server/modules/providers/tests/claude-auth.test.js +122 -0
  192. package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -0
  193. package/dist-server/server/modules/providers/tests/claude-sessions.test.js +44 -0
  194. package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -0
  195. package/dist-server/server/modules/providers/tests/codex-sessions.test.js +76 -4
  196. package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
  197. package/dist-server/server/modules/providers/tests/opencode-models.test.js +15 -126
  198. package/dist-server/server/modules/providers/tests/opencode-models.test.js.map +1 -1
  199. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +5 -5
  200. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -1
  201. package/dist-server/server/modules/providers/tests/{provider-image-history.test.js → provider-attachment-history.test.js} +60 -2
  202. package/dist-server/server/modules/providers/tests/provider-attachment-history.test.js.map +1 -0
  203. package/dist-server/server/modules/providers/tests/provider-models.service.test.js +241 -271
  204. package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
  205. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +126 -0
  206. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -0
  207. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +166 -0
  208. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -0
  209. package/dist-server/server/modules/providers/tests/provider.routes.test.js +126 -0
  210. package/dist-server/server/modules/providers/tests/provider.routes.test.js.map +1 -0
  211. package/dist-server/server/modules/providers/tests/sessions-details.test.js +62 -0
  212. package/dist-server/server/modules/providers/tests/sessions-details.test.js.map +1 -0
  213. package/dist-server/server/modules/providers/tests/sessions.service.test.js +87 -0
  214. package/dist-server/server/modules/providers/tests/sessions.service.test.js.map +1 -0
  215. package/dist-server/server/modules/providers/tests/skills.test.js +4 -2
  216. package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
  217. package/dist-server/server/modules/settings/index.js +3 -0
  218. package/dist-server/server/modules/settings/index.js.map +1 -0
  219. package/dist-server/server/modules/settings/settings.module.js +35 -0
  220. package/dist-server/server/modules/settings/settings.module.js.map +1 -0
  221. package/dist-server/server/modules/settings/settings.routes.js +34 -0
  222. package/dist-server/server/modules/settings/settings.routes.js.map +1 -0
  223. package/dist-server/server/modules/settings/settings.service.js +116 -0
  224. package/dist-server/server/modules/settings/settings.service.js.map +1 -0
  225. package/dist-server/server/modules/settings/tests/settings.service.test.js +48 -0
  226. package/dist-server/server/modules/settings/tests/settings.service.test.js.map +1 -0
  227. package/dist-server/server/modules/system/index.js +3 -0
  228. package/dist-server/server/modules/system/index.js.map +1 -0
  229. package/dist-server/server/modules/system/system.module.js +44 -0
  230. package/dist-server/server/modules/system/system.module.js.map +1 -0
  231. package/dist-server/server/modules/system/system.routes.js +16 -0
  232. package/dist-server/server/modules/system/system.routes.js.map +1 -0
  233. package/dist-server/server/modules/system/system.service.js +45 -0
  234. package/dist-server/server/modules/system/system.service.js.map +1 -0
  235. package/dist-server/server/modules/system/tests/system.service.test.js +100 -0
  236. package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -0
  237. package/dist-server/server/modules/taskmaster/index.js +3 -0
  238. package/dist-server/server/modules/taskmaster/index.js.map +1 -0
  239. package/dist-server/server/modules/taskmaster/taskmaster.module.js +20 -0
  240. package/dist-server/server/modules/taskmaster/taskmaster.module.js.map +1 -0
  241. package/dist-server/server/modules/taskmaster/taskmaster.routes.js +1372 -0
  242. package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -0
  243. package/dist-server/server/modules/taskmaster/taskmaster.service.js +107 -0
  244. package/dist-server/server/modules/taskmaster/taskmaster.service.js.map +1 -0
  245. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +132 -0
  246. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -0
  247. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js +85 -0
  248. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js.map +1 -0
  249. package/dist-server/server/modules/user/index.js +3 -0
  250. package/dist-server/server/modules/user/index.js.map +1 -0
  251. package/dist-server/server/modules/user/tests/user.service.test.js +53 -0
  252. package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -0
  253. package/dist-server/server/modules/user/user.module.js +47 -0
  254. package/dist-server/server/modules/user/user.module.js.map +1 -0
  255. package/dist-server/server/modules/user/user.routes.js +44 -0
  256. package/dist-server/server/modules/user/user.routes.js.map +1 -0
  257. package/dist-server/server/modules/user/user.service.js +59 -0
  258. package/dist-server/server/modules/user/user.service.js.map +1 -0
  259. package/dist-server/server/modules/voice/index.js +3 -0
  260. package/dist-server/server/modules/voice/index.js.map +1 -0
  261. package/dist-server/server/modules/voice/tests/voice.service.test.js +86 -0
  262. package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -0
  263. package/dist-server/server/modules/voice/voice.module.js +44 -0
  264. package/dist-server/server/modules/voice/voice.module.js.map +1 -0
  265. package/dist-server/server/modules/voice/voice.routes.js +87 -0
  266. package/dist-server/server/modules/voice/voice.routes.js.map +1 -0
  267. package/dist-server/server/modules/voice/voice.service.js +148 -0
  268. package/dist-server/server/modules/voice/voice.service.js.map +1 -0
  269. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +2 -2
  270. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +44 -29
  271. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
  272. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +76 -8
  273. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
  274. package/dist-server/server/modules/websocket/services/websocket-server.service.js +51 -20
  275. package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -1
  276. package/dist-server/server/modules/websocket/tests/{chat-image-filter.test.js → chat-attachment-filter.test.js} +10 -3
  277. package/dist-server/server/modules/websocket/tests/chat-attachment-filter.test.js.map +1 -0
  278. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +97 -0
  279. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -0
  280. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js +61 -0
  281. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js.map +1 -0
  282. package/dist-server/server/modules/worktrees/index.js +3 -0
  283. package/dist-server/server/modules/worktrees/index.js.map +1 -0
  284. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js +37 -0
  285. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js.map +1 -0
  286. package/dist-server/server/modules/worktrees/services/worktree-create.service.js +67 -0
  287. package/dist-server/server/modules/worktrees/services/worktree-create.service.js.map +1 -0
  288. package/dist-server/server/modules/worktrees/services/worktree-git.service.js +172 -0
  289. package/dist-server/server/modules/worktrees/services/worktree-git.service.js.map +1 -0
  290. package/dist-server/server/modules/worktrees/services/worktree-list.service.js +91 -0
  291. package/dist-server/server/modules/worktrees/services/worktree-list.service.js.map +1 -0
  292. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js +118 -0
  293. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js.map +1 -0
  294. package/dist-server/server/modules/worktrees/services/worktree-open.service.js +58 -0
  295. package/dist-server/server/modules/worktrees/services/worktree-open.service.js.map +1 -0
  296. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +65 -0
  297. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js.map +1 -0
  298. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js +58 -0
  299. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js.map +1 -0
  300. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js +85 -0
  301. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js.map +1 -0
  302. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js +58 -0
  303. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js.map +1 -0
  304. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js +34 -0
  305. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js.map +1 -0
  306. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js +137 -0
  307. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js.map +1 -0
  308. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js +99 -0
  309. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js.map +1 -0
  310. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js +157 -0
  311. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js.map +1 -0
  312. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js +167 -0
  313. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js.map +1 -0
  314. package/dist-server/server/modules/worktrees/worktrees.module.js +97 -0
  315. package/dist-server/server/modules/worktrees/worktrees.module.js.map +1 -0
  316. package/dist-server/server/modules/worktrees/worktrees.routes.js +84 -0
  317. package/dist-server/server/modules/worktrees/worktrees.routes.js.map +1 -0
  318. package/dist-server/server/shared/image-attachments.js +90 -17
  319. package/dist-server/server/shared/image-attachments.js.map +1 -1
  320. package/dist-server/server/shared/tests/image-attachments.test.js +43 -1
  321. package/dist-server/server/shared/tests/image-attachments.test.js.map +1 -1
  322. package/dist-server/server/shared/utils.js +66 -142
  323. package/dist-server/server/shared/utils.js.map +1 -1
  324. package/package.json +9 -5
  325. package/server/index.ts +401 -0
  326. package/server/{load-env.js → load-env.ts} +18 -5
  327. package/server/modules/agent/agent.module.ts +51 -0
  328. package/server/modules/agent/agent.routes.ts +1287 -0
  329. package/server/modules/agent/index.ts +2 -0
  330. package/server/modules/agent/tests/agent.routes.test.ts +205 -0
  331. package/server/modules/assets/assets.routes.ts +63 -16
  332. package/server/modules/assets/index.ts +2 -2
  333. package/server/modules/assets/services/image-assets.service.ts +46 -1
  334. package/server/modules/assets/tests/image-assets.service.test.ts +28 -0
  335. package/server/{middleware/auth.js → modules/auth/auth.middleware.ts} +38 -7
  336. package/server/modules/auth/auth.module.ts +38 -0
  337. package/server/modules/auth/auth.routes.ts +57 -0
  338. package/server/modules/auth/auth.service.ts +155 -0
  339. package/server/modules/auth/index.ts +9 -0
  340. package/server/modules/auth/tests/auth.service.test.ts +95 -0
  341. package/server/{browser-use-mcp.ts → modules/browser-use/browser-use-mcp.ts} +3 -1
  342. package/server/modules/browser-use/browser-use.service.ts +3 -4
  343. package/server/modules/browser-use/index.ts +8 -0
  344. package/server/modules/cli/cli.module.ts +96 -0
  345. package/server/modules/cli/cli.service.ts +281 -0
  346. package/server/modules/cli/cli.ts +13 -0
  347. package/server/modules/cli/index.ts +2 -0
  348. package/server/modules/cli/sandbox.service.ts +413 -0
  349. package/server/modules/cli/tests/cli.service.test.ts +91 -0
  350. package/server/modules/cli/tests/sandbox.service.test.ts +61 -0
  351. package/server/modules/commands/commands.module.ts +22 -0
  352. package/server/{routes/commands.js → modules/commands/commands.routes.ts} +46 -38
  353. package/server/modules/commands/index.ts +2 -0
  354. package/server/modules/commands/tests/commands.test.ts +114 -0
  355. package/server/modules/database/index.ts +3 -0
  356. package/server/modules/database/migrations.ts +35 -0
  357. package/server/modules/database/repositories/provider-models.ts +168 -0
  358. package/server/modules/database/repositories/sessions.db.ts +103 -8
  359. package/server/modules/database/schema.ts +30 -0
  360. package/server/modules/database/tests/provider-models.db.integration.test.ts +125 -0
  361. package/server/modules/database/tests/sessions-provider-mapping.test.ts +2 -1
  362. package/server/modules/database/tests/sessions.db.integration.test.ts +32 -0
  363. package/server/modules/file-tree/file-tree.module.ts +116 -0
  364. package/server/modules/file-tree/file-tree.routes.ts +258 -0
  365. package/server/modules/file-tree/file-tree.service.ts +664 -0
  366. package/server/modules/file-tree/index.ts +2 -0
  367. package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -0
  368. package/server/modules/file-tree/tests/file-tree.service.test.ts +317 -0
  369. package/server/modules/git/git-parsing.service.ts +66 -0
  370. package/server/modules/git/git.module.ts +22 -0
  371. package/server/{routes/git.js → modules/git/git.routes.ts} +91 -132
  372. package/server/modules/git/index.ts +2 -0
  373. package/server/modules/git/tests/git-init.routes.test.ts +52 -0
  374. package/server/{routes/git.test.js → modules/git/tests/git.test.ts} +3 -3
  375. package/server/modules/notifications/index.ts +9 -0
  376. package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -0
  377. package/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.ts} +3 -1
  378. package/server/modules/plugins/index.ts +9 -0
  379. package/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.ts} +3 -1
  380. package/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.ts} +1 -0
  381. package/server/modules/plugins/plugins.module.ts +33 -0
  382. package/server/modules/plugins/plugins.routes.ts +66 -0
  383. package/server/modules/plugins/plugins.service.ts +147 -0
  384. package/server/modules/plugins/tests/plugins.service.test.ts +32 -0
  385. package/server/modules/projects/index.ts +5 -0
  386. package/server/modules/providers/README.md +41 -9
  387. package/server/modules/providers/index.ts +4 -0
  388. package/server/modules/providers/list/claude/claude-auth.provider.ts +8 -0
  389. package/server/modules/providers/list/claude/claude-models.provider.ts +47 -26
  390. package/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +73 -59
  391. package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +6 -4
  392. package/server/modules/providers/list/claude/claude-sessions.provider.ts +27 -4
  393. package/server/modules/providers/list/claude/claude.provider.ts +3 -0
  394. package/server/modules/providers/list/codex/codex-models.provider.ts +58 -108
  395. package/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +54 -36
  396. package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +1 -60
  397. package/server/modules/providers/list/codex/codex-sessions.provider.ts +331 -7
  398. package/server/modules/providers/list/codex/codex-skills.provider.ts +5 -0
  399. package/server/modules/providers/list/codex/codex.provider.ts +3 -0
  400. package/server/modules/providers/list/cursor/cursor-models.provider.ts +32 -719
  401. package/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +58 -27
  402. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +26 -15
  403. package/server/modules/providers/list/cursor/cursor.provider.ts +3 -0
  404. package/server/modules/providers/list/opencode/opencode-models.provider.ts +112 -423
  405. package/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +56 -28
  406. package/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +41 -3
  407. package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +0 -13
  408. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +13 -5
  409. package/server/modules/providers/list/opencode/opencode.provider.ts +3 -0
  410. package/server/modules/providers/provider.routes.ts +228 -39
  411. package/server/modules/providers/services/provider-capabilities.service.ts +7 -1
  412. package/server/modules/providers/services/provider-models.service.ts +312 -269
  413. package/server/modules/providers/services/provider-runtime.service.ts +108 -0
  414. package/server/modules/providers/services/provider-token-usage.service.ts +357 -0
  415. package/server/modules/providers/services/session-conversations-search.service.ts +12 -4
  416. package/server/modules/providers/services/sessions-watcher.service.ts +2 -0
  417. package/server/modules/providers/services/sessions.service.ts +166 -3
  418. package/server/modules/providers/shared/base/abstract.provider.ts +4 -3
  419. package/server/modules/providers/tests/claude-auth.test.ts +150 -0
  420. package/server/modules/providers/tests/claude-sessions.test.ts +61 -0
  421. package/server/modules/providers/tests/codex-sessions.test.ts +83 -4
  422. package/server/modules/providers/tests/opencode-models.test.ts +34 -135
  423. package/server/modules/providers/tests/opencode-sessions.test.ts +5 -5
  424. package/server/modules/providers/tests/{provider-image-history.test.ts → provider-attachment-history.test.ts} +68 -1
  425. package/server/modules/providers/tests/provider-models.service.test.ts +300 -296
  426. package/server/modules/providers/tests/provider-runtime.service.test.ts +138 -0
  427. package/server/modules/providers/tests/provider-token-usage.service.test.ts +186 -0
  428. package/server/modules/providers/tests/provider.routes.test.ts +183 -0
  429. package/server/modules/providers/tests/sessions-details.test.ts +73 -0
  430. package/server/modules/providers/tests/sessions.service.test.ts +127 -0
  431. package/server/modules/providers/tests/skills.test.ts +9 -2
  432. package/server/modules/settings/index.ts +2 -0
  433. package/server/modules/settings/settings.module.ts +50 -0
  434. package/server/modules/settings/settings.routes.ts +51 -0
  435. package/server/modules/settings/settings.service.ts +186 -0
  436. package/server/modules/settings/tests/settings.service.test.ts +54 -0
  437. package/server/modules/system/index.ts +2 -0
  438. package/server/modules/system/system.module.ts +62 -0
  439. package/server/modules/system/system.routes.ts +21 -0
  440. package/server/modules/system/system.service.ts +76 -0
  441. package/server/modules/system/tests/system.service.test.ts +118 -0
  442. package/server/modules/taskmaster/index.ts +2 -0
  443. package/server/modules/taskmaster/taskmaster.module.ts +24 -0
  444. package/server/modules/taskmaster/taskmaster.routes.ts +1482 -0
  445. package/server/modules/taskmaster/taskmaster.service.ts +132 -0
  446. package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -0
  447. package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -0
  448. package/server/modules/user/index.ts +2 -0
  449. package/server/modules/user/tests/user.service.test.ts +61 -0
  450. package/server/modules/user/user.module.ts +58 -0
  451. package/server/modules/user/user.routes.ts +50 -0
  452. package/server/modules/user/user.service.ts +85 -0
  453. package/server/modules/voice/index.ts +2 -0
  454. package/server/modules/voice/tests/voice.service.test.ts +98 -0
  455. package/server/modules/voice/voice.module.ts +47 -0
  456. package/server/modules/voice/voice.routes.ts +113 -0
  457. package/server/modules/voice/voice.service.ts +192 -0
  458. package/server/modules/websocket/README.md +7 -7
  459. package/server/modules/websocket/services/chat-session-writer.service.ts +2 -2
  460. package/server/modules/websocket/services/chat-websocket.service.ts +77 -61
  461. package/server/modules/websocket/services/shell-websocket.service.ts +88 -12
  462. package/server/modules/websocket/services/websocket-server.service.ts +63 -19
  463. package/server/modules/websocket/tests/{chat-image-filter.test.ts → chat-attachment-filter.test.ts} +17 -2
  464. package/server/modules/websocket/tests/shell-websocket.service.test.ts +119 -0
  465. package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -0
  466. package/server/modules/worktrees/index.ts +2 -0
  467. package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -0
  468. package/server/modules/worktrees/services/worktree-create.service.ts +104 -0
  469. package/server/modules/worktrees/services/worktree-git.service.ts +207 -0
  470. package/server/modules/worktrees/services/worktree-list.service.ts +143 -0
  471. package/server/modules/worktrees/services/worktree-merge.service.ts +157 -0
  472. package/server/modules/worktrees/services/worktree-open.service.ts +85 -0
  473. package/server/modules/worktrees/services/worktree-remove.service.ts +88 -0
  474. package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -0
  475. package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -0
  476. package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -0
  477. package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -0
  478. package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -0
  479. package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -0
  480. package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -0
  481. package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -0
  482. package/server/modules/worktrees/worktrees.module.ts +113 -0
  483. package/server/modules/worktrees/worktrees.routes.ts +116 -0
  484. package/server/shared/image-attachments.ts +112 -18
  485. package/server/shared/interfaces.ts +33 -25
  486. package/server/shared/tests/image-attachments.test.ts +55 -0
  487. package/server/shared/types.ts +685 -36
  488. package/server/shared/utils.ts +77 -212
  489. package/dist/assets/index-CcCsKitq.js +0 -1423
  490. package/dist/assets/index-DLmhQ15L.css +0 -32
  491. package/dist-server/server/browser-use-mcp.js.map +0 -1
  492. package/dist-server/server/claude-sdk.js.map +0 -1
  493. package/dist-server/server/cli.js +0 -647
  494. package/dist-server/server/cli.js.map +0 -1
  495. package/dist-server/server/cursor-cli.js.map +0 -1
  496. package/dist-server/server/middleware/auth.js.map +0 -1
  497. package/dist-server/server/modules/providers/tests/provider-image-history.test.js.map +0 -1
  498. package/dist-server/server/modules/websocket/tests/chat-image-filter.test.js.map +0 -1
  499. package/dist-server/server/openai-codex.js.map +0 -1
  500. package/dist-server/server/opencode-cli.js.map +0 -1
  501. package/dist-server/server/opencode-cli.test.js.map +0 -1
  502. package/dist-server/server/routes/agent.js +0 -1155
  503. package/dist-server/server/routes/agent.js.map +0 -1
  504. package/dist-server/server/routes/auth.js +0 -119
  505. package/dist-server/server/routes/auth.js.map +0 -1
  506. package/dist-server/server/routes/commands.js +0 -492
  507. package/dist-server/server/routes/commands.js.map +0 -1
  508. package/dist-server/server/routes/cursor.js +0 -49
  509. package/dist-server/server/routes/cursor.js.map +0 -1
  510. package/dist-server/server/routes/git.js +0 -1389
  511. package/dist-server/server/routes/git.js.map +0 -1
  512. package/dist-server/server/routes/git.test.js.map +0 -1
  513. package/dist-server/server/routes/mcp-utils.js +0 -29
  514. package/dist-server/server/routes/mcp-utils.js.map +0 -1
  515. package/dist-server/server/routes/plugins.js +0 -266
  516. package/dist-server/server/routes/plugins.js.map +0 -1
  517. package/dist-server/server/routes/settings.js +0 -249
  518. package/dist-server/server/routes/settings.js.map +0 -1
  519. package/dist-server/server/routes/taskmaster.js +0 -1362
  520. package/dist-server/server/routes/taskmaster.js.map +0 -1
  521. package/dist-server/server/routes/tests/commands.test.js +0 -76
  522. package/dist-server/server/routes/tests/commands.test.js.map +0 -1
  523. package/dist-server/server/routes/user.js +0 -116
  524. package/dist-server/server/routes/user.js.map +0 -1
  525. package/dist-server/server/services/notification-orchestrator.js +0 -2
  526. package/dist-server/server/services/notification-orchestrator.js.map +0 -1
  527. package/dist-server/server/services/tests/notification-orchestrator.test.js +0 -64
  528. package/dist-server/server/services/tests/notification-orchestrator.test.js.map +0 -1
  529. package/dist-server/server/services/vapid-keys.js.map +0 -1
  530. package/dist-server/server/utils/colors.js +0 -20
  531. package/dist-server/server/utils/colors.js.map +0 -1
  532. package/dist-server/server/utils/commandParser.js +0 -255
  533. package/dist-server/server/utils/commandParser.js.map +0 -1
  534. package/dist-server/server/utils/gitConfig.js +0 -37
  535. package/dist-server/server/utils/gitConfig.js.map +0 -1
  536. package/dist-server/server/utils/mcp-detector.js +0 -134
  537. package/dist-server/server/utils/mcp-detector.js.map +0 -1
  538. package/dist-server/server/utils/plugin-loader.js.map +0 -1
  539. package/dist-server/server/utils/plugin-process-manager.js.map +0 -1
  540. package/dist-server/server/utils/runtime-paths.js +0 -30
  541. package/dist-server/server/utils/runtime-paths.js.map +0 -1
  542. package/dist-server/server/utils/taskmaster-websocket.js +0 -124
  543. package/dist-server/server/utils/taskmaster-websocket.js.map +0 -1
  544. package/dist-server/server/utils/url-detection.js +0 -58
  545. package/dist-server/server/utils/url-detection.js.map +0 -1
  546. package/dist-server/server/voice-proxy.js +0 -226
  547. package/dist-server/server/voice-proxy.js.map +0 -1
  548. package/server/cli.js +0 -695
  549. package/server/index.js +0 -1651
  550. package/server/routes/agent.js +0 -1257
  551. package/server/routes/auth.js +0 -137
  552. package/server/routes/cursor.js +0 -52
  553. package/server/routes/mcp-utils.js +0 -31
  554. package/server/routes/plugins.js +0 -307
  555. package/server/routes/settings.js +0 -282
  556. package/server/routes/taskmaster.js +0 -1470
  557. package/server/routes/tests/commands.test.js +0 -82
  558. package/server/routes/user.js +0 -124
  559. package/server/services/notification-orchestrator.js +0 -7
  560. package/server/services/tests/notification-orchestrator.test.js +0 -80
  561. package/server/utils/colors.js +0 -21
  562. package/server/utils/commandParser.js +0 -305
  563. package/server/utils/gitConfig.js +0 -35
  564. package/server/utils/mcp-detector.js +0 -147
  565. package/server/utils/runtime-paths.js +0 -37
  566. package/server/utils/taskmaster-websocket.js +0 -135
  567. package/server/utils/url-detection.js +0 -71
  568. package/server/voice-proxy.js +0 -224
  569. /package/server/constants/{config.js → config.ts} +0 -0
@@ -1,12 +1,29 @@
1
- import express from 'express';
2
- // cross-spawn: drop-in spawn with Windows .cmd/PATHEXT resolution.
3
- import spawn from 'cross-spawn';
1
+ // @ts-nocheck -- temporary while Git workflows are extracted into the injected service.
4
2
  import path from 'path';
5
- import { promises as fs } from 'fs';
6
- import { projectsDb } from '../modules/database/index.js';
7
- import { queryClaudeSDK } from '../claude-sdk.js';
8
- import { spawnCursor } from '../cursor-cli.js';
9
3
 
4
+ import express from 'express';
5
+
6
+ import type { ProviderRunFunction } from '@/shared/types.js';
7
+ import { AppError } from '@/shared/utils.js';
8
+
9
+ // cross-spawn: drop-in spawn with Windows .cmd/PATHEXT resolution.
10
+ import { parseGitLogWithStats, parseGitStatusOutput } from './git-parsing.service.js';
11
+
12
+ type GitRouterDependencies = {
13
+ fileSystem: typeof import('node:fs/promises');
14
+ spawnProcess: typeof import('cross-spawn').default;
15
+ resolveProjectPathById(projectId: string): string | null;
16
+ queryClaude: ProviderRunFunction;
17
+ queryCursor: ProviderRunFunction;
18
+ };
19
+
20
+ /** Creates Git routes around explicit repository, filesystem, subprocess, and AI adapters. */
21
+ export function createGitRouter(dependencies: GitRouterDependencies): express.Router {
22
+ const fs = dependencies.fileSystem;
23
+ const spawn = dependencies.spawnProcess;
24
+ const projectsDb = { getProjectPathById: dependencies.resolveProjectPathById };
25
+ const queryClaudeSDK = dependencies.queryClaude;
26
+ const spawnCursor = dependencies.queryCursor;
10
27
  const router = express.Router();
11
28
  const COMMIT_DIFF_CHARACTER_LIMIT = 500_000;
12
29
 
@@ -162,13 +179,30 @@ async function validateGitRepository(projectPath) {
162
179
  const { stdout: insideWorkTreeOutput } = await spawnAsync('git', ['rev-parse', '--is-inside-work-tree'], { cwd: projectPath });
163
180
  const isInsideWorkTree = insideWorkTreeOutput.trim() === 'true';
164
181
  if (!isInsideWorkTree) {
165
- throw new Error('Not inside a git work tree');
182
+ throw new AppError('Not a git repository', {
183
+ code: 'NOT_A_GIT_REPOSITORY',
184
+ statusCode: 400,
185
+ });
166
186
  }
167
187
 
168
188
  // Ensure git can resolve the repository root for this directory.
169
189
  await spawnAsync('git', ['rev-parse', '--show-toplevel'], { cwd: projectPath });
170
- } catch {
171
- throw new Error('Not a git repository. This directory does not contain a .git folder. Initialize a git repository with "git init" to use source control features.');
190
+ } catch (error) {
191
+ if (
192
+ error instanceof AppError
193
+ && error.code === 'NOT_A_GIT_REPOSITORY'
194
+ ) {
195
+ throw error;
196
+ }
197
+
198
+ if (/not a git repository/i.test(getGitErrorDetails(error))) {
199
+ throw new AppError('Not a git repository. Initialize a git repository with "git init" to use source control features.', {
200
+ code: 'NOT_A_GIT_REPOSITORY',
201
+ statusCode: 400,
202
+ });
203
+ }
204
+
205
+ throw error;
172
206
  }
173
207
  }
174
208
 
@@ -293,77 +327,7 @@ async function resolveRepositoryFilePath(projectPath, filePath) {
293
327
  };
294
328
  }
295
329
 
296
- // Get git status for a project
297
- /**
298
- * Parses `git status --porcelain=v1 -z` output into the response shape the
299
- * git panel consumes. NUL-separated entries carry no path quoting, so names
300
- * with spaces/unicode survive intact (the plain porcelain output quotes and
301
- * escapes them, which broke the old line-based parser).
302
- *
303
- * `staged` lists paths with index-side changes. The UI renders its "Staged"
304
- * section from this list so it always mirrors the real git index (including
305
- * files staged outside the app, e.g. via VSCode or the terminal).
306
- *
307
- * Exported for tests.
308
- */
309
- export function parseGitStatusOutput(statusOutput) {
310
- const modified = [];
311
- const added = [];
312
- const deleted = [];
313
- const untracked = [];
314
- const staged = [];
315
-
316
- const statusEntries = statusOutput.split('\0');
317
- for (let entryIndex = 0; entryIndex < statusEntries.length; entryIndex++) {
318
- const entry = statusEntries[entryIndex];
319
- if (!entry || entry.length < 4) continue;
320
-
321
- // Porcelain v1: X = index (staged) status, Y = worktree (unstaged) status.
322
- const indexStatus = entry[0];
323
- const worktreeStatus = entry[1];
324
- const file = entry.slice(3);
325
-
326
- // Renames/copies carry the original path as the following NUL entry;
327
- // the UI tracks the post-rename path only.
328
- if (indexStatus === 'R' || indexStatus === 'C') {
329
- entryIndex += 1;
330
- }
331
-
332
- if (indexStatus === '?') {
333
- untracked.push(file);
334
- continue;
335
- }
336
- if (indexStatus === '!') {
337
- continue; // ignored files are never reported
338
- }
339
-
340
- const isConflict =
341
- indexStatus === 'U' || worktreeStatus === 'U' ||
342
- (indexStatus === 'A' && worktreeStatus === 'A') ||
343
- (indexStatus === 'D' && worktreeStatus === 'D');
344
- if (isConflict) {
345
- // Merge conflicts must be resolved in the worktree first; surface them
346
- // as modified and never as staged.
347
- modified.push(file);
348
- continue;
349
- }
350
-
351
- if (indexStatus !== ' ') {
352
- staged.push(file);
353
- }
354
-
355
- if (indexStatus === 'D' || worktreeStatus === 'D') {
356
- deleted.push(file);
357
- } else if (indexStatus === 'A' || worktreeStatus === 'A') {
358
- added.push(file);
359
- } else {
360
- modified.push(file);
361
- }
362
- }
363
-
364
- return { modified, added, deleted, untracked, staged };
365
- }
366
-
330
+ // Get Git status for a project; parsing is isolated in git-parsing.service.ts.
367
331
  router.get('/status', async (req, res) => {
368
332
  const { project } = req.query;
369
333
 
@@ -393,18 +357,55 @@ router.get('/status', async (req, res) => {
393
357
  staged
394
358
  });
395
359
  } catch (error) {
396
- console.error('Git status error:', error);
360
+ // Case-insensitive so "Not a git repository..." from validateGitRepository
361
+ // matches; `notGitRepository` lets the UI offer a one-click `git init`.
362
+ const isNotGitRepository = error instanceof AppError && error.code === 'NOT_A_GIT_REPOSITORY';
363
+ // A project without a repository is an expected state, not a failure.
364
+ if (!isNotGitRepository) {
365
+ console.error('Git status error:', error);
366
+ }
397
367
  res.json({
398
- error: error.message.includes('not a git repository') || error.message.includes('Project directory is not a git repository')
399
- ? error.message
400
- : 'Git operation failed',
401
- details: error.message.includes('not a git repository') || error.message.includes('Project directory is not a git repository')
402
- ? error.message
403
- : `Failed to get git status: ${error.message}`
368
+ error: isNotGitRepository ? 'Not a git repository' : 'Git operation failed',
369
+ details: isNotGitRepository ? error.message : `Failed to get git status: ${error.message}`,
370
+ notGitRepository: isNotGitRepository
404
371
  });
405
372
  }
406
373
  });
407
374
 
375
+ // Initialize a new git repository in the project directory
376
+ router.post('/init', async (req, res) => {
377
+ const { project } = req.body;
378
+
379
+ if (!project) {
380
+ return res.status(400).json({ error: 'Project id is required' });
381
+ }
382
+
383
+ try {
384
+ const projectPath = await getActualProjectPath(project);
385
+
386
+ let isAlreadyRepository = false;
387
+ try {
388
+ await validateGitRepository(projectPath);
389
+ isAlreadyRepository = true;
390
+ } catch (error) {
391
+ if (!(error instanceof AppError) || error.code !== 'NOT_A_GIT_REPOSITORY') {
392
+ throw error;
393
+ }
394
+ // Not a repository yet — proceed with git init.
395
+ }
396
+
397
+ if (isAlreadyRepository) {
398
+ return res.json({ success: true, output: 'Repository already initialized' });
399
+ }
400
+
401
+ const { stdout, stderr } = await spawnAsync('git', ['init'], { cwd: projectPath });
402
+ res.json({ success: true, output: stdout.trim() || stderr.trim() });
403
+ } catch (error) {
404
+ console.error('Git init error:', error);
405
+ res.json({ success: false, error: error.stderr?.trim() || error.message });
406
+ }
407
+ });
408
+
408
409
  // Get diff for a specific file
409
410
  router.get('/diff', async (req, res) => {
410
411
  const { project, file } = req.query;
@@ -864,51 +865,8 @@ router.post('/delete-branch', async (req, res) => {
864
865
 
865
866
  // Fields are joined with the ASCII unit separator so pipes (or anything else
866
867
  // typed into a commit subject) cannot break parsing.
867
- const GIT_LOG_FIELD_SEPARATOR = '\u001f';
868
868
  const GIT_LOG_PRETTY_FORMAT = '%H%x1f%P%x1f%D%x1f%an%x1f%ae%x1f%ad%x1f%s';
869
869
 
870
- /**
871
- * Parses `git log --shortstat` output produced with GIT_LOG_PRETTY_FORMAT.
872
- *
873
- * Each commit is one format line (hash, parent hashes, ref decorations,
874
- * author, email, date, subject) optionally followed by its `--shortstat`
875
- * summary line ("N files changed, ..."). Parents and refs feed the commit
876
- * graph rendered by the History view; merge commits carry no shortstat line,
877
- * so their `stats` stays empty.
878
- *
879
- * Exported for tests.
880
- */
881
- export function parseGitLogWithStats(stdout) {
882
- const commits = [];
883
-
884
- for (const rawLine of stdout.split('\n')) {
885
- const line = rawLine.trimEnd();
886
- if (!line.trim()) continue;
887
-
888
- if (line.includes(GIT_LOG_FIELD_SEPARATOR)) {
889
- const [hash, parents, refs, author, email, date, ...messageParts] = line.split(GIT_LOG_FIELD_SEPARATOR);
890
- commits.push({
891
- hash,
892
- parents: parents ? parents.split(' ').filter(Boolean) : [],
893
- // `%D` decorations, e.g. "HEAD -> main", "origin/main", "tag: v1.0".
894
- refs: refs ? refs.split(', ').filter(Boolean) : [],
895
- author,
896
- email,
897
- date,
898
- message: messageParts.join(GIT_LOG_FIELD_SEPARATOR),
899
- stats: ''
900
- });
901
- continue;
902
- }
903
-
904
- if (commits.length > 0 && /files? changed/.test(line)) {
905
- commits[commits.length - 1].stats = line.trim();
906
- }
907
- }
908
-
909
- return commits;
910
- }
911
-
912
870
  // Get recent commits (across all branches, in graph order)
913
871
  router.get('/commits', async (req, res) => {
914
872
  const { project, limit = 10 } = req.query;
@@ -1631,4 +1589,5 @@ router.post('/delete-untracked', async (req, res) => {
1631
1589
  }
1632
1590
  });
1633
1591
 
1634
- export default router;
1592
+ return router;
1593
+ }
@@ -0,0 +1,2 @@
1
+ // createGitModule: used by the server entrypoint to assemble Git routes with provider runtimes.
2
+ export { createGitModule } from './git.module.js';
@@ -0,0 +1,52 @@
1
+ import assert from 'node:assert/strict';
2
+ import { EventEmitter, once } from 'node:events';
3
+ import type { AddressInfo } from 'node:net';
4
+ import { PassThrough } from 'node:stream';
5
+ import test from 'node:test';
6
+
7
+ import express from 'express';
8
+
9
+ import { createGitRouter } from '@/modules/git/git.routes.js';
10
+
11
+ test('git init does not run when repository validation fails for an execution error', async () => {
12
+ const commands: string[][] = [];
13
+ const spawnProcess = ((_command: string, args: string[]) => {
14
+ commands.push(args);
15
+ const child = new EventEmitter() as EventEmitter & { stdout: PassThrough; stderr: PassThrough };
16
+ child.stdout = new PassThrough();
17
+ child.stderr = new PassThrough();
18
+ process.nextTick(() => child.emit('error', Object.assign(new Error('permission denied'), {
19
+ code: 'EACCES',
20
+ })));
21
+ return child;
22
+ }) as Parameters<typeof createGitRouter>[0]['spawnProcess'];
23
+ const unexpectedProvider = async (): Promise<never> => { throw new Error('unexpected provider call'); };
24
+ const router = createGitRouter({
25
+ fileSystem: { access: async () => undefined } as unknown as Parameters<typeof createGitRouter>[0]['fileSystem'],
26
+ spawnProcess,
27
+ resolveProjectPathById: () => '/workspace/repo',
28
+ queryClaude: unexpectedProvider,
29
+ queryCursor: unexpectedProvider,
30
+ });
31
+ const app = express();
32
+ app.use(express.json());
33
+ app.use('/api/git', router);
34
+ const server = app.listen(0, '127.0.0.1');
35
+ await once(server, 'listening');
36
+
37
+ try {
38
+ const address = server.address() as AddressInfo;
39
+ const response = await fetch(`http://127.0.0.1:${address.port}/api/git/init`, {
40
+ method: 'POST',
41
+ headers: { 'content-type': 'application/json' },
42
+ body: JSON.stringify({ project: 'project-1' }),
43
+ });
44
+ const body = await response.json() as { success: boolean; error: string };
45
+ assert.equal(body.success, false);
46
+ assert.match(body.error, /permission denied/);
47
+ } finally {
48
+ await new Promise<void>((resolve) => server.close(() => resolve()));
49
+ }
50
+
51
+ assert.deepEqual(commands, [['rev-parse', '--is-inside-work-tree']]);
52
+ });
@@ -1,11 +1,11 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import test from 'node:test';
3
3
 
4
- import { parseGitLogWithStats, parseGitStatusOutput } from './git.js';
4
+ import { parseGitLogWithStats, parseGitStatusOutput } from '../git-parsing.service.js';
5
5
 
6
6
  // Builds `git status --porcelain=v1 -z` output: NUL-separated entries with a
7
7
  // trailing NUL, exactly as git emits it.
8
- const porcelain = (...entries) => entries.join('\0') + '\0';
8
+ const porcelain = (...entries: string[]) => entries.join('\0') + '\0';
9
9
 
10
10
  test('parseGitStatusOutput buckets files and reports index-side staging', () => {
11
11
  const output = porcelain(
@@ -69,7 +69,7 @@ test('parseGitStatusOutput handles empty output', () => {
69
69
 
70
70
  // Builds one `git log --pretty=format:%H%x1f%P%x1f%D%x1f%an%x1f%ae%x1f%ad%x1f%s` line.
71
71
  const US = '';
72
- const logLine = (hash, parents, refs, subject) =>
72
+ const logLine = (hash: string, parents: string, refs: string, subject: string) =>
73
73
  [hash, parents, refs, 'Alice', 'a@x.com', '2026-07-06T10:00:00+03:00', subject].join(US);
74
74
 
75
75
  test('parseGitLogWithStats parses commits with parents, refs, and shortstat lines', () => {
@@ -1,8 +1,13 @@
1
1
  export {
2
+ // Used by notification tests and delivery workflows to create channel payloads.
2
3
  buildNotificationPayload,
4
+ // Used by provider runtimes and Settings to create normalized notification events.
3
5
  createNotificationEvent,
6
+ // Used by provider runtimes and Settings to deliver events through enabled channels.
4
7
  notifyUserIfEnabled,
8
+ // Used by provider runtimes to report failed agent runs.
5
9
  notifyRunFailed,
10
+ // Used by provider runtimes to report stopped or completed agent runs.
6
11
  notifyRunStopped,
7
12
  } from '@/modules/notifications/services/notification-orchestrator.service.js';
8
13
  export {
@@ -11,3 +16,7 @@ export {
11
16
  unregisterDesktopNotificationClient,
12
17
  } from '@/modules/notifications/services/desktop-notification-clients.service.js';
13
18
  export { handleDesktopNotificationsConnection } from '@/modules/notifications/websocket/desktop-notifications-websocket.service.js';
19
+ // getPublicKey: used by Settings to expose the Web Push subscription key.
20
+ export { getPublicKey } from './vapid-keys.service.js';
21
+ // configureWebPush: used by the server entrypoint during notification startup.
22
+ export { configureWebPush } from './vapid-keys.service.js';
@@ -0,0 +1,55 @@
1
+ import assert from 'node:assert/strict';
2
+ import { mkdtemp, rm } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import path from 'node:path';
5
+ import test from 'node:test';
6
+
7
+ import {
8
+ closeConnection,
9
+ initializeDatabase,
10
+ sessionsDb,
11
+ } from '@/modules/database/index.js';
12
+
13
+ import {
14
+ buildNotificationPayload,
15
+ } from '../services/notification-orchestrator.service.js';
16
+
17
+ async function withIsolatedDatabase(runTest: () => void | Promise<void>): Promise<void> {
18
+ const previousDatabasePath = process.env.DATABASE_PATH;
19
+ const temporaryDirectory = await mkdtemp(path.join(tmpdir(), 'notification-orchestrator-'));
20
+ const databasePath = path.join(temporaryDirectory, 'auth.db');
21
+
22
+ closeConnection();
23
+ process.env.DATABASE_PATH = databasePath;
24
+ await initializeDatabase();
25
+
26
+ try {
27
+ await runTest();
28
+ } finally {
29
+ closeConnection();
30
+ if (previousDatabasePath === undefined) {
31
+ delete process.env.DATABASE_PATH;
32
+ } else {
33
+ process.env.DATABASE_PATH = previousDatabasePath;
34
+ }
35
+ await rm(temporaryDirectory, { recursive: true, force: true });
36
+ }
37
+ }
38
+
39
+ test('notification payload uses the app session id for a provider session id', async () => {
40
+ await withIsolatedDatabase(() => {
41
+ sessionsDb.createAppSession('app-session-1', 'claude', '/workspace/demo');
42
+ sessionsDb.assignProviderSessionId('app-session-1', 'claude-native-1');
43
+
44
+ const payload = buildNotificationPayload({
45
+ provider: 'claude',
46
+ sessionId: 'claude-native-1',
47
+ kind: 'stop',
48
+ code: 'run.stopped',
49
+ meta: { stopReason: 'completed' },
50
+ });
51
+
52
+ assert.equal(payload.data.sessionId, 'app-session-1');
53
+ assert.match(payload.data.tag, /app-session-1/);
54
+ });
55
+ });
@@ -1,5 +1,7 @@
1
+ // @ts-nocheck -- web-push does not provide declarations in this project.
1
2
  import webPush from 'web-push';
2
- import { getConnection } from '../modules/database/connection.js';
3
+
4
+ import { getConnection } from '../database/index.js';
3
5
 
4
6
  let cachedKeys = null;
5
7
  const db = getConnection();
@@ -0,0 +1,9 @@
1
+ // pluginsRoutes: used by the server entrypoint to mount protected plugin-management endpoints.
2
+ export { pluginsRoutes } from './plugins.module.js';
3
+
4
+ // startEnabledPluginServers: used by the server entrypoint to start enabled plugin subprocesses.
5
+ export { startEnabledPluginServers } from './plugin-process.service.js';
6
+ // stopAllPlugins: used by the server entrypoint to stop plugin subprocesses during shutdown.
7
+ export { stopAllPlugins } from './plugin-process.service.js';
8
+ // getPluginPort: used by WebSocket setup in the server entrypoint to proxy plugin connections.
9
+ export { getPluginPort } from './plugin-process.service.js';
@@ -1,8 +1,10 @@
1
+ // @ts-nocheck -- subprocess records are narrowed at the Plugins composition boundary.
1
2
  import path from 'path';
2
3
 
3
4
  // cross-spawn: drop-in spawn with Windows .cmd/PATHEXT resolution.
4
5
  import spawn from 'cross-spawn';
5
- import { scanPlugins, getPluginsConfig, getPluginDir } from './plugin-loader.js';
6
+
7
+ import { scanPlugins, getPluginsConfig, getPluginDir } from './plugin-registry.service.js';
6
8
 
7
9
  // Map<pluginName, { process, port }>
8
10
  const runningPlugins = new Map();
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck -- the registry's dynamic manifest schema is narrowed by Plugins service adapters.
1
2
  import fs from 'fs';
2
3
  import path from 'path';
3
4
  import os from 'os';
@@ -0,0 +1,33 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ import mime from 'mime-types';
5
+
6
+ import {
7
+ getPluginDir, getPluginsConfig, getPluginsDir, installPluginFromGit,
8
+ resolvePluginAssetPath, savePluginsConfig, scanPlugins, uninstallPlugin, updatePluginFromGit,
9
+ } from './plugin-registry.service.js';
10
+ import {
11
+ getPluginPort, isPluginRunning, startPluginServer, stopPluginServer,
12
+ } from './plugin-process.service.js';
13
+ import { createPluginsRouter } from './plugins.routes.js';
14
+ import { createPluginsService } from './plugins.service.js';
15
+
16
+ const pluginsService = createPluginsService({
17
+ scanPlugins, readConfig: getPluginsConfig, saveConfig: savePluginsConfig,
18
+ getPluginDirectory: getPluginDir, getPluginsDirectory: getPluginsDir,
19
+ resolveAsset: resolvePluginAssetPath,
20
+ assetIsFile: (assetPath) => { try { return fs.statSync(assetPath).isFile(); } catch { return false; } },
21
+ contentType: (assetPath) => mime.lookup(assetPath) || 'application/octet-stream',
22
+ install: installPluginFromGit,
23
+ update: updatePluginFromGit,
24
+ uninstall: async (pluginName) => { await uninstallPlugin(pluginName); },
25
+ startServer: startPluginServer,
26
+ stopServer: async (pluginName) => { await stopPluginServer(pluginName); },
27
+ getServerPort: getPluginPort, isServerRunning: isPluginRunning,
28
+ joinPath: path.join,
29
+ logError: (message, error) => console.error(message, error),
30
+ });
31
+
32
+ /** Plugin router assembled with filesystem, loader, and process adapters. */
33
+ export const pluginsRoutes = createPluginsRouter(pluginsService);
@@ -0,0 +1,66 @@
1
+ import fs from 'node:fs';
2
+ import http from 'node:http';
3
+
4
+ import express from 'express';
5
+
6
+ import type { createPluginsService } from './plugins.service.js';
7
+
8
+ function wildcardPath(req: express.Request): string {
9
+ return ((req.params as Record<string, string>)['0'] ?? '').trim();
10
+ }
11
+
12
+ function routeParameter(value: string | string[]): string {
13
+ return Array.isArray(value) ? value[0] ?? '' : value;
14
+ }
15
+
16
+ /** Creates plugin routes; transport streaming remains here while decisions live in the service. */
17
+ export function createPluginsRouter(service: ReturnType<typeof createPluginsService>): express.Router {
18
+ const router = express.Router();
19
+ const respond = (operation: (req: express.Request) => unknown | Promise<unknown>) =>
20
+ async (req: express.Request, res: express.Response, next: express.NextFunction) => {
21
+ try { res.json(await operation(req)); } catch (error) { next(error); }
22
+ };
23
+
24
+ router.get('/', respond(() => service.list()));
25
+ router.get('/:name/manifest', respond((req) => service.getManifest(routeParameter(req.params.name))));
26
+ router.get('/:name/assets/*', async (req, res, next) => {
27
+ try {
28
+ const asset = service.resolveAsset(routeParameter(req.params.name), wildcardPath(req));
29
+ res.setHeader('Content-Type', asset.contentType);
30
+ res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
31
+ const stream = fs.createReadStream(asset.path);
32
+ stream.on('error', next);
33
+ stream.pipe(res);
34
+ } catch (error) { next(error); }
35
+ });
36
+ router.put('/:name/enable', respond((req) => service.setEnabled(routeParameter(req.params.name), req.body?.enabled)));
37
+ router.post('/install', respond((req) => service.install(req.body?.url)));
38
+ router.post('/:name/update', respond((req) => service.update(routeParameter(req.params.name))));
39
+ router.all('/:name/rpc/*', async (req, res, next) => {
40
+ try {
41
+ const { port, secrets } = await service.prepareRpc(routeParameter(req.params.name));
42
+ const headers: Record<string, string> = {
43
+ 'content-type': String(req.headers['content-type'] ?? 'application/json'),
44
+ };
45
+ for (const [key, value] of Object.entries(secrets)) {
46
+ headers[`x-plugin-secret-${key.toLowerCase()}`] = String(value);
47
+ }
48
+ const query = req.url.includes('?') ? `?${req.url.split('?').slice(1).join('?')}` : '';
49
+ const proxyRequest = http.request({
50
+ hostname: '127.0.0.1', port, path: `/${wildcardPath(req)}${query}`, method: req.method, headers,
51
+ }, (proxyResponse) => {
52
+ res.writeHead(proxyResponse.statusCode ?? 502, proxyResponse.headers);
53
+ proxyResponse.pipe(res);
54
+ });
55
+ proxyRequest.on('error', next);
56
+ if (req.headers['content-length'] && req.body !== undefined) {
57
+ const body = JSON.stringify(req.body);
58
+ proxyRequest.setHeader('content-length', Buffer.byteLength(body));
59
+ proxyRequest.write(body);
60
+ }
61
+ proxyRequest.end();
62
+ } catch (error) { next(error); }
63
+ });
64
+ router.delete('/:name', respond((req) => service.uninstall(routeParameter(req.params.name))));
65
+ return router;
66
+ }