coding-tool-x 3.8.3 → 3.8.5

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 (434) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +86 -15
  3. package/dist/web/assets/AgentsDrawer-BG6P3DX-.js +1 -0
  4. package/dist/web/assets/AgentsDrawer-Pw2k-ZAa.css +1 -0
  5. package/dist/web/assets/Analytics--z_FmL5P.js +1 -0
  6. package/dist/web/assets/Analytics-CyHhR126.css +1 -0
  7. package/dist/web/assets/AssetPathField-CrJtRKHy.js +1 -0
  8. package/dist/web/assets/ChatHistoryDrawer-B2qBQs9L.css +1 -0
  9. package/dist/web/assets/ChatHistoryDrawer-BiuEryJj.js +1 -0
  10. package/dist/web/assets/CollapseItem-BAYEsL_Q.js +1 -0
  11. package/dist/web/assets/CommandsDrawer-BZJxlPvV.css +1 -0
  12. package/dist/web/assets/CommandsDrawer-YJ-U7BXN.js +1 -0
  13. package/dist/web/assets/ConfigExportDrawer-Ce_hAknW.js +1 -0
  14. package/dist/web/assets/ConfigExportDrawer-dwruRKWr.css +1 -0
  15. package/dist/web/assets/ConfigTemplates-Bvr1NN6K.js +1 -0
  16. package/dist/web/assets/ConfigTemplatesDrawer-BfDi8yO3.css +1 -0
  17. package/dist/web/assets/ConfigTemplatesDrawer-BjIeHfF-.js +1 -0
  18. package/dist/web/assets/ConfigTemplatesPanel-AV00tm_D.js +1 -0
  19. package/dist/web/assets/ConfigTemplatesPanel-CWyPtk67.css +1 -0
  20. package/dist/web/assets/Divider-D28g1gwj.js +1 -0
  21. package/dist/web/assets/DrawerContent-ChXgZ1Xm.js +1 -0
  22. package/dist/web/assets/FavoritesDrawer-CG9eI9Ay.css +1 -0
  23. package/dist/web/assets/FavoritesDrawer-Cz95o4CD.js +1 -0
  24. package/dist/web/assets/GatewayConvertDrawer-CuNlf7AC.css +1 -0
  25. package/dist/web/assets/GatewayConvertDrawer-DLlbMz27.js +1 -0
  26. package/dist/web/assets/Home-CSuFuJ9Y.css +1 -0
  27. package/dist/web/assets/Home-D7CCOFQC.js +1 -0
  28. package/dist/web/assets/MarkdownEditor-qfVgSre_.css +1 -0
  29. package/dist/web/assets/MarkdownEditor-rEZ-c72L.js +1 -0
  30. package/dist/web/assets/McpDrawer-C0dnsZhQ.css +1 -0
  31. package/dist/web/assets/McpDrawer-DfoCyxU2.js +1 -0
  32. package/dist/web/assets/McpFormDrawer-BRbDcawn.css +1 -0
  33. package/dist/web/assets/McpFormDrawer-SKu8HNUR.js +1 -0
  34. package/dist/web/assets/PluginManager-BbeK-3rV.js +1 -0
  35. package/dist/web/assets/PluginsDrawer-CWVJ7yjS.js +1 -0
  36. package/dist/web/assets/PluginsDrawer-DM3QjprE.css +1 -0
  37. package/dist/web/assets/PluginsPanel-Cm2N3StG.js +1 -0
  38. package/dist/web/assets/PluginsPanel-D6ZqITcR.css +1 -0
  39. package/dist/web/assets/ProjectList-677RLZ8O.css +1 -0
  40. package/dist/web/assets/ProjectList-CsjnsNPv.js +1 -0
  41. package/dist/web/assets/PromptsDrawer-BIgiYCEQ.css +1 -0
  42. package/dist/web/assets/PromptsDrawer-EGd3djFa.js +1 -0
  43. package/dist/web/assets/RecentSessionsDrawer-CKFsOYDM.css +1 -0
  44. package/dist/web/assets/RecentSessionsDrawer-D1vtoLAs.js +1 -0
  45. package/dist/web/assets/SessionCard-BgLg49U3.js +1 -0
  46. package/dist/web/assets/SessionCard-aM2NHu6i.css +1 -0
  47. package/dist/web/assets/SessionList-BpYRz1cX.css +1 -0
  48. package/dist/web/assets/SessionList-TRiTklWk.js +1 -0
  49. package/dist/web/assets/SettingsDrawer-d5liXjHq.css +1 -0
  50. package/dist/web/assets/SettingsDrawer-rz2WejGY.js +1 -0
  51. package/dist/web/assets/SkillManager-BTjTUbHq.js +1 -0
  52. package/dist/web/assets/SkillManager-C0GCT2Kb.css +1 -0
  53. package/dist/web/assets/SkillsDrawer-BCNme-aJ.css +1 -0
  54. package/dist/web/assets/SkillsDrawer-pN0hbkK3.js +1 -0
  55. package/dist/web/assets/SkillsPanel-B3Nm5j32.css +1 -0
  56. package/dist/web/assets/SkillsPanel-gmBWEoiF.js +1 -0
  57. package/dist/web/assets/SpeedTestDrawer-Dc0WToJ_.css +1 -0
  58. package/dist/web/assets/SpeedTestDrawer-DcNzuVJk.js +1 -0
  59. package/dist/web/assets/Upload-v5rV0qTT.js +1 -0
  60. package/dist/web/assets/WorkspaceDrawer-CGnMu9p1.css +1 -0
  61. package/dist/web/assets/WorkspaceDrawer-DxmicM4U.js +1 -0
  62. package/dist/web/assets/WorkspaceManager-CJHCjARN.js +1 -0
  63. package/dist/web/assets/WorkspacePanel-D0-zHTHP.css +1 -0
  64. package/dist/web/assets/WorkspacePanel-D8_Zq-du.js +1 -0
  65. package/dist/web/assets/_plugin-vue_export-helper-BeLZJZij.js +1 -0
  66. package/dist/web/assets/client-UDwXBP9i.js +1 -0
  67. package/dist/web/assets/clipboard-B46yyoz_.js +1 -0
  68. package/dist/web/assets/headers-cf-QapUq.js +1 -0
  69. package/dist/web/assets/icons-B2Vg-IOC.js +1 -0
  70. package/dist/web/assets/index-C0EHRym0.css +1 -0
  71. package/dist/web/assets/index-DnEocV0M.js +2 -0
  72. package/dist/web/assets/light-Cp0t7v32.js +1 -0
  73. package/dist/web/assets/markdown-u082bbtj.js +1 -0
  74. package/dist/web/assets/platforms-CBkB45JP.js +1 -0
  75. package/dist/web/assets/platforms-FTpjxAT6.js +1 -0
  76. package/dist/web/assets/project-config-B2baPzYL.js +1 -0
  77. package/dist/web/assets/sessions-Cmy31slD.js +1 -0
  78. package/dist/web/assets/sessions-yC_oVVh8.js +1 -0
  79. package/dist/web/assets/skill-repo-input-B_fkGlUK.js +1 -0
  80. package/dist/web/assets/use-lock-html-scroll-DXIqmUW4.js +1 -0
  81. package/dist/web/assets/use-message-DoLM8C1C.js +1 -0
  82. package/dist/web/assets/useResponsiveDrawer-B3uojyvV.js +1 -0
  83. package/dist/web/assets/vendors-D0c_0KLP.js +1 -0
  84. package/dist/web/assets/vue-vendor-BqZbbXHA.js +1 -0
  85. package/dist/web/assets/workspaces-mjyPVGS8.js +1 -0
  86. package/dist/web/assets/xml-CgY3RMlX.js +1 -0
  87. package/dist/web/index.html +12 -8
  88. package/docs/native-log-memory-2026-09-16.md +43 -0
  89. package/docs/superpowers/plans/2026-08-26-configuration-driven-cli-platform.md +1578 -0
  90. package/docs/superpowers/plans/2026-08-30-project-scoped-config-control.md +1260 -0
  91. package/docs/superpowers/plans/2026-09-01-omp-skill-refresh-boundary.md +213 -0
  92. package/docs/superpowers/plans/2026-09-01-realtime-logs-panel.md +125 -0
  93. package/docs/superpowers/plans/2026-09-02-config-driven-platform-boundary.md +86 -0
  94. package/docs/superpowers/plans/2026-09-02-platform-implementation-drivers.md +508 -0
  95. package/docs/superpowers/plans/2026-09-03-cli-platform-correctness-boundary.md +760 -0
  96. package/docs/superpowers/plans/2026-09-03-dependency-security-remediation.md +133 -0
  97. package/docs/superpowers/plans/2026-09-04-model-catalog-pricing-sync.md +1078 -0
  98. package/docs/superpowers/plans/2026-09-05-codex-project-scan-500.md +128 -0
  99. package/docs/superpowers/plans/2026-09-06-project-skill-path-fix.md +97 -0
  100. package/docs/superpowers/specs/2026-08-26-configuration-driven-cli-platform-design.md +408 -0
  101. package/docs/superpowers/specs/2026-08-30-project-scoped-config-control-design.md +467 -0
  102. package/docs/superpowers/specs/2026-09-01-claude-session-content-repair-design.md +111 -0
  103. package/docs/superpowers/specs/2026-09-01-omp-skill-refresh-boundary-design.md +83 -0
  104. package/docs/superpowers/specs/2026-09-01-realtime-logs-panel-design.md +27 -0
  105. package/docs/superpowers/specs/2026-09-02-config-driven-platform-boundary-design.md +64 -0
  106. package/docs/superpowers/specs/2026-09-02-platform-implementation-driver-boundary-design.md +123 -0
  107. package/docs/superpowers/specs/2026-09-03-cli-platform-correctness-boundary-design.md +249 -0
  108. package/docs/superpowers/specs/2026-09-03-dependency-security-remediation-design.md +87 -0
  109. package/docs/superpowers/specs/2026-09-04-model-catalog-pricing-sync-design.md +301 -0
  110. package/docs/superpowers/specs/2026-09-05-codex-project-scan-500-design.md +24 -0
  111. package/package.json +13 -8
  112. package/src/commands/channels.js +88 -191
  113. package/src/commands/cli-type.js +19 -11
  114. package/src/commands/daemon.js +94 -32
  115. package/src/commands/doctor.js +16 -9
  116. package/src/commands/export-config.js +23 -5
  117. package/src/commands/list.js +130 -52
  118. package/src/commands/logs.js +44 -27
  119. package/src/commands/platform-command-registry.js +78 -0
  120. package/src/commands/plugin.js +11 -5
  121. package/src/commands/port-config.js +34 -52
  122. package/src/commands/proxy-control.js +207 -145
  123. package/src/commands/proxy.js +2 -2
  124. package/src/commands/resume.js +87 -91
  125. package/src/commands/search.js +137 -67
  126. package/src/commands/stats.js +30 -22
  127. package/src/commands/switch.js +1 -1
  128. package/src/commands/toggle-proxy.js +94 -111
  129. package/src/commands/ui.js +67 -6
  130. package/src/commands/workspace.js +90 -8
  131. package/src/config/default.js +6 -53
  132. package/src/config/loader.js +61 -24
  133. package/src/config/model-metadata.js +49 -59
  134. package/src/config/model-metadata.json +4095 -99
  135. package/src/config/paths.js +181 -8
  136. package/src/index.js +134 -71
  137. package/src/platforms/access.js +196 -0
  138. package/src/{server/services → platforms}/agents-service.js +354 -197
  139. package/src/platforms/channel-auth-registry.js +162 -0
  140. package/src/platforms/channel-auth-service.js +82 -0
  141. package/src/{server/services → platforms}/commands-service.js +195 -115
  142. package/src/platforms/driver-registry.js +59 -0
  143. package/src/platforms/drivers/claude/api-operations.js +62 -0
  144. package/src/{server/services/channels.js → platforms/drivers/claude/channels-implementation.js} +131 -33
  145. package/src/platforms/drivers/claude/channels.js +39 -0
  146. package/src/{server/services/config-sync-service.js → platforms/drivers/claude/config-sync.js} +29 -5
  147. package/src/{server/services → platforms/drivers/claude}/health-check.js +4 -4
  148. package/src/platforms/drivers/claude/health.js +22 -0
  149. package/src/platforms/drivers/claude/mcp.js +9 -0
  150. package/src/{server/services/settings-manager.js → platforms/drivers/claude/native-config-implementation.js} +13 -4
  151. package/src/platforms/drivers/claude/native-config.js +46 -0
  152. package/src/platforms/drivers/claude/native-logs.js +72 -0
  153. package/src/{server/services/claude-openai-gateway.js → platforms/drivers/claude/openai-gateway.js} +8 -65
  154. package/src/platforms/drivers/claude/project-config.js +21 -0
  155. package/src/platforms/drivers/claude/projects.js +62 -0
  156. package/src/platforms/drivers/claude/prompts.js +9 -0
  157. package/src/{server/proxy-server.js → platforms/drivers/claude/proxy-implementation.js} +41 -278
  158. package/src/platforms/drivers/claude/proxy.js +16 -0
  159. package/src/platforms/drivers/claude/resource-sync.js +9 -0
  160. package/src/platforms/drivers/claude/session-history-adapter.js +313 -0
  161. package/src/{server/services/sessions.js → platforms/drivers/claude/sessions-implementation.js} +145 -35
  162. package/src/platforms/drivers/claude/sessions.js +76 -0
  163. package/src/{server/services/claude-statistics-service.js → platforms/drivers/claude/statistics-implementation.js} +2 -2
  164. package/src/platforms/drivers/claude/statistics.js +16 -0
  165. package/src/{server/services/claude-wire.js → platforms/drivers/claude/wire.js} +1 -1
  166. package/src/platforms/drivers/codex/api-operations.js +9 -0
  167. package/src/{server/services/codex-channels.js → platforms/drivers/codex/channels-implementation.js} +149 -14
  168. package/src/platforms/drivers/codex/channels.js +45 -0
  169. package/src/{server/services/codex-config.js → platforms/drivers/codex/config.js} +12 -2
  170. package/src/{server/services/codex-env-manager.js → platforms/drivers/codex/env-manager.js} +1 -1
  171. package/src/platforms/drivers/codex/mcp.js +9 -0
  172. package/src/{server/services/codex-settings-manager.js → platforms/drivers/codex/native-config-implementation.js} +15 -6
  173. package/src/platforms/drivers/codex/native-config.js +47 -0
  174. package/src/platforms/drivers/codex/native-logs.js +166 -0
  175. package/src/platforms/drivers/codex/project-config.js +21 -0
  176. package/src/platforms/drivers/codex/projects.js +26 -0
  177. package/src/platforms/drivers/codex/prompts.js +9 -0
  178. package/src/{server/codex-proxy-server.js → platforms/drivers/codex/proxy-implementation.js} +30 -233
  179. package/src/platforms/drivers/codex/proxy.js +16 -0
  180. package/src/platforms/drivers/codex/resource-sync.js +9 -0
  181. package/src/{server/services/session-history-adapters/codex.js → platforms/drivers/codex/session-history-adapter.js} +37 -23
  182. package/src/{server/services/codex-sessions.js → platforms/drivers/codex/sessions-implementation.js} +81 -75
  183. package/src/platforms/drivers/codex/sessions.js +36 -0
  184. package/src/{server/services/codex-statistics-service.js → platforms/drivers/codex/statistics-implementation.js} +2 -2
  185. package/src/platforms/drivers/codex/statistics.js +16 -0
  186. package/src/platforms/drivers/gemini/api-operations.js +9 -0
  187. package/src/{server/services/gemini-channels.js → platforms/drivers/gemini/channels-implementation.js} +202 -37
  188. package/src/platforms/drivers/gemini/channels.js +39 -0
  189. package/src/{server/services/gemini-config.js → platforms/drivers/gemini/config.js} +12 -2
  190. package/src/platforms/drivers/gemini/mcp.js +9 -0
  191. package/src/{server/services/gemini-settings-manager.js → platforms/drivers/gemini/native-config-implementation.js} +14 -5
  192. package/src/platforms/drivers/gemini/native-config.js +39 -0
  193. package/src/platforms/drivers/gemini/native-logs.js +180 -0
  194. package/src/platforms/drivers/gemini/project-config.js +21 -0
  195. package/src/platforms/drivers/gemini/projects.js +26 -0
  196. package/src/platforms/drivers/gemini/prompts.js +9 -0
  197. package/src/{server/gemini-proxy-server.js → platforms/drivers/gemini/proxy-implementation.js} +36 -267
  198. package/src/platforms/drivers/gemini/proxy.js +16 -0
  199. package/src/platforms/drivers/gemini/resource-sync.js +9 -0
  200. package/src/{server/services/session-history-adapters/gemini.js → platforms/drivers/gemini/session-history-adapter.js} +70 -18
  201. package/src/{server/services/gemini-sessions.js → platforms/drivers/gemini/sessions-implementation.js} +53 -37
  202. package/src/platforms/drivers/gemini/sessions.js +47 -0
  203. package/src/{server/services/gemini-statistics-service.js → platforms/drivers/gemini/statistics-implementation.js} +2 -2
  204. package/src/platforms/drivers/gemini/statistics.js +16 -0
  205. package/src/{server/services/gemini-wire.js → platforms/drivers/gemini/wire.js} +1 -1
  206. package/src/platforms/drivers/generic-filesystem.js +166 -0
  207. package/src/platforms/drivers/generic-jsonl.js +141 -0
  208. package/src/platforms/drivers/generic-mcp.js +44 -0
  209. package/src/platforms/drivers/generic-openai-compatible.js +45 -0
  210. package/src/platforms/drivers/generic-prompt.js +41 -0
  211. package/src/platforms/drivers/legacy.js +677 -0
  212. package/src/platforms/drivers/native-config-snapshot.js +125 -0
  213. package/src/platforms/drivers/native-log-utils.js +1292 -0
  214. package/src/platforms/drivers/notification-hooks.js +578 -0
  215. package/src/{server/api/omp-config.js → platforms/drivers/omp/api-operations.js} +52 -64
  216. package/src/{server/services/omp-auth-provider-worker.js → platforms/drivers/omp/auth-provider-worker.js} +1 -1
  217. package/src/{server/services/omp-auth-providers.js → platforms/drivers/omp/auth-providers.js} +1 -1
  218. package/src/{server/services/omp-channels.js → platforms/drivers/omp/channels-implementation.js} +166 -39
  219. package/src/platforms/drivers/omp/channels.js +58 -0
  220. package/src/{server/services/omp-config.js → platforms/drivers/omp/config.js} +53 -13
  221. package/src/{server/services/omp-gateway-routing.js → platforms/drivers/omp/gateway-routing.js} +14 -7
  222. package/src/{server/services/omp-gateway.js → platforms/drivers/omp/gateway.js} +4 -262
  223. package/src/platforms/drivers/omp/mcp.js +9 -0
  224. package/src/{server/services/omp-settings-manager.js → platforms/drivers/omp/native-config-implementation.js} +75 -10
  225. package/src/platforms/drivers/omp/native-config.js +46 -0
  226. package/src/platforms/drivers/omp/native-logs.js +52 -0
  227. package/src/{server/services/omp-native-plugin-adapter.js → platforms/drivers/omp/native-plugin-adapter.js} +91 -4
  228. package/src/platforms/drivers/omp/project-config.js +29 -0
  229. package/src/platforms/drivers/omp/projects.js +20 -0
  230. package/src/platforms/drivers/omp/prompts.js +9 -0
  231. package/src/{server/omp-proxy-server.js → platforms/drivers/omp/proxy-implementation.js} +6 -15
  232. package/src/platforms/drivers/omp/proxy.js +16 -0
  233. package/src/platforms/drivers/omp/resource-sync.js +9 -0
  234. package/src/{server/services/session-history-adapters/omp.js → platforms/drivers/omp/session-history-adapter.js} +42 -18
  235. package/src/{server/services/omp-sessions.js → platforms/drivers/omp/sessions-implementation.js} +130 -94
  236. package/src/platforms/drivers/omp/sessions.js +36 -0
  237. package/src/{server/services/omp-skill-discovery.js → platforms/drivers/omp/skill-discovery.js} +159 -32
  238. package/src/{server/services/omp-skill-settings-service.js → platforms/drivers/omp/skill-settings.js} +1 -1
  239. package/src/{server/services/omp-statistics-service.js → platforms/drivers/omp/statistics-implementation.js} +3 -3
  240. package/src/platforms/drivers/omp/statistics.js +16 -0
  241. package/src/platforms/drivers/opencode/api-operations.js +9 -0
  242. package/src/{server/services/opencode-channels.js → platforms/drivers/opencode/channels-implementation.js} +28 -9
  243. package/src/platforms/drivers/opencode/channels.js +40 -0
  244. package/src/platforms/drivers/opencode/conversion.js +41 -0
  245. package/src/{server/services/opencode-gateway-converter.js → platforms/drivers/opencode/gateway-converter.js} +1 -1
  246. package/src/platforms/drivers/opencode/mcp.js +9 -0
  247. package/src/{server/services/opencode-settings-manager.js → platforms/drivers/opencode/native-config-implementation.js} +17 -6
  248. package/src/platforms/drivers/opencode/native-config.js +26 -0
  249. package/src/platforms/drivers/opencode/native-logs.js +133 -0
  250. package/src/platforms/drivers/opencode/project-config.js +98 -0
  251. package/src/platforms/drivers/opencode/projects.js +20 -0
  252. package/src/platforms/drivers/opencode/prompts.js +9 -0
  253. package/src/{server/opencode-proxy-server.js → platforms/drivers/opencode/proxy-implementation.js} +27 -362
  254. package/src/platforms/drivers/opencode/proxy.js +16 -0
  255. package/src/platforms/drivers/opencode/resource-sync.js +9 -0
  256. package/src/{server/services/opencode-sessions.js → platforms/drivers/opencode/sessions-implementation.js} +211 -64
  257. package/src/platforms/drivers/opencode/sessions.js +48 -0
  258. package/src/{server/services/opencode-statistics-service.js → platforms/drivers/opencode/statistics-implementation.js} +2 -2
  259. package/src/platforms/drivers/opencode/statistics.js +16 -0
  260. package/src/platforms/drivers/secure-file-driver.js +272 -0
  261. package/src/platforms/drivers/unsupported.js +7 -0
  262. package/src/platforms/manifest-schema.js +398 -0
  263. package/src/platforms/manifests/claude.json +489 -0
  264. package/src/platforms/manifests/codex.json +448 -0
  265. package/src/platforms/manifests/gemini.json +447 -0
  266. package/src/platforms/manifests/omp.json +496 -0
  267. package/src/platforms/manifests/opencode.json +422 -0
  268. package/src/{server/services → platforms}/native-oauth-adapters.js +87 -417
  269. package/src/{server/services → platforms}/notification-hooks.js +140 -1023
  270. package/src/platforms/oauth-credentials-service.js +506 -0
  271. package/src/platforms/path-resolver.js +179 -0
  272. package/src/platforms/platform-path-context.js +305 -0
  273. package/src/platforms/registry.js +248 -0
  274. package/src/platforms/remote-notification-providers.js +678 -0
  275. package/src/platforms/runtime.js +259 -0
  276. package/src/{server/services/session-history-adapters/index.js → platforms/session-history-adapters.js} +8 -1
  277. package/src/plugins/plugin-loader.js +2 -2
  278. package/src/plugins/plugin-manager.js +2 -2
  279. package/src/plugins/registry.js +27 -10
  280. package/src/reset-config.js +21 -5
  281. package/src/server/api/agents.js +46 -72
  282. package/src/server/api/commands.js +16 -6
  283. package/src/server/api/config-registry.js +206 -59
  284. package/src/server/api/config-sync.js +3 -2
  285. package/src/server/api/config-templates.js +20 -4
  286. package/src/server/api/config.js +111 -102
  287. package/src/server/api/convert.js +54 -178
  288. package/src/server/api/dashboard.js +168 -102
  289. package/src/server/api/hooks.js +1 -1
  290. package/src/server/api/mcp.js +224 -84
  291. package/src/server/api/platform-api-config.js +102 -0
  292. package/src/server/api/platform-route-factory.js +215 -0
  293. package/src/server/api/platform-routes.js +26 -0
  294. package/src/server/api/platforms.js +110 -0
  295. package/src/server/api/plugins.js +57 -57
  296. package/src/server/api/project-config.js +168 -0
  297. package/src/server/api/prompts.js +58 -45
  298. package/src/server/api/settings.js +55 -8
  299. package/src/server/api/skills.js +262 -133
  300. package/src/server/api/ui-config.js +2 -2
  301. package/src/server/api/validation-errors.js +18 -4
  302. package/src/server/api/workspaces.js +47 -12
  303. package/src/server/index.js +164 -213
  304. package/src/server/platform-context.js +81 -0
  305. package/src/server/services/channel-balance.js +11 -20
  306. package/src/server/services/channel-health.js +21 -6
  307. package/src/server/services/channel-scheduler.js +29 -39
  308. package/src/server/services/channel-sync-utils.js +23 -13
  309. package/src/server/services/config-export-service.js +350 -319
  310. package/src/server/services/config-registry-service.js +280 -54
  311. package/src/server/services/config-sync-manager.js +172 -944
  312. package/src/server/services/config-templates-service.js +419 -353
  313. package/src/server/services/control-manifest-store.js +206 -0
  314. package/src/server/services/dashboard-snapshot-worker.js +656 -100
  315. package/src/server/services/effective-control-service.js +557 -0
  316. package/src/server/services/local-resource-index.js +314 -0
  317. package/src/server/services/mcp-service.js +607 -977
  318. package/src/server/services/model-detector.js +15 -10
  319. package/src/server/services/native-log-channel-resolver.js +214 -0
  320. package/src/server/services/native-log-observer.js +291 -0
  321. package/src/server/services/network-access.js +1 -1
  322. package/src/server/services/platform-catalog.js +82 -0
  323. package/src/server/services/platform-resolution.js +32 -29
  324. package/src/server/services/plugins-service.js +376 -122
  325. package/src/server/services/project-config-service.js +550 -0
  326. package/src/server/services/project-path-validation.js +31 -0
  327. package/src/server/services/prompts-service.js +267 -233
  328. package/src/server/services/proxy-runtime.js +7 -4
  329. package/src/server/services/remote-credential-cache.js +43 -0
  330. package/src/server/services/repo-scanner-base.js +182 -75
  331. package/src/server/services/request-logger.js +7 -4
  332. package/src/server/services/session-history-index.js +780 -213
  333. package/src/server/services/session-history-worker.js +228 -33
  334. package/src/server/services/session-snapshot-worker.js +124 -34
  335. package/src/server/services/session-snapshots.js +4 -2
  336. package/src/server/services/skill-artifact-store.js +355 -0
  337. package/src/server/services/skill-format-adapters.js +65 -0
  338. package/src/server/services/skill-projection-service.js +323 -0
  339. package/src/server/services/skill-refresh-task-service.js +275 -0
  340. package/src/server/services/skill-service.js +2020 -677
  341. package/src/server/services/snapshot-cache.js +30 -8
  342. package/src/server/services/speed-test.js +8 -8
  343. package/src/server/services/sqlite-connection.js +19 -3
  344. package/src/server/services/statistics-service.js +240 -57
  345. package/src/server/services/ui-config.js +107 -76
  346. package/src/server/services/usage-log-utils.js +98 -0
  347. package/src/server/services/web-build.js +1 -1
  348. package/src/server/services/workspace-service.js +59 -29
  349. package/src/server/utils/pricing.js +10 -19
  350. package/src/server/websocket-server.js +153 -28
  351. package/src/{server/services/base → shared}/base-channel-service.js +156 -28
  352. package/src/shared/capability-driver.js +104 -0
  353. package/src/shared/channel-auth-policy.js +27 -0
  354. package/src/shared/channel-driver.js +161 -0
  355. package/src/shared/driver-factories/api.js +180 -0
  356. package/src/shared/driver-factories/mcp.js +244 -0
  357. package/src/shared/driver-factories/projects.js +121 -0
  358. package/src/shared/driver-factories/prompts.js +58 -0
  359. package/src/shared/driver-factories/resource-sync.js +375 -0
  360. package/src/shared/driver-result.js +78 -0
  361. package/src/shared/mcp-format.js +189 -0
  362. package/src/shared/platforms.js +104 -167
  363. package/src/shared/project-config.js +512 -0
  364. package/src/shared/proxy-driver.js +57 -0
  365. package/src/{server/services/base → shared}/response-usage-parser.js +8 -4
  366. package/src/ui/menu.js +91 -67
  367. package/src/utils/port-helper.js +35 -19
  368. package/src/utils/session.js +1 -1
  369. package/dist/web/assets/Analytics-COEUXmd4.js +0 -25
  370. package/dist/web/assets/Analytics-RNn1BUbG.css +0 -1
  371. package/dist/web/assets/ConfigTemplates-DLLkS53H.js +0 -1
  372. package/dist/web/assets/Home-DCEyLzwX.js +0 -1
  373. package/dist/web/assets/Home-DYVy4cGZ.css +0 -1
  374. package/dist/web/assets/PluginManager-Oe1ZHoMO.js +0 -1
  375. package/dist/web/assets/ProjectList-CWjuAFof.js +0 -1
  376. package/dist/web/assets/ProjectList-VeMNXfgO.css +0 -1
  377. package/dist/web/assets/SessionList-C4chCPxK.css +0 -1
  378. package/dist/web/assets/SessionList-v3ehGg9U.js +0 -1
  379. package/dist/web/assets/SkillManager-BsX8Qpj0.css +0 -1
  380. package/dist/web/assets/SkillManager-DUF_qP5S.js +0 -1
  381. package/dist/web/assets/WorkspaceManager-CjAWBosO.js +0 -1
  382. package/dist/web/assets/icons-nGdSKQn2.js +0 -1
  383. package/dist/web/assets/index-D5hyHPj7.js +0 -2
  384. package/dist/web/assets/index-bJRG3RXH.css +0 -1
  385. package/dist/web/assets/markdown-BNJfEgCA.js +0 -1
  386. package/dist/web/assets/markdown-BfC0goYb.css +0 -10
  387. package/dist/web/assets/naive-ui-BALVpMgd.js +0 -1
  388. package/dist/web/assets/vendors-DQA4Hw9v.js +0 -7
  389. package/dist/web/assets/vue-vendor-B5RqjEjQ.js +0 -45
  390. package/src/config/model-pricing.js +0 -35
  391. package/src/server/api/channels.js +0 -439
  392. package/src/server/api/claude-hooks.js +0 -56
  393. package/src/server/api/claude-statistics.js +0 -57
  394. package/src/server/api/codex-channels.js +0 -491
  395. package/src/server/api/codex-projects.js +0 -117
  396. package/src/server/api/codex-proxy.js +0 -293
  397. package/src/server/api/codex-sessions.js +0 -652
  398. package/src/server/api/codex-statistics.js +0 -57
  399. package/src/server/api/gemini-channels.js +0 -392
  400. package/src/server/api/gemini-projects.js +0 -103
  401. package/src/server/api/gemini-proxy.js +0 -231
  402. package/src/server/api/gemini-sessions.js +0 -550
  403. package/src/server/api/gemini-statistics.js +0 -57
  404. package/src/server/api/health-check.js +0 -31
  405. package/src/server/api/oauth-credentials.js +0 -198
  406. package/src/server/api/omp-channels.js +0 -575
  407. package/src/server/api/omp-projects.js +0 -88
  408. package/src/server/api/omp-proxy.js +0 -125
  409. package/src/server/api/omp-sessions.js +0 -386
  410. package/src/server/api/omp-statistics.js +0 -40
  411. package/src/server/api/opencode-channels.js +0 -471
  412. package/src/server/api/opencode-projects.js +0 -110
  413. package/src/server/api/opencode-proxy.js +0 -354
  414. package/src/server/api/opencode-sessions.js +0 -466
  415. package/src/server/api/opencode-statistics.js +0 -57
  416. package/src/server/api/projects.js +0 -120
  417. package/src/server/api/proxy.js +0 -330
  418. package/src/server/api/sessions.js +0 -810
  419. package/src/server/services/oauth-credentials-service.js +0 -945
  420. package/src/server/services/omp-session-log-observer.js +0 -138
  421. package/src/server/services/opencode-gateway-adapters.js +0 -43
  422. package/src/server/services/project-snapshots.js +0 -59
  423. package/src/server/services/proxy-log-helper.js +0 -298
  424. package/src/server/services/session-cache.js +0 -127
  425. package/src/server/services/session-converter.js +0 -582
  426. package/src/server/services/session-history-adapters/claude.js +0 -235
  427. /package/src/{server/services/claude-token-recovery.js → platforms/drivers/claude/token-recovery.js} +0 -0
  428. /package/src/{server/services/codex-parser.js → platforms/drivers/codex/parser.js} +0 -0
  429. /package/src/{server/services/codex-speed-test-template.json → platforms/drivers/codex/speed-test-template.json} +0 -0
  430. /package/src/{server/services/codex-wire.js → platforms/drivers/codex/wire.js} +0 -0
  431. /package/src/{server/services/omp-auth-gateway-client.js → platforms/drivers/omp/auth-gateway-client.js} +0 -0
  432. /package/src/{server/services/opencode-normalization.js → platforms/drivers/opencode/normalization.js} +0 -0
  433. /package/src/{server/services → shared}/config-artifact-paths.js +0 -0
  434. /package/src/{server/services/base → shared}/proxy-utils.js +0 -0
@@ -0,0 +1,760 @@
1
+ # CLI 平台正确性边界实施计划
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Remove remaining platform-specific correctness leaks from CLI and HTTP transport while preserving legacy Drivers, public CLI commands, old API URLs, and normal response shapes.
6
+
7
+ **Architecture:** Add one narrow `src/platforms/access.js` seam for Registry-backed platform, capability, and operation resolution. Migrate transport and interactive CLI callers to this seam; keep platform protocol implementations behind existing Runtime/`legacy:*` Drivers. Tighten Manifest route validation and make missing operations explicitly unsupported instead of returning empty success.
8
+
9
+ **Tech Stack:** Node.js 22, CommonJS, Express, Inquirer, Vitest, existing Platform Registry/Runtime, DriverResult conventions.
10
+
11
+ ---
12
+
13
+ ## Scope and invariants
14
+
15
+ The implementation must preserve:
16
+
17
+ - `ctx claude|codex|gemini|opencode|omp start|stop|restart|status`.
18
+ - Existing `/api/<platform>/...` and root alias URLs.
19
+ - Existing successful response fields and response codecs.
20
+ - Existing built-in `legacy:*` Driver IDs and platform implementations.
21
+ - Existing user data, native files, session files, and configuration formats.
22
+ - Default Claude behavior only when the caller supplies no platform at all and the existing public contract defines Claude as the default.
23
+
24
+ The implementation must change:
25
+
26
+ - A non-empty unknown platform must never become Claude.
27
+ - A registered platform without a requested capability must return `unsupported`.
28
+ - A declared capability without the requested operation must return `unsupported`.
29
+ - Interactive CLI session and status paths must use the selected platform, not direct Claude imports.
30
+ - Missing Driver operations must never be represented as a successful empty GET response.
31
+
32
+ Out of scope:
33
+
34
+ - Deleting `legacy.js` or `legacy:*` Drivers.
35
+ - Rewriting the five platform protocols.
36
+ - Extracting shared API route profiles.
37
+ - Changing `enabledOnly` or Manifest `enabled` semantics.
38
+ - Replacing the Commands/Agents resource implementations with new generic Drivers.
39
+ - Changing Web UI information architecture.
40
+
41
+ ---
42
+
43
+ ## File ownership map
44
+
45
+ ### New
46
+
47
+ - `src/platforms/access.js`: Registry/Runtime-backed platform and operation resolution, stable error objects.
48
+ - `tests/unit/platforms/access.test.js`: Access seam behavior.
49
+
50
+ ### Platform routing and Manifest
51
+
52
+ - `src/platforms/manifest-schema.js`: Route operation and codec contract validation.
53
+ - `src/server/api/platform-api-config.js`: Export codec lookup predicates used by schema validation.
54
+ - `src/server/api/platform-route-factory.js`: Return `unsupported` for missing Driver operations.
55
+ - `tests/unit/platforms/manifest-schema.test.js`: Invalid operation/codec tests.
56
+ - `tests/unit/api/platform-route-factory.test.js`: Missing-operation behavior.
57
+ - `tests/unit/api/platform-routes.test.js`: Existing alias regression.
58
+
59
+ ### HTTP transport
60
+
61
+ - `src/server/api/project-config.js`: Registry/capability validation instead of a fixed platform Set.
62
+ - `src/server/api/commands.js`: Preserve no-platform Claude default, reject unknown non-empty platform, report unsupported registered platforms.
63
+ - `src/server/api/agents.js`: Same platform resolution policy; preserve Codex scope behavior through service/manifest metadata where applicable.
64
+ - `src/server/api/mcp.js`: Remove fixed platform/export lists where Registry capability resolution already provides the answer.
65
+ - `src/server/services/platform-resolution.js`: Resolve against Registry or become a compatibility wrapper over `access.js`.
66
+ - `tests/unit/api/project-config-api.test.js`: Unknown, unsupported, and default platform behavior.
67
+ - `tests/unit/api/commands-api.test.js`: Unknown and registered custom platform behavior.
68
+ - `tests/unit/api/agents-api.test.js`: Unknown and registered custom platform behavior.
69
+ - `tests/unit/api/mcp-api.test.js`: Registry-driven platform behavior.
70
+
71
+ ### Interactive CLI
72
+
73
+ - `src/ui/menu.js`: Registry-derived label/color and Runtime-derived channel/proxy state.
74
+ - `src/commands/list.js`: Current platform `projects`/`sessions` Driver.
75
+ - `src/commands/search.js`: Current platform `projects`/`sessions` Driver.
76
+ - `src/commands/workspace.js`: Current platform project Driver.
77
+ - `src/commands/resume.js`: Current platform session launch operation.
78
+ - `src/index.js`: Pass current platform and runtime dependencies into CLI handlers where required; keep command dispatch unchanged.
79
+ - `tests/unit/commands/cli-type.test.js`: Dynamic platform choice behavior.
80
+ - `tests/unit/commands/channels.test.js`: Existing channel contract plus custom platform seam.
81
+ - `tests/unit/commands/runtime-driven-cli.test.js`: New CLI Runtime behavior tests.
82
+ - `tests/unit/commands/list.test.js`: Session Driver use and unsupported behavior.
83
+ - `tests/unit/commands/search.test.js`: Session Driver use and unsupported behavior.
84
+ - `tests/unit/commands/resume.test.js`: Launch Driver use and no Claude fallback.
85
+ - `tests/unit/commands/workspace.test.js`: Project Driver use.
86
+
87
+ ### Verification and documentation
88
+
89
+ - `scripts/test-driver-reachability.js`: Add checks for direct Claude imports in migrated interactive CLI paths.
90
+ - `README.md`: Verify existing configuration-driven boundary wording remains accurate; modify only its platform-boundary paragraph if implementation changes the claim.
91
+
92
+ ---
93
+
94
+ ## Task 1: Establish the platform access seam
95
+
96
+ **Files:**
97
+ - Create: `src/platforms/access.js`
98
+ - Create: `tests/unit/platforms/access.test.js`
99
+ - No other production file is required; `access.js` lazily reads `getPlatformContext()` when dependencies are not injected.
100
+
101
+ - [ ] **Step 1: Write behavior tests for platform resolution.**
102
+
103
+ Test the public behavior with injected fake Registry and Runtime objects:
104
+
105
+ ```js
106
+ const registry = {
107
+ resolve: key => key === 'demo-cli' ? { key, label: 'Demo CLI' } : null,
108
+ getCapability: (_key, capability) => capability === 'sessions' ? 'generic-jsonl' : null
109
+ };
110
+ const runtime = {
111
+ getDriver: (_key, capability) => capability === 'sessions' ? { recent: vi.fn() } : null
112
+ };
113
+ ```
114
+
115
+ Cover these cases:
116
+
117
+ - `resolvePlatform('demo-cli')` returns normalized key and manifest.
118
+ - `resolvePlatform('missing')` throws an error with `code: 'not_found'`.
119
+ - `resolveCapability('demo-cli', 'sessions')` returns the sessions Driver.
120
+ - Missing capability throws `code: 'unsupported'` with platform and capability.
121
+ - `resolveOperation('demo-cli', 'sessions', 'recent')` returns the bound operation.
122
+ - Missing operation throws `code: 'unsupported'` with operation.
123
+ - Empty key uses explicit `fallback` only when configured.
124
+ - A non-empty unknown key never uses fallback.
125
+ - Runtime creation errors are exposed as `code: 'failed'` and preserve the original cause non-enumerably.
126
+
127
+ Run:
128
+
129
+ ```bash
130
+ npx vitest run tests/unit/platforms/access.test.js --no-file-parallelism --maxWorkers=1
131
+ ```
132
+
133
+ Expected: FAIL because `src/platforms/access.js` does not exist.
134
+
135
+ - [ ] **Step 2: Implement the minimal access interface.**
136
+
137
+ Use this stable shape:
138
+
139
+ ```js
140
+ function resolvePlatform(key, options = {}) {}
141
+ function resolveCapability(key, capability, options = {}) {}
142
+ function resolveOperation(key, capability, operation, options = {}) {}
143
+
144
+ module.exports = {
145
+ resolvePlatform,
146
+ resolveCapability,
147
+ resolveOperation,
148
+ createPlatformAccessError
149
+ };
150
+ ```
151
+
152
+ The implementation must:
153
+
154
+ 1. Normalize keys with `normalizePlatformKey`.
155
+ 2. Use injected `registry`/`runtime`, defaulting to `getPlatformContext()` lazily.
156
+ 3. Throw `not_found` for non-empty unknown keys.
157
+ 4. Use a fallback only for an empty key.
158
+ 5. Check `registry.getCapability()` when available; otherwise inspect `manifest.capabilities`.
159
+ 6. Treat `null`, `undefined`, and `'unsupported'` as unsupported.
160
+ 7. Call Runtime only after capability validation.
161
+ 8. Return `{ key, manifest, driver }` for capability resolution.
162
+ 9. Return `{ key, manifest, driver, operation }` for operation resolution, where `operation` is the callable bound to the Driver.
163
+ 10. Attach `cause` as a non-enumerable property for runtime failures.
164
+
165
+ - [ ] **Step 3: Run the seam tests.**
166
+
167
+ Run:
168
+
169
+ ```bash
170
+ npx vitest run tests/unit/platforms/access.test.js --no-file-parallelism --maxWorkers=1
171
+ ```
172
+
173
+ Expected: PASS.
174
+
175
+ - [ ] **Step 4: Commit the seam.**
176
+
177
+ ```bash
178
+ git add src/platforms/access.js tests/unit/platforms/access.test.js
179
+ git commit -m "feat: add registry-backed platform access seam"
180
+ ```
181
+
182
+ ---
183
+
184
+ ## Task 2: Make Manifest route contracts fail early
185
+
186
+ **Files:**
187
+ - Modify: `src/platforms/manifest-schema.js`
188
+ - Modify: `src/server/api/platform-api-config.js`
189
+ - Modify: `tests/unit/platforms/manifest-schema.test.js`
190
+ - Modify: `tests/unit/api/platform-route-factory.test.js`
191
+ - Modify: `tests/unit/api/platform-routes.test.js`
192
+
193
+ - [ ] **Step 1: Add failing Manifest tests.**
194
+
195
+ Add valid and invalid descriptors using the existing Manifest fixture style:
196
+
197
+ ```js
198
+ const base = {
199
+ key: 'demo-cli',
200
+ label: 'Demo CLI',
201
+ command: 'demo',
202
+ capabilities: { sessions: 'generic-jsonl' },
203
+ api: { prefix: 'demo', routes: [] }
204
+ };
205
+ ```
206
+
207
+ Assert that validation rejects:
208
+
209
+ - `operation: 'notAnOperation'` for `sessions`.
210
+ - `request: 'missing-codec'`.
211
+ - `response: 'missing-codec'`.
212
+ - A route whose capability is not declared.
213
+
214
+ Assert that existing custom operation names used by the five built-in manifests remain valid.
215
+
216
+ Add route factory tests with a Driver that has no requested method. Assert both GET and POST return HTTP 404 with `body.error.code === 'unsupported'`; neither may return 200 or an empty payload.
217
+
218
+ Run:
219
+
220
+ ```bash
221
+ npx vitest run tests/unit/platforms/manifest-schema.test.js tests/unit/api/platform-route-factory.test.js --no-file-parallelism --maxWorkers=1
222
+ ```
223
+
224
+ Expected: new tests fail before implementation.
225
+
226
+ - [ ] **Step 2: Export codec existence predicates.**
227
+
228
+ In `src/server/api/platform-api-config.js`, add narrow predicates next to the existing codec maps:
229
+
230
+ ```js
231
+ function hasRequestCodec(codec) {
232
+ return typeof codec === 'function' || typeof requestCodecs[codec] === 'function';
233
+ }
234
+
235
+ function hasResponseCodec(codec) {
236
+ return typeof codec === 'function' || typeof responseCodecs[codec] === 'function';
237
+ }
238
+ ```
239
+
240
+ Export both functions. Do not expose the codec implementation maps to user configuration validation.
241
+
242
+ - [ ] **Step 3: Add operation contract data and validation.**
243
+
244
+ In `manifest-schema.js`, add the exact frozen capability-to-operation map below; it is the union currently declared by the five built-in Manifests:
245
+
246
+ ```js
247
+ const CAPABILITY_OPERATIONS = Object.freeze({
248
+ api: new Set(['getConfig', 'getConfigAuthProviders', 'getConfigCapabilities', 'getConfigResources']),
249
+ channels: new Set(['applyToSettings', 'bestForRestore', 'catalogMetadata', 'create', 'current', 'enabled', 'list', 'models', 'order', 'poolStatus', 'probeModels', 'remove', 'resetHealth', 'speedTest', 'speedTestAll', 'sync', 'update']),
250
+ health: new Set(['healthCheck']),
251
+ hooks: new Set(['getHooks', 'saveHooks', 'testHooks']),
252
+ projects: new Set(['createProject', 'deleteProject', 'listProjects', 'saveProjectOrder']),
253
+ proxy: new Set(['clearLogs', 'start', 'status', 'stop']),
254
+ sessions: new Set(['batchDelete', 'createSession', 'delete', 'fork', 'launch', 'listSessions', 'messages', 'outline', 'recent', 'saveSessionOrder', 'search', 'searchAcrossProjects', 'status']),
255
+ statistics: new Set(['daily', 'summary', 'today'])
256
+ });
257
+ ```
258
+
259
+ Reject operations absent from the matching Set with `/api/routes/<index>/operation`. Validate named request codecs against `default` and named response codecs against `default`, `projects-list`, `projects`, `sessions-list`, and `sessions` through the predicates exported from `platform-api-config.js`. Function-valued codecs remain valid only for in-process built-in definitions; user JSON cannot contain functions.
260
+
261
+ - [ ] **Step 4: Remove missing-operation empty success.**
262
+
263
+ In `platform-route-factory.js`, change the missing Driver/operation branch so it always calls `makeUnsupported(context)` and `sendDriverResult()`. Leave `emptyPayload()` for explicitly successful Driver results only.
264
+
265
+ - [ ] **Step 5: Run focused route tests.**
266
+
267
+ ```bash
268
+ npx vitest run tests/unit/platforms/manifest-schema.test.js tests/unit/api/platform-route-factory.test.js tests/unit/api/platform-routes.test.js --no-file-parallelism --maxWorkers=1
269
+ ```
270
+
271
+ Expected: PASS, including all existing alias and response-shape assertions.
272
+
273
+ - [ ] **Step 6: Commit route contract enforcement.**
274
+
275
+ ```bash
276
+ git add src/platforms/manifest-schema.js src/server/api/platform-api-config.js src/server/api/platform-route-factory.js tests/unit/platforms/manifest-schema.test.js tests/unit/api/platform-route-factory.test.js tests/unit/api/platform-routes.test.js
277
+ git commit -m "fix: reject invalid platform route operations"
278
+ ```
279
+
280
+ ---
281
+
282
+ ## Task 3: Remove HTTP platform allowlists and silent fallbacks
283
+
284
+ **Files:**
285
+ - Modify: `src/server/api/project-config.js`
286
+ - Modify: `src/server/api/commands.js`
287
+ - Modify: `src/server/api/agents.js`
288
+ - Modify: `src/server/api/mcp.js`
289
+ - Modify: `src/server/services/platform-resolution.js`
290
+ - Modify: corresponding API tests
291
+
292
+ - [ ] **Step 1: Add failing HTTP behavior tests.**
293
+
294
+ For each API family, add tests for:
295
+
296
+ 1. No platform supplied: existing Claude default remains.
297
+ 2. `platform=missing`: 404/not-found behavior; no Claude service constructed.
298
+ 3. Registered `demo-cli` without the requested capability: 404/unsupported behavior.
299
+ 4. Registered `demo-cli` with the required capability and injected service/Driver: request reaches that platform.
300
+
301
+ Use fake Registry/Runtime injection or the existing module cache seam already used by the API tests. Do not assert implementation source text.
302
+
303
+ Run:
304
+
305
+ ```bash
306
+ npx vitest run tests/unit/api/project-config-api.test.js tests/unit/api/commands-api.test.js tests/unit/api/agents-api.test.js tests/unit/api/mcp-api.test.js --no-file-parallelism --maxWorkers=1
307
+ ```
308
+
309
+ Expected: new tests fail because the APIs currently use fixed Sets and Claude fallback.
310
+
311
+ - [ ] **Step 2: Migrate Project Config platform validation.**
312
+
313
+ Replace the fixed Set in `project-config.js` with `resolveCapability(platform, 'projectConfig')` or the existing `ProjectConfigService` adapter lookup. Keep request field validation and existing `sendApiError` status mapping. Preserve the default `claude` when `platform` is absent.
314
+
315
+ - [ ] **Step 3: Migrate Commands and Agents platform resolution.**
316
+
317
+ Use the access seam for platform existence. Keep their existing platform-specific format maps and Codex scope restrictions for built-in platforms. Change behavior as follows:
318
+
319
+ ```text
320
+ empty platform → claude
321
+ non-empty unknown platform → not_found
322
+ registered platform without commands/agents implementation → unsupported
323
+ registered built-in platform → existing service behavior
324
+ ```
325
+
326
+ A custom Manifest must not be treated as fully supported merely because it exists or declares an unrelated resource type.
327
+
328
+ - [ ] **Step 4: Migrate MCP platform/export checks.**
329
+
330
+ Resolve import/export platform capability through Registry and Runtime. Keep `json` as the generic export format. A platform name is valid only if Registry resolves it and the platform declares MCP capability; unsupported formats continue to return the existing 404 body.
331
+
332
+ - [ ] **Step 5: Narrow the managed-platform resolver.**
333
+
334
+ If `src/server/services/platform-resolution.js` remains for compatibility, make it delegate to Registry-backed resolution and keep the existing `pi` → `omp` deprecation mapping. It must no longer own a hardcoded supported-platform array.
335
+
336
+ - [ ] **Step 6: Run focused HTTP tests.**
337
+
338
+ ```bash
339
+ npx vitest run tests/unit/api/project-config-api.test.js tests/unit/api/commands-api.test.js tests/unit/api/agents-api.test.js tests/unit/api/mcp-api.test.js tests/unit/services/project-config-service.test.js --no-file-parallelism --maxWorkers=1
340
+ ```
341
+
342
+ Expected: PASS; absent-platform Claude compatibility remains, while non-empty unknown platforms never touch Claude services.
343
+
344
+ - [ ] **Step 7: Commit the HTTP boundary fix.**
345
+
346
+ ```bash
347
+ git add src/server/api/project-config.js src/server/api/commands.js src/server/api/agents.js src/server/api/mcp.js src/server/services/platform-resolution.js tests/unit/api/project-config-api.test.js tests/unit/api/commands-api.test.js tests/unit/api/agents-api.test.js tests/unit/api/mcp-api.test.js
348
+ git commit -m "fix: resolve HTTP platforms through registry"
349
+ ```
350
+
351
+ ---
352
+
353
+ ## Task 4: Migrate the interactive menu to Registry/Runtime
354
+
355
+ **Files:**
356
+ - Modify: `src/ui/menu.js`
357
+ - Modify: `src/index.js` to keep the existing one-argument production menu call while allowing injected test dependencies
358
+ - Modify: `tests/unit/commands/channels.test.js`
359
+ - Create: `tests/unit/commands/runtime-driven-cli.test.js`
360
+
361
+ - [ ] **Step 1: Add failing menu tests.**
362
+
363
+ Inject a fake Registry with `demo-cli` and fake Runtime Drivers:
364
+
365
+ ```js
366
+ const registry = {
367
+ resolve: key => key === 'demo-cli' ? {
368
+ key: 'demo-cli', label: 'Demo CLI', terminalColor: 'blue', cliSelectable: true
369
+ } : null,
370
+ getCapability: (_key, capability) => ['channels', 'proxy'].includes(capability) ? 'fake' : null
371
+ };
372
+ const runtime = {
373
+ getDriver: (_key, capability) => capability === 'channels'
374
+ ? { current: () => ({ name: 'Demo Channel' }) }
375
+ : { status: () => ({ running: false }) }
376
+ };
377
+ ```
378
+
379
+ Assert that `showMainMenu({ currentCliType: 'demo-cli' })` calls only demo Drivers. Assert that `omp` is not normalized to Claude. Assert that missing channel/proxy capabilities produce a visible unsupported state or omitted optional status, not a Claude lookup.
380
+
381
+ - [ ] **Step 2: Replace platform enum and direct imports.**
382
+
383
+ Remove `normalizeCliType()` comparisons and the four-way `getChannelAndProxyStatus()` branch. Resolve the current platform through `access.js`; call the declared `channels.current` operation when available, otherwise `channels.list`; call `proxy.status` when available.
384
+
385
+ Derive display name and color from Manifest fields with safe terminal-color fallback. Preserve menu choices and user-facing menu action values.
386
+
387
+ - [ ] **Step 3: Pass explicit dependencies where tests need isolation.**
388
+
389
+ Keep production defaults lazy. Allow `showMainMenu(config, { registry, runtime })` or an equivalent dependency object without changing the existing one-argument call contract.
390
+
391
+ - [ ] **Step 4: Run menu and channel tests.**
392
+
393
+ ```bash
394
+ npx vitest run tests/unit/commands/channels.test.js tests/unit/commands/cli-type.test.js tests/unit/commands/runtime-driven-cli.test.js --no-file-parallelism --maxWorkers=1
395
+ ```
396
+
397
+ Expected: PASS, including dynamic `demo-cli` and `omp` cases.
398
+
399
+ - [ ] **Step 5: Commit menu migration.**
400
+
401
+ ```bash
402
+ git add src/ui/menu.js src/index.js tests/unit/commands/channels.test.js tests/unit/commands/cli-type.test.js tests/unit/commands/runtime-driven-cli.test.js
403
+ git commit -m "refactor: drive interactive menu from platform runtime"
404
+ ```
405
+
406
+ ---
407
+
408
+ ## Task 5: Migrate session list and search commands
409
+
410
+ **Files:**
411
+ - Modify: `src/commands/list.js`
412
+ - Modify: `src/commands/search.js`
413
+ - Modify: `src/index.js` call sites for `handleList` and `handleSearch`
414
+ - Create: `tests/unit/commands/list.test.js`
415
+ - Create: `tests/unit/commands/search.test.js`
416
+
417
+ - [ ] **Step 1: Add failing Driver seam tests.**
418
+
419
+ Test `listRecentSessionsAcrossProjects`, `searchSessionsAcrossProjects`, and the handler path using a fake `demo-cli` Runtime:
420
+
421
+ ```js
422
+ const sessions = {
423
+ recent: vi.fn().mockResolvedValue([{ sessionId: 's1', projectName: 'demo', firstMessage: 'hello' }]),
424
+ searchAcrossProjects: vi.fn().mockResolvedValue([{ sessionId: 's1', projectName: 'demo', matches: [], matchCount: 1 }])
425
+ };
426
+ const projects = { listProjects: vi.fn().mockResolvedValue([{ name: 'demo' }]) };
427
+ ```
428
+
429
+ Assert the fake Driver is called and the Claude module is not imported. Add a missing-operation test that returns `unsupported` without scanning Claude sessions.
430
+
431
+ - [ ] **Step 2: Add platform parameters without breaking existing calls.**
432
+
433
+ Use an options object after existing arguments, for example:
434
+
435
+ ```js
436
+ listRecentSessionsAcrossProjects(config, limit, {
437
+ platform: config.currentCliType,
438
+ runtime,
439
+ registry
440
+ });
441
+ ```
442
+
443
+ Existing callers that omit the options object continue to use `config.currentCliType || 'claude'` through the access seam.
444
+
445
+ - [ ] **Step 3: Replace direct Claude session imports.**
446
+
447
+ For listing:
448
+
449
+ - Resolve `projects`/`sessions` Drivers from the selected platform.
450
+ - Use `sessions.recent(limit, { config })` for cross-project recent sessions.
451
+ - Use `sessions.listSessions(projectName, { config })` for a project list.
452
+
453
+ For search:
454
+
455
+ - Use `sessions.searchAcrossProjects(keyword, limit, { config })` when available.
456
+ - Use the platform session Driver’s `parse`/normalization result for project and message display fields.
457
+ - Do not call Claude helpers for path parsing or aliases.
458
+
459
+ Preserve prompt text, choice values, sorting, alias presentation, and fork confirmation.
460
+
461
+ - [ ] **Step 4: Route resume through the platform-aware handler.**
462
+
463
+ Pass the selected platform through `resumeSession(config, sessionId, fork, { platform, runtime, registry })`. Do not rely on a global mutable platform.
464
+
465
+ - [ ] **Step 5: Run focused CLI tests.**
466
+
467
+ ```bash
468
+ npx vitest run tests/unit/commands/list.test.js tests/unit/commands/search.test.js tests/unit/commands/channels.test.js --no-file-parallelism --maxWorkers=1
469
+ ```
470
+
471
+ Expected: PASS with fake platform Driver calls and no Claude fallback.
472
+
473
+ - [ ] **Step 6: Commit session list/search migration.**
474
+
475
+ ```bash
476
+ git add src/commands/list.js src/commands/search.js src/index.js tests/unit/commands/list.test.js tests/unit/commands/search.test.js
477
+ git commit -m "refactor: route CLI session reads through platform drivers"
478
+ ```
479
+
480
+ ---
481
+
482
+ ## Task 6: Migrate workspace project discovery
483
+
484
+ **Files:**
485
+ - Modify: `src/commands/workspace.js`
486
+ - Modify: `src/index.js` to pass the selected platform into workspace handling
487
+ - Create: `tests/unit/commands/workspace.test.js`
488
+
489
+ - [ ] **Step 1: Add a failing project Driver test.**
490
+
491
+ Inject a `demo-cli` `projects` Driver exposing `listProjects` and assert workspace project choices use its result. Include a test where the project Driver is unsupported and workspace creation stops with an explicit message rather than reading Claude sessions.
492
+
493
+ - [ ] **Step 2: Replace `getProjectsWithStats` import.**
494
+
495
+ Resolve the selected platform’s `projects` Driver. Normalize its result into the existing workspace choice fields (`displayName`, `fullPath`, `sessionCount`) using generic fields first. Preserve the existing worktree creation and workspace persistence logic.
496
+
497
+ - [ ] **Step 3: Remove the Claude-specific user-facing instruction.**
498
+
499
+ Build the final message from the selected platform Manifest label/command. Use the Manifest command alias only for display; do not execute it in workspace code.
500
+
501
+ - [ ] **Step 4: Run workspace tests.**
502
+
503
+ ```bash
504
+ npx vitest run tests/unit/commands/workspace.test.js tests/unit/services/workspace-service.test.js --no-file-parallelism --maxWorkers=1
505
+ ```
506
+
507
+ Expected: PASS, with workspace creation behavior unchanged for Claude and Runtime-based discovery for other platforms.
508
+
509
+ - [ ] **Step 5: Commit workspace migration.**
510
+
511
+ ```bash
512
+ git add src/commands/workspace.js src/index.js tests/unit/commands/workspace.test.js
513
+ git commit -m "refactor: use platform project drivers in workspace CLI"
514
+ ```
515
+
516
+ ---
517
+
518
+ ## Task 7: Route Claude session launch through the Driver seam
519
+
520
+ **Files:**
521
+ - Modify: `src/commands/resume.js`
522
+ - Modify: `src/platforms/drivers/claude/sessions.js`
523
+ - Modify: `src/platforms/drivers/claude/sessions-implementation.js`
524
+ - Create: `tests/unit/commands/resume.test.js`
525
+ - Modify: `tests/unit/platforms/builtin-driver-contract.test.js`
526
+
527
+ - [ ] **Step 1: Characterize current Claude resume behavior.**
528
+
529
+ Add a test around injected process execution and filesystem/session metadata that verifies Claude still receives:
530
+
531
+ ```text
532
+ executable: claude
533
+ arguments: -r <sessionId>
534
+ arguments: --fork-session only when fork=true
535
+ stdio: inherit
536
+ cwd: session cwd when readable, otherwise current cwd
537
+ ```
538
+
539
+ Do not run a real Claude executable.
540
+
541
+ - [ ] **Step 2: Add the `sessions.launch` Driver operation.**
542
+
543
+ Expose this method only from the Claude session Driver in this repair:
544
+
545
+ ```js
546
+ launch(sessionId, {
547
+ fork: false,
548
+ config,
549
+ cwd,
550
+ processRunner
551
+ })
552
+ ```
553
+
554
+ Move existing Claude session-file cwd discovery and executable argument construction into `claude/sessions-implementation.js`. Use an argument-vector runner such as `spawnSync('claude', args, { cwd, stdio: 'inherit', windowsHide: true })`; never construct a shell command string. Codex, Gemini, OpenCode, OMP, and generic user platforms do not gain launch behavior in this scope and therefore resolve as `unsupported`.
555
+
556
+ - [ ] **Step 3: Migrate `resume.js`.**
557
+
558
+ Remove `execSync`, direct Claude session-file parsing, and the hardcoded `claude` command. Resolve the selected platform `sessions.launch` operation. Keep terminal cleanup, spinner, display, and process exit handling in the CLI facade. Pass structured arguments to the Driver and preserve the child exit status/SIGINT behavior.
559
+
560
+ - [ ] **Step 4: Test no-fallback behavior.**
561
+
562
+ Assert:
563
+
564
+ - `demo-cli` without launch returns `unsupported`.
565
+ - Codex, Gemini, OpenCode, and OMP return `unsupported` until they own verified launch semantics.
566
+ - An unknown platform does not invoke Claude.
567
+ - Claude preserves existing arguments, cwd selection, inherited stdio, and exit behavior.
568
+
569
+ Run:
570
+
571
+ ```bash
572
+ npx vitest run tests/unit/commands/resume.test.js tests/unit/platforms/builtin-driver-contract.test.js --no-file-parallelism --maxWorkers=1
573
+ ```
574
+
575
+ Expected: PASS.
576
+
577
+ - [ ] **Step 5: Commit launch migration.**
578
+
579
+ ```bash
580
+ git add src/commands/resume.js src/platforms/drivers/claude/sessions.js src/platforms/drivers/claude/sessions-implementation.js tests/unit/commands/resume.test.js tests/unit/platforms/builtin-driver-contract.test.js
581
+ git commit -m "refactor: launch Claude sessions through platform driver"
582
+ ```
583
+
584
+ ---
585
+
586
+ ## Task 8: Remove direct-import regressions and update compatibility tests
587
+
588
+ **Files:**
589
+ - Modify: `scripts/test-driver-reachability.js`
590
+ - Modify: `tests/unit/platforms/demo-cli-contract.test.js`
591
+ - Modify: tests that currently mock the five migrated concrete Claude seams, limited to the test files named in Tasks 4–7.
592
+
593
+ - [ ] **Step 1: Add reachability assertions.**
594
+
595
+ The reachability script must fail if these migrated files directly reference a concrete Claude implementation:
596
+
597
+ ```text
598
+ src/ui/menu.js
599
+ src/commands/list.js
600
+ src/commands/search.js
601
+ src/commands/workspace.js
602
+ src/commands/resume.js
603
+ ```
604
+
605
+ The assertion may allow `src/platforms/drivers/legacy.js`, because it remains the intentional compatibility adapter. Do not ban platform-specific code inside platform Driver directories.
606
+
607
+ - [ ] **Step 2: Expand `demo-cli` contract coverage.**
608
+
609
+ Register a Manifest with generic sessions/projects/resource capability and assert:
610
+
611
+ - Registry resolves it.
612
+ - CLI-facing access resolves its Drivers.
613
+ - Missing proxy or launch reports `unsupported`.
614
+ - No built-in platform branch is required.
615
+
616
+ - [ ] **Step 3: Run reachability and platform contracts.**
617
+
618
+ ```bash
619
+ node scripts/test-driver-reachability.js
620
+ npx vitest run tests/unit/platforms/demo-cli-contract.test.js tests/unit/commands/platform-command-registry.test.js tests/unit/platforms/access.test.js --no-file-parallelism --maxWorkers=1
621
+ ```
622
+
623
+ Expected: PASS with no migrated interactive CLI direct Claude imports.
624
+
625
+ - [ ] **Step 4: Commit regression guards.**
626
+
627
+ ```bash
628
+ git add scripts/test-driver-reachability.js tests/unit/platforms/demo-cli-contract.test.js tests/unit/commands/platform-command-registry.test.js
629
+ git commit -m "test: guard runtime-driven CLI platform boundaries"
630
+ ```
631
+
632
+ ---
633
+
634
+ ## Task 9: Verify documentation boundary
635
+
636
+ **Files:**
637
+ - Read: `README.md`
638
+ - Modify: `README.md` when its platform-boundary paragraph is inaccurate after implementation.
639
+
640
+ - [ ] **Step 1: Compare documentation with the implemented boundary.**
641
+
642
+ Keep the existing statements that generic platforms use allowlisted Drivers and special protocols require code. The final documented claim must state that Registry/Runtime resolves transport platforms while platform-specific protocols remain in Capability Drivers. Do not claim that a Manifest alone provides full feature parity.
643
+
644
+ - [ ] **Step 2: Run Markdown diff validation.**
645
+
646
+ ```bash
647
+ git diff --check
648
+ ```
649
+
650
+ Expected: no whitespace errors.
651
+
652
+ - [ ] **Step 3: Commit documentation when the comparison identifies an inaccurate claim.**
653
+
654
+ ```bash
655
+ git add README.md
656
+ git commit -m "docs: clarify runtime-driven platform boundary"
657
+ ```
658
+
659
+ ---
660
+
661
+ ## Task 10: Full verification and smoke checks
662
+
663
+ **Files:**
664
+ - No source changes expected unless a verification failure identifies a specific regression.
665
+
666
+ - [ ] **Step 1: Run all focused platform and CLI tests.**
667
+
668
+ ```bash
669
+ npx vitest run \
670
+ tests/unit/platforms/access.test.js \
671
+ tests/unit/platforms/manifest-schema.test.js \
672
+ tests/unit/platforms/runtime.test.js \
673
+ tests/unit/platforms/registry.test.js \
674
+ tests/unit/platforms/demo-cli-contract.test.js \
675
+ tests/unit/platforms/builtin-driver-contract.test.js \
676
+ tests/unit/api/platform-route-factory.test.js \
677
+ tests/unit/api/platform-routes.test.js \
678
+ tests/unit/api/project-config-api.test.js \
679
+ tests/unit/api/commands-api.test.js \
680
+ tests/unit/api/agents-api.test.js \
681
+ tests/unit/api/mcp-api.test.js \
682
+ tests/unit/commands/cli-type.test.js \
683
+ tests/unit/commands/channels.test.js \
684
+ tests/unit/commands/list.test.js \
685
+ tests/unit/commands/search.test.js \
686
+ tests/unit/commands/workspace.test.js \
687
+ tests/unit/commands/resume.test.js \
688
+ --no-file-parallelism --maxWorkers=1 --testTimeout=30000
689
+ ```
690
+
691
+ Expected: PASS.
692
+
693
+ - [ ] **Step 2: Run the repository reachability and API checks.**
694
+
695
+ ```bash
696
+ node scripts/test-driver-reachability.js
697
+ node scripts/test-api-consistency.js
698
+ node scripts/test-basic.js
699
+ ```
700
+
701
+ Expected: each command exits 0.
702
+
703
+ - [ ] **Step 3: Run the complete unit suite.**
704
+
705
+ ```bash
706
+ npx vitest run tests/unit --no-file-parallelism --maxWorkers=1 --testTimeout=30000
707
+ ```
708
+
709
+ Expected: all unit tests pass. Any environment-only failure must be recorded with the exact command output and must not be hidden.
710
+
711
+ - [ ] **Step 4: Exercise CLI help and platform dispatch.**
712
+
713
+ Run:
714
+
715
+ ```bash
716
+ node bin/ctx.js --help
717
+ node -e "const cli=require('./src/index.js'); console.log(typeof cli._test.dispatchPlatformCommand)"
718
+ ```
719
+
720
+ Expected:
721
+
722
+ - Help lists Registry-derived proxy commands.
723
+ - The exported dispatch helper remains callable.
724
+ - No command starts a real proxy during this smoke check.
725
+
726
+ - [ ] **Step 5: Check the final diff and working tree.**
727
+
728
+ ```bash
729
+ git diff --check
730
+ git status --short
731
+ ```
732
+
733
+ Expected: no whitespace errors and only intentional source/test/documentation changes.
734
+
735
+ - [ ] **Step 6: Commit a final test-only correction when verification required one, then stop.**
736
+
737
+ Stage exactly the test files changed to repair the failing observable contract and commit them with:
738
+
739
+ ```bash
740
+ git commit -m "test: preserve platform compatibility contract"
741
+ ```
742
+
743
+ Do not introduce unrelated cleanup, new platform features, route profile extraction, or legacy Driver removal during final verification.
744
+
745
+ ---
746
+
747
+ ## Acceptance criteria
748
+
749
+ The refactor is complete only when all of the following are observable:
750
+
751
+ 1. A non-empty unknown platform never reaches Claude code through CLI or HTTP.
752
+ 2. `omp` remains `omp` in the interactive menu and status paths.
753
+ 3. `demo-cli` generic Drivers can be resolved without adding platform branches to CLI/HTTP callers.
754
+ 4. Interactive list/search/workspace paths use the selected platform Driver.
755
+ 5. Session resume does not construct a hardcoded Claude shell command.
756
+ 6. Missing route operations return structured `unsupported`, not 200 empty success.
757
+ 7. Manifest invalid operation and codec names fail validation.
758
+ 8. Project Config, Commands, Agents, and MCP no longer maintain authoritative fixed platform lists.
759
+ 9. Existing built-in CLI commands, old API aliases, and normal response shapes remain compatible.
760
+ 10. Focused tests, reachability checks, API consistency checks, and the complete unit suite pass.