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.
- package/CHANGELOG.md +18 -0
- package/README.md +86 -15
- package/dist/web/assets/AgentsDrawer-BG6P3DX-.js +1 -0
- package/dist/web/assets/AgentsDrawer-Pw2k-ZAa.css +1 -0
- package/dist/web/assets/Analytics--z_FmL5P.js +1 -0
- package/dist/web/assets/Analytics-CyHhR126.css +1 -0
- package/dist/web/assets/AssetPathField-CrJtRKHy.js +1 -0
- package/dist/web/assets/ChatHistoryDrawer-B2qBQs9L.css +1 -0
- package/dist/web/assets/ChatHistoryDrawer-BiuEryJj.js +1 -0
- package/dist/web/assets/CollapseItem-BAYEsL_Q.js +1 -0
- package/dist/web/assets/CommandsDrawer-BZJxlPvV.css +1 -0
- package/dist/web/assets/CommandsDrawer-YJ-U7BXN.js +1 -0
- package/dist/web/assets/ConfigExportDrawer-Ce_hAknW.js +1 -0
- package/dist/web/assets/ConfigExportDrawer-dwruRKWr.css +1 -0
- package/dist/web/assets/ConfigTemplates-Bvr1NN6K.js +1 -0
- package/dist/web/assets/ConfigTemplatesDrawer-BfDi8yO3.css +1 -0
- package/dist/web/assets/ConfigTemplatesDrawer-BjIeHfF-.js +1 -0
- package/dist/web/assets/ConfigTemplatesPanel-AV00tm_D.js +1 -0
- package/dist/web/assets/ConfigTemplatesPanel-CWyPtk67.css +1 -0
- package/dist/web/assets/Divider-D28g1gwj.js +1 -0
- package/dist/web/assets/DrawerContent-ChXgZ1Xm.js +1 -0
- package/dist/web/assets/FavoritesDrawer-CG9eI9Ay.css +1 -0
- package/dist/web/assets/FavoritesDrawer-Cz95o4CD.js +1 -0
- package/dist/web/assets/GatewayConvertDrawer-CuNlf7AC.css +1 -0
- package/dist/web/assets/GatewayConvertDrawer-DLlbMz27.js +1 -0
- package/dist/web/assets/Home-CSuFuJ9Y.css +1 -0
- package/dist/web/assets/Home-D7CCOFQC.js +1 -0
- package/dist/web/assets/MarkdownEditor-qfVgSre_.css +1 -0
- package/dist/web/assets/MarkdownEditor-rEZ-c72L.js +1 -0
- package/dist/web/assets/McpDrawer-C0dnsZhQ.css +1 -0
- package/dist/web/assets/McpDrawer-DfoCyxU2.js +1 -0
- package/dist/web/assets/McpFormDrawer-BRbDcawn.css +1 -0
- package/dist/web/assets/McpFormDrawer-SKu8HNUR.js +1 -0
- package/dist/web/assets/PluginManager-BbeK-3rV.js +1 -0
- package/dist/web/assets/PluginsDrawer-CWVJ7yjS.js +1 -0
- package/dist/web/assets/PluginsDrawer-DM3QjprE.css +1 -0
- package/dist/web/assets/PluginsPanel-Cm2N3StG.js +1 -0
- package/dist/web/assets/PluginsPanel-D6ZqITcR.css +1 -0
- package/dist/web/assets/ProjectList-677RLZ8O.css +1 -0
- package/dist/web/assets/ProjectList-CsjnsNPv.js +1 -0
- package/dist/web/assets/PromptsDrawer-BIgiYCEQ.css +1 -0
- package/dist/web/assets/PromptsDrawer-EGd3djFa.js +1 -0
- package/dist/web/assets/RecentSessionsDrawer-CKFsOYDM.css +1 -0
- package/dist/web/assets/RecentSessionsDrawer-D1vtoLAs.js +1 -0
- package/dist/web/assets/SessionCard-BgLg49U3.js +1 -0
- package/dist/web/assets/SessionCard-aM2NHu6i.css +1 -0
- package/dist/web/assets/SessionList-BpYRz1cX.css +1 -0
- package/dist/web/assets/SessionList-TRiTklWk.js +1 -0
- package/dist/web/assets/SettingsDrawer-d5liXjHq.css +1 -0
- package/dist/web/assets/SettingsDrawer-rz2WejGY.js +1 -0
- package/dist/web/assets/SkillManager-BTjTUbHq.js +1 -0
- package/dist/web/assets/SkillManager-C0GCT2Kb.css +1 -0
- package/dist/web/assets/SkillsDrawer-BCNme-aJ.css +1 -0
- package/dist/web/assets/SkillsDrawer-pN0hbkK3.js +1 -0
- package/dist/web/assets/SkillsPanel-B3Nm5j32.css +1 -0
- package/dist/web/assets/SkillsPanel-gmBWEoiF.js +1 -0
- package/dist/web/assets/SpeedTestDrawer-Dc0WToJ_.css +1 -0
- package/dist/web/assets/SpeedTestDrawer-DcNzuVJk.js +1 -0
- package/dist/web/assets/Upload-v5rV0qTT.js +1 -0
- package/dist/web/assets/WorkspaceDrawer-CGnMu9p1.css +1 -0
- package/dist/web/assets/WorkspaceDrawer-DxmicM4U.js +1 -0
- package/dist/web/assets/WorkspaceManager-CJHCjARN.js +1 -0
- package/dist/web/assets/WorkspacePanel-D0-zHTHP.css +1 -0
- package/dist/web/assets/WorkspacePanel-D8_Zq-du.js +1 -0
- package/dist/web/assets/_plugin-vue_export-helper-BeLZJZij.js +1 -0
- package/dist/web/assets/client-UDwXBP9i.js +1 -0
- package/dist/web/assets/clipboard-B46yyoz_.js +1 -0
- package/dist/web/assets/headers-cf-QapUq.js +1 -0
- package/dist/web/assets/icons-B2Vg-IOC.js +1 -0
- package/dist/web/assets/index-C0EHRym0.css +1 -0
- package/dist/web/assets/index-DnEocV0M.js +2 -0
- package/dist/web/assets/light-Cp0t7v32.js +1 -0
- package/dist/web/assets/markdown-u082bbtj.js +1 -0
- package/dist/web/assets/platforms-CBkB45JP.js +1 -0
- package/dist/web/assets/platforms-FTpjxAT6.js +1 -0
- package/dist/web/assets/project-config-B2baPzYL.js +1 -0
- package/dist/web/assets/sessions-Cmy31slD.js +1 -0
- package/dist/web/assets/sessions-yC_oVVh8.js +1 -0
- package/dist/web/assets/skill-repo-input-B_fkGlUK.js +1 -0
- package/dist/web/assets/use-lock-html-scroll-DXIqmUW4.js +1 -0
- package/dist/web/assets/use-message-DoLM8C1C.js +1 -0
- package/dist/web/assets/useResponsiveDrawer-B3uojyvV.js +1 -0
- package/dist/web/assets/vendors-D0c_0KLP.js +1 -0
- package/dist/web/assets/vue-vendor-BqZbbXHA.js +1 -0
- package/dist/web/assets/workspaces-mjyPVGS8.js +1 -0
- package/dist/web/assets/xml-CgY3RMlX.js +1 -0
- package/dist/web/index.html +12 -8
- package/docs/native-log-memory-2026-09-16.md +43 -0
- package/docs/superpowers/plans/2026-08-26-configuration-driven-cli-platform.md +1578 -0
- package/docs/superpowers/plans/2026-08-30-project-scoped-config-control.md +1260 -0
- package/docs/superpowers/plans/2026-09-01-omp-skill-refresh-boundary.md +213 -0
- package/docs/superpowers/plans/2026-09-01-realtime-logs-panel.md +125 -0
- package/docs/superpowers/plans/2026-09-02-config-driven-platform-boundary.md +86 -0
- package/docs/superpowers/plans/2026-09-02-platform-implementation-drivers.md +508 -0
- package/docs/superpowers/plans/2026-09-03-cli-platform-correctness-boundary.md +760 -0
- package/docs/superpowers/plans/2026-09-03-dependency-security-remediation.md +133 -0
- package/docs/superpowers/plans/2026-09-04-model-catalog-pricing-sync.md +1078 -0
- package/docs/superpowers/plans/2026-09-05-codex-project-scan-500.md +128 -0
- package/docs/superpowers/plans/2026-09-06-project-skill-path-fix.md +97 -0
- package/docs/superpowers/specs/2026-08-26-configuration-driven-cli-platform-design.md +408 -0
- package/docs/superpowers/specs/2026-08-30-project-scoped-config-control-design.md +467 -0
- package/docs/superpowers/specs/2026-09-01-claude-session-content-repair-design.md +111 -0
- package/docs/superpowers/specs/2026-09-01-omp-skill-refresh-boundary-design.md +83 -0
- package/docs/superpowers/specs/2026-09-01-realtime-logs-panel-design.md +27 -0
- package/docs/superpowers/specs/2026-09-02-config-driven-platform-boundary-design.md +64 -0
- package/docs/superpowers/specs/2026-09-02-platform-implementation-driver-boundary-design.md +123 -0
- package/docs/superpowers/specs/2026-09-03-cli-platform-correctness-boundary-design.md +249 -0
- package/docs/superpowers/specs/2026-09-03-dependency-security-remediation-design.md +87 -0
- package/docs/superpowers/specs/2026-09-04-model-catalog-pricing-sync-design.md +301 -0
- package/docs/superpowers/specs/2026-09-05-codex-project-scan-500-design.md +24 -0
- package/package.json +13 -8
- package/src/commands/channels.js +88 -191
- package/src/commands/cli-type.js +19 -11
- package/src/commands/daemon.js +94 -32
- package/src/commands/doctor.js +16 -9
- package/src/commands/export-config.js +23 -5
- package/src/commands/list.js +130 -52
- package/src/commands/logs.js +44 -27
- package/src/commands/platform-command-registry.js +78 -0
- package/src/commands/plugin.js +11 -5
- package/src/commands/port-config.js +34 -52
- package/src/commands/proxy-control.js +207 -145
- package/src/commands/proxy.js +2 -2
- package/src/commands/resume.js +87 -91
- package/src/commands/search.js +137 -67
- package/src/commands/stats.js +30 -22
- package/src/commands/switch.js +1 -1
- package/src/commands/toggle-proxy.js +94 -111
- package/src/commands/ui.js +67 -6
- package/src/commands/workspace.js +90 -8
- package/src/config/default.js +6 -53
- package/src/config/loader.js +61 -24
- package/src/config/model-metadata.js +49 -59
- package/src/config/model-metadata.json +4095 -99
- package/src/config/paths.js +181 -8
- package/src/index.js +134 -71
- package/src/platforms/access.js +196 -0
- package/src/{server/services → platforms}/agents-service.js +354 -197
- package/src/platforms/channel-auth-registry.js +162 -0
- package/src/platforms/channel-auth-service.js +82 -0
- package/src/{server/services → platforms}/commands-service.js +195 -115
- package/src/platforms/driver-registry.js +59 -0
- package/src/platforms/drivers/claude/api-operations.js +62 -0
- package/src/{server/services/channels.js → platforms/drivers/claude/channels-implementation.js} +131 -33
- package/src/platforms/drivers/claude/channels.js +39 -0
- package/src/{server/services/config-sync-service.js → platforms/drivers/claude/config-sync.js} +29 -5
- package/src/{server/services → platforms/drivers/claude}/health-check.js +4 -4
- package/src/platforms/drivers/claude/health.js +22 -0
- package/src/platforms/drivers/claude/mcp.js +9 -0
- package/src/{server/services/settings-manager.js → platforms/drivers/claude/native-config-implementation.js} +13 -4
- package/src/platforms/drivers/claude/native-config.js +46 -0
- package/src/platforms/drivers/claude/native-logs.js +72 -0
- package/src/{server/services/claude-openai-gateway.js → platforms/drivers/claude/openai-gateway.js} +8 -65
- package/src/platforms/drivers/claude/project-config.js +21 -0
- package/src/platforms/drivers/claude/projects.js +62 -0
- package/src/platforms/drivers/claude/prompts.js +9 -0
- package/src/{server/proxy-server.js → platforms/drivers/claude/proxy-implementation.js} +41 -278
- package/src/platforms/drivers/claude/proxy.js +16 -0
- package/src/platforms/drivers/claude/resource-sync.js +9 -0
- package/src/platforms/drivers/claude/session-history-adapter.js +313 -0
- package/src/{server/services/sessions.js → platforms/drivers/claude/sessions-implementation.js} +145 -35
- package/src/platforms/drivers/claude/sessions.js +76 -0
- package/src/{server/services/claude-statistics-service.js → platforms/drivers/claude/statistics-implementation.js} +2 -2
- package/src/platforms/drivers/claude/statistics.js +16 -0
- package/src/{server/services/claude-wire.js → platforms/drivers/claude/wire.js} +1 -1
- package/src/platforms/drivers/codex/api-operations.js +9 -0
- package/src/{server/services/codex-channels.js → platforms/drivers/codex/channels-implementation.js} +149 -14
- package/src/platforms/drivers/codex/channels.js +45 -0
- package/src/{server/services/codex-config.js → platforms/drivers/codex/config.js} +12 -2
- package/src/{server/services/codex-env-manager.js → platforms/drivers/codex/env-manager.js} +1 -1
- package/src/platforms/drivers/codex/mcp.js +9 -0
- package/src/{server/services/codex-settings-manager.js → platforms/drivers/codex/native-config-implementation.js} +15 -6
- package/src/platforms/drivers/codex/native-config.js +47 -0
- package/src/platforms/drivers/codex/native-logs.js +166 -0
- package/src/platforms/drivers/codex/project-config.js +21 -0
- package/src/platforms/drivers/codex/projects.js +26 -0
- package/src/platforms/drivers/codex/prompts.js +9 -0
- package/src/{server/codex-proxy-server.js → platforms/drivers/codex/proxy-implementation.js} +30 -233
- package/src/platforms/drivers/codex/proxy.js +16 -0
- package/src/platforms/drivers/codex/resource-sync.js +9 -0
- package/src/{server/services/session-history-adapters/codex.js → platforms/drivers/codex/session-history-adapter.js} +37 -23
- package/src/{server/services/codex-sessions.js → platforms/drivers/codex/sessions-implementation.js} +81 -75
- package/src/platforms/drivers/codex/sessions.js +36 -0
- package/src/{server/services/codex-statistics-service.js → platforms/drivers/codex/statistics-implementation.js} +2 -2
- package/src/platforms/drivers/codex/statistics.js +16 -0
- package/src/platforms/drivers/gemini/api-operations.js +9 -0
- package/src/{server/services/gemini-channels.js → platforms/drivers/gemini/channels-implementation.js} +202 -37
- package/src/platforms/drivers/gemini/channels.js +39 -0
- package/src/{server/services/gemini-config.js → platforms/drivers/gemini/config.js} +12 -2
- package/src/platforms/drivers/gemini/mcp.js +9 -0
- package/src/{server/services/gemini-settings-manager.js → platforms/drivers/gemini/native-config-implementation.js} +14 -5
- package/src/platforms/drivers/gemini/native-config.js +39 -0
- package/src/platforms/drivers/gemini/native-logs.js +180 -0
- package/src/platforms/drivers/gemini/project-config.js +21 -0
- package/src/platforms/drivers/gemini/projects.js +26 -0
- package/src/platforms/drivers/gemini/prompts.js +9 -0
- package/src/{server/gemini-proxy-server.js → platforms/drivers/gemini/proxy-implementation.js} +36 -267
- package/src/platforms/drivers/gemini/proxy.js +16 -0
- package/src/platforms/drivers/gemini/resource-sync.js +9 -0
- package/src/{server/services/session-history-adapters/gemini.js → platforms/drivers/gemini/session-history-adapter.js} +70 -18
- package/src/{server/services/gemini-sessions.js → platforms/drivers/gemini/sessions-implementation.js} +53 -37
- package/src/platforms/drivers/gemini/sessions.js +47 -0
- package/src/{server/services/gemini-statistics-service.js → platforms/drivers/gemini/statistics-implementation.js} +2 -2
- package/src/platforms/drivers/gemini/statistics.js +16 -0
- package/src/{server/services/gemini-wire.js → platforms/drivers/gemini/wire.js} +1 -1
- package/src/platforms/drivers/generic-filesystem.js +166 -0
- package/src/platforms/drivers/generic-jsonl.js +141 -0
- package/src/platforms/drivers/generic-mcp.js +44 -0
- package/src/platforms/drivers/generic-openai-compatible.js +45 -0
- package/src/platforms/drivers/generic-prompt.js +41 -0
- package/src/platforms/drivers/legacy.js +677 -0
- package/src/platforms/drivers/native-config-snapshot.js +125 -0
- package/src/platforms/drivers/native-log-utils.js +1292 -0
- package/src/platforms/drivers/notification-hooks.js +578 -0
- package/src/{server/api/omp-config.js → platforms/drivers/omp/api-operations.js} +52 -64
- package/src/{server/services/omp-auth-provider-worker.js → platforms/drivers/omp/auth-provider-worker.js} +1 -1
- package/src/{server/services/omp-auth-providers.js → platforms/drivers/omp/auth-providers.js} +1 -1
- package/src/{server/services/omp-channels.js → platforms/drivers/omp/channels-implementation.js} +166 -39
- package/src/platforms/drivers/omp/channels.js +58 -0
- package/src/{server/services/omp-config.js → platforms/drivers/omp/config.js} +53 -13
- package/src/{server/services/omp-gateway-routing.js → platforms/drivers/omp/gateway-routing.js} +14 -7
- package/src/{server/services/omp-gateway.js → platforms/drivers/omp/gateway.js} +4 -262
- package/src/platforms/drivers/omp/mcp.js +9 -0
- package/src/{server/services/omp-settings-manager.js → platforms/drivers/omp/native-config-implementation.js} +75 -10
- package/src/platforms/drivers/omp/native-config.js +46 -0
- package/src/platforms/drivers/omp/native-logs.js +52 -0
- package/src/{server/services/omp-native-plugin-adapter.js → platforms/drivers/omp/native-plugin-adapter.js} +91 -4
- package/src/platforms/drivers/omp/project-config.js +29 -0
- package/src/platforms/drivers/omp/projects.js +20 -0
- package/src/platforms/drivers/omp/prompts.js +9 -0
- package/src/{server/omp-proxy-server.js → platforms/drivers/omp/proxy-implementation.js} +6 -15
- package/src/platforms/drivers/omp/proxy.js +16 -0
- package/src/platforms/drivers/omp/resource-sync.js +9 -0
- package/src/{server/services/session-history-adapters/omp.js → platforms/drivers/omp/session-history-adapter.js} +42 -18
- package/src/{server/services/omp-sessions.js → platforms/drivers/omp/sessions-implementation.js} +130 -94
- package/src/platforms/drivers/omp/sessions.js +36 -0
- package/src/{server/services/omp-skill-discovery.js → platforms/drivers/omp/skill-discovery.js} +159 -32
- package/src/{server/services/omp-skill-settings-service.js → platforms/drivers/omp/skill-settings.js} +1 -1
- package/src/{server/services/omp-statistics-service.js → platforms/drivers/omp/statistics-implementation.js} +3 -3
- package/src/platforms/drivers/omp/statistics.js +16 -0
- package/src/platforms/drivers/opencode/api-operations.js +9 -0
- package/src/{server/services/opencode-channels.js → platforms/drivers/opencode/channels-implementation.js} +28 -9
- package/src/platforms/drivers/opencode/channels.js +40 -0
- package/src/platforms/drivers/opencode/conversion.js +41 -0
- package/src/{server/services/opencode-gateway-converter.js → platforms/drivers/opencode/gateway-converter.js} +1 -1
- package/src/platforms/drivers/opencode/mcp.js +9 -0
- package/src/{server/services/opencode-settings-manager.js → platforms/drivers/opencode/native-config-implementation.js} +17 -6
- package/src/platforms/drivers/opencode/native-config.js +26 -0
- package/src/platforms/drivers/opencode/native-logs.js +133 -0
- package/src/platforms/drivers/opencode/project-config.js +98 -0
- package/src/platforms/drivers/opencode/projects.js +20 -0
- package/src/platforms/drivers/opencode/prompts.js +9 -0
- package/src/{server/opencode-proxy-server.js → platforms/drivers/opencode/proxy-implementation.js} +27 -362
- package/src/platforms/drivers/opencode/proxy.js +16 -0
- package/src/platforms/drivers/opencode/resource-sync.js +9 -0
- package/src/{server/services/opencode-sessions.js → platforms/drivers/opencode/sessions-implementation.js} +211 -64
- package/src/platforms/drivers/opencode/sessions.js +48 -0
- package/src/{server/services/opencode-statistics-service.js → platforms/drivers/opencode/statistics-implementation.js} +2 -2
- package/src/platforms/drivers/opencode/statistics.js +16 -0
- package/src/platforms/drivers/secure-file-driver.js +272 -0
- package/src/platforms/drivers/unsupported.js +7 -0
- package/src/platforms/manifest-schema.js +398 -0
- package/src/platforms/manifests/claude.json +489 -0
- package/src/platforms/manifests/codex.json +448 -0
- package/src/platforms/manifests/gemini.json +447 -0
- package/src/platforms/manifests/omp.json +496 -0
- package/src/platforms/manifests/opencode.json +422 -0
- package/src/{server/services → platforms}/native-oauth-adapters.js +87 -417
- package/src/{server/services → platforms}/notification-hooks.js +140 -1023
- package/src/platforms/oauth-credentials-service.js +506 -0
- package/src/platforms/path-resolver.js +179 -0
- package/src/platforms/platform-path-context.js +305 -0
- package/src/platforms/registry.js +248 -0
- package/src/platforms/remote-notification-providers.js +678 -0
- package/src/platforms/runtime.js +259 -0
- package/src/{server/services/session-history-adapters/index.js → platforms/session-history-adapters.js} +8 -1
- package/src/plugins/plugin-loader.js +2 -2
- package/src/plugins/plugin-manager.js +2 -2
- package/src/plugins/registry.js +27 -10
- package/src/reset-config.js +21 -5
- package/src/server/api/agents.js +46 -72
- package/src/server/api/commands.js +16 -6
- package/src/server/api/config-registry.js +206 -59
- package/src/server/api/config-sync.js +3 -2
- package/src/server/api/config-templates.js +20 -4
- package/src/server/api/config.js +111 -102
- package/src/server/api/convert.js +54 -178
- package/src/server/api/dashboard.js +168 -102
- package/src/server/api/hooks.js +1 -1
- package/src/server/api/mcp.js +224 -84
- package/src/server/api/platform-api-config.js +102 -0
- package/src/server/api/platform-route-factory.js +215 -0
- package/src/server/api/platform-routes.js +26 -0
- package/src/server/api/platforms.js +110 -0
- package/src/server/api/plugins.js +57 -57
- package/src/server/api/project-config.js +168 -0
- package/src/server/api/prompts.js +58 -45
- package/src/server/api/settings.js +55 -8
- package/src/server/api/skills.js +262 -133
- package/src/server/api/ui-config.js +2 -2
- package/src/server/api/validation-errors.js +18 -4
- package/src/server/api/workspaces.js +47 -12
- package/src/server/index.js +164 -213
- package/src/server/platform-context.js +81 -0
- package/src/server/services/channel-balance.js +11 -20
- package/src/server/services/channel-health.js +21 -6
- package/src/server/services/channel-scheduler.js +29 -39
- package/src/server/services/channel-sync-utils.js +23 -13
- package/src/server/services/config-export-service.js +350 -319
- package/src/server/services/config-registry-service.js +280 -54
- package/src/server/services/config-sync-manager.js +172 -944
- package/src/server/services/config-templates-service.js +419 -353
- package/src/server/services/control-manifest-store.js +206 -0
- package/src/server/services/dashboard-snapshot-worker.js +656 -100
- package/src/server/services/effective-control-service.js +557 -0
- package/src/server/services/local-resource-index.js +314 -0
- package/src/server/services/mcp-service.js +607 -977
- package/src/server/services/model-detector.js +15 -10
- package/src/server/services/native-log-channel-resolver.js +214 -0
- package/src/server/services/native-log-observer.js +291 -0
- package/src/server/services/network-access.js +1 -1
- package/src/server/services/platform-catalog.js +82 -0
- package/src/server/services/platform-resolution.js +32 -29
- package/src/server/services/plugins-service.js +376 -122
- package/src/server/services/project-config-service.js +550 -0
- package/src/server/services/project-path-validation.js +31 -0
- package/src/server/services/prompts-service.js +267 -233
- package/src/server/services/proxy-runtime.js +7 -4
- package/src/server/services/remote-credential-cache.js +43 -0
- package/src/server/services/repo-scanner-base.js +182 -75
- package/src/server/services/request-logger.js +7 -4
- package/src/server/services/session-history-index.js +780 -213
- package/src/server/services/session-history-worker.js +228 -33
- package/src/server/services/session-snapshot-worker.js +124 -34
- package/src/server/services/session-snapshots.js +4 -2
- package/src/server/services/skill-artifact-store.js +355 -0
- package/src/server/services/skill-format-adapters.js +65 -0
- package/src/server/services/skill-projection-service.js +323 -0
- package/src/server/services/skill-refresh-task-service.js +275 -0
- package/src/server/services/skill-service.js +2020 -677
- package/src/server/services/snapshot-cache.js +30 -8
- package/src/server/services/speed-test.js +8 -8
- package/src/server/services/sqlite-connection.js +19 -3
- package/src/server/services/statistics-service.js +240 -57
- package/src/server/services/ui-config.js +107 -76
- package/src/server/services/usage-log-utils.js +98 -0
- package/src/server/services/web-build.js +1 -1
- package/src/server/services/workspace-service.js +59 -29
- package/src/server/utils/pricing.js +10 -19
- package/src/server/websocket-server.js +153 -28
- package/src/{server/services/base → shared}/base-channel-service.js +156 -28
- package/src/shared/capability-driver.js +104 -0
- package/src/shared/channel-auth-policy.js +27 -0
- package/src/shared/channel-driver.js +161 -0
- package/src/shared/driver-factories/api.js +180 -0
- package/src/shared/driver-factories/mcp.js +244 -0
- package/src/shared/driver-factories/projects.js +121 -0
- package/src/shared/driver-factories/prompts.js +58 -0
- package/src/shared/driver-factories/resource-sync.js +375 -0
- package/src/shared/driver-result.js +78 -0
- package/src/shared/mcp-format.js +189 -0
- package/src/shared/platforms.js +104 -167
- package/src/shared/project-config.js +512 -0
- package/src/shared/proxy-driver.js +57 -0
- package/src/{server/services/base → shared}/response-usage-parser.js +8 -4
- package/src/ui/menu.js +91 -67
- package/src/utils/port-helper.js +35 -19
- package/src/utils/session.js +1 -1
- package/dist/web/assets/Analytics-COEUXmd4.js +0 -25
- package/dist/web/assets/Analytics-RNn1BUbG.css +0 -1
- package/dist/web/assets/ConfigTemplates-DLLkS53H.js +0 -1
- package/dist/web/assets/Home-DCEyLzwX.js +0 -1
- package/dist/web/assets/Home-DYVy4cGZ.css +0 -1
- package/dist/web/assets/PluginManager-Oe1ZHoMO.js +0 -1
- package/dist/web/assets/ProjectList-CWjuAFof.js +0 -1
- package/dist/web/assets/ProjectList-VeMNXfgO.css +0 -1
- package/dist/web/assets/SessionList-C4chCPxK.css +0 -1
- package/dist/web/assets/SessionList-v3ehGg9U.js +0 -1
- package/dist/web/assets/SkillManager-BsX8Qpj0.css +0 -1
- package/dist/web/assets/SkillManager-DUF_qP5S.js +0 -1
- package/dist/web/assets/WorkspaceManager-CjAWBosO.js +0 -1
- package/dist/web/assets/icons-nGdSKQn2.js +0 -1
- package/dist/web/assets/index-D5hyHPj7.js +0 -2
- package/dist/web/assets/index-bJRG3RXH.css +0 -1
- package/dist/web/assets/markdown-BNJfEgCA.js +0 -1
- package/dist/web/assets/markdown-BfC0goYb.css +0 -10
- package/dist/web/assets/naive-ui-BALVpMgd.js +0 -1
- package/dist/web/assets/vendors-DQA4Hw9v.js +0 -7
- package/dist/web/assets/vue-vendor-B5RqjEjQ.js +0 -45
- package/src/config/model-pricing.js +0 -35
- package/src/server/api/channels.js +0 -439
- package/src/server/api/claude-hooks.js +0 -56
- package/src/server/api/claude-statistics.js +0 -57
- package/src/server/api/codex-channels.js +0 -491
- package/src/server/api/codex-projects.js +0 -117
- package/src/server/api/codex-proxy.js +0 -293
- package/src/server/api/codex-sessions.js +0 -652
- package/src/server/api/codex-statistics.js +0 -57
- package/src/server/api/gemini-channels.js +0 -392
- package/src/server/api/gemini-projects.js +0 -103
- package/src/server/api/gemini-proxy.js +0 -231
- package/src/server/api/gemini-sessions.js +0 -550
- package/src/server/api/gemini-statistics.js +0 -57
- package/src/server/api/health-check.js +0 -31
- package/src/server/api/oauth-credentials.js +0 -198
- package/src/server/api/omp-channels.js +0 -575
- package/src/server/api/omp-projects.js +0 -88
- package/src/server/api/omp-proxy.js +0 -125
- package/src/server/api/omp-sessions.js +0 -386
- package/src/server/api/omp-statistics.js +0 -40
- package/src/server/api/opencode-channels.js +0 -471
- package/src/server/api/opencode-projects.js +0 -110
- package/src/server/api/opencode-proxy.js +0 -354
- package/src/server/api/opencode-sessions.js +0 -466
- package/src/server/api/opencode-statistics.js +0 -57
- package/src/server/api/projects.js +0 -120
- package/src/server/api/proxy.js +0 -330
- package/src/server/api/sessions.js +0 -810
- package/src/server/services/oauth-credentials-service.js +0 -945
- package/src/server/services/omp-session-log-observer.js +0 -138
- package/src/server/services/opencode-gateway-adapters.js +0 -43
- package/src/server/services/project-snapshots.js +0 -59
- package/src/server/services/proxy-log-helper.js +0 -298
- package/src/server/services/session-cache.js +0 -127
- package/src/server/services/session-converter.js +0 -582
- package/src/server/services/session-history-adapters/claude.js +0 -235
- /package/src/{server/services/claude-token-recovery.js → platforms/drivers/claude/token-recovery.js} +0 -0
- /package/src/{server/services/codex-parser.js → platforms/drivers/codex/parser.js} +0 -0
- /package/src/{server/services/codex-speed-test-template.json → platforms/drivers/codex/speed-test-template.json} +0 -0
- /package/src/{server/services/codex-wire.js → platforms/drivers/codex/wire.js} +0 -0
- /package/src/{server/services/omp-auth-gateway-client.js → platforms/drivers/omp/auth-gateway-client.js} +0 -0
- /package/src/{server/services/opencode-normalization.js → platforms/drivers/opencode/normalization.js} +0 -0
- /package/src/{server/services → shared}/config-artifact-paths.js +0 -0
- /package/src/{server/services/base → shared}/proxy-utils.js +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Codex Project Scan 500 Implementation Plan
|
|
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:** 修复 Codex 项目扫描因 Worker 循环加载导致的 500,并锁定回归行为。
|
|
6
|
+
|
|
7
|
+
**Architecture:** 保持 `session-history-index` 的生产 Worker 隔离。让 `runInventoryWorker()` 为 fork 子进程显式设置 `CC_TOOL_SESSION_HISTORY_CHILD=1`,使 Worker 子进程直接执行本地索引而不再递归启动 Worker。使用现有 Vitest 单元测试和真实 Codex 项目扫描命令验证。
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Node.js 22、CommonJS、Vitest、better-sqlite3。
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
### Task 1: Add regression test for Worker recursion
|
|
14
|
+
|
|
15
|
+
**Files:**
|
|
16
|
+
- Create: `tests/unit/services/session-history-worker.test.js`
|
|
17
|
+
- Reference: `src/server/services/session-history-worker.js`
|
|
18
|
+
|
|
19
|
+
- [ ] **Step 1: Write the failing test**
|
|
20
|
+
|
|
21
|
+
Create a Vitest test that starts a production-mode Node subprocess, requires `runInventoryWorker`, and invokes it with a temporary SQLite path and empty Codex projects directory. The test must assert the subprocess exits successfully. Before the fix, the forked Worker inherits production mode without a child marker, recursively enters the Worker path, and exits with `runInventoryWorker is not a function`.
|
|
22
|
+
|
|
23
|
+
- [ ] **Step 2: Run the test to verify it fails for the regression**
|
|
24
|
+
|
|
25
|
+
Run:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx vitest run tests/unit/services/session-history-worker.test.js
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Expected before the fix: FAIL with a non-zero child-process status. The failure is at the real process boundary, not a source-text assertion.
|
|
32
|
+
|
|
33
|
+
- [ ] **Step 3: Keep the test isolated**
|
|
34
|
+
|
|
35
|
+
The subprocess must set `NODE_ENV=production`, use a temporary database, and use an empty temporary projects directory. It must not depend on the user's Codex files.
|
|
36
|
+
|
|
37
|
+
- [ ] **Step 4: Commit the regression test**
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
git add tests/unit/services/session-history-worker.test.js
|
|
41
|
+
git commit -m "test: reproduce codex session worker recursion"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Task 2: Mark forked Worker children
|
|
45
|
+
|
|
46
|
+
**Files:**
|
|
47
|
+
- Modify: `src/server/services/session-history-worker.js:152-160`
|
|
48
|
+
|
|
49
|
+
- [ ] **Step 1: Add the child-process marker**
|
|
50
|
+
|
|
51
|
+
Add `CC_TOOL_SESSION_HISTORY_CHILD: '1'` to the environment passed to `childProcess.fork`:
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
env: {
|
|
55
|
+
...process.env,
|
|
56
|
+
CC_TOOL_SESSION_HISTORY_WORKER: '1',
|
|
57
|
+
CC_TOOL_SESSION_HISTORY_CHILD: '1',
|
|
58
|
+
CC_TOOL_SESSION_HISTORY_SOURCE: source,
|
|
59
|
+
CC_TOOL_SESSION_HISTORY_DB: indexDbPath,
|
|
60
|
+
CC_TOOL_SESSION_HISTORY_FORCE: options.force === true ? '1' : '0',
|
|
61
|
+
CC_TOOL_SESSION_HISTORY_PROJECTS_DIR: options.projectsDir || ''
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
This makes the forked Worker run the index locally instead of starting another Worker. Do not change IPC, timeout behavior, or error serialization.
|
|
66
|
+
|
|
67
|
+
- [ ] **Step 2: Run the focused regression test**
|
|
68
|
+
|
|
69
|
+
Run:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx vitest run tests/unit/services/session-history-worker.test.js
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Expected: PASS, with no `runInventoryWorker is not a function` error.
|
|
76
|
+
|
|
77
|
+
- [ ] **Step 3: Run the real Codex scan feedback loop**
|
|
78
|
+
|
|
79
|
+
Run:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
node -e "require('./src/platforms/drivers/codex/sessions-implementation').getProjects().then(v=>{if(!Array.isArray(v)) throw new Error('projects is not an array'); console.log(JSON.stringify({count:v.length,projects:v.slice(0,3)},null,2)}).catch(e=>{console.error(e.stack);process.exit(1)})"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Expected: exit code 0 and JSON containing a numeric `count`; no 500-equivalent Worker error.
|
|
86
|
+
|
|
87
|
+
- [ ] **Step 4: Run related existing tests**
|
|
88
|
+
|
|
89
|
+
Run:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx vitest run tests/unit/services/codex-sessions.test.js tests/unit/services/session-history-index.test.js tests/unit/api/platform-route-factory.test.js
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Expected: all selected tests pass.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
### Task 3: Final verification and review
|
|
99
|
+
|
|
100
|
+
**Files:**
|
|
101
|
+
- Review: `src/server/services/session-history-worker.js`
|
|
102
|
+
- Review: `tests/unit/services/session-history-worker.test.js`
|
|
103
|
+
- Review: `docs/superpowers/specs/2026-09-05-codex-project-scan-500-design.md`
|
|
104
|
+
|
|
105
|
+
- [ ] **Step 1: Run the project API consistency check**
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npm run test:api
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Expected: PASS.
|
|
112
|
+
|
|
113
|
+
- [ ] **Step 2: Run the full unit suite**
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npm run test:unit
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Expected: PASS with no new Worker or Codex failures.
|
|
120
|
+
|
|
121
|
+
- [ ] **Step 3: Inspect the final diff**
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
git diff --check HEAD~2..HEAD
|
|
125
|
+
git diff --stat HEAD~2..HEAD
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Expected: no whitespace errors; only the child-environment marker, regression test, and design/plan documents are included in this fix (unrelated existing workspace changes remain untouched).
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Project Skill Path Fix Implementation Plan
|
|
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:** Prevent project configuration Skills from triggering the generic project-path scan error, especially for OMP projects, while preserving project-scoped refresh and toggle behavior across all CLI platforms.
|
|
6
|
+
|
|
7
|
+
**Architecture:** The project configuration drawer already fetches a canonical project snapshot through `/project-config`. The Skills panel will use `/project-config/skills` for its initial project-scope load instead of issuing a second generic `/skills` request. The returned `{ project, inherited }` collections will be flattened for the existing card model; user-scope panels continue using `/skills` unchanged. Project refresh, approval, and toggles retain their existing APIs.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Vue 3 `<script setup>`, Vitest, Express API client.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
### Task 1: Add failing project-scope API regression coverage
|
|
14
|
+
|
|
15
|
+
**Files:**
|
|
16
|
+
- Modify: `src/web/src/components/__tests__/SkillsPanelProjectScope.test.js`
|
|
17
|
+
|
|
18
|
+
- [ ] **Step 1: Extend the API mocks with `getProjectSkills`**
|
|
19
|
+
|
|
20
|
+
Add a hoisted mock for `getProjectSkills`, mock `../../api/project-config` with both `getProjectSkills` and `setProjectSkillEnabled`, and reset/configure it in `beforeEach` to return:
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
{
|
|
24
|
+
supported: true,
|
|
25
|
+
project: [{ name: 'project-skill', sourceScope: 'project', scope: 'project' }],
|
|
26
|
+
inherited: [{ name: 'user-skill', sourceScope: 'user', scope: 'user' }],
|
|
27
|
+
path: '.omp/skills'
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- [ ] **Step 2: Change the project-scope expectation to the project config endpoint**
|
|
32
|
+
|
|
33
|
+
Keep the existing project props (`platform: 'codex'`, `scope: 'project'`, `projectPath: '/tmp/project'`) and assert that `getProjectSkills` is called with `'/tmp/project'` and `'codex'`, while `getSkills` is not called during the initial scan.
|
|
34
|
+
|
|
35
|
+
- [ ] **Step 3: Run the focused test and verify it fails**
|
|
36
|
+
|
|
37
|
+
Run:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm exec vitest run src/web/src/components/__tests__/SkillsPanelProjectScope.test.js
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Expected: FAIL because `SkillsPanel` currently calls `getSkills` for project scope.
|
|
44
|
+
|
|
45
|
+
### Task 2: Route project initial scans through project configuration
|
|
46
|
+
|
|
47
|
+
**Files:**
|
|
48
|
+
- Modify: `src/web/src/components/SkillsPanel.vue:153-155,260-285`
|
|
49
|
+
|
|
50
|
+
- [ ] **Step 1: Import the project Skills API**
|
|
51
|
+
|
|
52
|
+
Change the project-config import to include `getProjectSkills` alongside `setProjectSkillEnabled`.
|
|
53
|
+
|
|
54
|
+
- [ ] **Step 2: Add a project response normalizer at the scan seam**
|
|
55
|
+
|
|
56
|
+
In `scanLocalSkills`, use `getProjectSkills(props.projectPath, platform)` when `props.scope === 'project'`; otherwise retain `getSkills(platform, scopeOptions.value)`. For the project response, concatenate `response.project` and `response.inherited`, defaulting non-arrays to empty arrays. For user scope, continue validating the generic response through `validateOmpSkillListResponse`.
|
|
57
|
+
|
|
58
|
+
The resulting behavior must preserve the existing request-id/platform race guards, refresh state handling, loading cleanup, and error message.
|
|
59
|
+
|
|
60
|
+
- [ ] **Step 3: Run the focused test and verify it passes**
|
|
61
|
+
|
|
62
|
+
Run:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm exec vitest run src/web/src/components/__tests__/SkillsPanelProjectScope.test.js
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Expected: PASS, including the assertion that the generic `/skills` API is not used for the initial project scan.
|
|
69
|
+
|
|
70
|
+
### Task 3: Verify all affected behavior
|
|
71
|
+
|
|
72
|
+
**Files:**
|
|
73
|
+
- No additional files unless the focused regression test exposes an existing contract mismatch.
|
|
74
|
+
|
|
75
|
+
- [ ] **Step 1: Run project configuration and Skills component tests**
|
|
76
|
+
|
|
77
|
+
Run:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm exec vitest run tests/unit/services/project-config-service.test.js tests/unit/api/project-config-api.test.js src/web/src/components/__tests__/SkillsPanelProjectScope.test.js src/web/src/components/__tests__/ProjectConfigDrawer.test.js
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Expected: all tests pass.
|
|
84
|
+
|
|
85
|
+
- [ ] **Step 2: Run the broader unit suite**
|
|
86
|
+
|
|
87
|
+
Run:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npm run test:unit
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Expected: Vitest exits successfully with no regressions in user-scope Skills or other project configuration panels.
|
|
94
|
+
|
|
95
|
+
- [ ] **Step 3: Smoke-test the running API/UI path**
|
|
96
|
+
|
|
97
|
+
With the development server running, request the OMP project snapshot and confirm it returns `skills.project`, `skills.inherited`, and `path: '.omp/skills'`. Then open the OMP project configuration Skills tab and verify the browser network log contains the project-config Skills request rather than a duplicate generic project `/skills` scan, with no path error.
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
# Configuration-Driven CLI Platform Design
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
将平台扩展重构为“Manifest + Capability Driver”架构:通用 CLI 能力由声明式配置和共享用例层提供;会话格式、原生配置、认证和代理协议等差异由能力 driver 隔离。
|
|
6
|
+
|
|
7
|
+
目标不是让任意 CLI 无条件获得全部功能,而是让符合已有通用协议的 CLI 只新增 Manifest;特殊 CLI 只新增对应 driver,不再复制一整套 API、服务、Dashboard 和前端代码。
|
|
8
|
+
|
|
9
|
+
现有五个平台 Claude、Codex、Gemini、OpenCode、OMP 的行为、CLI 命令、API 路径和原生文件保护规则保持不变。
|
|
10
|
+
|
|
11
|
+
## Current Problems
|
|
12
|
+
|
|
13
|
+
当前平台扩展的主要重复来自:
|
|
14
|
+
|
|
15
|
+
- `src/index.js` 在一个入口中集中处理服务、代理、日志、统计、插件和交互菜单。
|
|
16
|
+
- `src/server/index.js` 手动注册每个平台路由,并在 `autoRestoreProxies()` 中重复启动逻辑。
|
|
17
|
+
- `src/server/services/dashboard-snapshot-worker.js` 对项目、统计、渠道使用平台 `switch`。
|
|
18
|
+
- `src/shared/platforms.js` 与 `src/web/src/config/platforms.js` 各自维护平台定义。
|
|
19
|
+
- `src/web/src/components/channel/channelPanelFactories.js` 同时承载通用表单逻辑和各平台差异。
|
|
20
|
+
- `config-sync-manager.js` 已有配置类型定义,但同步、移除和批量处理仍按平台重复分支。
|
|
21
|
+
- `config-templates-service.js`、配置导出和统计聚合继续维护多份平台映射。
|
|
22
|
+
|
|
23
|
+
可复用的现有边界是 `src/server/services/session-history-adapters/`:索引层已经通过 `inventory()` 和 `parse()` 接收平台适配器。
|
|
24
|
+
|
|
25
|
+
## Scope
|
|
26
|
+
|
|
27
|
+
### Included
|
|
28
|
+
|
|
29
|
+
- 统一平台 Manifest 与 Registry。
|
|
30
|
+
- 将平台能力拆为独立 driver:项目、会话、渠道、代理、统计、资源同步、原生配置。
|
|
31
|
+
- 用 Registry 驱动 CLI、Dashboard、daemon 恢复、配置同步和服务端路由工厂。
|
|
32
|
+
- 后端作为平台目录的权威来源,前端消费安全的只读平台元数据。
|
|
33
|
+
- 保留现有模块路径、导出契约和测试 mock path。
|
|
34
|
+
- 以渐进迁移替代一次性重写。
|
|
35
|
+
|
|
36
|
+
### Excluded
|
|
37
|
+
|
|
38
|
+
- 不重写五个平台的协议实现。
|
|
39
|
+
- 不把所有平台强行统一成同一个代理或会话协议。
|
|
40
|
+
- 不允许用户配置动态加载任意 Node.js 模块。
|
|
41
|
+
- 不在本次设计中增加新的业务能力,例如新的 OAuth provider、统计维度或代理协议。
|
|
42
|
+
- 不改变现有公开 CLI 命令和现有 API 响应格式。
|
|
43
|
+
|
|
44
|
+
## Architecture
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
CLI / HTTP API / Web UI
|
|
48
|
+
|
|
|
49
|
+
v
|
|
50
|
+
Transport adapters
|
|
51
|
+
|
|
|
52
|
+
v
|
|
53
|
+
Application use cases
|
|
54
|
+
(projects, sessions, channels, proxy, stats, sync)
|
|
55
|
+
|
|
|
56
|
+
v
|
|
57
|
+
Platform Registry
|
|
58
|
+
(manifest, capability check, path resolution, driver lookup)
|
|
59
|
+
|
|
|
60
|
+
+-------------------+
|
|
61
|
+
v v
|
|
62
|
+
Capability drivers Shared infrastructure
|
|
63
|
+
(session, channel, storage, cache, logging,
|
|
64
|
+
proxy, resources...) snapshot, filesystem, network
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Platform Manifest
|
|
68
|
+
|
|
69
|
+
平台定义统一放在以下目录:
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
src/platforms/
|
|
73
|
+
manifests/
|
|
74
|
+
claude.json
|
|
75
|
+
codex.json
|
|
76
|
+
gemini.json
|
|
77
|
+
opencode.json
|
|
78
|
+
omp.json
|
|
79
|
+
registry.js
|
|
80
|
+
path-resolver.js
|
|
81
|
+
driver-registry.js
|
|
82
|
+
drivers/
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
内置 Manifest 和用户扩展平台都使用同一份 schema。用户扩展配置放在 `~/.cc-tool/config/platforms.json`,内置定义仍随包发布。
|
|
86
|
+
|
|
87
|
+
Manifest 包含:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"key": "codex",
|
|
92
|
+
"label": "Codex",
|
|
93
|
+
"title": "Codex-CLI",
|
|
94
|
+
"command": "codex",
|
|
95
|
+
"iconToken": "code",
|
|
96
|
+
"color": "#3b82f6",
|
|
97
|
+
"defaultVisible": true,
|
|
98
|
+
"paths": {
|
|
99
|
+
"home": "$CODEX_HOME",
|
|
100
|
+
"config": "{home}/config.toml",
|
|
101
|
+
"sessions": "{home}/sessions"
|
|
102
|
+
},
|
|
103
|
+
"capabilities": {
|
|
104
|
+
"projects": "codex",
|
|
105
|
+
"sessions": "codex",
|
|
106
|
+
"channels": "codex",
|
|
107
|
+
"proxy": "codex",
|
|
108
|
+
"statistics": "codex",
|
|
109
|
+
"resourceSync": "standard"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
约束:
|
|
115
|
+
|
|
116
|
+
- `key` 全局唯一,只允许小写字母、数字、下划线和中划线。
|
|
117
|
+
- `paths` 只允许受控变量、用户目录和 Manifest 声明的相对路径。
|
|
118
|
+
- `capabilities` 的值必须指向已注册的 driver ID,不能任意填写模块路径。
|
|
119
|
+
- `iconToken` 是前端安全字符串,不在共享配置中存放 Vue 组件或函数。
|
|
120
|
+
- 用户平台不能覆盖内置平台 key。
|
|
121
|
+
- 用户平台可以使用内置 generic driver,但不能声明新的可执行代码。
|
|
122
|
+
|
|
123
|
+
### Platform Registry
|
|
124
|
+
|
|
125
|
+
Registry 提供以下职责:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
resolve(key)
|
|
129
|
+
list({ enabledOnly })
|
|
130
|
+
getCapability(key, capability)
|
|
131
|
+
resolvePaths(key)
|
|
132
|
+
getPublicDefinition(key)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`getPublicDefinition()` 只返回 UI 所需的 key、label、iconToken、color、defaultVisible 和能力状态;绝对路径、driver ID 和内部配置不返回浏览器。
|
|
136
|
+
|
|
137
|
+
Registry 初始化时完成 Manifest 校验。内置 Manifest 无效时启动失败;用户 Manifest 无效时只拒绝该条目并记录明确诊断,不影响其他平台。
|
|
138
|
+
|
|
139
|
+
### Capability Drivers
|
|
140
|
+
|
|
141
|
+
每种能力拥有独立契约,避免出现包含所有平台方法的巨型 `Platform` 基类。
|
|
142
|
+
|
|
143
|
+
核心契约:
|
|
144
|
+
|
|
145
|
+
```text
|
|
146
|
+
ProjectDriver
|
|
147
|
+
listProjects(options)
|
|
148
|
+
getProjectAndSessionCounts(options)
|
|
149
|
+
deleteProject(projectId)
|
|
150
|
+
|
|
151
|
+
SessionDriver
|
|
152
|
+
inventory()
|
|
153
|
+
parse(descriptor)
|
|
154
|
+
getMessages(sessionId, options)
|
|
155
|
+
delete(sessionId)
|
|
156
|
+
fork(sessionId, options)
|
|
157
|
+
|
|
158
|
+
ChannelDriver
|
|
159
|
+
list()
|
|
160
|
+
create(input)
|
|
161
|
+
update(id, input)
|
|
162
|
+
remove(id)
|
|
163
|
+
syncCurrent()
|
|
164
|
+
resetHealth(id)
|
|
165
|
+
|
|
166
|
+
ProxyDriver
|
|
167
|
+
status()
|
|
168
|
+
start(options)
|
|
169
|
+
stop(options)
|
|
170
|
+
|
|
171
|
+
StatisticsDriver
|
|
172
|
+
getTodayStatistics()
|
|
173
|
+
getStatistics(range)
|
|
174
|
+
|
|
175
|
+
ResourceSyncDriver
|
|
176
|
+
sync(type, name)
|
|
177
|
+
remove(type, name)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
driver 返回统一结果或规范化 DTO。平台特有字段通过 `extra` 或平台专用 DTO 扩展,不污染通用必需字段。
|
|
181
|
+
|
|
182
|
+
`session-history-adapters` 迁移为 `SessionDriver` 的兼容实现。已有 `inventory()` / `parse()` 适配器先保持不变,再逐步补齐读取和变更能力。
|
|
183
|
+
|
|
184
|
+
### Generic Drivers
|
|
185
|
+
|
|
186
|
+
提供少量受控的通用 driver:
|
|
187
|
+
|
|
188
|
+
- `generic-jsonl`:声明 glob、session ID、project 字段和消息字段映射。
|
|
189
|
+
- `generic-filesystem`:声明资源目录、文件扩展名、目录/文件语义。
|
|
190
|
+
- `generic-openai-compatible`:声明标准 OpenAI-compatible endpoint 和认证字段。
|
|
191
|
+
- `unsupported`:明确返回不支持,不伪造成功。
|
|
192
|
+
|
|
193
|
+
通用 driver 只能覆盖可声明的稳定协议。遇到特殊 SQLite schema、OAuth/keychain、非标准配置或特殊 fork 语义时,必须增加能力 driver。
|
|
194
|
+
|
|
195
|
+
## Application and Transport Changes
|
|
196
|
+
|
|
197
|
+
### CLI
|
|
198
|
+
|
|
199
|
+
CLI 入口只负责:
|
|
200
|
+
|
|
201
|
+
1. 解析命令和平台 key。
|
|
202
|
+
2. 从 Registry 取得平台和能力。
|
|
203
|
+
3. 调用 application use case。
|
|
204
|
+
4. 将统一结果格式化为终端输出。
|
|
205
|
+
|
|
206
|
+
平台列表、服务标签、端口标签和可用操作从 Registry 派生。现有 `ctx claude ...`、`ctx codex ...` 等命令保持不变。
|
|
207
|
+
|
|
208
|
+
### HTTP API
|
|
209
|
+
|
|
210
|
+
第一阶段不改变现有 API 路径。现有平台 API 模块改为稳定 facade,并由 route factory 复用通用 handler。
|
|
211
|
+
|
|
212
|
+
可新增只读目录接口:
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
GET /api/platforms
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
现有 `/api/codex/...`、`/api/gemini/...` 等路径继续返回当前格式;新通用 handler 只复用内部 application 层,不要求前端立即迁移 URL。
|
|
219
|
+
|
|
220
|
+
### Dashboard and Daemon
|
|
221
|
+
|
|
222
|
+
Dashboard snapshot、统计聚合和 daemon proxy recovery 通过 Registry 遍历启用平台,再按 capability 选择 driver。不存在针对五个平台的重复 `switch`。
|
|
223
|
+
|
|
224
|
+
OMP 的 managed mode、gateway drain、原生配置恢复和退出清理作为 OMP 专用 ProxyDriver 语义保留,不能被 generic proxy driver 覆盖。
|
|
225
|
+
|
|
226
|
+
### Web UI
|
|
227
|
+
|
|
228
|
+
前端只通过 `/api/platforms` 获取平台元数据。接口不可用时仅使用最小 UI fallback,不保留第二份完整内置平台定义。`src/web/src/config/platforms.js` 最终只保留:
|
|
229
|
+
|
|
230
|
+
- API 返回值归一化;
|
|
231
|
+
- iconToken 到 Vue 图标的通用映射;
|
|
232
|
+
- UI fallback 和排序规则。
|
|
233
|
+
|
|
234
|
+
渠道面板拆成:
|
|
235
|
+
|
|
236
|
+
```text
|
|
237
|
+
common channel panel schema
|
|
238
|
+
provider fields
|
|
239
|
+
auth fields
|
|
240
|
+
schedule fields
|
|
241
|
+
health fields
|
|
242
|
+
|
|
243
|
+
platform manifest fields
|
|
244
|
+
display metadata
|
|
245
|
+
capabilities
|
|
246
|
+
|
|
247
|
+
platform channel driver schema
|
|
248
|
+
platform-specific fields
|
|
249
|
+
validation
|
|
250
|
+
API serialization
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Claude、Codex、Gemini、OpenCode、OMP 仍可保留各自特殊字段,但通用列表、健康状态、启停、删除和基础表单行为只实现一次。
|
|
254
|
+
|
|
255
|
+
## Error Model
|
|
256
|
+
|
|
257
|
+
统一结果状态:
|
|
258
|
+
|
|
259
|
+
```text
|
|
260
|
+
ok
|
|
261
|
+
unsupported
|
|
262
|
+
unavailable
|
|
263
|
+
invalid
|
|
264
|
+
failed
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
语义:
|
|
268
|
+
|
|
269
|
+
- `unsupported`:Manifest 未声明能力,映射为隐藏功能或 404。
|
|
270
|
+
- `unavailable`:CLI 未安装、目录不存在或环境不可用。
|
|
271
|
+
- `invalid`:Manifest 或用户输入不符合 schema。
|
|
272
|
+
- `failed`:driver 已支持,但实际 I/O、解析或网络操作失败。
|
|
273
|
+
- `ok`:操作成功。
|
|
274
|
+
|
|
275
|
+
显式传入未知平台时不得回退到 Claude。只有没有提供平台时,才允许使用默认平台。
|
|
276
|
+
|
|
277
|
+
错误必须带有 `platform`、`capability` 和 `operation` 上下文,并保留原始 cause。仅允许已有 snapshot 的 stale-while-refresh 行为作为明确的缓存策略,不能用空结果掩盖 driver 错误。
|
|
278
|
+
|
|
279
|
+
## Mock Path and Dependency Injection
|
|
280
|
+
|
|
281
|
+
现有路径保持不变并继续作为稳定测试 seam,包括:
|
|
282
|
+
|
|
283
|
+
```text
|
|
284
|
+
src/config/paths.js
|
|
285
|
+
src/server/services/channels.js
|
|
286
|
+
src/server/services/codex-channels.js
|
|
287
|
+
src/server/services/gemini-channels.js
|
|
288
|
+
src/server/services/opencode-channels.js
|
|
289
|
+
src/server/services/omp-channels.js
|
|
290
|
+
src/server/omp-proxy-server.js
|
|
291
|
+
src/server/api/channels.js
|
|
292
|
+
src/server/api/codex-channels.js
|
|
293
|
+
src/server/api/gemini-channels.js
|
|
294
|
+
src/server/api/opencode-channels.js
|
|
295
|
+
src/server/api/omp-channels.js
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
这些模块可以变成 facade,但不能在本次迁移中删除、改名或绕过其加载边界。现有测试继续使用:
|
|
299
|
+
|
|
300
|
+
```js
|
|
301
|
+
const modulePath = require.resolve('...');
|
|
302
|
+
require.cache[modulePath] = { ... };
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
通用 application 层增加显式依赖注入:
|
|
306
|
+
|
|
307
|
+
```text
|
|
308
|
+
createPlatformUseCases({
|
|
309
|
+
registry,
|
|
310
|
+
drivers,
|
|
311
|
+
paths,
|
|
312
|
+
storage,
|
|
313
|
+
clock,
|
|
314
|
+
logger
|
|
315
|
+
})
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
这样现有 `require.cache` mock 仍能拦截 facade,新测试可直接传入 fake Registry、fake driver、临时路径和固定时钟。
|
|
319
|
+
|
|
320
|
+
不将测试强制迁移到另一套 mock API,也不允许通用层在测试路径被替换后私自重新加载真实模块。
|
|
321
|
+
|
|
322
|
+
## Migration Plan
|
|
323
|
+
|
|
324
|
+
### Phase 1: Extract and Validate
|
|
325
|
+
|
|
326
|
+
- 从现有 `src/shared/platforms.js`、`paths.js` 和同步配置提取内置 Manifest。
|
|
327
|
+
- 建立 Registry、PathResolver、Manifest schema 和 driver allowlist。
|
|
328
|
+
- 保持现有模块与导出不变。
|
|
329
|
+
- 为五个平台增加 Manifest contract test。
|
|
330
|
+
|
|
331
|
+
### Phase 2: Migrate Read Paths
|
|
332
|
+
|
|
333
|
+
- 将 session-history adapters 接入 Registry。
|
|
334
|
+
- 迁移项目、会话、Dashboard snapshot 和统计聚合。
|
|
335
|
+
- 先保留现有 API facade,验证响应格式和快照行为不变。
|
|
336
|
+
|
|
337
|
+
### Phase 3: Migrate Mutations
|
|
338
|
+
|
|
339
|
+
- 迁移渠道 CRUD、健康检查、代理控制和配置同步。
|
|
340
|
+
- 用 route factory 替换平台 API 中重复的通用 handler。
|
|
341
|
+
- 保留 Claude/Codex/Gemini/OpenCode/OMP 的专用 driver。
|
|
342
|
+
|
|
343
|
+
### Phase 4: Migrate CLI and Web UI
|
|
344
|
+
|
|
345
|
+
- CLI 平台路由改为 Registry 派生。
|
|
346
|
+
- daemon 自动恢复改为 capability driver 遍历。
|
|
347
|
+
- 前端消费平台目录,拆分渠道面板通用 schema 与平台字段。
|
|
348
|
+
|
|
349
|
+
### Phase 5: Enable Config-Only Extensions
|
|
350
|
+
|
|
351
|
+
- 增加用户 `platforms.json` 的加载、校验和安全字段过滤。
|
|
352
|
+
- 将现有 `ui-config.customCliPlatforms` 作为兼容输入迁移到平台目录;迁移期间继续读取旧字段,但 `platforms.json` 成为运行时权威来源。
|
|
353
|
+
- 用虚拟 `demo-cli` 验证只添加 Manifest 和已存在的 generic driver 配置即可进入通用聚合。
|
|
354
|
+
- 仅当所有旧测试和 contract test 通过后删除重复平台数组和无法再被调用的旧分支。
|
|
355
|
+
|
|
356
|
+
## Testing Contract
|
|
357
|
+
|
|
358
|
+
### Existing Regression Tests
|
|
359
|
+
|
|
360
|
+
现有 unit、API、Windows、Codex、OMP、skill 和 plugin 测试继续运行。重构不能改变它们的 mock path、模块导出和外部响应契约。
|
|
361
|
+
|
|
362
|
+
### Manifest Contract Tests
|
|
363
|
+
|
|
364
|
+
每个 Manifest 必须覆盖:
|
|
365
|
+
|
|
366
|
+
- key 唯一且合法;
|
|
367
|
+
- label、command 和路径可解析;
|
|
368
|
+
- capability 与 driver allowlist 一致;
|
|
369
|
+
- 禁止覆盖内置平台;
|
|
370
|
+
- 不支持能力返回 `unsupported`。
|
|
371
|
+
|
|
372
|
+
### Driver Contract Tests
|
|
373
|
+
|
|
374
|
+
在临时目录和注入路径下验证:
|
|
375
|
+
|
|
376
|
+
- 正常 inventory / parse;
|
|
377
|
+
- 缺失、损坏和权限错误文件;
|
|
378
|
+
- 文件读取期间发生变化;
|
|
379
|
+
- CRUD 与删除幂等性;
|
|
380
|
+
- driver 错误包含平台、能力和操作上下文。
|
|
381
|
+
|
|
382
|
+
### Mock Compatibility Tests
|
|
383
|
+
|
|
384
|
+
验证:
|
|
385
|
+
|
|
386
|
+
- mock `paths.js` 后不会读取真实用户目录;
|
|
387
|
+
- mock 各平台 service facade 后不会偷偷加载真实 service;
|
|
388
|
+
- mock `omp-proxy-server.js` 后退出清理仍受测试控制;
|
|
389
|
+
- API 模块重新加载时仍使用 `require.cache` stub;
|
|
390
|
+
- 注入 `adapterRegistry` 后 session index 不访问真实平台目录。
|
|
391
|
+
|
|
392
|
+
### Config-Only Extension Test
|
|
393
|
+
|
|
394
|
+
加入虚拟 `demo-cli`:
|
|
395
|
+
|
|
396
|
+
1. 只注册 Manifest 和已存在的 generic driver。
|
|
397
|
+
2. 不修改 Dashboard、统计聚合、CLI router 和前端平台列表源码。
|
|
398
|
+
3. 验证 Registry、能力枚举、路径解析和通用聚合自动发现该平台。
|
|
399
|
+
|
|
400
|
+
## Acceptance Criteria
|
|
401
|
+
|
|
402
|
+
- 新增符合 generic-jsonl 或 generic-filesystem 契约的 CLI 时,不需要复制平台 API、服务或 Dashboard 分支。
|
|
403
|
+
- 特殊 CLI 只需要新增对应能力 driver,不需要新增一套完整平台栈。
|
|
404
|
+
- 现有五个平台的 CLI、API、原生配置保护、OMP managed mode 和退出恢复行为不变。
|
|
405
|
+
- 现有 `require.resolve()` + `require.cache` mock path 全部保持有效。
|
|
406
|
+
- 显式未知平台不会静默回退到 Claude。
|
|
407
|
+
- 前后端不再各自维护一份完整内置平台定义。
|
|
408
|
+
- 未支持能力返回明确的 `unsupported`,而不是空成功或隐式 fallback。
|