wind-agent-cli 1.37.2 → 1.37.3

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 (374) hide show
  1. package/LICENSE +718 -718
  2. package/README.md +1 -1
  3. package/dist/api-docs.html +901 -901
  4. package/dist/assets/{CodeEditor-B2Wf7Fg0.js → CodeEditor-BqmxpZ_D.js} +1 -1
  5. package/dist/assets/{FileTree-N2IkkHlv.js → FileTree-DLE7Ioai.js} +1 -1
  6. package/dist/assets/{GitPanel-DZCeuFZ2.js → GitPanel-f8RMRa8D.js} +1 -1
  7. package/dist/assets/{MarkdownPreview-C0tqYnVu.js → MarkdownPreview-93h_1tJa.js} +1 -1
  8. package/dist/assets/{PluginTabContent-Bnuf-fb8.js → PluginTabContent-DU1jjkXP.js} +1 -1
  9. package/dist/assets/{Shell-BfFnMZ-f.js → Shell-CN_2MRIM.js} +1 -1
  10. package/dist/assets/{StandaloneShell-QmyYwNAl.js → StandaloneShell-D0avS8UE.js} +1 -1
  11. package/dist/assets/{TaskMasterPanel-fMsmvN9L.js → TaskMasterPanel-Cpf1Q5Ph.js} +3 -3
  12. package/dist/assets/{abnfDiagram-N423BO3Z-DjPU7HLs.js → abnfDiagram-N423BO3Z-p3aJIm4T.js} +1 -1
  13. package/dist/assets/{arc-Pdq6Tvr3.js → arc-CTeud6Fl.js} +1 -1
  14. package/dist/assets/{architectureDiagram-T3A2C74G-D0JnT0Vh.js → architectureDiagram-T3A2C74G-CG7kRCJU.js} +1 -1
  15. package/dist/assets/{blockDiagram-VBNYF7ZC-DpaEf3mv.js → blockDiagram-VBNYF7ZC-oSjQ1SgE.js} +1 -1
  16. package/dist/assets/{c4Diagram-5PPSVZJV-MpqlPGFi.js → c4Diagram-5PPSVZJV-RkzF0DJV.js} +1 -1
  17. package/dist/assets/channel-BfQbarn9.js +1 -0
  18. package/dist/assets/{chunk-2GRJ4B5K-DoSdNo8u.js → chunk-2GRJ4B5K-B07uZ07O.js} +1 -1
  19. package/dist/assets/{chunk-2Q5K7J3B-CE7I3uMn.js → chunk-2Q5K7J3B-DNSfO7xS.js} +1 -1
  20. package/dist/assets/{chunk-5RXB4S5H-B4UQ8snD.js → chunk-5RXB4S5H-BTeYcgyb.js} +1 -1
  21. package/dist/assets/{chunk-5VM5RSS4-B55XgqHZ.js → chunk-5VM5RSS4-B7vZV0zC.js} +1 -1
  22. package/dist/assets/{chunk-6Q2QTUOP-BS1KpefW.js → chunk-6Q2QTUOP-DuS_xUGG.js} +1 -1
  23. package/dist/assets/{chunk-GF5L2VYU-DkEPedJP.js → chunk-GF5L2VYU-CKLZ3iVD.js} +1 -1
  24. package/dist/assets/{chunk-JWPE2WC7-DOtkNhMm.js → chunk-JWPE2WC7-DD2hcXvs.js} +1 -1
  25. package/dist/assets/{chunk-KBJHAD2P-BXLjviqM.js → chunk-KBJHAD2P-Cz-l38qp.js} +1 -1
  26. package/dist/assets/{chunk-RYQCIY6F-C50fjNNz.js → chunk-RYQCIY6F-DGFIU1YM.js} +1 -1
  27. package/dist/assets/{chunk-XXDRQBXY-QBYqCkb7.js → chunk-XXDRQBXY-CmfzoYFl.js} +1 -1
  28. package/dist/assets/classDiagram-JCYQIIEL-Bpfe3kq7.js +1 -0
  29. package/dist/assets/classDiagram-v2-OCEON4UE-Bpfe3kq7.js +1 -0
  30. package/dist/assets/{code-xml-VK1YfShP.js → code-xml-CLpHzEOP.js} +1 -1
  31. package/dist/assets/{cose-bilkent-JH36ORCC-DrVTo1Nh.js → cose-bilkent-JH36ORCC-DlFcLXCB.js} +1 -1
  32. package/dist/assets/{cynefin-VYW2F7L2-DnJa_OlQ.js → cynefin-VYW2F7L2-P1HecReO.js} +1 -1
  33. package/dist/assets/{cynefinDiagram-MW4NZA55-CCxBjw9E.js → cynefinDiagram-MW4NZA55-COgduz5P.js} +1 -1
  34. package/dist/assets/{dagre-VZM6K2ZE-C_GvE4lu.js → dagre-VZM6K2ZE-Bbb-siGp.js} +1 -1
  35. package/dist/assets/{diagram-7IWD3JNH-pFzs9HEu.js → diagram-7IWD3JNH-9CWGFMYR.js} +1 -1
  36. package/dist/assets/{diagram-B4RE2ZJO-CcehQC7x.js → diagram-B4RE2ZJO-TWK59T6V.js} +1 -1
  37. package/dist/assets/{diagram-LBJQPF4R-hfKcrrxe.js → diagram-LBJQPF4R-ErMC9yaa.js} +1 -1
  38. package/dist/assets/{diagram-Q27KOJAE-C1semJfK.js → diagram-Q27KOJAE-Dt_-C7hV.js} +1 -1
  39. package/dist/assets/{diagram-UB23O5K3-57hvXQXO.js → diagram-UB23O5K3-BJ1DnRAF.js} +1 -1
  40. package/dist/assets/{ebnfDiagram-BXEA7PRR-9KIAlAVw.js → ebnfDiagram-BXEA7PRR-CE1YaQ9s.js} +1 -1
  41. package/dist/assets/{erDiagram-JOGREHBK-B7OzJ767.js → erDiagram-JOGREHBK-Bqk7N9aY.js} +1 -1
  42. package/dist/assets/{flowDiagram-UKHOOZJN-CJV8fQPR.js → flowDiagram-UKHOOZJN-DEr2II5V.js} +1 -1
  43. package/dist/assets/{ganttDiagram-PKOTCBZU-CbMNWWQu.js → ganttDiagram-PKOTCBZU-CWYAUeYN.js} +1 -1
  44. package/dist/assets/{gitGraphDiagram-DS77QQ5N-I_vZ5waO.js → gitGraphDiagram-DS77QQ5N-tdEcEIM6.js} +1 -1
  45. package/dist/assets/{index-ZHwIojzi.js → index-B-sTfSZq.js} +1 -1
  46. package/dist/assets/{index-GFhXZyl2.js → index-BSe3UiFA.js} +1 -1
  47. package/dist/assets/{index-DFnVoqpx.js → index-B_FDMWar.js} +5 -5
  48. package/dist/assets/{index-DlSeAkw_.js → index-CWJtg2pR.js} +1 -1
  49. package/dist/assets/{infoDiagram-6WML65LV-Dh20Tsbq.js → infoDiagram-6WML65LV-A3IqRUnO.js} +1 -1
  50. package/dist/assets/{ishikawaDiagram-WSZJBQD7-DH2Sm3ko.js → ishikawaDiagram-WSZJBQD7-B2uL6bkK.js} +1 -1
  51. package/dist/assets/{journeyDiagram-NVQOT4AX-BNFQqlVu.js → journeyDiagram-NVQOT4AX-D9JB-hRW.js} +1 -1
  52. package/dist/assets/{kanban-definition-27J2QSJJ-B3iL0ztJ.js → kanban-definition-27J2QSJJ-DmlgiV7K.js} +1 -1
  53. package/dist/assets/{linear-Cwe9dEKA.js → linear-Ct_eoJQk.js} +1 -1
  54. package/dist/assets/{mermaid.core-BYRQSshi.js → mermaid.core-CQ698HNn.js} +5 -5
  55. package/dist/assets/{mindmap-definition-FAOFIHXS-BgfBYMzr.js → mindmap-definition-FAOFIHXS-DGtMgQhf.js} +1 -1
  56. package/dist/assets/{pegDiagram-VL7TDLO6-CNYpECr8.js → pegDiagram-VL7TDLO6-CO6vP4n9.js} +1 -1
  57. package/dist/assets/{pieDiagram-7S7Q4E2Y-DeSrxc4I.js → pieDiagram-7S7Q4E2Y-DMkt_Zfr.js} +1 -1
  58. package/dist/assets/{quadrantDiagram-CIZ2JOQS-BXVVQsa6.js → quadrantDiagram-CIZ2JOQS-DgNxRz6t.js} +1 -1
  59. package/dist/assets/{railroadDiagram-AXF67PYL-JTroIW8F.js → railroadDiagram-AXF67PYL-DKz9UqA9.js} +1 -1
  60. package/dist/assets/{requirementDiagram-LRYGKXZP-C1Z_inLz.js → requirementDiagram-LRYGKXZP-L84XyGgV.js} +1 -1
  61. package/dist/assets/{sankeyDiagram-W5VNT64P-DCJgKFUk.js → sankeyDiagram-W5VNT64P-CQqWbJ3j.js} +1 -1
  62. package/dist/assets/{sequenceDiagram-SI44F4Z6-D8Wrx5Vc.js → sequenceDiagram-SI44F4Z6--tnzS2tb.js} +1 -1
  63. package/dist/assets/{sizeCapture-X5ZJPWSS-CXqD68vD.js → sizeCapture-X5ZJPWSS-DujwEOtm.js} +1 -1
  64. package/dist/assets/{stateDiagram-OKZ733FA-CF0Ekqjo.js → stateDiagram-OKZ733FA-BK3TcZY2.js} +1 -1
  65. package/dist/assets/stateDiagram-v2-UEYNNEHI-_medyomK.js +1 -0
  66. package/dist/assets/{swimlanes-SLNWSIFB-DVIax_k4.js → swimlanes-SLNWSIFB-naX-Uv1B.js} +2 -2
  67. package/dist/assets/swimlanesDiagram-ULZ7WXOC-DstIv3TC.js +8 -0
  68. package/dist/assets/{timeline-definition-Z64GVDOM-DSqk3ApG.js → timeline-definition-Z64GVDOM-C-vP_ddU.js} +1 -1
  69. package/dist/assets/{vennDiagram-T6HMQDX7-DNbTqyG5.js → vennDiagram-T6HMQDX7-DN-I7o-7.js} +1 -1
  70. package/dist/assets/{wardleyDiagram-T6FBY63Y-BNCpsFZV.js → wardleyDiagram-T6FBY63Y-Db9dsaXv.js} +1 -1
  71. package/dist/assets/{xychartDiagram-ELKLHX3M-XsVZphHr.js → xychartDiagram-ELKLHX3M-DE6OxW_p.js} +1 -1
  72. package/dist/clear-cache.html +85 -85
  73. package/dist/convert-icons.md +52 -52
  74. package/dist/favicon.svg +8 -8
  75. package/dist/generate-icons.js +48 -48
  76. package/dist/icons/codex-white.svg +3 -3
  77. package/dist/icons/codex.svg +3 -3
  78. package/dist/icons/cursor-white.svg +11 -11
  79. package/dist/icons/icon-128x128.svg +11 -11
  80. package/dist/icons/icon-144x144.svg +11 -11
  81. package/dist/icons/icon-152x152.svg +11 -11
  82. package/dist/icons/icon-192x192.svg +11 -11
  83. package/dist/icons/icon-384x384.svg +11 -11
  84. package/dist/icons/icon-512x512.svg +11 -11
  85. package/dist/icons/icon-72x72.svg +11 -11
  86. package/dist/icons/icon-96x96.svg +11 -11
  87. package/dist/icons/icon-template.svg +11 -11
  88. package/dist/index.html +56 -56
  89. package/dist/logo.svg +17 -17
  90. package/dist/manifest.json +60 -60
  91. package/dist/sw.js +124 -124
  92. package/dist-server/server/modules/cli/cli.service.js +36 -36
  93. package/dist-server/server/modules/cli/sandbox.service.js +38 -38
  94. package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js +74 -74
  95. package/dist-server/server/modules/commands/commands.routes.js +24 -24
  96. package/dist-server/server/modules/database/migrations.js +190 -190
  97. package/dist-server/server/modules/database/repositories/api-keys.js +3 -3
  98. package/dist-server/server/modules/database/repositories/github-tokens.js +2 -2
  99. package/dist-server/server/modules/database/repositories/notification-channel-endpoints.js +28 -28
  100. package/dist-server/server/modules/database/repositories/notification-preferences.js +4 -4
  101. package/dist-server/server/modules/database/repositories/projects.db.js +61 -61
  102. package/dist-server/server/modules/database/repositories/provider-models.js +35 -35
  103. package/dist-server/server/modules/database/repositories/push-subscriptions.js +5 -5
  104. package/dist-server/server/modules/database/repositories/scan-state.db.js +5 -5
  105. package/dist-server/server/modules/database/repositories/sessions.db.js +92 -92
  106. package/dist-server/server/modules/database/schema.js +177 -177
  107. package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js +6 -6
  108. package/dist-server/server/modules/git/git.routes.js +17 -17
  109. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +12 -12
  110. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js +9 -9
  111. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js +17 -17
  112. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +25 -25
  113. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +27 -27
  114. package/dist-server/server/modules/providers/services/provider-token-usage.service.js +9 -9
  115. package/dist-server/server/modules/providers/tests/mcp.test.js +3 -3
  116. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +96 -96
  117. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +18 -18
  118. package/dist-server/server/modules/taskmaster/taskmaster.routes.js +419 -419
  119. package/electron/cloud.js +260 -260
  120. package/electron/desktopNotifications.js +378 -378
  121. package/electron/desktopWindow.js +766 -766
  122. package/electron/launcher/index.html +14 -14
  123. package/electron/launcher/launcher.css +801 -801
  124. package/electron/launcher/launcher.js +687 -687
  125. package/electron/localServer.js +549 -549
  126. package/electron/main.js +944 -944
  127. package/electron/preload.cjs +60 -60
  128. package/electron/scripts/generate-macos-icon.js +62 -62
  129. package/electron/serverInstaller.js +277 -277
  130. package/electron/tabs.js +87 -87
  131. package/electron/viewHost.js +331 -331
  132. package/package.json +250 -247
  133. package/public/api-docs.html +901 -901
  134. package/scripts/fix-node-pty.js +67 -67
  135. package/scripts/promote-dist-server.mjs +50 -50
  136. package/scripts/release/build-server-bundle.js +176 -176
  137. package/scripts/release/prepare-desktop-app.js +152 -152
  138. package/server/index.ts +399 -399
  139. package/server/load-env.ts +47 -47
  140. package/server/modules/agent/agent.module.ts +52 -52
  141. package/server/modules/agent/agent.routes.ts +1287 -1287
  142. package/server/modules/agent/index.ts +2 -2
  143. package/server/modules/agent/tests/agent.routes.test.ts +205 -205
  144. package/server/modules/assets/assets.routes.ts +150 -150
  145. package/server/modules/assets/index.ts +3 -3
  146. package/server/modules/assets/services/image-assets.service.ts +127 -127
  147. package/server/modules/assets/tests/image-assets.service.test.ts +74 -74
  148. package/server/modules/auth/auth.middleware.ts +163 -163
  149. package/server/modules/auth/auth.module.ts +38 -38
  150. package/server/modules/auth/auth.routes.ts +57 -57
  151. package/server/modules/auth/auth.service.ts +155 -155
  152. package/server/modules/auth/index.ts +9 -9
  153. package/server/modules/auth/tests/auth.service.test.ts +95 -95
  154. package/server/modules/browser-use/browser-use-mcp.routes.ts +120 -120
  155. package/server/modules/browser-use/browser-use-mcp.ts +386 -386
  156. package/server/modules/browser-use/browser-use-runtime.ts +10 -10
  157. package/server/modules/browser-use/browser-use.routes.ts +96 -96
  158. package/server/modules/browser-use/browser-use.service.ts +836 -836
  159. package/server/modules/browser-use/index.ts +11 -11
  160. package/server/modules/browser-use/tests/browser-use.service.test.ts +10 -10
  161. package/server/modules/cli/cli.module.ts +93 -93
  162. package/server/modules/cli/cli.service.ts +248 -248
  163. package/server/modules/cli/cli.ts +19 -19
  164. package/server/modules/cli/index.ts +2 -2
  165. package/server/modules/cli/sandbox.service.ts +398 -398
  166. package/server/modules/cli/tests/cli-environment-bootstrap.test.ts +186 -186
  167. package/server/modules/cli/tests/cli.service.test.ts +86 -86
  168. package/server/modules/cli/tests/sandbox.service.test.ts +58 -58
  169. package/server/modules/commands/commands.module.ts +22 -22
  170. package/server/modules/commands/commands.routes.ts +586 -586
  171. package/server/modules/commands/index.ts +2 -2
  172. package/server/modules/commands/tests/commands.test.ts +109 -109
  173. package/server/modules/database/connection.ts +143 -143
  174. package/server/modules/database/index.ts +17 -17
  175. package/server/modules/database/init-db.ts +17 -17
  176. package/server/modules/database/migrations.ts +515 -515
  177. package/server/modules/database/repositories/api-keys.ts +119 -119
  178. package/server/modules/database/repositories/app-config.ts +53 -53
  179. package/server/modules/database/repositories/credentials.ts +106 -106
  180. package/server/modules/database/repositories/github-tokens.ts +100 -100
  181. package/server/modules/database/repositories/notification-channel-endpoints.ts +153 -153
  182. package/server/modules/database/repositories/notification-preferences.ts +117 -117
  183. package/server/modules/database/repositories/projects.db.ts +196 -196
  184. package/server/modules/database/repositories/provider-models.ts +168 -168
  185. package/server/modules/database/repositories/push-subscriptions.ts +80 -80
  186. package/server/modules/database/repositories/scan-state.db.ts +42 -42
  187. package/server/modules/database/repositories/sessions.db.ts +524 -524
  188. package/server/modules/database/repositories/users.ts +140 -140
  189. package/server/modules/database/repositories/vapid-keys.ts +57 -57
  190. package/server/modules/database/schema.ts +210 -210
  191. package/server/modules/database/tests/projects.db.integration.test.ts +72 -72
  192. package/server/modules/database/tests/provider-models.db.integration.test.ts +125 -125
  193. package/server/modules/database/tests/sessions-provider-mapping.test.ts +109 -109
  194. package/server/modules/database/tests/sessions.db.integration.test.ts +116 -116
  195. package/server/modules/file-tree/file-tree.module.ts +116 -116
  196. package/server/modules/file-tree/file-tree.routes.ts +258 -258
  197. package/server/modules/file-tree/file-tree.service.ts +675 -675
  198. package/server/modules/file-tree/index.ts +2 -2
  199. package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -157
  200. package/server/modules/file-tree/tests/file-tree.service.test.ts +371 -371
  201. package/server/modules/git/git-branch.service.ts +43 -43
  202. package/server/modules/git/git-parsing.service.ts +66 -66
  203. package/server/modules/git/git.module.ts +22 -22
  204. package/server/modules/git/git.routes.ts +1596 -1596
  205. package/server/modules/git/index.ts +2 -2
  206. package/server/modules/git/tests/git-branch.service.test.ts +60 -60
  207. package/server/modules/git/tests/git-init.routes.test.ts +132 -132
  208. package/server/modules/git/tests/git.test.ts +106 -106
  209. package/server/modules/notifications/index.ts +24 -24
  210. package/server/modules/notifications/notifications.routes.ts +127 -127
  211. package/server/modules/notifications/services/desktop-notification-clients.service.ts +124 -124
  212. package/server/modules/notifications/services/notification-orchestrator.service.js +310 -310
  213. package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -55
  214. package/server/modules/notifications/vapid-keys.service.ts +38 -38
  215. package/server/modules/notifications/websocket/desktop-notifications-websocket.service.ts +109 -109
  216. package/server/modules/plugins/index.ts +9 -9
  217. package/server/modules/plugins/plugin-process.service.ts +217 -217
  218. package/server/modules/plugins/plugin-registry.service.ts +459 -459
  219. package/server/modules/plugins/plugins.module.ts +33 -33
  220. package/server/modules/plugins/plugins.routes.ts +66 -66
  221. package/server/modules/plugins/plugins.service.ts +147 -147
  222. package/server/modules/plugins/tests/plugins.service.test.ts +32 -32
  223. package/server/modules/projects/index.ts +11 -11
  224. package/server/modules/projects/projects.routes.ts +273 -273
  225. package/server/modules/projects/services/project-clone.service.ts +323 -323
  226. package/server/modules/projects/services/project-delete.service.ts +90 -90
  227. package/server/modules/projects/services/project-management.service.ts +144 -144
  228. package/server/modules/projects/services/project-star.service.ts +78 -78
  229. package/server/modules/projects/services/projects-has-taskmaster.service.ts +248 -248
  230. package/server/modules/projects/services/projects-with-sessions-fetch.service.ts +314 -314
  231. package/server/modules/projects/tests/project-clone.service.test.ts +183 -183
  232. package/server/modules/projects/tests/project-management.service.test.ts +117 -117
  233. package/server/modules/projects/tests/project-star.service.test.ts +123 -123
  234. package/server/modules/projects/tests/projects-has-taskmaster.service.test.ts +105 -105
  235. package/server/modules/providers/README.md +380 -380
  236. package/server/modules/providers/index.ts +10 -10
  237. package/server/modules/providers/list/claude/claude-auth.provider.ts +160 -160
  238. package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -135
  239. package/server/modules/providers/list/claude/claude-models.provider.ts +294 -294
  240. package/server/modules/providers/list/claude/claude-runtime.provider.js +1068 -1068
  241. package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +203 -203
  242. package/server/modules/providers/list/claude/claude-sessions.provider.ts +684 -684
  243. package/server/modules/providers/list/claude/claude-skills.provider.ts +265 -265
  244. package/server/modules/providers/list/claude/claude.provider.ts +30 -30
  245. package/server/modules/providers/list/codex/codex-auth.provider.ts +100 -100
  246. package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -135
  247. package/server/modules/providers/list/codex/codex-models.provider.ts +123 -123
  248. package/server/modules/providers/list/codex/codex-runtime.provider.js +533 -533
  249. package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +203 -203
  250. package/server/modules/providers/list/codex/codex-sessions.provider.ts +938 -938
  251. package/server/modules/providers/list/codex/codex-skills.provider.ts +73 -73
  252. package/server/modules/providers/list/codex/codex.provider.ts +28 -28
  253. package/server/modules/providers/list/cursor/cursor-auth.provider.ts +143 -143
  254. package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -108
  255. package/server/modules/providers/list/cursor/cursor-models.provider.ts +119 -119
  256. package/server/modules/providers/list/cursor/cursor-runtime.provider.js +385 -385
  257. package/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.ts +159 -159
  258. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +654 -654
  259. package/server/modules/providers/list/cursor/cursor-skills.provider.ts +39 -39
  260. package/server/modules/providers/list/cursor/cursor.provider.ts +30 -30
  261. package/server/modules/providers/list/opencode/opencode-auth.provider.ts +110 -110
  262. package/server/modules/providers/list/opencode/opencode-mcp.provider.ts +228 -228
  263. package/server/modules/providers/list/opencode/opencode-models.provider.ts +203 -203
  264. package/server/modules/providers/list/opencode/opencode-runtime.provider.js +434 -434
  265. package/server/modules/providers/list/opencode/opencode-runtime.provider.test.js +261 -261
  266. package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +179 -179
  267. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +500 -500
  268. package/server/modules/providers/list/opencode/opencode-skills.provider.ts +78 -78
  269. package/server/modules/providers/list/opencode/opencode.provider.ts +30 -30
  270. package/server/modules/providers/provider.registry.ts +36 -36
  271. package/server/modules/providers/provider.routes.ts +877 -877
  272. package/server/modules/providers/services/mcp.service.ts +109 -109
  273. package/server/modules/providers/services/provider-auth.service.ts +26 -26
  274. package/server/modules/providers/services/provider-capabilities.service.ts +97 -97
  275. package/server/modules/providers/services/provider-models.service.ts +401 -401
  276. package/server/modules/providers/services/provider-runtime.service.ts +108 -108
  277. package/server/modules/providers/services/provider-token-usage.service.ts +357 -357
  278. package/server/modules/providers/services/session-conversations-search.service.ts +1321 -1321
  279. package/server/modules/providers/services/session-synchronizer.service.ts +74 -74
  280. package/server/modules/providers/services/sessions-watcher.service.ts +247 -247
  281. package/server/modules/providers/services/sessions.service.ts +471 -471
  282. package/server/modules/providers/services/skills.service.ts +39 -39
  283. package/server/modules/providers/shared/base/abstract.provider.ts +32 -32
  284. package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -151
  285. package/server/modules/providers/shared/skills/skills.provider.ts +287 -287
  286. package/server/modules/providers/tests/claude-auth.test.ts +150 -150
  287. package/server/modules/providers/tests/claude-sessions.test.ts +61 -61
  288. package/server/modules/providers/tests/codex-sessions.test.ts +231 -231
  289. package/server/modules/providers/tests/mcp.test.ts +349 -349
  290. package/server/modules/providers/tests/opencode-models.test.ts +41 -41
  291. package/server/modules/providers/tests/opencode-sessions.test.ts +522 -522
  292. package/server/modules/providers/tests/provider-attachment-history.test.ts +247 -247
  293. package/server/modules/providers/tests/provider-models.service.test.ts +353 -353
  294. package/server/modules/providers/tests/provider-runtime.service.test.ts +138 -138
  295. package/server/modules/providers/tests/provider-token-usage.service.test.ts +186 -186
  296. package/server/modules/providers/tests/provider.routes.test.ts +244 -244
  297. package/server/modules/providers/tests/sessions-details.test.ts +73 -73
  298. package/server/modules/providers/tests/sessions.service.test.ts +127 -127
  299. package/server/modules/providers/tests/skills.test.ts +692 -692
  300. package/server/modules/settings/index.ts +2 -2
  301. package/server/modules/settings/settings.module.ts +50 -50
  302. package/server/modules/settings/settings.routes.ts +51 -51
  303. package/server/modules/settings/settings.service.ts +186 -186
  304. package/server/modules/settings/tests/settings.service.test.ts +54 -54
  305. package/server/modules/system/index.ts +2 -2
  306. package/server/modules/system/system.module.ts +62 -62
  307. package/server/modules/system/system.routes.ts +21 -21
  308. package/server/modules/system/system.service.ts +76 -76
  309. package/server/modules/system/tests/system.service.test.ts +118 -118
  310. package/server/modules/taskmaster/index.ts +2 -2
  311. package/server/modules/taskmaster/taskmaster.module.ts +24 -24
  312. package/server/modules/taskmaster/taskmaster.routes.ts +1482 -1482
  313. package/server/modules/taskmaster/taskmaster.service.ts +132 -132
  314. package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -144
  315. package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -97
  316. package/server/modules/user/index.ts +2 -2
  317. package/server/modules/user/tests/user.service.test.ts +61 -61
  318. package/server/modules/user/user.module.ts +58 -58
  319. package/server/modules/user/user.routes.ts +50 -50
  320. package/server/modules/user/user.service.ts +85 -85
  321. package/server/modules/voice/index.ts +2 -2
  322. package/server/modules/voice/tests/voice.service.test.ts +98 -98
  323. package/server/modules/voice/voice.module.ts +47 -47
  324. package/server/modules/voice/voice.routes.ts +113 -113
  325. package/server/modules/voice/voice.service.ts +192 -192
  326. package/server/modules/websocket/README.md +273 -273
  327. package/server/modules/websocket/index.ts +3 -3
  328. package/server/modules/websocket/services/chat-run-registry.service.ts +343 -343
  329. package/server/modules/websocket/services/chat-session-writer.service.ts +145 -145
  330. package/server/modules/websocket/services/chat-websocket.service.ts +425 -425
  331. package/server/modules/websocket/services/plugin-websocket-proxy.service.ts +65 -65
  332. package/server/modules/websocket/services/shell-websocket.service.ts +502 -502
  333. package/server/modules/websocket/services/websocket-auth.service.ts +59 -59
  334. package/server/modules/websocket/services/websocket-server.service.ts +124 -124
  335. package/server/modules/websocket/services/websocket-state.service.ts +16 -16
  336. package/server/modules/websocket/services/websocket-writer.service.ts +38 -38
  337. package/server/modules/websocket/tests/chat-attachment-filter.test.ts +59 -59
  338. package/server/modules/websocket/tests/chat-run-registry.test.ts +282 -282
  339. package/server/modules/websocket/tests/shell-websocket.service.test.ts +100 -100
  340. package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -78
  341. package/server/modules/worktrees/index.ts +2 -2
  342. package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -53
  343. package/server/modules/worktrees/services/worktree-create.service.ts +104 -104
  344. package/server/modules/worktrees/services/worktree-git.service.ts +207 -207
  345. package/server/modules/worktrees/services/worktree-list.service.ts +143 -143
  346. package/server/modules/worktrees/services/worktree-merge.service.ts +157 -157
  347. package/server/modules/worktrees/services/worktree-open.service.ts +85 -85
  348. package/server/modules/worktrees/services/worktree-remove.service.ts +88 -88
  349. package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -68
  350. package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -142
  351. package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -84
  352. package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -45
  353. package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -213
  354. package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -122
  355. package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -227
  356. package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -199
  357. package/server/modules/worktrees/worktrees.module.ts +113 -113
  358. package/server/modules/worktrees/worktrees.routes.ts +116 -116
  359. package/server/shared/claude-cli-path.ts +139 -139
  360. package/server/shared/frontmatter.ts +18 -18
  361. package/server/shared/image-attachments.ts +435 -435
  362. package/server/shared/interfaces.ts +179 -179
  363. package/server/shared/tests/claude-cli-path.test.ts +61 -61
  364. package/server/shared/tests/image-attachments.test.ts +353 -353
  365. package/server/shared/tests/slice-tail-page.test.ts +42 -42
  366. package/server/shared/types.ts +1226 -1226
  367. package/server/shared/utils.ts +1161 -1161
  368. package/server/tsconfig.json +40 -40
  369. package/shared/networkHosts.js +22 -22
  370. package/dist/assets/channel-Bm0ZLE4z.js +0 -1
  371. package/dist/assets/classDiagram-JCYQIIEL-DqEOcNxw.js +0 -1
  372. package/dist/assets/classDiagram-v2-OCEON4UE-DqEOcNxw.js +0 -1
  373. package/dist/assets/stateDiagram-v2-UEYNNEHI-DARLpEFJ.js +0 -1
  374. package/dist/assets/swimlanesDiagram-ULZ7WXOC-CrgDgaY8.js +0 -8
@@ -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
+