@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,4 +1,5 @@
1
1
  import type { IncomingMessage } from 'node:http';
2
+ import type { Readable } from 'node:stream';
2
3
 
3
4
  //----------------- HTTP RESPONSE SHAPES ------------
4
5
  /**
@@ -74,6 +75,10 @@ export type ProviderModelOption = {
74
75
  value: string;
75
76
  label: string;
76
77
  description?: string;
78
+ /** Stable SQLite row id used only by model-management actions. */
79
+ recordId?: number;
80
+ /** True for user-created rows; false for immutable CloudCLI defaults. */
81
+ isCustom?: boolean;
77
82
  effort?: {
78
83
  default?: string;
79
84
  values: {
@@ -92,28 +97,31 @@ export type ProviderModelsDefinition = {
92
97
  };
93
98
 
94
99
  /**
95
- * Cache metadata returned alongside one provider model catalog.
100
+ * One persisted custom-model row in the provider model library.
96
101
  *
97
- * `updatedAt` is when the current cached snapshot was last refreshed from the
98
- * provider itself. `expiresAt` is the backend cache expiry timestamp, and
99
- * `source` tells callers whether the current response came from in-memory cache,
100
- * persisted disk cache, or a fresh provider fetch.
102
+ * Provider modules use this shape at the database boundary. Predefined models
103
+ * never use this type because they remain source-controlled in provider
104
+ * adapters. `modelId` is sent to the provider runtime, while `model` is the
105
+ * user-supplied display name shown in pickers.
101
106
  */
102
- export type ProviderModelsCacheInfo = {
103
- updatedAt: string;
104
- expiresAt: string;
105
- source: 'memory' | 'disk' | 'fresh';
107
+ export type CustomProviderModelRecord = {
108
+ recordId: number;
109
+ provider: LLMProvider;
110
+ modelId: string;
111
+ model: string;
112
+ sortOrder: number;
106
113
  };
107
114
 
108
115
  /**
109
- * Full provider model lookup result returned by the backend service layer.
116
+ * User-editable values accepted when creating or changing a custom model.
110
117
  *
111
- * Use this shape when a caller needs both the selectable model catalog and the
112
- * cache metadata that explains how current the catalog is.
118
+ * `id` must be the exact provider-facing model identifier and cannot contain
119
+ * whitespace. `model` is a concise display name. The provider is supplied by
120
+ * the route path so a row can never be moved across providers accidentally.
113
121
  */
114
- export type ProviderModelsResult = {
115
- models: ProviderModelsDefinition;
116
- cache: ProviderModelsCacheInfo;
122
+ export type CustomProviderModelInput = {
123
+ id: string;
124
+ model: string;
117
125
  };
118
126
 
119
127
  // ---------------------------
@@ -131,34 +139,35 @@ export type ProviderCurrentActiveModel = {
131
139
  };
132
140
 
133
141
  /**
134
- * Input payload used when one session needs to use a different model on its
135
- * next resumed turn.
142
+ * Where a resolved session model came from.
136
143
  *
137
- * This is a backend-owned session override, not a claim that the provider has
138
- * already switched the currently running session in-place. Provider adapters
139
- * persist this request so the next CLI/SDK resume can inject the chosen model
140
- * using the provider-specific mechanism supported by that runtime.
144
+ * `session` means the app has recorded a model for this session (the user
145
+ * picked one, or the session has been sent on at least once) and that value is
146
+ * authoritative. `provider` means the session predates any app-recorded model
147
+ * and the value was read back from the provider's own session state — the case
148
+ * for sessions started directly in a provider CLI. `default` means neither was
149
+ * available and the catalog default is standing in.
150
+ *
151
+ * Routes surface this so the frontend can tell a real selection apart from a
152
+ * placeholder without re-deriving the precedence chain.
141
153
  */
142
- export type ProviderChangeActiveModelInput = {
143
- sessionId: string;
144
- model: string;
145
- };
154
+ export type ProviderSessionModelSource = 'session' | 'provider' | 'default';
146
155
 
147
156
  /**
148
- * Provider-neutral session model-change state.
157
+ * The model one session runs with, its persisted reasoning effort when one has
158
+ * been recorded, and where the model answer came from.
149
159
  *
150
- * `supported` indicates whether the provider adapter supports the app's
151
- * session-scoped resume override flow. `changed` is the persisted boolean the
152
- * resume layer checks before forcing a model on the next resumed turn. When
153
- * `changed` is `false`, `model` is `null` and the runtime should use the
154
- * normal request/default model selection path.
160
+ * Returned by `providerModelsService.resolveSessionModel` and used by the
161
+ * `/models`, `/cost` and `/status` commands, the active-model route, and the
162
+ * composer's model picker so every surface agrees on one answer.
155
163
  */
156
- export type ProviderSessionActiveModelChange = {
164
+ export type ProviderSessionModel = {
157
165
  provider: LLMProvider;
158
- sessionId: string;
159
- supported: boolean;
160
- changed: boolean;
161
- model: string | null;
166
+ sessionId: string | null;
167
+ model: string;
168
+ /** NULL means this session has not recorded an effort choice yet. */
169
+ effort: string | null;
170
+ source: ProviderSessionModelSource;
162
171
  };
163
172
 
164
173
  /**
@@ -243,6 +252,8 @@ export type NormalizedMessage = {
243
252
  isLocalCommandStdout?: boolean;
244
253
  isCompactSummary?: boolean;
245
254
  images?: unknown;
255
+ /** Non-image files attached to a user turn after provider history normalization. */
256
+ files?: unknown;
246
257
  toolName?: string;
247
258
  toolInput?: unknown;
248
259
  toolId?: string;
@@ -270,6 +281,55 @@ export type NormalizedMessage = {
270
281
  [key: string]: unknown;
271
282
  };
272
283
 
284
+ /**
285
+ * Output gateway shared by WebSocket and SSE provider runs.
286
+ *
287
+ * Runtime adapters only depend on this structural surface, which keeps them
288
+ * independent from the transport that ultimately delivers normalized events.
289
+ */
290
+ export type ProviderRuntimeWriter = {
291
+ send(data: unknown): void;
292
+ setSessionId?(sessionId: string): void;
293
+ userId?: string | number | null;
294
+ isWebSocketWriter?: boolean;
295
+ isSSEStreamWriter?: boolean;
296
+ };
297
+
298
+ export type ProviderPermissionDecision = {
299
+ allow: boolean;
300
+ updatedInput?: unknown;
301
+ message?: string;
302
+ rememberEntry?: unknown;
303
+ };
304
+
305
+ export type ProviderRuntimePermissionGateway = {
306
+ resolve(requestId: string, decision: ProviderPermissionDecision): void;
307
+ listPending(sessionId: string): unknown[];
308
+ };
309
+
310
+ /**
311
+ * Provider-scoped application capabilities supplied to a runtime for one run.
312
+ *
313
+ * Keeping these lookups outside concrete SDK/CLI adapters prevents the
314
+ * adapters from importing services that resolve back through providerRegistry.
315
+ */
316
+ export type ProviderRuntimeContext = {
317
+ resolveProviderSessionId(sessionId: string | null | undefined): string | null;
318
+ resolveResumeModel(
319
+ sessionId: string | undefined,
320
+ requestedModel?: string | null,
321
+ ): Promise<string | undefined>;
322
+ getProviderModels(): Promise<ProviderModelsDefinition>;
323
+ normalizeMessage(raw: unknown, sessionId: string | null): NormalizedMessage[];
324
+ isProviderInstalled(): Promise<boolean>;
325
+ };
326
+
327
+ export type ProviderRunFunction = (
328
+ command: string,
329
+ options: AnyRecord,
330
+ writer: ProviderRuntimeWriter,
331
+ ) => Promise<unknown>;
332
+
273
333
  /**
274
334
  * Shared options used to fetch historical provider messages.
275
335
  *
@@ -580,3 +640,592 @@ export type WorkspacePathValidationResult = {
580
640
  resolvedPath?: string;
581
641
  error?: string;
582
642
  };
643
+
644
+ // ---------------------------
645
+ //----------------- GIT WORKTREE MANAGEMENT ------------
646
+ /**
647
+ * Captured output of one completed `git` invocation.
648
+ *
649
+ * Returned by `GitCommandRunner` implementations so worktree services can read
650
+ * both streams without caring about process plumbing.
651
+ */
652
+ export type GitCommandResult = {
653
+ stdout: string;
654
+ stderr: string;
655
+ };
656
+
657
+ /**
658
+ * Executes `git <args>` inside `cwd` and resolves with the captured output.
659
+ *
660
+ * All worktree services receive their git access through this contract so
661
+ * tests can inject a fake runner instead of spawning real processes. The
662
+ * promise must reject (with `stderr` attached when available) on a non-zero
663
+ * exit code.
664
+ */
665
+ export type GitCommandRunner = (args: string[], cwd: string) => Promise<GitCommandResult>;
666
+
667
+ /**
668
+ * One entry parsed from `git worktree list --porcelain`.
669
+ *
670
+ * This is the raw repository-level view (path/HEAD/branch/flags) before any
671
+ * enrichment with project links or ahead/behind counts. `branch` is null for
672
+ * detached-HEAD worktrees.
673
+ */
674
+ export type WorktreePorcelainEntry = {
675
+ path: string;
676
+ headSha: string | null;
677
+ branch: string | null;
678
+ isDetached: boolean;
679
+ isLocked: boolean;
680
+ isPrunable: boolean;
681
+ };
682
+
683
+ /**
684
+ * Fully enriched worktree row served to the UI.
685
+ *
686
+ * Extends the porcelain entry with everything the Worktrees panel renders:
687
+ * dirty-file count, ahead/behind relative to the base branch (the branch
688
+ * checked out in the main worktree), last-commit metadata, and the CloudCLI
689
+ * project row linked to the worktree directory (if one was registered).
690
+ */
691
+ export type WorktreeDescriptor = {
692
+ path: string;
693
+ branch: string | null;
694
+ headSha: string | null;
695
+ isMain: boolean;
696
+ isCurrent: boolean;
697
+ isLocked: boolean;
698
+ isDetached: boolean;
699
+ changedFileCount: number;
700
+ ahead: number;
701
+ behind: number;
702
+ lastCommitSubject: string | null;
703
+ lastCommitDate: string | null;
704
+ linkedProjectId: string | null;
705
+ linkedProjectArchived: boolean;
706
+ };
707
+
708
+ /**
709
+ * Response payload of `GET /api/worktrees`.
710
+ *
711
+ * `baseBranch` is the branch checked out in the main worktree — the merge
712
+ * target offered by the UI. `worktrees` always lists the main worktree first.
713
+ */
714
+ export type WorktreeListResult = {
715
+ repositoryRoot: string;
716
+ baseBranch: string | null;
717
+ worktrees: WorktreeDescriptor[];
718
+ };
719
+
720
+ // ---------------------------
721
+ //----------------- WORKTREE SERVICE INPUTS AND RESULTS ------------
722
+ /**
723
+ * Input accepted by the worktree-listing workflow.
724
+ *
725
+ * `projectPath` may point at the main checkout or any linked worktree. The
726
+ * service uses Git to resolve the complete repository-level worktree list.
727
+ */
728
+ export type ListWorktreesInput = {
729
+ projectPath: string;
730
+ };
731
+
732
+ /**
733
+ * Input accepted when creating a linked Git worktree.
734
+ *
735
+ * `branch` is checked out when it already exists, otherwise it is created from
736
+ * `baseBranch`. When `baseBranch` is omitted, the main worktree branch is used.
737
+ */
738
+ export type CreateWorktreeInput = {
739
+ projectPath: string;
740
+ branch: string;
741
+ baseBranch?: string | null;
742
+ };
743
+
744
+ /**
745
+ * Result of successfully creating a linked Git worktree.
746
+ *
747
+ * `createdBranch` distinguishes a new branch from an existing branch checkout,
748
+ * allowing API clients to accurately describe what Git changed.
749
+ */
750
+ export type CreateWorktreeResult = {
751
+ worktreePath: string;
752
+ branch: string;
753
+ createdBranch: boolean;
754
+ };
755
+
756
+ /**
757
+ * Result of atomically creating and registering a worktree for project use.
758
+ *
759
+ * The Worktrees application service compensates the Git creation if project
760
+ * registration fails, so routes only receive this shape after both steps pass.
761
+ */
762
+ export type CreateAndOpenWorktreeResult = CreateWorktreeResult & {
763
+ project: WorktreeProjectView;
764
+ };
765
+
766
+ /**
767
+ * Input accepted when registering an existing worktree as a CloudCLI project.
768
+ *
769
+ * The service verifies that `worktreePath` belongs to the repository containing
770
+ * `projectPath` before it creates or restores any project record.
771
+ */
772
+ export type OpenWorktreeInput = {
773
+ projectPath: string;
774
+ worktreePath: string;
775
+ };
776
+
777
+ /**
778
+ * Project view returned after a worktree is opened in CloudCLI.
779
+ *
780
+ * This deliberately mirrors the project-selection payload used by the Projects
781
+ * module so the frontend can switch to the worktree without another lookup.
782
+ */
783
+ export type WorktreeProjectView = {
784
+ projectId: string;
785
+ path: string;
786
+ fullPath: string;
787
+ displayName: string;
788
+ isStarred: boolean;
789
+ sessions: [];
790
+ sessionMeta: { hasMore: false; total: 0 };
791
+ };
792
+
793
+ /**
794
+ * Input accepted when removing a linked Git worktree.
795
+ *
796
+ * `force` permits removal with local changes. `deleteBranch` requests
797
+ * best-effort branch cleanup after the worktree directory is removed.
798
+ */
799
+ export type RemoveWorktreeInput = {
800
+ projectPath: string;
801
+ worktreePath: string;
802
+ force?: boolean;
803
+ deleteBranch?: boolean;
804
+ };
805
+
806
+ /**
807
+ * Result of removing a linked Git worktree.
808
+ *
809
+ * `archivalError` reports best-effort project archival failure after Git has
810
+ * already removed the worktree, allowing callers to represent partial success.
811
+ */
812
+ export type RemoveWorktreeResult = {
813
+ removedPath: string;
814
+ branch: string | null;
815
+ branchDeleted: boolean;
816
+ archivedProjectId: string | null;
817
+ archivalError: string | null;
818
+ };
819
+
820
+ /**
821
+ * Input accepted when merging a linked worktree into the main worktree branch.
822
+ *
823
+ * The service verifies both worktrees are clean, supports squash and regular
824
+ * merges, and may remove the source worktree after a successful merge.
825
+ */
826
+ export type MergeWorktreeInput = {
827
+ projectPath: string;
828
+ worktreePath: string;
829
+ squash?: boolean;
830
+ message?: string | null;
831
+ removeAfterMerge?: boolean;
832
+ };
833
+
834
+ /**
835
+ * Result of a completed worktree merge.
836
+ *
837
+ * `removedWorktree` is populated only when post-merge removal succeeds.
838
+ * `cleanupError` reports failed optional removal without misrepresenting the
839
+ * already-completed merge as a failure.
840
+ */
841
+ export type MergeWorktreeResult = {
842
+ mergedBranch: string;
843
+ targetBranch: string;
844
+ squash: boolean;
845
+ removedWorktree: RemoveWorktreeResult | null;
846
+ cleanupError: string | null;
847
+ };
848
+
849
+ // ---------------------------
850
+ //----------------- WORKTREE MODULE DEPENDENCY CONTRACTS ------------
851
+ /**
852
+ * Filesystem capability required by the Worktrees module.
853
+ *
854
+ * Production wiring checks the real filesystem; unit tests provide a small
855
+ * deterministic fake so worktree creation never touches developer directories.
856
+ */
857
+ export type WorktreeFileSystem = {
858
+ pathExists(candidatePath: string): Promise<boolean>;
859
+ };
860
+
861
+ /**
862
+ * Project-management boundary consumed by Worktrees workflows.
863
+ *
864
+ * The Worktrees module uses this contract instead of importing Database or
865
+ * Projects internals. Production adapters delegate through those modules'
866
+ * `index.ts` barrels, while unit tests supply in-memory functions.
867
+ */
868
+ export type WorktreeProjectGateway = {
869
+ getProjectPathById(projectId: string): string | null;
870
+ getProjectByPath(projectPath: string): ProjectRepositoryRow | null;
871
+ createProject(input: {
872
+ projectPath: string;
873
+ customName: string;
874
+ }): Promise<{
875
+ outcome: 'created' | 'reactivated_archived';
876
+ project: { projectId: string };
877
+ }>;
878
+ restoreProject(projectId: string): void | Promise<void>;
879
+ archiveProject(projectId: string): void | Promise<void>;
880
+ };
881
+
882
+ /**
883
+ * Complete application-service surface used by the Worktrees HTTP router.
884
+ *
885
+ * Routes parse transport values and call these functions; they do not import
886
+ * repositories, filesystem adapters, Git runners, or individual service files.
887
+ */
888
+ export type WorktreeServices = {
889
+ resolveProjectPath(projectId: string): string;
890
+ list(input: ListWorktreesInput): Promise<WorktreeListResult>;
891
+ create(input: CreateWorktreeInput): Promise<CreateWorktreeResult>;
892
+ createAndOpen(input: CreateWorktreeInput): Promise<CreateAndOpenWorktreeResult>;
893
+ open(input: OpenWorktreeInput): Promise<WorktreeProjectView>;
894
+ merge(input: MergeWorktreeInput): Promise<MergeWorktreeResult>;
895
+ remove(input: RemoveWorktreeInput): Promise<RemoveWorktreeResult>;
896
+ };
897
+
898
+ // ---------------------------
899
+ //----------------- FILE TREE MODULE CONTRACTS ------------
900
+ /**
901
+ * One filesystem item returned by the File Tree API.
902
+ *
903
+ * The service populates metadata without following symlinks and recursively
904
+ * attaches `children` only while the requested depth permits traversal. The
905
+ * frontend uses the absolute `path` as the stable identifier for editor and
906
+ * file-operation requests.
907
+ */
908
+ export type FileTreeNode = {
909
+ name: string;
910
+ path: string;
911
+ type: 'file' | 'directory';
912
+ size: number;
913
+ modified: string | null;
914
+ permissions: string;
915
+ permissionsRwx: string;
916
+ isSymlink?: boolean;
917
+ children?: FileTreeNode[];
918
+ };
919
+
920
+ /**
921
+ * Minimal directory-entry shape required during File Tree traversal.
922
+ *
923
+ * Production adapts Node `Dirent` objects to this structural contract. Tests
924
+ * provide small handwritten entries and therefore never read real directories.
925
+ */
926
+ export type FileTreeDirectoryEntry = {
927
+ name: string;
928
+ isDirectory(): boolean;
929
+ };
930
+
931
+ /**
932
+ * Minimal file-stat shape used for tree metadata and delete decisions.
933
+ *
934
+ * The numeric mode is converted to octal and rwx strings for the UI. `lstat`
935
+ * supplies symlink state while `stat` is used when deciding file versus folder
936
+ * deletion behavior.
937
+ */
938
+ export type FileTreeStats = {
939
+ size: number;
940
+ mtime: Date;
941
+ mode: number;
942
+ isDirectory(): boolean;
943
+ isSymbolicLink(): boolean;
944
+ };
945
+
946
+ /**
947
+ * Complete filesystem capability injected into File Tree services.
948
+ *
949
+ * The production composition root delegates these operations to Node's fs
950
+ * APIs. Unit tests provide deterministic path-keyed fakes so service tests
951
+ * cannot inspect, write, rename, or delete developer files.
952
+ */
953
+ export type FileTreeFileSystem = {
954
+ access(candidatePath: string): Promise<void>;
955
+ stat(candidatePath: string): Promise<FileTreeStats>;
956
+ lstat(candidatePath: string): Promise<FileTreeStats>;
957
+ // Streamed rather than returned as an array so a directory with millions of
958
+ // children is abandoned at the entry limit instead of being materialized.
959
+ openDirectory(directoryPath: string): AsyncIterable<FileTreeDirectoryEntry>;
960
+ realpath(candidatePath: string): Promise<string>;
961
+ readTextFile(filePath: string): Promise<string>;
962
+ writeTextFile(filePath: string, content: string): Promise<void>;
963
+ makeDirectory(directoryPath: string, recursive: boolean): Promise<void>;
964
+ rename(oldPath: string, newPath: string): Promise<void>;
965
+ removeDirectory(directoryPath: string): Promise<void>;
966
+ unlink(filePath: string): Promise<void>;
967
+ copyFile(sourcePath: string, destinationPath: string): Promise<void>;
968
+ createReadStream(filePath: string): Readable;
969
+ };
970
+
971
+ /**
972
+ * Project lookup boundary consumed by File Tree workflows.
973
+ *
974
+ * File Tree services resolve DB-assigned project ids through this contract and
975
+ * never import the Database module or its repositories directly.
976
+ */
977
+ export type FileTreeProjectGateway = {
978
+ getProjectPathById(projectId: string): string | null | Promise<string | null>;
979
+ };
980
+
981
+ /**
982
+ * Workspace validation boundary used by filesystem browsing and folder creation.
983
+ *
984
+ * The injected validator enforces the configured workspace root and resolves
985
+ * symlinks before the File Tree service exposes or mutates paths.
986
+ */
987
+ export type FileTreeWorkspaceGateway = {
988
+ rootPath: string;
989
+ validatePath(candidatePath: string): Promise<WorkspacePathValidationResult>;
990
+ };
991
+
992
+ /**
993
+ * Uploaded-file record passed from the Multer transport adapter into the File
994
+ * Tree service.
995
+ *
996
+ * Transport-specific field names are normalized so upload workflows do not
997
+ * depend on Express or Multer types.
998
+ */
999
+ export type FileTreeUploadedFile = {
1000
+ originalName: string;
1001
+ temporaryPath: string;
1002
+ size: number;
1003
+ mimeType: string;
1004
+ };
1005
+
1006
+ /**
1007
+ * Logger boundary for expected File Tree diagnostics.
1008
+ *
1009
+ * Production delegates to the server console. Unit tests use no-op or captured
1010
+ * loggers and never patch the global console singleton.
1011
+ */
1012
+ export type FileTreeLogger = {
1013
+ error(message: string, error?: unknown): void;
1014
+ };
1015
+
1016
+ /**
1017
+ * Required production dependencies for the File Tree application service.
1018
+ *
1019
+ * Filesystem, project lookup, workspace policy, MIME detection, concurrency,
1020
+ * and logging are all explicit so service construction has no hidden process,
1021
+ * repository, or machine-wide defaults.
1022
+ */
1023
+ export type FileTreeServiceDependencies = {
1024
+ fileSystem: FileTreeFileSystem;
1025
+ projects: FileTreeProjectGateway;
1026
+ workspace: FileTreeWorkspaceGateway;
1027
+ resolveMimeType(filePath: string): string;
1028
+ fileSystemConcurrency: number;
1029
+ logger: FileTreeLogger;
1030
+ };
1031
+
1032
+ /**
1033
+ * Complete File Tree application-service surface consumed by HTTP routes.
1034
+ *
1035
+ * Routes parse transport inputs and call these methods; they never resolve
1036
+ * project repositories, validate filesystem ownership, or perform filesystem
1037
+ * mutations themselves.
1038
+ */
1039
+ export type FileTreeServices = {
1040
+ browseWorkspace(inputPath: string | null): Promise<{
1041
+ path: string;
1042
+ suggestions: Array<{ path: string; name: string; type: 'directory' }>;
1043
+ }>;
1044
+ createWorkspaceFolder(folderPath: string): Promise<{ success: true; path: string }>;
1045
+ readTextFile(projectId: string, filePath: string): Promise<{ content: string; path: string }>;
1046
+ openFile(projectId: string, filePath: string): Promise<{ contentType: string; stream: Readable }>;
1047
+ saveTextFile(projectId: string, filePath: string, content: string): Promise<{
1048
+ success: true;
1049
+ path: string;
1050
+ message: string;
1051
+ }>;
1052
+ listProjectFiles(
1053
+ projectId: string,
1054
+ options?: { respectGitignore: boolean },
1055
+ ): Promise<FileTreeNode[]>;
1056
+ createEntry(input: {
1057
+ projectId: string;
1058
+ parentPath: string;
1059
+ type: 'file' | 'directory';
1060
+ name: string;
1061
+ }): Promise<{ success: true; path: string; name: string; type: 'file' | 'directory'; message: string }>;
1062
+ renameEntry(input: { projectId: string; oldPath: string; newName: string }): Promise<{
1063
+ success: true;
1064
+ oldPath: string;
1065
+ newPath: string;
1066
+ newName: string;
1067
+ message: string;
1068
+ }>;
1069
+ deleteEntry(input: { projectId: string; targetPath: string }): Promise<{
1070
+ success: true;
1071
+ path: string;
1072
+ type: 'file' | 'directory';
1073
+ message: string;
1074
+ }>;
1075
+ storeUploadedFiles(input: {
1076
+ projectId: string;
1077
+ targetPath: string;
1078
+ relativePaths: string[];
1079
+ requestedFileCount: number;
1080
+ files: FileTreeUploadedFile[];
1081
+ }): Promise<{
1082
+ success: true;
1083
+ files: Array<{ name: string; path: string; size: number; mimeType: string }>;
1084
+ uploadedCount: number;
1085
+ requestedFileCount: number;
1086
+ targetPath: string;
1087
+ message: string;
1088
+ }>;
1089
+ };
1090
+
1091
+ // ---------------------------
1092
+ //----------------- VOICE MODULE CONTRACTS ------------
1093
+ /**
1094
+ * Per-request voice settings parsed from authenticated HTTP headers.
1095
+ *
1096
+ * The Voice routes create this value from the optional `x-voice-*` headers and
1097
+ * pass it to the Voice service. Empty values mean "use the server-configured
1098
+ * default"; the backend base URL is intentionally absent because clients must
1099
+ * never control the server's outbound destination.
1100
+ */
1101
+ export type VoiceRequestOverrides = {
1102
+ apiKey?: string;
1103
+ sttModel?: string;
1104
+ ttsModel?: string;
1105
+ ttsVoice?: string;
1106
+ ttsFormat?: string;
1107
+ };
1108
+
1109
+ /**
1110
+ * Uploaded audio accepted by the Voice transcription service.
1111
+ *
1112
+ * Routes translate Multer's transport-specific file object into this minimal
1113
+ * shape so the service does not depend on Express or Multer types.
1114
+ */
1115
+ export type VoiceAudioUpload = {
1116
+ bytes: Buffer;
1117
+ mimeType: string;
1118
+ fileName: string;
1119
+ };
1120
+
1121
+ /**
1122
+ * Successful speech payload returned by the Voice service.
1123
+ *
1124
+ * The route copies `contentType` to the client response and pipes `body`
1125
+ * without buffering the complete synthesized audio in application memory.
1126
+ */
1127
+ export type VoiceSpeechPayload = {
1128
+ contentType: string;
1129
+ body: ReadableStream<Uint8Array> | null;
1130
+ };
1131
+
1132
+ /**
1133
+ * Explicit service result used by Voice routes instead of transport-aware
1134
+ * exceptions.
1135
+ *
1136
+ * Services return `ok: false` with the exact client status/message for expected
1137
+ * backend, validation, and timeout failures. Routes only translate the result
1138
+ * into HTTP output, while unexpected programming errors still reject normally.
1139
+ */
1140
+ export type VoiceServiceResult<TValue> =
1141
+ | { ok: true; value: TValue }
1142
+ | { ok: false; status: number; error: string };
1143
+
1144
+ /**
1145
+ * Complete application-service surface consumed by the Voice HTTP router.
1146
+ *
1147
+ * The composition root supplies a concrete implementation with environment
1148
+ * configuration and an injected outbound HTTP adapter. Unit tests use the same
1149
+ * contract with handwritten fetch fakes and never patch global state.
1150
+ */
1151
+ export type VoiceService = {
1152
+ getHealth(): { configured: boolean };
1153
+ transcribe(input: {
1154
+ audio: VoiceAudioUpload;
1155
+ overrides: VoiceRequestOverrides;
1156
+ }): Promise<VoiceServiceResult<{ text: string }>>;
1157
+ synthesizeSpeech(input: {
1158
+ text: string;
1159
+ overrides: VoiceRequestOverrides;
1160
+ }): Promise<VoiceServiceResult<VoiceSpeechPayload>>;
1161
+ };
1162
+
1163
+ // ---------------------------
1164
+ //----------------- CLI MODULE CONTRACTS ------------
1165
+ /**
1166
+ * Output boundary used by the CLI and Sandbox services.
1167
+ *
1168
+ * Production wiring delegates to the real console. Unit tests collect these
1169
+ * calls in arrays, which keeps command assertions deterministic and avoids
1170
+ * monkey-patching the global console singleton.
1171
+ */
1172
+ export type CliOutput = {
1173
+ log(message?: string): void;
1174
+ error(message?: string): void;
1175
+ };
1176
+
1177
+ /**
1178
+ * Minimal synchronous filesystem surface shared by CLI status reporting and
1179
+ * sandbox workspace validation.
1180
+ *
1181
+ * The production composition root adapts Node's filesystem module. Tests supply
1182
+ * path-keyed fakes, so service tests never inspect or modify the real machine.
1183
+ */
1184
+ export type CliFileSystem = {
1185
+ readTextFile(filePath: string): string;
1186
+ pathExists(filePath: string): boolean;
1187
+ getFileStats(filePath: string): { size: number; modifiedAt: Date };
1188
+ };
1189
+
1190
+ /**
1191
+ * Mutable environment view owned by the CLI application.
1192
+ *
1193
+ * CLI options update this object before the server starts. Production passes
1194
+ * `process.env`; tests pass a plain record to verify option precedence without
1195
+ * changing process-wide environment state.
1196
+ */
1197
+ export type CliEnvironment = Record<string, string | undefined>;
1198
+
1199
+ /**
1200
+ * Package metadata displayed by CLI help, status, version, and update commands.
1201
+ *
1202
+ * The composition root reads this once from the application package file and
1203
+ * injects only the fields the service needs.
1204
+ */
1205
+ export type CliPackageMetadata = {
1206
+ version: string;
1207
+ homepage?: string;
1208
+ bugsUrl?: string;
1209
+ };
1210
+
1211
+ /**
1212
+ * Executable CLI application returned by the CLI composition root.
1213
+ *
1214
+ * The thin executable entrypoint passes `process.argv` arguments to `run` and
1215
+ * copies the returned code to `process.exitCode`. Tests invoke the same method
1216
+ * directly with isolated dependencies.
1217
+ */
1218
+ export type CliApplication = {
1219
+ run(argumentsList: string[]): Promise<number>;
1220
+ };
1221
+
1222
+ /**
1223
+ * Sandbox command service consumed by the top-level CLI command dispatcher.
1224
+ *
1225
+ * Keeping this behind one required dependency lets CLI tests use a tiny fake,
1226
+ * while focused Sandbox tests exercise subprocess and filesystem behavior with
1227
+ * their own handwritten adapters.
1228
+ */
1229
+ export type SandboxCommandService = {
1230
+ execute(argumentsList: string[]): Promise<number>;
1231
+ };