wind-agent-cli 1.37.2 → 1.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (510) hide show
  1. package/LICENSE +718 -718
  2. package/README.md +17 -2
  3. package/dist/api-docs.html +901 -901
  4. package/dist/assets/{CodeEditor-B2Wf7Fg0.js → CodeEditor-FvgsnJ7J.js} +6 -6
  5. package/dist/assets/FileTree-NLULrBDi.js +1 -0
  6. package/dist/assets/GitPanel-51KUBbEW.js +4 -0
  7. package/dist/assets/{MarkdownPreview-C0tqYnVu.js → MarkdownPreview-PEEWVWeS.js} +17 -27
  8. package/dist/assets/Shell-BEx66cW_.js +76 -0
  9. package/dist/assets/Shell-DrlLKa8f.css +1 -0
  10. package/dist/assets/StandaloneShell-BkuUCPZP.js +1 -0
  11. package/dist/assets/TaskMasterPanel-DfQG80SF.js +2 -0
  12. package/dist/assets/abnfDiagram-N423BO3Z-Cc0ul87U.js +1 -0
  13. package/dist/assets/arc-BAuugHw_.js +1 -0
  14. package/dist/assets/architectureDiagram-T3A2C74G-DA3G7QZD.js +36 -0
  15. package/dist/assets/{blockDiagram-VBNYF7ZC-DpaEf3mv.js → blockDiagram-VBNYF7ZC-tJ12IJs3.js} +4 -4
  16. package/dist/assets/c4Diagram-5PPSVZJV-5BTMCXL4.js +10 -0
  17. package/dist/assets/channel-BGDgNNQz.js +1 -0
  18. package/dist/assets/{chunk-2GRJ4B5K-DoSdNo8u.js → chunk-2GRJ4B5K-BPaI06Ou.js} +1 -1
  19. package/dist/assets/{chunk-2Q5K7J3B-CE7I3uMn.js → chunk-2Q5K7J3B-HV4zmsEe.js} +1 -1
  20. package/dist/assets/chunk-5RXB4S5H-BAwutJoU.js +231 -0
  21. package/dist/assets/{chunk-5VM5RSS4-B55XgqHZ.js → chunk-5VM5RSS4-B9QAJPrv.js} +1 -1
  22. package/dist/assets/{chunk-6Q2QTUOP-BS1KpefW.js → chunk-6Q2QTUOP-BOIW8bzI.js} +1 -1
  23. package/dist/assets/chunk-GF5L2VYU-DD13o00-.js +206 -0
  24. package/dist/assets/{chunk-JWPE2WC7-DOtkNhMm.js → chunk-JWPE2WC7-CFBm23VK.js} +1 -1
  25. package/dist/assets/{chunk-KBJHAD2P-BXLjviqM.js → chunk-KBJHAD2P-C0i0v8Op.js} +1 -1
  26. package/dist/assets/{chunk-RYQCIY6F-C50fjNNz.js → chunk-RYQCIY6F-DfeK0taV.js} +1 -1
  27. package/dist/assets/{chunk-XXDRQBXY-QBYqCkb7.js → chunk-XXDRQBXY-BKWvf-QE.js} +1 -1
  28. package/dist/assets/classDiagram-JCYQIIEL-C2SNM4oy.js +1 -0
  29. package/dist/assets/classDiagram-v2-OCEON4UE-C2SNM4oy.js +1 -0
  30. package/dist/assets/cose-bilkent-JH36ORCC-CBE8oM7L.js +1 -0
  31. package/dist/assets/{cynefin-VYW2F7L2-DnJa_OlQ.js → cynefin-VYW2F7L2-DziGp35A.js} +11 -23
  32. package/dist/assets/cynefinDiagram-MW4NZA55-CNvtHl39.js +62 -0
  33. package/dist/assets/cytoscape.esm-yzknjiTM.js +321 -0
  34. package/dist/assets/dagre-VZM6K2ZE-Bz9lsU7m.js +4 -0
  35. package/dist/assets/{diagram-7IWD3JNH-pFzs9HEu.js → diagram-7IWD3JNH-CV7D3VSd.js} +5 -5
  36. package/dist/assets/{diagram-B4RE2ZJO-CcehQC7x.js → diagram-B4RE2ZJO-Dj4EjDNC.js} +2 -2
  37. package/dist/assets/diagram-LBJQPF4R-wJ6FHvf-.js +24 -0
  38. package/dist/assets/diagram-Q27KOJAE-DMFYMhOB.js +24 -0
  39. package/dist/assets/diagram-UB23O5K3-DeBSbWAI.js +41 -0
  40. package/dist/assets/ebnfDiagram-BXEA7PRR-2NnJSGhT.js +1 -0
  41. package/dist/assets/erDiagram-JOGREHBK-DrSlg8hr.js +85 -0
  42. package/dist/assets/feature-chat-CvOCyaLe.js +88 -0
  43. package/dist/assets/feature-workspace-CAB6bgPy.js +39 -0
  44. package/dist/assets/{flowDiagram-UKHOOZJN-CJV8fQPR.js → flowDiagram-UKHOOZJN-C0pejU6W.js} +4 -4
  45. package/dist/assets/ganttDiagram-PKOTCBZU-BM0VCUUz.js +292 -0
  46. package/dist/assets/gitGraphDiagram-DS77QQ5N-SbLG0c5_.js +106 -0
  47. package/dist/assets/graph-DOmOIIwC.js +1 -0
  48. package/dist/assets/{index-GFhXZyl2.js → index-BflGfU1C.js} +3 -3
  49. package/dist/assets/index-Btkf0_rU.js +1 -0
  50. package/dist/assets/index-Cr5MbHuj.css +1 -0
  51. package/dist/assets/index-Gqazqfs3.js +1 -0
  52. package/dist/assets/index-nyrkoQK6.js +35 -0
  53. package/dist/assets/infoDiagram-6WML65LV-Cf5DSa66.js +2 -0
  54. package/dist/assets/ishikawaDiagram-WSZJBQD7-DwyFutKy.js +70 -0
  55. package/dist/assets/journeyDiagram-NVQOT4AX-Df0FRhLo.js +139 -0
  56. package/dist/assets/{kanban-definition-27J2QSJJ-B3iL0ztJ.js → kanban-definition-27J2QSJJ-HmpbjrZz.js} +6 -6
  57. package/dist/assets/{layout-D6BstSzF.js → layout-D-LzfAck.js} +1 -1
  58. package/dist/assets/{linear-Cwe9dEKA.js → linear-DOM01LBe.js} +1 -1
  59. package/dist/assets/map-DxJ2ADlA.js +1 -0
  60. package/dist/assets/mermaid.core-C2Ma-_S6.js +306 -0
  61. package/dist/assets/{mindmap-definition-FAOFIHXS-BgfBYMzr.js → mindmap-definition-FAOFIHXS-B4GOIn76.js} +4 -4
  62. package/dist/assets/pegDiagram-VL7TDLO6-BHur7aH2.js +1 -0
  63. package/dist/assets/{pieDiagram-7S7Q4E2Y-DeSrxc4I.js → pieDiagram-7S7Q4E2Y-Cw0UELLV.js} +2 -2
  64. package/dist/assets/quadrantDiagram-CIZ2JOQS-CB2BrX3g.js +7 -0
  65. package/dist/assets/railroadDiagram-AXF67PYL-DPYZYmLX.js +1 -0
  66. package/dist/assets/requirementDiagram-LRYGKXZP-DSX4IJ1n.js +84 -0
  67. package/dist/assets/sankeyDiagram-W5VNT64P-TenC3ZQo.js +40 -0
  68. package/dist/assets/sequenceDiagram-SI44F4Z6-DltGsf3F.js +162 -0
  69. package/dist/assets/sizeCapture-X5ZJPWSS-D7llwbJZ.js +1 -0
  70. package/dist/assets/stateDiagram-OKZ733FA-C-hAvbnY.js +1 -0
  71. package/dist/assets/stateDiagram-v2-UEYNNEHI-DaYSFcRQ.js +1 -0
  72. package/dist/assets/swimlanes-SLNWSIFB-DWD30fv6.js +2 -0
  73. package/dist/assets/swimlanesDiagram-ULZ7WXOC-LTkF2T6t.js +8 -0
  74. package/dist/assets/timeline-definition-Z64GVDOM-quWmimSE.js +120 -0
  75. package/dist/assets/vendor-data-DsEZeNPr.js +4 -0
  76. package/dist/assets/vendor-i18n-B6HjLCnN.js +1 -0
  77. package/dist/assets/vendor-markdown-DkITEES2.js +298 -0
  78. package/dist/assets/vendor-react-C2GTiUCy.js +10 -0
  79. package/dist/assets/vendor-ui-CAUHSABu.js +49 -0
  80. package/dist/assets/vennDiagram-T6HMQDX7-aUQcm8h5.js +34 -0
  81. package/dist/assets/{wardleyDiagram-T6FBY63Y-BNCpsFZV.js → wardleyDiagram-T6FBY63Y-BZ0bwsFQ.js} +2 -2
  82. package/dist/assets/workbox-window.prod.es5-BBnX5xw4.js +2 -0
  83. package/dist/assets/xychartDiagram-ELKLHX3M-DOVzAq63.js +7 -0
  84. package/dist/clear-cache.html +85 -85
  85. package/dist/convert-icons.md +52 -52
  86. package/dist/favicon.png +0 -0
  87. package/dist/favicon.svg +8 -8
  88. package/dist/generate-icons.js +48 -48
  89. package/dist/icons/codex-white.svg +3 -3
  90. package/dist/icons/codex.svg +3 -3
  91. package/dist/icons/cursor-white.svg +11 -11
  92. package/dist/icons/icon-128x128.png +0 -0
  93. package/dist/icons/icon-128x128.svg +11 -11
  94. package/dist/icons/icon-144x144.png +0 -0
  95. package/dist/icons/icon-144x144.svg +11 -11
  96. package/dist/icons/icon-152x152.png +0 -0
  97. package/dist/icons/icon-152x152.svg +11 -11
  98. package/dist/icons/icon-180x180.png +0 -0
  99. package/dist/icons/icon-192x192.png +0 -0
  100. package/dist/icons/icon-192x192.svg +11 -11
  101. package/dist/icons/icon-384x384.png +0 -0
  102. package/dist/icons/icon-384x384.svg +11 -11
  103. package/dist/icons/icon-512x512.png +0 -0
  104. package/dist/icons/icon-512x512.svg +11 -11
  105. package/dist/icons/icon-72x72.png +0 -0
  106. package/dist/icons/icon-72x72.svg +11 -11
  107. package/dist/icons/icon-96x96.png +0 -0
  108. package/dist/icons/icon-96x96.svg +11 -11
  109. package/dist/icons/icon-maskable-192x192.png +0 -0
  110. package/dist/icons/icon-maskable-512x512.png +0 -0
  111. package/dist/icons/icon-template.svg +11 -11
  112. package/dist/icons/new-icon.png +0 -0
  113. package/dist/index.html +48 -58
  114. package/dist/logo-128.png +0 -0
  115. package/dist/logo-256.png +0 -0
  116. package/dist/logo.svg +17 -17
  117. package/dist/manifest.webmanifest +1 -0
  118. package/dist/push-sw.js +48 -0
  119. package/dist/screenshots/setup-screen-mobile.png +0 -0
  120. package/dist/screenshots/setup-screen.png +0 -0
  121. package/dist/sw.js +1 -124
  122. package/dist/workbox-ae5c0bb2.js +1 -0
  123. package/dist-server/server/index.js +1 -1
  124. package/dist-server/server/index.js.map +1 -1
  125. package/dist-server/server/load-env.js +4 -2
  126. package/dist-server/server/load-env.js.map +1 -1
  127. package/dist-server/server/modules/agent/agent.routes.js +1 -1
  128. package/dist-server/server/modules/agent/agent.routes.js.map +1 -1
  129. package/dist-server/server/modules/browser-use/browser-use.service.js +1 -1
  130. package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
  131. package/dist-server/server/modules/cli/cli.service.js +37 -37
  132. package/dist-server/server/modules/cli/cli.service.js.map +1 -1
  133. package/dist-server/server/modules/cli/sandbox.service.js +43 -43
  134. package/dist-server/server/modules/cli/sandbox.service.js.map +1 -1
  135. package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js +74 -74
  136. package/dist-server/server/modules/commands/commands.routes.js +25 -25
  137. package/dist-server/server/modules/commands/commands.routes.js.map +1 -1
  138. package/dist-server/server/modules/commands/tests/commands.test.js +1 -1
  139. package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -1
  140. package/dist-server/server/modules/database/connection.js +1 -1
  141. package/dist-server/server/modules/database/connection.js.map +1 -1
  142. package/dist-server/server/modules/database/migrations.js +190 -190
  143. package/dist-server/server/modules/database/repositories/api-keys.js +3 -3
  144. package/dist-server/server/modules/database/repositories/github-tokens.js +2 -2
  145. package/dist-server/server/modules/database/repositories/notification-channel-endpoints.js +28 -28
  146. package/dist-server/server/modules/database/repositories/notification-preferences.js +4 -4
  147. package/dist-server/server/modules/database/repositories/projects.db.js +61 -61
  148. package/dist-server/server/modules/database/repositories/provider-models.js +35 -35
  149. package/dist-server/server/modules/database/repositories/push-subscriptions.js +5 -5
  150. package/dist-server/server/modules/database/repositories/scan-state.db.js +5 -5
  151. package/dist-server/server/modules/database/repositories/sessions.db.js +93 -93
  152. package/dist-server/server/modules/database/schema.js +177 -177
  153. package/dist-server/server/modules/database/tests/projects.db.integration.test.js +3 -2
  154. package/dist-server/server/modules/database/tests/projects.db.integration.test.js.map +1 -1
  155. package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js +6 -6
  156. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +4 -3
  157. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js.map +1 -1
  158. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js +2 -1
  159. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -1
  160. package/dist-server/server/modules/git/git.routes.js +17 -17
  161. package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js +1 -1
  162. package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js.map +1 -1
  163. package/dist-server/server/modules/notifications/vapid-keys.service.js +1 -1
  164. package/dist-server/server/modules/notifications/vapid-keys.service.js.map +1 -1
  165. package/dist-server/server/modules/projects/tests/project-management.service.test.js +2 -1
  166. package/dist-server/server/modules/projects/tests/project-management.service.test.js.map +1 -1
  167. package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js +2 -2
  168. package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js.map +1 -1
  169. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +1 -1
  170. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
  171. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +1 -1
  172. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -1
  173. package/dist-server/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.js.map +1 -1
  174. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +13 -13
  175. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js +9 -9
  176. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js +17 -17
  177. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +25 -25
  178. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +27 -27
  179. package/dist-server/server/modules/providers/services/provider-token-usage.service.js +9 -9
  180. package/dist-server/server/modules/providers/services/sessions.service.js +1 -1
  181. package/dist-server/server/modules/providers/tests/claude-auth.test.js +8 -0
  182. package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -1
  183. package/dist-server/server/modules/providers/tests/codex-sessions.test.js +1 -1
  184. package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
  185. package/dist-server/server/modules/providers/tests/mcp.test.js +3 -3
  186. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +98 -98
  187. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -1
  188. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +18 -18
  189. package/dist-server/server/modules/providers/tests/provider.routes.test.js +1 -1
  190. package/dist-server/server/modules/providers/tests/provider.routes.test.js.map +1 -1
  191. package/dist-server/server/modules/system/system.service.js +1 -1
  192. package/dist-server/server/modules/system/system.service.js.map +1 -1
  193. package/dist-server/server/modules/system/tests/system.service.test.js +1 -1
  194. package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -1
  195. package/dist-server/server/modules/taskmaster/taskmaster.routes.js +423 -422
  196. package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -1
  197. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +1 -1
  198. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
  199. package/dist-server/server/modules/worktrees/services/worktree-list.service.js +1 -1
  200. package/dist-server/server/modules/worktrees/services/worktree-open.service.js +1 -1
  201. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +1 -1
  202. package/electron/cloud.js +260 -260
  203. package/electron/desktopNotifications.js +378 -378
  204. package/electron/desktopWindow.js +766 -766
  205. package/electron/launcher/index.html +14 -14
  206. package/electron/launcher/launcher.css +801 -801
  207. package/electron/launcher/launcher.js +687 -687
  208. package/electron/localServer.js +549 -549
  209. package/electron/main.js +944 -944
  210. package/electron/preload.cjs +60 -60
  211. package/electron/scripts/generate-macos-icon.js +62 -62
  212. package/electron/serverInstaller.js +277 -277
  213. package/electron/tabs.js +87 -87
  214. package/electron/viewHost.js +331 -331
  215. package/package.json +262 -247
  216. package/public/api-docs.html +901 -901
  217. package/scripts/build-client.mjs +30 -0
  218. package/scripts/fix-node-pty.js +67 -67
  219. package/scripts/generate-pwa-icons.ps1 +33 -0
  220. package/scripts/promote-dist-server.mjs +50 -50
  221. package/scripts/release/build-server-bundle.js +176 -176
  222. package/scripts/release/prepare-desktop-app.js +152 -152
  223. package/scripts/verify-pwa-build.mjs +37 -0
  224. package/server/index.ts +399 -399
  225. package/server/load-env.ts +49 -47
  226. package/server/modules/agent/agent.module.ts +52 -52
  227. package/server/modules/agent/agent.routes.ts +1287 -1287
  228. package/server/modules/agent/index.ts +2 -2
  229. package/server/modules/agent/tests/agent.routes.test.ts +205 -205
  230. package/server/modules/assets/assets.routes.ts +150 -150
  231. package/server/modules/assets/index.ts +3 -3
  232. package/server/modules/assets/services/image-assets.service.ts +127 -127
  233. package/server/modules/assets/tests/image-assets.service.test.ts +74 -74
  234. package/server/modules/auth/auth.middleware.ts +163 -163
  235. package/server/modules/auth/auth.module.ts +38 -38
  236. package/server/modules/auth/auth.routes.ts +57 -57
  237. package/server/modules/auth/auth.service.ts +155 -155
  238. package/server/modules/auth/index.ts +9 -9
  239. package/server/modules/auth/tests/auth.service.test.ts +95 -95
  240. package/server/modules/browser-use/browser-use-mcp.routes.ts +120 -120
  241. package/server/modules/browser-use/browser-use-mcp.ts +386 -386
  242. package/server/modules/browser-use/browser-use-runtime.ts +10 -10
  243. package/server/modules/browser-use/browser-use.routes.ts +96 -96
  244. package/server/modules/browser-use/browser-use.service.ts +836 -836
  245. package/server/modules/browser-use/index.ts +11 -11
  246. package/server/modules/browser-use/tests/browser-use.service.test.ts +10 -10
  247. package/server/modules/cli/cli.module.ts +93 -93
  248. package/server/modules/cli/cli.service.ts +248 -248
  249. package/server/modules/cli/cli.ts +19 -19
  250. package/server/modules/cli/index.ts +2 -2
  251. package/server/modules/cli/sandbox.service.ts +398 -398
  252. package/server/modules/cli/tests/cli-environment-bootstrap.test.ts +186 -186
  253. package/server/modules/cli/tests/cli.service.test.ts +86 -86
  254. package/server/modules/cli/tests/sandbox.service.test.ts +58 -58
  255. package/server/modules/commands/commands.module.ts +22 -22
  256. package/server/modules/commands/commands.routes.ts +587 -587
  257. package/server/modules/commands/index.ts +2 -2
  258. package/server/modules/commands/tests/commands.test.ts +110 -110
  259. package/server/modules/database/connection.ts +144 -143
  260. package/server/modules/database/index.ts +17 -17
  261. package/server/modules/database/init-db.ts +17 -17
  262. package/server/modules/database/migrations.ts +515 -515
  263. package/server/modules/database/repositories/api-keys.ts +119 -119
  264. package/server/modules/database/repositories/app-config.ts +53 -53
  265. package/server/modules/database/repositories/credentials.ts +106 -106
  266. package/server/modules/database/repositories/github-tokens.ts +100 -100
  267. package/server/modules/database/repositories/notification-channel-endpoints.ts +153 -153
  268. package/server/modules/database/repositories/notification-preferences.ts +117 -117
  269. package/server/modules/database/repositories/projects.db.ts +196 -196
  270. package/server/modules/database/repositories/provider-models.ts +168 -168
  271. package/server/modules/database/repositories/push-subscriptions.ts +80 -80
  272. package/server/modules/database/repositories/scan-state.db.ts +42 -42
  273. package/server/modules/database/repositories/sessions.db.ts +524 -524
  274. package/server/modules/database/repositories/users.ts +140 -140
  275. package/server/modules/database/repositories/vapid-keys.ts +57 -57
  276. package/server/modules/database/schema.ts +210 -210
  277. package/server/modules/database/tests/projects.db.integration.test.ts +73 -72
  278. package/server/modules/database/tests/provider-models.db.integration.test.ts +125 -125
  279. package/server/modules/database/tests/sessions-provider-mapping.test.ts +110 -109
  280. package/server/modules/database/tests/sessions.db.integration.test.ts +117 -116
  281. package/server/modules/file-tree/file-tree.module.ts +116 -116
  282. package/server/modules/file-tree/file-tree.routes.ts +258 -258
  283. package/server/modules/file-tree/file-tree.service.ts +675 -675
  284. package/server/modules/file-tree/index.ts +2 -2
  285. package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -157
  286. package/server/modules/file-tree/tests/file-tree.service.test.ts +371 -371
  287. package/server/modules/git/git-branch.service.ts +43 -43
  288. package/server/modules/git/git-parsing.service.ts +66 -66
  289. package/server/modules/git/git.module.ts +22 -22
  290. package/server/modules/git/git.routes.ts +1596 -1596
  291. package/server/modules/git/index.ts +2 -2
  292. package/server/modules/git/tests/git-branch.service.test.ts +60 -60
  293. package/server/modules/git/tests/git-init.routes.test.ts +132 -132
  294. package/server/modules/git/tests/git.test.ts +106 -106
  295. package/server/modules/notifications/index.ts +24 -24
  296. package/server/modules/notifications/notifications.routes.ts +127 -127
  297. package/server/modules/notifications/services/desktop-notification-clients.service.ts +124 -124
  298. package/server/modules/notifications/services/notification-orchestrator.service.js +310 -310
  299. package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -55
  300. package/server/modules/notifications/vapid-keys.service.ts +38 -38
  301. package/server/modules/notifications/websocket/desktop-notifications-websocket.service.ts +109 -109
  302. package/server/modules/plugins/index.ts +9 -9
  303. package/server/modules/plugins/plugin-process.service.ts +217 -217
  304. package/server/modules/plugins/plugin-registry.service.ts +459 -459
  305. package/server/modules/plugins/plugins.module.ts +33 -33
  306. package/server/modules/plugins/plugins.routes.ts +66 -66
  307. package/server/modules/plugins/plugins.service.ts +147 -147
  308. package/server/modules/plugins/tests/plugins.service.test.ts +32 -32
  309. package/server/modules/projects/index.ts +11 -11
  310. package/server/modules/projects/projects.routes.ts +273 -273
  311. package/server/modules/projects/services/project-clone.service.ts +323 -323
  312. package/server/modules/projects/services/project-delete.service.ts +90 -90
  313. package/server/modules/projects/services/project-management.service.ts +144 -144
  314. package/server/modules/projects/services/project-star.service.ts +78 -78
  315. package/server/modules/projects/services/projects-has-taskmaster.service.ts +248 -248
  316. package/server/modules/projects/services/projects-with-sessions-fetch.service.ts +314 -314
  317. package/server/modules/projects/tests/project-clone.service.test.ts +183 -183
  318. package/server/modules/projects/tests/project-management.service.test.ts +118 -117
  319. package/server/modules/projects/tests/project-star.service.test.ts +123 -123
  320. package/server/modules/projects/tests/projects-has-taskmaster.service.test.ts +105 -105
  321. package/server/modules/providers/README.md +380 -380
  322. package/server/modules/providers/index.ts +10 -10
  323. package/server/modules/providers/list/claude/claude-auth.provider.ts +160 -160
  324. package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -135
  325. package/server/modules/providers/list/claude/claude-models.provider.ts +294 -294
  326. package/server/modules/providers/list/claude/claude-runtime.provider.js +1068 -1068
  327. package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +203 -203
  328. package/server/modules/providers/list/claude/claude-sessions.provider.ts +684 -684
  329. package/server/modules/providers/list/claude/claude-skills.provider.ts +265 -265
  330. package/server/modules/providers/list/claude/claude.provider.ts +30 -30
  331. package/server/modules/providers/list/codex/codex-app-server.client.ts +2 -2
  332. package/server/modules/providers/list/codex/codex-auth.provider.ts +100 -100
  333. package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -135
  334. package/server/modules/providers/list/codex/codex-models.provider.ts +123 -123
  335. package/server/modules/providers/list/codex/codex-runtime.provider.js +533 -533
  336. package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +203 -203
  337. package/server/modules/providers/list/codex/codex-sessions.provider.ts +938 -938
  338. package/server/modules/providers/list/codex/codex-skills.provider.ts +73 -73
  339. package/server/modules/providers/list/codex/codex.provider.ts +28 -28
  340. package/server/modules/providers/list/cursor/cursor-auth.provider.ts +143 -143
  341. package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -108
  342. package/server/modules/providers/list/cursor/cursor-models.provider.ts +119 -119
  343. package/server/modules/providers/list/cursor/cursor-runtime.provider.js +385 -385
  344. package/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.ts +158 -159
  345. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +654 -654
  346. package/server/modules/providers/list/cursor/cursor-skills.provider.ts +39 -39
  347. package/server/modules/providers/list/cursor/cursor.provider.ts +30 -30
  348. package/server/modules/providers/list/opencode/opencode-auth.provider.ts +110 -110
  349. package/server/modules/providers/list/opencode/opencode-mcp.provider.ts +228 -228
  350. package/server/modules/providers/list/opencode/opencode-models.provider.ts +203 -203
  351. package/server/modules/providers/list/opencode/opencode-runtime.provider.js +434 -434
  352. package/server/modules/providers/list/opencode/opencode-runtime.provider.test.js +261 -261
  353. package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +179 -179
  354. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +500 -500
  355. package/server/modules/providers/list/opencode/opencode-skills.provider.ts +78 -78
  356. package/server/modules/providers/list/opencode/opencode.provider.ts +30 -30
  357. package/server/modules/providers/provider.registry.ts +36 -36
  358. package/server/modules/providers/provider.routes.ts +877 -877
  359. package/server/modules/providers/services/mcp.service.ts +109 -109
  360. package/server/modules/providers/services/provider-auth.service.ts +26 -26
  361. package/server/modules/providers/services/provider-capabilities.service.ts +97 -97
  362. package/server/modules/providers/services/provider-models.service.ts +401 -401
  363. package/server/modules/providers/services/provider-runtime.service.ts +108 -108
  364. package/server/modules/providers/services/provider-token-usage.service.ts +357 -357
  365. package/server/modules/providers/services/session-conversations-search.service.ts +1321 -1321
  366. package/server/modules/providers/services/session-synchronizer.service.ts +74 -74
  367. package/server/modules/providers/services/sessions-watcher.service.ts +247 -247
  368. package/server/modules/providers/services/sessions.service.ts +471 -471
  369. package/server/modules/providers/services/skills.service.ts +39 -39
  370. package/server/modules/providers/shared/base/abstract.provider.ts +32 -32
  371. package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -151
  372. package/server/modules/providers/shared/skills/skills.provider.ts +287 -287
  373. package/server/modules/providers/tests/claude-auth.test.ts +157 -150
  374. package/server/modules/providers/tests/claude-sessions.test.ts +61 -61
  375. package/server/modules/providers/tests/codex-sessions.test.ts +231 -231
  376. package/server/modules/providers/tests/mcp.test.ts +349 -349
  377. package/server/modules/providers/tests/opencode-models.test.ts +41 -41
  378. package/server/modules/providers/tests/opencode-sessions.test.ts +522 -522
  379. package/server/modules/providers/tests/provider-attachment-history.test.ts +247 -247
  380. package/server/modules/providers/tests/provider-models.service.test.ts +353 -353
  381. package/server/modules/providers/tests/provider-runtime.service.test.ts +138 -138
  382. package/server/modules/providers/tests/provider-token-usage.service.test.ts +186 -186
  383. package/server/modules/providers/tests/provider.routes.test.ts +244 -244
  384. package/server/modules/providers/tests/sessions-details.test.ts +73 -73
  385. package/server/modules/providers/tests/sessions.service.test.ts +127 -127
  386. package/server/modules/providers/tests/skills.test.ts +692 -692
  387. package/server/modules/settings/index.ts +2 -2
  388. package/server/modules/settings/settings.module.ts +50 -50
  389. package/server/modules/settings/settings.routes.ts +51 -51
  390. package/server/modules/settings/settings.service.ts +186 -186
  391. package/server/modules/settings/tests/settings.service.test.ts +54 -54
  392. package/server/modules/system/index.ts +2 -2
  393. package/server/modules/system/system.module.ts +62 -62
  394. package/server/modules/system/system.routes.ts +21 -21
  395. package/server/modules/system/system.service.ts +76 -76
  396. package/server/modules/system/tests/system.service.test.ts +118 -118
  397. package/server/modules/taskmaster/index.ts +2 -2
  398. package/server/modules/taskmaster/taskmaster.module.ts +24 -24
  399. package/server/modules/taskmaster/taskmaster.routes.ts +1483 -1482
  400. package/server/modules/taskmaster/taskmaster.service.ts +132 -132
  401. package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -144
  402. package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -97
  403. package/server/modules/user/index.ts +2 -2
  404. package/server/modules/user/tests/user.service.test.ts +61 -61
  405. package/server/modules/user/user.module.ts +58 -58
  406. package/server/modules/user/user.routes.ts +50 -50
  407. package/server/modules/user/user.service.ts +85 -85
  408. package/server/modules/voice/index.ts +2 -2
  409. package/server/modules/voice/tests/voice.service.test.ts +98 -98
  410. package/server/modules/voice/voice.module.ts +47 -47
  411. package/server/modules/voice/voice.routes.ts +113 -113
  412. package/server/modules/voice/voice.service.ts +192 -192
  413. package/server/modules/websocket/README.md +273 -273
  414. package/server/modules/websocket/index.ts +3 -3
  415. package/server/modules/websocket/services/chat-run-registry.service.ts +343 -343
  416. package/server/modules/websocket/services/chat-session-writer.service.ts +145 -145
  417. package/server/modules/websocket/services/chat-websocket.service.ts +425 -425
  418. package/server/modules/websocket/services/plugin-websocket-proxy.service.ts +65 -65
  419. package/server/modules/websocket/services/shell-websocket.service.ts +503 -503
  420. package/server/modules/websocket/services/websocket-auth.service.ts +59 -59
  421. package/server/modules/websocket/services/websocket-server.service.ts +124 -124
  422. package/server/modules/websocket/services/websocket-state.service.ts +16 -16
  423. package/server/modules/websocket/services/websocket-writer.service.ts +38 -38
  424. package/server/modules/websocket/tests/chat-attachment-filter.test.ts +59 -59
  425. package/server/modules/websocket/tests/chat-run-registry.test.ts +282 -282
  426. package/server/modules/websocket/tests/shell-websocket.service.test.ts +100 -100
  427. package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -78
  428. package/server/modules/worktrees/index.ts +2 -2
  429. package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -53
  430. package/server/modules/worktrees/services/worktree-create.service.ts +104 -104
  431. package/server/modules/worktrees/services/worktree-git.service.ts +207 -207
  432. package/server/modules/worktrees/services/worktree-list.service.ts +143 -143
  433. package/server/modules/worktrees/services/worktree-merge.service.ts +157 -157
  434. package/server/modules/worktrees/services/worktree-open.service.ts +85 -85
  435. package/server/modules/worktrees/services/worktree-remove.service.ts +88 -88
  436. package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -68
  437. package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -142
  438. package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -84
  439. package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -45
  440. package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -213
  441. package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -122
  442. package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -227
  443. package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -199
  444. package/server/modules/worktrees/worktrees.module.ts +113 -113
  445. package/server/modules/worktrees/worktrees.routes.ts +116 -116
  446. package/server/shared/claude-cli-path.ts +139 -139
  447. package/server/shared/frontmatter.ts +18 -18
  448. package/server/shared/image-attachments.ts +435 -435
  449. package/server/shared/interfaces.ts +179 -179
  450. package/server/shared/tests/claude-cli-path.test.ts +61 -61
  451. package/server/shared/tests/image-attachments.test.ts +353 -353
  452. package/server/shared/tests/slice-tail-page.test.ts +42 -42
  453. package/server/shared/types.ts +1228 -1228
  454. package/server/shared/utils.ts +1161 -1161
  455. package/server/tsconfig.json +40 -40
  456. package/shared/networkHosts.js +22 -22
  457. package/dist/assets/FileTree-N2IkkHlv.js +0 -127
  458. package/dist/assets/GitPanel-DZCeuFZ2.js +0 -29
  459. package/dist/assets/PluginTabContent-Bnuf-fb8.js +0 -1
  460. package/dist/assets/Shell-BfFnMZ-f.js +0 -81
  461. package/dist/assets/Shell-qxJ8_QYu.css +0 -32
  462. package/dist/assets/StandaloneShell-QmyYwNAl.js +0 -1
  463. package/dist/assets/TaskMasterPanel-fMsmvN9L.js +0 -32
  464. package/dist/assets/abnfDiagram-N423BO3Z-DjPU7HLs.js +0 -1
  465. package/dist/assets/arc-Pdq6Tvr3.js +0 -1
  466. package/dist/assets/architectureDiagram-T3A2C74G-D0JnT0Vh.js +0 -36
  467. package/dist/assets/c4Diagram-5PPSVZJV-MpqlPGFi.js +0 -10
  468. package/dist/assets/channel-Bm0ZLE4z.js +0 -1
  469. package/dist/assets/chunk-5RXB4S5H-B4UQ8snD.js +0 -231
  470. package/dist/assets/chunk-GF5L2VYU-DkEPedJP.js +0 -206
  471. package/dist/assets/classDiagram-JCYQIIEL-DqEOcNxw.js +0 -1
  472. package/dist/assets/classDiagram-v2-OCEON4UE-DqEOcNxw.js +0 -1
  473. package/dist/assets/code-xml-VK1YfShP.js +0 -6
  474. package/dist/assets/cose-bilkent-JH36ORCC-DrVTo1Nh.js +0 -1
  475. package/dist/assets/cynefinDiagram-MW4NZA55-CCxBjw9E.js +0 -62
  476. package/dist/assets/cytoscape.esm-C10L9Icf.js +0 -331
  477. package/dist/assets/dagre-VZM6K2ZE-C_GvE4lu.js +0 -4
  478. package/dist/assets/diagram-LBJQPF4R-hfKcrrxe.js +0 -24
  479. package/dist/assets/diagram-Q27KOJAE-C1semJfK.js +0 -24
  480. package/dist/assets/diagram-UB23O5K3-57hvXQXO.js +0 -41
  481. package/dist/assets/ebnfDiagram-BXEA7PRR-9KIAlAVw.js +0 -1
  482. package/dist/assets/erDiagram-JOGREHBK-B7OzJ767.js +0 -85
  483. package/dist/assets/ganttDiagram-PKOTCBZU-CbMNWWQu.js +0 -292
  484. package/dist/assets/gitGraphDiagram-DS77QQ5N-I_vZ5waO.js +0 -106
  485. package/dist/assets/graph-Cx-EqisW.js +0 -1
  486. package/dist/assets/index-DFnVoqpx.js +0 -1174
  487. package/dist/assets/index-DlSeAkw_.js +0 -11
  488. package/dist/assets/index-ZHwIojzi.js +0 -1
  489. package/dist/assets/index-t1w8KNxn.css +0 -1
  490. package/dist/assets/infoDiagram-6WML65LV-Dh20Tsbq.js +0 -2
  491. package/dist/assets/ishikawaDiagram-WSZJBQD7-DH2Sm3ko.js +0 -70
  492. package/dist/assets/journeyDiagram-NVQOT4AX-BNFQqlVu.js +0 -139
  493. package/dist/assets/map-CV9uif0g.js +0 -1
  494. package/dist/assets/mermaid.core-BYRQSshi.js +0 -312
  495. package/dist/assets/pegDiagram-VL7TDLO6-CNYpECr8.js +0 -1
  496. package/dist/assets/quadrantDiagram-CIZ2JOQS-BXVVQsa6.js +0 -7
  497. package/dist/assets/railroadDiagram-AXF67PYL-JTroIW8F.js +0 -1
  498. package/dist/assets/requirementDiagram-LRYGKXZP-C1Z_inLz.js +0 -84
  499. package/dist/assets/sankeyDiagram-W5VNT64P-DCJgKFUk.js +0 -40
  500. package/dist/assets/sequenceDiagram-SI44F4Z6-D8Wrx5Vc.js +0 -162
  501. package/dist/assets/sizeCapture-X5ZJPWSS-CXqD68vD.js +0 -1
  502. package/dist/assets/stateDiagram-OKZ733FA-CF0Ekqjo.js +0 -1
  503. package/dist/assets/stateDiagram-v2-UEYNNEHI-DARLpEFJ.js +0 -1
  504. package/dist/assets/swimlanes-SLNWSIFB-DVIax_k4.js +0 -2
  505. package/dist/assets/swimlanesDiagram-ULZ7WXOC-CrgDgaY8.js +0 -8
  506. package/dist/assets/timeline-definition-Z64GVDOM-DSqk3ApG.js +0 -120
  507. package/dist/assets/vendor-react-whEHfigN.js +0 -59
  508. package/dist/assets/vennDiagram-T6HMQDX7-DNbTqyG5.js +0 -34
  509. package/dist/assets/xychartDiagram-ELKLHX3M-XsVZphHr.js +0 -7
  510. package/dist/manifest.json +0 -61
@@ -1,380 +1,380 @@
1
- # Providers Module Guide
2
-
3
- This file documents the current provider contract in `server/modules/providers`.
4
- Keep it current whenever provider wiring, skill discovery, or session sync
5
- behavior changes. The goal is that a human or AI agent can add a new provider
6
- without guessing which files need to move.
7
-
8
- ## Current Provider Shape
9
-
10
- Every provider wrapper exposes seven facets:
11
-
12
- - `runtime`
13
- - `models`
14
- - `auth`
15
- - `mcp`
16
- - `skills`
17
- - `sessions`
18
- - `sessionSynchronizer`
19
-
20
- These correspond to the shared interfaces in `server/shared/interfaces.ts`:
21
-
22
- - `IProviderRuntime`
23
- - `IProviderModels`
24
- - `IProviderAuth`
25
- - `IProviderMcp`
26
- - `IProviderSkills`
27
- - `IProviderSessions`
28
- - `IProviderSessionSynchronizer`
29
-
30
- The services that consume them are:
31
-
32
- - `providerModelsService`
33
- - `providerAuthService`
34
- - `providerMcpService`
35
- - `providerSkillsService`
36
- - `sessionsService`
37
- - `sessionSynchronizerService`
38
-
39
- Live execution is consumed through `providerRuntimeService`, which resolves the
40
- provider-owned runtime through the same `providerRegistry` as every other facet.
41
-
42
- Current provider ids in this repo are:
43
-
44
- - `claude`
45
- - `codex`
46
- - `cursor`
47
- - `opencode`
48
-
49
- Those ids are mirrored in backend unions and frontend provider constants. If
50
- adding a new provider, update every place that hardcodes this list.
51
-
52
- ## Current File Layout
53
-
54
- Each provider lives under its own folder in `server/modules/providers/list/`:
55
-
56
- ```text
57
- server/modules/providers/list/<provider>/
58
- <provider>.provider.ts
59
- <provider>-runtime.provider.js
60
- <provider>-auth.provider.ts
61
- <provider>-models.provider.ts
62
- <provider>-mcp.provider.ts
63
- <provider>-skills.provider.ts
64
- <provider>-sessions.provider.ts
65
- <provider>-session-synchronizer.provider.ts
66
- ```
67
-
68
- The existing provider folders are `claude`, `codex`, `cursor`, and `opencode`.
69
-
70
- Each provider wrapper owns its SDK/CLI runtime alongside its auth, model, and
71
- session facets. Runtime adapters receive registry-backed model and session
72
- lookups from `providerRuntimeService` at execution time instead of importing
73
- those services themselves. This keeps `providerRegistry` as the only provider
74
- mapping without creating a circular dependency. Application-level consumers
75
- import the service from `server/modules/providers/index.ts`.
76
-
77
- ## What Each Facet Does
78
-
79
- | Facet | Responsibility | Base / Service |
80
- | --- | --- | --- |
81
- | `runtime` | Run and abort live SDK/CLI sessions | `IProviderRuntime` -> `providerRuntimeService` |
82
- | `models` | Resolve supported and active models | `IProviderModels` -> `providerModelsService` |
83
- | `auth` | Report install/auth state for the provider runtime | `IProviderAuth` -> `providerAuthService` |
84
- | `mcp` | Read, list, write, and remove provider-native MCP config | `McpProvider` -> `providerMcpService` |
85
- | `skills` | Discover provider-native skill markdown files | `SkillsProvider` -> `providerSkillsService` |
86
- | `sessions` | Normalize live events and fetch session history | `IProviderSessions` -> `sessionsService` |
87
- | `sessionSynchronizer` | Scan transcript artifacts and upsert session metadata | `IProviderSessionSynchronizer` -> `sessionSynchronizerService` |
88
-
89
- `sessions` and `sessionSynchronizer` are separate concerns:
90
-
91
- - `sessions` handles runtime event normalization and history fetches.
92
- - `sessionSynchronizer` handles file-backed session indexing into `sessionsDb`.
93
-
94
- ## How To Add A Provider
95
-
96
- 1. Add the provider id everywhere it is part of the contract.
97
-
98
- - Update `server/shared/types.ts` `LLMProvider`.
99
- - Update `src/types/app.ts` `LLMProvider` if the frontend should know about it.
100
- - Update `server/modules/providers/provider.routes.ts`.
101
- - Update `server/modules/agent/agent.routes.ts` if the provider is launchable from the agent runtime.
102
- - Update `server/index.ts` if the provider needs runtime boot or shutdown wiring.
103
- - Update the `PROVIDER_ORDER` list in `public/api-docs.html` if the provider should appear in the public API docs.
104
- - Update `src/components/chat/hooks/useChatProviderState.ts` and
105
- `src/components/chat/view/subcomponents/ProviderSelectionEmptyState.tsx` if
106
- the provider should be selectable in chat.
107
- - Update `src/components/provider-auth/view/ProviderLoginModal.tsx` if the
108
- provider has a login/setup flow.
109
-
110
- 2. Create the wrapper class.
111
-
112
- - Add `server/modules/providers/list/<provider>/<provider>.provider.ts`.
113
- - Add `server/modules/providers/list/<provider>/<provider>-runtime.provider.js`
114
- when the provider supports live SDK/CLI execution.
115
- - Extend `AbstractProvider`.
116
- - Expose readonly `auth`, `mcp`, `skills`, `sessions`, and `sessionSynchronizer`.
117
- - Call `super('<provider>')`.
118
-
119
- 3. Implement auth.
120
-
121
- - Return a full `ProviderAuthStatus`.
122
- - Treat normal `not installed` / `not authenticated` states as data, not exceptions.
123
- - Keep provider-specific credential discovery inside the auth provider.
124
- - If the provider has no auth step, return a stable unauthenticated or not-installed status instead of omitting the facet.
125
-
126
- 4. Implement MCP.
127
-
128
- - Extend `McpProvider`.
129
- - Pass the supported scopes and transports to `super(...)`.
130
- - Implement the four required methods:
131
- - `readScopedServers(...)`
132
- - `writeScopedServers(...)`
133
- - `buildServerConfig(...)`
134
- - `normalizeServerConfig(...)`
135
- - Use the shared validation and normalization behavior from `McpProvider`.
136
- - Keep the provider-specific config format local to the provider implementation.
137
-
138
- Current MCP formats in this repo are:
139
-
140
- | Provider | User / Project Storage | Supported Scopes | Supported Transports |
141
- | --- | --- | --- | --- |
142
- | Claude | `.mcp.json` in user / local / project locations | `user`, `local`, `project` | `stdio`, `http`, `sse` |
143
- | Codex | `.codex/config.toml` | `user`, `project` | `stdio`, `http` |
144
- | Cursor | `.cursor/mcp.json` | `user`, `project` | `stdio`, `http` |
145
- | OpenCode | `~/.config/opencode/opencode.json` or `<workspace>/opencode.json` (`.jsonc` is read when present) | `user`, `project` | `stdio`, `http` |
146
-
147
- 5. Implement skills.
148
-
149
- - Extend `SkillsProvider`.
150
- - Implement `getSkillSources(workspacePath)`.
151
- - Return the actual discovery roots for the provider.
152
- - Skills are discovered from `SKILL.md` files.
153
- - `readProviderSkillMarkdownDefinition(...)` reads front matter `name` and `description`.
154
- - If `name` is missing, the parent directory name is used as a fallback.
155
- - Use `recursive: true` only when the provider stores skills in nested trees.
156
- - Keep the emitted `command` string aligned with the provider's real skill syntax.
157
-
158
- Current skill discovery roots are:
159
-
160
- | Provider | User Roots | Project / Repo Roots | Prefix | Notes |
161
- | --- | --- | --- | --- | --- |
162
- | Claude | `~/.claude/skills` | `<workspace>/.claude/skills` | `/` | Also discovers Claude plugin skills from enabled plugin installs. Command skills live under `commands/`; markdown skills live under `skills/` and are scanned recursively. |
163
- | Codex | `~/.agents/skills`, `~/.codex/skills/.system`, `/etc/codex/skills` | `<workspace>/.agents/skills`, `path.dirname(workspacePath)/.agents/skills`, topmost git root `.agents/skills` | `$` | Overlapping roots are deduplicated before scanning. |
164
- | Cursor | `~/.cursor/skills` | `<workspace>/.cursor/skills`, `<workspace>/.agents/skills` | `/` | Uses slash-style commands. |
165
- | OpenCode | `~/.config/opencode/skills`, `~/.claude/skills`, `~/.agents/skills` | Cwd-to-topmost-git-root `.opencode/skills`, `.claude/skills`, and `.agents/skills` | `/` | Reuses OpenCode, Claude, and Agents skill locations. Overlapping roots are deduplicated before scanning. |
166
-
167
- Command forms currently used by the providers are:
168
-
169
- - Claude user/project skills: `/skill-name`
170
- - Claude plugin skills: `/plugin-name:skill-name`
171
- - Codex skills: `$skill-name`
172
- - Cursor skills: `/skill-name`
173
- - OpenCode skills: `/skill-name`
174
-
175
- 6. Implement sessions.
176
-
177
- - Implement `normalizeMessage(raw, sessionId)` and `fetchHistory(sessionId, options)`.
178
- - Use `createNormalizedMessage(...)` and `generateMessageId(...)` for emitted messages.
179
- - Keep normalized message ids unique. If one raw event produces multiple text
180
- parts, append a discriminator so ids do not collide.
181
- - Keep pagination consistent:
182
- - `limit: null` means unbounded/full history.
183
- - `limit: 0` means an empty page.
184
- - always return `total`, `hasMore`, `offset`, and `limit` when paginating.
185
- - Sanitize any filesystem-derived ids before using them in file or database paths.
186
- - Do not assume a provider's history format matches another provider's format.
187
-
188
- 7. Implement session synchronization.
189
-
190
- - Implement `synchronize(since?: Date)` to scan provider artifacts and upsert
191
- sessions into `sessionsDb`.
192
- - Implement `synchronizeFile(filePath)` for single-file watcher updates.
193
- - Use the existing helpers when they fit:
194
- - `buildLookupMap(...)`
195
- - `extractFirstValidJsonlData(...)`
196
- - `findFilesRecursivelyCreatedAfter(...)`
197
- - `normalizeSessionName(...)`
198
- - `readFileTimestamps(...)`
199
- - Make the sync resilient to partial, malformed, or missing provider files.
200
- - The orchestration service runs all provider synchronizers and only advances
201
- `scan_state.last_scanned_at` when every provider succeeds.
202
-
203
- Current session sync roots are:
204
-
205
- | Provider | Scan Roots | Metadata Helpers / Notes |
206
- | --- | --- | --- |
207
- | Claude | `~/.claude/projects/**/*.jsonl` | Uses `~/.claude/history.jsonl` for name lookup and the trailing `ai-title`, `last-prompt`, or `custom-title` entries for title recovery. |
208
- | Codex | `~/.codex/sessions/**/*.jsonl` | Uses `~/.codex/session_index.jsonl` for title lookup and the last `task_complete` message for a fallback title. |
209
- | Cursor | `~/.cursor/projects/**/*.jsonl` | Uses sibling `worker.log` to recover `workspacePath`, then derives the session title from the first user prompt. |
210
- | OpenCode | `~/.local/share/opencode/opencode.db` | Reads active sessions/messages/parts from OpenCode's shared SQLite database and stores `jsonl_path` as `null` so deleting one app session cannot remove the shared DB. |
211
-
212
- 8. Register the provider.
213
-
214
- - Add the new provider class to `server/modules/providers/provider.registry.ts`.
215
- - Update `server/modules/providers/provider.routes.ts` provider parsing.
216
- - If the provider introduces a new service or lifecycle hook, export it from the module entrypoint that consumes providers.
217
-
218
- 9. Wire runtime and UI surfaces outside the providers module when needed.
219
-
220
- If the provider can run live chat sessions, update the runtime entrypoints too:
221
-
222
- - `server/modules/providers/list/<provider>/<provider>-runtime.provider.js`
223
- - `server/modules/providers/list/<provider>/<provider>.provider.ts`
224
- - `server/modules/agent/agent.routes.ts`
225
- - `server/index.ts`
226
-
227
- If the provider is visible in the UI, update:
228
-
229
- - provider model fallback files under `server/modules/providers/list/<provider>/`
230
- - `src/components/chat/hooks/useChatProviderState.ts`
231
- - `src/components/chat/view/subcomponents/ProviderSelectionEmptyState.tsx`
232
- - `src/components/provider-auth/view/ProviderLoginModal.tsx`
233
- - `src/components/mcp/constants.ts`
234
-
235
- ## Minimal Wrapper Template
236
-
237
- ```ts
238
- import { AbstractProvider } from '@/modules/providers/shared/base/abstract.provider.js';
239
- import { <Provider>ProviderAuth } from './<provider>-auth.provider.js';
240
- import { <Provider>ProviderModels } from './<provider>-models.provider.js';
241
- import { <Provider>McpProvider } from './<provider>-mcp.provider.js';
242
- import { <provider>Runtime } from './<provider>-runtime.provider.js';
243
- import { <Provider>SkillsProvider } from './<provider>-skills.provider.js';
244
- import { <Provider>SessionsProvider } from './<provider>-sessions.provider.js';
245
- import { <Provider>SessionSynchronizer } from './<provider>-session-synchronizer.provider.js';
246
- import type {
247
- IProviderAuth,
248
- IProviderMcp,
249
- IProviderModels,
250
- IProviderRuntime,
251
- IProviderSessionSynchronizer,
252
- IProviderSessions,
253
- IProviderSkills,
254
- } from '@/shared/interfaces.js';
255
-
256
- export class <Provider>Provider extends AbstractProvider {
257
- readonly runtime: IProviderRuntime = <provider>Runtime;
258
- readonly models: IProviderModels = new <Provider>ProviderModels();
259
- readonly auth: IProviderAuth = new <Provider>ProviderAuth();
260
- readonly mcp: IProviderMcp = new <Provider>McpProvider();
261
- readonly skills: IProviderSkills = new <Provider>SkillsProvider();
262
- readonly sessions: IProviderSessions = new <Provider>SessionsProvider();
263
- readonly sessionSynchronizer: IProviderSessionSynchronizer =
264
- new <Provider>SessionSynchronizer();
265
-
266
- constructor() {
267
- super('<provider>');
268
- }
269
- }
270
- ```
271
-
272
- ## Minimal Skills Template
273
-
274
- ```ts
275
- import path from 'node:path';
276
-
277
- import { SkillsProvider } from '@/modules/providers/shared/skills/skills.provider.js';
278
- import type { ProviderSkillSource } from '@/shared/types.js';
279
-
280
- export class <Provider>SkillsProvider extends SkillsProvider {
281
- constructor() {
282
- super('<provider>');
283
- }
284
-
285
- protected async getSkillSources(workspacePath: string): Promise<ProviderSkillSource[]> {
286
- return [
287
- {
288
- scope: 'project',
289
- rootDir: path.join(workspacePath, '.<provider>', 'skills'),
290
- commandPrefix: '/',
291
- },
292
- ];
293
- }
294
- }
295
- ```
296
-
297
- ## Minimal Session Sync Template
298
-
299
- ```ts
300
- import type { IProviderSessionSynchronizer } from '@/shared/interfaces.js';
301
-
302
- export class <Provider>SessionSynchronizer implements IProviderSessionSynchronizer {
303
- async synchronize(since?: Date): Promise<number> {
304
- return 0;
305
- }
306
-
307
- async synchronizeFile(filePath: string): Promise<string | null> {
308
- return null;
309
- }
310
- }
311
- ```
312
-
313
- ## AI Prompt Template
314
-
315
- Use this prompt when asking an AI agent to add a provider:
316
-
317
- ```text
318
- Add a new provider "<provider>" using the current provider module architecture.
319
-
320
- Requirements:
321
- 1) Create:
322
- - server/modules/providers/list/<provider>/<provider>.provider.ts
323
- - server/modules/providers/list/<provider>/<provider>-runtime.provider.js
324
- - server/modules/providers/list/<provider>/<provider>-auth.provider.ts
325
- - server/modules/providers/list/<provider>/<provider>-models.provider.ts
326
- - server/modules/providers/list/<provider>/<provider>-mcp.provider.ts
327
- - server/modules/providers/list/<provider>/<provider>-skills.provider.ts
328
- - server/modules/providers/list/<provider>/<provider>-sessions.provider.ts
329
- - server/modules/providers/list/<provider>/<provider>-session-synchronizer.provider.ts
330
- 2) Register in:
331
- - server/modules/providers/provider.registry.ts
332
- - server/modules/providers/provider.routes.ts
333
- - server/shared/types.ts LLMProvider
334
- - src/types/app.ts LLMProvider
335
- 3) Mirror the nearest existing provider implementation for file naming, style,
336
- and error handling.
337
- 4) Implement skills support with SkillsProvider and the current skill roots.
338
- 5) Implement session synchronization if the provider stores transcript files.
339
- 6) Ensure sessions use unique ids, safe path handling, and correct pagination.
340
- 7) Keep `sessions` and `sessionSynchronizer` separate.
341
- 8) Run:
342
- - npx eslint <touched files>
343
- - npx tsc --noEmit -p server/tsconfig.json
344
- ```
345
-
346
- ## Validation
347
-
348
- After adding or changing a provider, run the relevant checks:
349
-
350
- ```bash
351
- npx eslint server/modules/providers/**/*.ts server/shared/types.ts server/shared/interfaces.ts
352
- npx tsc --noEmit -p server/tsconfig.json
353
- ```
354
-
355
- Useful tests in this repo:
356
-
357
- - `server/modules/providers/tests/mcp.test.ts`
358
- - `server/modules/providers/tests/skills.test.ts`
359
- - `server/modules/providers/tests/opencode-sessions.test.ts`
360
-
361
- If you touch sessions or session synchronization, add or update focused tests
362
- alongside the implementation.
363
-
364
- ## Common Mistakes
365
-
366
- - Adding provider files but forgetting `provider.registry.ts` or
367
- `provider.routes.ts`.
368
- - Adding a live runtime without exposing it from the provider wrapper.
369
- - Updating backend provider ids but not `src/types/app.ts` or the frontend
370
- provider constants.
371
- - Omitting `runtime`, `skills`, or `sessionSynchronizer` from the wrapper.
372
- - Returning duplicate normalized message ids for split content.
373
- - Treating `limit === 0` as unbounded history.
374
- - Building file paths from raw session ids without validation.
375
- - Hardcoding a skill root without checking the provider's actual discovery rules.
376
- - Forgetting that Claude plugin skills are discovered differently from normal
377
- user/project skill folders.
378
- - Assuming one provider's MCP config file format works for the others.
379
-
380
-
1
+ # Providers Module Guide
2
+
3
+ This file documents the current provider contract in `server/modules/providers`.
4
+ Keep it current whenever provider wiring, skill discovery, or session sync
5
+ behavior changes. The goal is that a human or AI agent can add a new provider
6
+ without guessing which files need to move.
7
+
8
+ ## Current Provider Shape
9
+
10
+ Every provider wrapper exposes seven facets:
11
+
12
+ - `runtime`
13
+ - `models`
14
+ - `auth`
15
+ - `mcp`
16
+ - `skills`
17
+ - `sessions`
18
+ - `sessionSynchronizer`
19
+
20
+ These correspond to the shared interfaces in `server/shared/interfaces.ts`:
21
+
22
+ - `IProviderRuntime`
23
+ - `IProviderModels`
24
+ - `IProviderAuth`
25
+ - `IProviderMcp`
26
+ - `IProviderSkills`
27
+ - `IProviderSessions`
28
+ - `IProviderSessionSynchronizer`
29
+
30
+ The services that consume them are:
31
+
32
+ - `providerModelsService`
33
+ - `providerAuthService`
34
+ - `providerMcpService`
35
+ - `providerSkillsService`
36
+ - `sessionsService`
37
+ - `sessionSynchronizerService`
38
+
39
+ Live execution is consumed through `providerRuntimeService`, which resolves the
40
+ provider-owned runtime through the same `providerRegistry` as every other facet.
41
+
42
+ Current provider ids in this repo are:
43
+
44
+ - `claude`
45
+ - `codex`
46
+ - `cursor`
47
+ - `opencode`
48
+
49
+ Those ids are mirrored in backend unions and frontend provider constants. If
50
+ adding a new provider, update every place that hardcodes this list.
51
+
52
+ ## Current File Layout
53
+
54
+ Each provider lives under its own folder in `server/modules/providers/list/`:
55
+
56
+ ```text
57
+ server/modules/providers/list/<provider>/
58
+ <provider>.provider.ts
59
+ <provider>-runtime.provider.js
60
+ <provider>-auth.provider.ts
61
+ <provider>-models.provider.ts
62
+ <provider>-mcp.provider.ts
63
+ <provider>-skills.provider.ts
64
+ <provider>-sessions.provider.ts
65
+ <provider>-session-synchronizer.provider.ts
66
+ ```
67
+
68
+ The existing provider folders are `claude`, `codex`, `cursor`, and `opencode`.
69
+
70
+ Each provider wrapper owns its SDK/CLI runtime alongside its auth, model, and
71
+ session facets. Runtime adapters receive registry-backed model and session
72
+ lookups from `providerRuntimeService` at execution time instead of importing
73
+ those services themselves. This keeps `providerRegistry` as the only provider
74
+ mapping without creating a circular dependency. Application-level consumers
75
+ import the service from `server/modules/providers/index.ts`.
76
+
77
+ ## What Each Facet Does
78
+
79
+ | Facet | Responsibility | Base / Service |
80
+ | --- | --- | --- |
81
+ | `runtime` | Run and abort live SDK/CLI sessions | `IProviderRuntime` -> `providerRuntimeService` |
82
+ | `models` | Resolve supported and active models | `IProviderModels` -> `providerModelsService` |
83
+ | `auth` | Report install/auth state for the provider runtime | `IProviderAuth` -> `providerAuthService` |
84
+ | `mcp` | Read, list, write, and remove provider-native MCP config | `McpProvider` -> `providerMcpService` |
85
+ | `skills` | Discover provider-native skill markdown files | `SkillsProvider` -> `providerSkillsService` |
86
+ | `sessions` | Normalize live events and fetch session history | `IProviderSessions` -> `sessionsService` |
87
+ | `sessionSynchronizer` | Scan transcript artifacts and upsert session metadata | `IProviderSessionSynchronizer` -> `sessionSynchronizerService` |
88
+
89
+ `sessions` and `sessionSynchronizer` are separate concerns:
90
+
91
+ - `sessions` handles runtime event normalization and history fetches.
92
+ - `sessionSynchronizer` handles file-backed session indexing into `sessionsDb`.
93
+
94
+ ## How To Add A Provider
95
+
96
+ 1. Add the provider id everywhere it is part of the contract.
97
+
98
+ - Update `server/shared/types.ts` `LLMProvider`.
99
+ - Update `src/types/app.ts` `LLMProvider` if the frontend should know about it.
100
+ - Update `server/modules/providers/provider.routes.ts`.
101
+ - Update `server/modules/agent/agent.routes.ts` if the provider is launchable from the agent runtime.
102
+ - Update `server/index.ts` if the provider needs runtime boot or shutdown wiring.
103
+ - Update the `PROVIDER_ORDER` list in `public/api-docs.html` if the provider should appear in the public API docs.
104
+ - Update `src/components/chat/hooks/useChatProviderState.ts` and
105
+ `src/components/chat/view/subcomponents/ProviderSelectionEmptyState.tsx` if
106
+ the provider should be selectable in chat.
107
+ - Update `src/components/provider-auth/view/ProviderLoginModal.tsx` if the
108
+ provider has a login/setup flow.
109
+
110
+ 2. Create the wrapper class.
111
+
112
+ - Add `server/modules/providers/list/<provider>/<provider>.provider.ts`.
113
+ - Add `server/modules/providers/list/<provider>/<provider>-runtime.provider.js`
114
+ when the provider supports live SDK/CLI execution.
115
+ - Extend `AbstractProvider`.
116
+ - Expose readonly `auth`, `mcp`, `skills`, `sessions`, and `sessionSynchronizer`.
117
+ - Call `super('<provider>')`.
118
+
119
+ 3. Implement auth.
120
+
121
+ - Return a full `ProviderAuthStatus`.
122
+ - Treat normal `not installed` / `not authenticated` states as data, not exceptions.
123
+ - Keep provider-specific credential discovery inside the auth provider.
124
+ - If the provider has no auth step, return a stable unauthenticated or not-installed status instead of omitting the facet.
125
+
126
+ 4. Implement MCP.
127
+
128
+ - Extend `McpProvider`.
129
+ - Pass the supported scopes and transports to `super(...)`.
130
+ - Implement the four required methods:
131
+ - `readScopedServers(...)`
132
+ - `writeScopedServers(...)`
133
+ - `buildServerConfig(...)`
134
+ - `normalizeServerConfig(...)`
135
+ - Use the shared validation and normalization behavior from `McpProvider`.
136
+ - Keep the provider-specific config format local to the provider implementation.
137
+
138
+ Current MCP formats in this repo are:
139
+
140
+ | Provider | User / Project Storage | Supported Scopes | Supported Transports |
141
+ | --- | --- | --- | --- |
142
+ | Claude | `.mcp.json` in user / local / project locations | `user`, `local`, `project` | `stdio`, `http`, `sse` |
143
+ | Codex | `.codex/config.toml` | `user`, `project` | `stdio`, `http` |
144
+ | Cursor | `.cursor/mcp.json` | `user`, `project` | `stdio`, `http` |
145
+ | OpenCode | `~/.config/opencode/opencode.json` or `<workspace>/opencode.json` (`.jsonc` is read when present) | `user`, `project` | `stdio`, `http` |
146
+
147
+ 5. Implement skills.
148
+
149
+ - Extend `SkillsProvider`.
150
+ - Implement `getSkillSources(workspacePath)`.
151
+ - Return the actual discovery roots for the provider.
152
+ - Skills are discovered from `SKILL.md` files.
153
+ - `readProviderSkillMarkdownDefinition(...)` reads front matter `name` and `description`.
154
+ - If `name` is missing, the parent directory name is used as a fallback.
155
+ - Use `recursive: true` only when the provider stores skills in nested trees.
156
+ - Keep the emitted `command` string aligned with the provider's real skill syntax.
157
+
158
+ Current skill discovery roots are:
159
+
160
+ | Provider | User Roots | Project / Repo Roots | Prefix | Notes |
161
+ | --- | --- | --- | --- | --- |
162
+ | Claude | `~/.claude/skills` | `<workspace>/.claude/skills` | `/` | Also discovers Claude plugin skills from enabled plugin installs. Command skills live under `commands/`; markdown skills live under `skills/` and are scanned recursively. |
163
+ | Codex | `~/.agents/skills`, `~/.codex/skills/.system`, `/etc/codex/skills` | `<workspace>/.agents/skills`, `path.dirname(workspacePath)/.agents/skills`, topmost git root `.agents/skills` | `$` | Overlapping roots are deduplicated before scanning. |
164
+ | Cursor | `~/.cursor/skills` | `<workspace>/.cursor/skills`, `<workspace>/.agents/skills` | `/` | Uses slash-style commands. |
165
+ | OpenCode | `~/.config/opencode/skills`, `~/.claude/skills`, `~/.agents/skills` | Cwd-to-topmost-git-root `.opencode/skills`, `.claude/skills`, and `.agents/skills` | `/` | Reuses OpenCode, Claude, and Agents skill locations. Overlapping roots are deduplicated before scanning. |
166
+
167
+ Command forms currently used by the providers are:
168
+
169
+ - Claude user/project skills: `/skill-name`
170
+ - Claude plugin skills: `/plugin-name:skill-name`
171
+ - Codex skills: `$skill-name`
172
+ - Cursor skills: `/skill-name`
173
+ - OpenCode skills: `/skill-name`
174
+
175
+ 6. Implement sessions.
176
+
177
+ - Implement `normalizeMessage(raw, sessionId)` and `fetchHistory(sessionId, options)`.
178
+ - Use `createNormalizedMessage(...)` and `generateMessageId(...)` for emitted messages.
179
+ - Keep normalized message ids unique. If one raw event produces multiple text
180
+ parts, append a discriminator so ids do not collide.
181
+ - Keep pagination consistent:
182
+ - `limit: null` means unbounded/full history.
183
+ - `limit: 0` means an empty page.
184
+ - always return `total`, `hasMore`, `offset`, and `limit` when paginating.
185
+ - Sanitize any filesystem-derived ids before using them in file or database paths.
186
+ - Do not assume a provider's history format matches another provider's format.
187
+
188
+ 7. Implement session synchronization.
189
+
190
+ - Implement `synchronize(since?: Date)` to scan provider artifacts and upsert
191
+ sessions into `sessionsDb`.
192
+ - Implement `synchronizeFile(filePath)` for single-file watcher updates.
193
+ - Use the existing helpers when they fit:
194
+ - `buildLookupMap(...)`
195
+ - `extractFirstValidJsonlData(...)`
196
+ - `findFilesRecursivelyCreatedAfter(...)`
197
+ - `normalizeSessionName(...)`
198
+ - `readFileTimestamps(...)`
199
+ - Make the sync resilient to partial, malformed, or missing provider files.
200
+ - The orchestration service runs all provider synchronizers and only advances
201
+ `scan_state.last_scanned_at` when every provider succeeds.
202
+
203
+ Current session sync roots are:
204
+
205
+ | Provider | Scan Roots | Metadata Helpers / Notes |
206
+ | --- | --- | --- |
207
+ | Claude | `~/.claude/projects/**/*.jsonl` | Uses `~/.claude/history.jsonl` for name lookup and the trailing `ai-title`, `last-prompt`, or `custom-title` entries for title recovery. |
208
+ | Codex | `~/.codex/sessions/**/*.jsonl` | Uses `~/.codex/session_index.jsonl` for title lookup and the last `task_complete` message for a fallback title. |
209
+ | Cursor | `~/.cursor/projects/**/*.jsonl` | Uses sibling `worker.log` to recover `workspacePath`, then derives the session title from the first user prompt. |
210
+ | OpenCode | `~/.local/share/opencode/opencode.db` | Reads active sessions/messages/parts from OpenCode's shared SQLite database and stores `jsonl_path` as `null` so deleting one app session cannot remove the shared DB. |
211
+
212
+ 8. Register the provider.
213
+
214
+ - Add the new provider class to `server/modules/providers/provider.registry.ts`.
215
+ - Update `server/modules/providers/provider.routes.ts` provider parsing.
216
+ - If the provider introduces a new service or lifecycle hook, export it from the module entrypoint that consumes providers.
217
+
218
+ 9. Wire runtime and UI surfaces outside the providers module when needed.
219
+
220
+ If the provider can run live chat sessions, update the runtime entrypoints too:
221
+
222
+ - `server/modules/providers/list/<provider>/<provider>-runtime.provider.js`
223
+ - `server/modules/providers/list/<provider>/<provider>.provider.ts`
224
+ - `server/modules/agent/agent.routes.ts`
225
+ - `server/index.ts`
226
+
227
+ If the provider is visible in the UI, update:
228
+
229
+ - provider model fallback files under `server/modules/providers/list/<provider>/`
230
+ - `src/components/chat/hooks/useChatProviderState.ts`
231
+ - `src/components/chat/view/subcomponents/ProviderSelectionEmptyState.tsx`
232
+ - `src/components/provider-auth/view/ProviderLoginModal.tsx`
233
+ - `src/components/mcp/constants.ts`
234
+
235
+ ## Minimal Wrapper Template
236
+
237
+ ```ts
238
+ import { AbstractProvider } from '@/modules/providers/shared/base/abstract.provider.js';
239
+ import { <Provider>ProviderAuth } from './<provider>-auth.provider.js';
240
+ import { <Provider>ProviderModels } from './<provider>-models.provider.js';
241
+ import { <Provider>McpProvider } from './<provider>-mcp.provider.js';
242
+ import { <provider>Runtime } from './<provider>-runtime.provider.js';
243
+ import { <Provider>SkillsProvider } from './<provider>-skills.provider.js';
244
+ import { <Provider>SessionsProvider } from './<provider>-sessions.provider.js';
245
+ import { <Provider>SessionSynchronizer } from './<provider>-session-synchronizer.provider.js';
246
+ import type {
247
+ IProviderAuth,
248
+ IProviderMcp,
249
+ IProviderModels,
250
+ IProviderRuntime,
251
+ IProviderSessionSynchronizer,
252
+ IProviderSessions,
253
+ IProviderSkills,
254
+ } from '@/shared/interfaces.js';
255
+
256
+ export class <Provider>Provider extends AbstractProvider {
257
+ readonly runtime: IProviderRuntime = <provider>Runtime;
258
+ readonly models: IProviderModels = new <Provider>ProviderModels();
259
+ readonly auth: IProviderAuth = new <Provider>ProviderAuth();
260
+ readonly mcp: IProviderMcp = new <Provider>McpProvider();
261
+ readonly skills: IProviderSkills = new <Provider>SkillsProvider();
262
+ readonly sessions: IProviderSessions = new <Provider>SessionsProvider();
263
+ readonly sessionSynchronizer: IProviderSessionSynchronizer =
264
+ new <Provider>SessionSynchronizer();
265
+
266
+ constructor() {
267
+ super('<provider>');
268
+ }
269
+ }
270
+ ```
271
+
272
+ ## Minimal Skills Template
273
+
274
+ ```ts
275
+ import path from 'node:path';
276
+
277
+ import { SkillsProvider } from '@/modules/providers/shared/skills/skills.provider.js';
278
+ import type { ProviderSkillSource } from '@/shared/types.js';
279
+
280
+ export class <Provider>SkillsProvider extends SkillsProvider {
281
+ constructor() {
282
+ super('<provider>');
283
+ }
284
+
285
+ protected async getSkillSources(workspacePath: string): Promise<ProviderSkillSource[]> {
286
+ return [
287
+ {
288
+ scope: 'project',
289
+ rootDir: path.join(workspacePath, '.<provider>', 'skills'),
290
+ commandPrefix: '/',
291
+ },
292
+ ];
293
+ }
294
+ }
295
+ ```
296
+
297
+ ## Minimal Session Sync Template
298
+
299
+ ```ts
300
+ import type { IProviderSessionSynchronizer } from '@/shared/interfaces.js';
301
+
302
+ export class <Provider>SessionSynchronizer implements IProviderSessionSynchronizer {
303
+ async synchronize(since?: Date): Promise<number> {
304
+ return 0;
305
+ }
306
+
307
+ async synchronizeFile(filePath: string): Promise<string | null> {
308
+ return null;
309
+ }
310
+ }
311
+ ```
312
+
313
+ ## AI Prompt Template
314
+
315
+ Use this prompt when asking an AI agent to add a provider:
316
+
317
+ ```text
318
+ Add a new provider "<provider>" using the current provider module architecture.
319
+
320
+ Requirements:
321
+ 1) Create:
322
+ - server/modules/providers/list/<provider>/<provider>.provider.ts
323
+ - server/modules/providers/list/<provider>/<provider>-runtime.provider.js
324
+ - server/modules/providers/list/<provider>/<provider>-auth.provider.ts
325
+ - server/modules/providers/list/<provider>/<provider>-models.provider.ts
326
+ - server/modules/providers/list/<provider>/<provider>-mcp.provider.ts
327
+ - server/modules/providers/list/<provider>/<provider>-skills.provider.ts
328
+ - server/modules/providers/list/<provider>/<provider>-sessions.provider.ts
329
+ - server/modules/providers/list/<provider>/<provider>-session-synchronizer.provider.ts
330
+ 2) Register in:
331
+ - server/modules/providers/provider.registry.ts
332
+ - server/modules/providers/provider.routes.ts
333
+ - server/shared/types.ts LLMProvider
334
+ - src/types/app.ts LLMProvider
335
+ 3) Mirror the nearest existing provider implementation for file naming, style,
336
+ and error handling.
337
+ 4) Implement skills support with SkillsProvider and the current skill roots.
338
+ 5) Implement session synchronization if the provider stores transcript files.
339
+ 6) Ensure sessions use unique ids, safe path handling, and correct pagination.
340
+ 7) Keep `sessions` and `sessionSynchronizer` separate.
341
+ 8) Run:
342
+ - npx eslint <touched files>
343
+ - npx tsc --noEmit -p server/tsconfig.json
344
+ ```
345
+
346
+ ## Validation
347
+
348
+ After adding or changing a provider, run the relevant checks:
349
+
350
+ ```bash
351
+ npx eslint server/modules/providers/**/*.ts server/shared/types.ts server/shared/interfaces.ts
352
+ npx tsc --noEmit -p server/tsconfig.json
353
+ ```
354
+
355
+ Useful tests in this repo:
356
+
357
+ - `server/modules/providers/tests/mcp.test.ts`
358
+ - `server/modules/providers/tests/skills.test.ts`
359
+ - `server/modules/providers/tests/opencode-sessions.test.ts`
360
+
361
+ If you touch sessions or session synchronization, add or update focused tests
362
+ alongside the implementation.
363
+
364
+ ## Common Mistakes
365
+
366
+ - Adding provider files but forgetting `provider.registry.ts` or
367
+ `provider.routes.ts`.
368
+ - Adding a live runtime without exposing it from the provider wrapper.
369
+ - Updating backend provider ids but not `src/types/app.ts` or the frontend
370
+ provider constants.
371
+ - Omitting `runtime`, `skills`, or `sessionSynchronizer` from the wrapper.
372
+ - Returning duplicate normalized message ids for split content.
373
+ - Treating `limit === 0` as unbounded history.
374
+ - Building file paths from raw session ids without validation.
375
+ - Hardcoding a skill root without checking the provider's actual discovery rules.
376
+ - Forgetting that Claude plugin skills are discovered differently from normal
377
+ user/project skill folders.
378
+ - Assuming one provider's MCP config file format works for the others.
379
+
380
+