coding-tool-x 3.8.4 → 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 +15 -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 +8 -4
- 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,168 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const express = require('express');
|
|
4
|
+
const { ProjectConfigService } = require('../services/project-config-service');
|
|
5
|
+
const { resolvePlatform } = require('../../platforms/access');
|
|
6
|
+
const { sendApiError } = require('./validation-errors');
|
|
7
|
+
|
|
8
|
+
const router = express.Router();
|
|
9
|
+
const projectConfigService = new ProjectConfigService();
|
|
10
|
+
|
|
11
|
+
function requireProjectPath(source = {}) {
|
|
12
|
+
const projectPath = source.projectPath;
|
|
13
|
+
if (typeof projectPath !== 'string' || !projectPath.trim()) {
|
|
14
|
+
throw new Error('projectPath is required');
|
|
15
|
+
}
|
|
16
|
+
return projectPath.trim();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function requirePlatform(source = {}) {
|
|
20
|
+
return resolvePlatform(source.platform, { fallback: 'claude' }).key;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function queryInput(req) {
|
|
24
|
+
return { ...req.query, ...(req.body && typeof req.body === 'object' ? req.body : {}) };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
router.get('/', async (req, res) => {
|
|
28
|
+
try {
|
|
29
|
+
const input = queryInput(req);
|
|
30
|
+
const projectPath = requireProjectPath(input);
|
|
31
|
+
const platform = requirePlatform(input);
|
|
32
|
+
const snapshot = await projectConfigService.getSnapshot(projectPath, platform);
|
|
33
|
+
res.json(snapshot);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.error('[Project Config API] Get snapshot failed:', error);
|
|
36
|
+
sendApiError(res, error);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
router.get('/skills', async (req, res) => {
|
|
41
|
+
try {
|
|
42
|
+
const input = queryInput(req);
|
|
43
|
+
const projectPath = requireProjectPath(input);
|
|
44
|
+
const platform = requirePlatform(input);
|
|
45
|
+
const skills = await projectConfigService.listProjectSkills(projectPath, platform);
|
|
46
|
+
res.json({ success: true, projectPath, platform, skills });
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error('[Project Config API] List project Skills failed:', error);
|
|
49
|
+
sendApiError(res, error);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
router.put('/skills/toggle', async (req, res) => {
|
|
54
|
+
try {
|
|
55
|
+
const projectPath = requireProjectPath(req.body);
|
|
56
|
+
const platform = requirePlatform(req.body);
|
|
57
|
+
if (!req.body.controlKey) throw new Error('Skill controlKey is required');
|
|
58
|
+
const result = await projectConfigService.setProjectSkillEnabled(
|
|
59
|
+
projectPath,
|
|
60
|
+
platform,
|
|
61
|
+
req.body.controlKey,
|
|
62
|
+
req.body.enabled
|
|
63
|
+
);
|
|
64
|
+
res.json({ success: true, projectPath, platform, ...result });
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error('[Project Config API] Toggle project Skill failed:', error);
|
|
67
|
+
sendApiError(res, error);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
router.get('/instruction', async (req, res) => {
|
|
72
|
+
try {
|
|
73
|
+
const input = queryInput(req);
|
|
74
|
+
const projectPath = requireProjectPath(input);
|
|
75
|
+
const platform = requirePlatform(input);
|
|
76
|
+
const instruction = await projectConfigService.readInstruction(projectPath, platform);
|
|
77
|
+
res.json({ success: true, projectPath, platform, instruction });
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error('[Project Config API] Read instruction failed:', error);
|
|
80
|
+
sendApiError(res, error);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
router.put('/instruction', async (req, res) => {
|
|
85
|
+
try {
|
|
86
|
+
const projectPath = requireProjectPath(req.body);
|
|
87
|
+
const platform = requirePlatform(req.body);
|
|
88
|
+
if (typeof req.body.content !== 'string') throw new Error('Instruction content must be a string');
|
|
89
|
+
const instruction = await projectConfigService.writeInstruction(projectPath, platform, req.body.content);
|
|
90
|
+
res.json({ success: true, projectPath, platform, instruction });
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error('[Project Config API] Write instruction failed:', error);
|
|
93
|
+
sendApiError(res, error);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
router.delete('/instruction', async (req, res) => {
|
|
98
|
+
try {
|
|
99
|
+
const input = queryInput(req);
|
|
100
|
+
const projectPath = requireProjectPath(input);
|
|
101
|
+
const platform = requirePlatform(input);
|
|
102
|
+
const instruction = await projectConfigService.deleteInstruction(projectPath, platform);
|
|
103
|
+
res.json({ success: true, projectPath, platform, instruction });
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error('[Project Config API] Delete instruction failed:', error);
|
|
106
|
+
sendApiError(res, error);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
router.get('/mcp', async (req, res) => {
|
|
111
|
+
try {
|
|
112
|
+
const input = queryInput(req);
|
|
113
|
+
const projectPath = requireProjectPath(input);
|
|
114
|
+
const platform = requirePlatform(input);
|
|
115
|
+
const mcp = await projectConfigService.listProjectMcp(projectPath, platform);
|
|
116
|
+
res.json({ success: true, projectPath, platform, mcp });
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error('[Project Config API] List project MCP failed:', error);
|
|
119
|
+
sendApiError(res, error);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
router.put('/mcp/:id', async (req, res) => {
|
|
124
|
+
try {
|
|
125
|
+
const projectPath = requireProjectPath(req.body);
|
|
126
|
+
const platform = requirePlatform(req.body);
|
|
127
|
+
if (!req.body.server || typeof req.body.server !== 'object' || Array.isArray(req.body.server)) {
|
|
128
|
+
throw new Error('MCP server spec must be an object');
|
|
129
|
+
}
|
|
130
|
+
const result = await projectConfigService.upsertProjectMcp(
|
|
131
|
+
projectPath,
|
|
132
|
+
platform,
|
|
133
|
+
req.params.id,
|
|
134
|
+
req.body.server
|
|
135
|
+
);
|
|
136
|
+
res.json({ success: result.success !== false, projectPath, platform, server: result });
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error('[Project Config API] Upsert project MCP failed:', error);
|
|
139
|
+
sendApiError(res, error);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
router.delete('/mcp/:id', async (req, res) => {
|
|
144
|
+
try {
|
|
145
|
+
const input = queryInput(req);
|
|
146
|
+
const projectPath = requireProjectPath(input);
|
|
147
|
+
const platform = requirePlatform(input);
|
|
148
|
+
const result = await projectConfigService.removeProjectMcp(projectPath, platform, req.params.id);
|
|
149
|
+
res.json({ success: result.success !== false, projectPath, platform, server: result });
|
|
150
|
+
} catch (error) {
|
|
151
|
+
console.error('[Project Config API] Remove project MCP failed:', error);
|
|
152
|
+
sendApiError(res, error);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
router.post('/mcp/:id/test', async (req, res) => {
|
|
157
|
+
try {
|
|
158
|
+
const projectPath = requireProjectPath(req.body);
|
|
159
|
+
const platform = requirePlatform(req.body);
|
|
160
|
+
const result = await projectConfigService.testProjectMcp(projectPath, platform, req.params.id);
|
|
161
|
+
res.json({ success: true, projectPath, platform, result });
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.error('[Project Config API] Test project MCP failed:', error);
|
|
164
|
+
sendApiError(res, error, error.code === 'MCP_DISABLED' ? 403 : 500);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
module.exports = router;
|
|
@@ -5,7 +5,45 @@
|
|
|
5
5
|
const express = require('express');
|
|
6
6
|
const router = express.Router();
|
|
7
7
|
const promptsService = require('../services/prompts-service');
|
|
8
|
-
const
|
|
8
|
+
const { getPlatformContext } = require('../platform-context');
|
|
9
|
+
|
|
10
|
+
function normalizePlatformKey(platform) {
|
|
11
|
+
return String(platform || '').trim().toLowerCase();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function createCapabilityError(platform, code) {
|
|
15
|
+
const key = normalizePlatformKey(platform);
|
|
16
|
+
const error = new Error(code === 'not_found'
|
|
17
|
+
? `无效的平台: ${key}`
|
|
18
|
+
: `平台 ${key} 未声明 prompts capability`);
|
|
19
|
+
error.status = 404;
|
|
20
|
+
error.code = code;
|
|
21
|
+
error.platform = key;
|
|
22
|
+
error.capability = 'prompts';
|
|
23
|
+
return error;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function resolvePromptPlatform(platform) {
|
|
27
|
+
const key = normalizePlatformKey(platform);
|
|
28
|
+
const registry = getPlatformContext().registry;
|
|
29
|
+
if (!registry.resolve(key)) return { error: createCapabilityError(key, 'not_found') };
|
|
30
|
+
const driverId = registry.getCapability(key, 'prompts');
|
|
31
|
+
if (!driverId || driverId === 'unsupported') {
|
|
32
|
+
return { error: createCapabilityError(key, 'unsupported') };
|
|
33
|
+
}
|
|
34
|
+
return { key, driverId };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function sendCapabilityError(res, error, fallbackStatus = 400) {
|
|
38
|
+
const status = error?.status === 404 && error?.code ? 404 : fallbackStatus;
|
|
39
|
+
return res.status(status).json({
|
|
40
|
+
success: false,
|
|
41
|
+
error: error.message,
|
|
42
|
+
code: error.code || undefined,
|
|
43
|
+
platform: error.platform || undefined,
|
|
44
|
+
capability: error.capability || undefined
|
|
45
|
+
});
|
|
46
|
+
}
|
|
9
47
|
|
|
10
48
|
/**
|
|
11
49
|
* GET /api/prompts/presets
|
|
@@ -77,7 +115,7 @@ router.get('/presets/:id', (req, res) => {
|
|
|
77
115
|
* POST /api/prompts/presets
|
|
78
116
|
* 添加或更新预设
|
|
79
117
|
*/
|
|
80
|
-
router.post('/presets', (req, res) => {
|
|
118
|
+
router.post('/presets', async (req, res) => {
|
|
81
119
|
try {
|
|
82
120
|
const preset = req.body;
|
|
83
121
|
|
|
@@ -95,17 +133,14 @@ router.post('/presets', (req, res) => {
|
|
|
95
133
|
});
|
|
96
134
|
}
|
|
97
135
|
|
|
98
|
-
const result = promptsService.savePreset(preset);
|
|
136
|
+
const result = await promptsService.savePreset(preset);
|
|
99
137
|
res.json({
|
|
100
138
|
success: true,
|
|
101
139
|
preset: result
|
|
102
140
|
});
|
|
103
141
|
} catch (error) {
|
|
104
142
|
console.error('[Prompts API] Save preset failed:', error);
|
|
105
|
-
res
|
|
106
|
-
success: false,
|
|
107
|
-
error: error.message
|
|
108
|
-
});
|
|
143
|
+
return sendCapabilityError(res, error, 400);
|
|
109
144
|
}
|
|
110
145
|
});
|
|
111
146
|
|
|
@@ -180,49 +215,36 @@ router.post('/deactivate', async (req, res) => {
|
|
|
180
215
|
* GET /api/prompts/platform-status
|
|
181
216
|
* 获取各平台提示词状态
|
|
182
217
|
*/
|
|
183
|
-
router.get('/platform-status', (req, res) => {
|
|
218
|
+
router.get('/platform-status', async (req, res) => {
|
|
184
219
|
try {
|
|
185
|
-
const status = promptsService.getPlatformStatus();
|
|
220
|
+
const status = await promptsService.getPlatformStatus();
|
|
186
221
|
res.json({
|
|
187
222
|
success: true,
|
|
188
223
|
status
|
|
189
224
|
});
|
|
190
225
|
} catch (error) {
|
|
191
226
|
console.error('[Prompts API] Get platform status failed:', error);
|
|
192
|
-
res
|
|
193
|
-
success: false,
|
|
194
|
-
error: error.message
|
|
195
|
-
});
|
|
227
|
+
return sendCapabilityError(res, error, 500);
|
|
196
228
|
}
|
|
197
229
|
});
|
|
198
|
-
|
|
199
230
|
/**
|
|
200
231
|
* GET /api/prompts/platform/:platform
|
|
201
232
|
* 读取指定平台的提示词
|
|
202
233
|
*/
|
|
203
|
-
router.get('/platform/:platform', (req, res) => {
|
|
234
|
+
router.get('/platform/:platform', async (req, res) => {
|
|
204
235
|
try {
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
if (!PROMPT_FILE_PLATFORMS.includes(platform)) {
|
|
208
|
-
return res.status(400).json({
|
|
209
|
-
success: false,
|
|
210
|
-
error: `无效的平台: ${platform}`
|
|
211
|
-
});
|
|
212
|
-
}
|
|
236
|
+
const resolved = resolvePromptPlatform(req.params.platform);
|
|
237
|
+
if (resolved.error) return sendCapabilityError(res, resolved.error, 404);
|
|
213
238
|
|
|
214
|
-
const content = promptsService.readPlatformPrompt(
|
|
239
|
+
const content = await promptsService.readPlatformPrompt(resolved.key);
|
|
215
240
|
res.json({
|
|
216
241
|
success: true,
|
|
217
|
-
platform,
|
|
242
|
+
platform: resolved.key,
|
|
218
243
|
content
|
|
219
244
|
});
|
|
220
245
|
} catch (error) {
|
|
221
246
|
console.error('[Prompts API] Read platform prompt failed:', error);
|
|
222
|
-
res
|
|
223
|
-
success: false,
|
|
224
|
-
error: error.message
|
|
225
|
-
});
|
|
247
|
+
return sendCapabilityError(res, error, 500);
|
|
226
248
|
}
|
|
227
249
|
});
|
|
228
250
|
|
|
@@ -230,30 +252,21 @@ router.get('/platform/:platform', (req, res) => {
|
|
|
230
252
|
* POST /api/prompts/import/:platform
|
|
231
253
|
* 从指定平台导入提示词
|
|
232
254
|
*/
|
|
233
|
-
router.post('/import/:platform', (req, res) => {
|
|
255
|
+
router.post('/import/:platform', async (req, res) => {
|
|
234
256
|
try {
|
|
235
|
-
const
|
|
236
|
-
|
|
257
|
+
const resolved = resolvePromptPlatform(req.params.platform);
|
|
258
|
+
if (resolved.error) return sendCapabilityError(res, resolved.error, 404);
|
|
237
259
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
success: false,
|
|
241
|
-
error: `无效的平台: ${platform}`
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const preset = promptsService.importFromPlatform(platform, name);
|
|
260
|
+
const { name } = req.body;
|
|
261
|
+
const preset = await promptsService.importFromPlatform(resolved.key, name);
|
|
246
262
|
res.json({
|
|
247
263
|
success: true,
|
|
248
264
|
preset,
|
|
249
|
-
message: `成功从 ${
|
|
265
|
+
message: `成功从 ${resolved.key} 导入提示词`
|
|
250
266
|
});
|
|
251
267
|
} catch (error) {
|
|
252
268
|
console.error('[Prompts API] Import failed:', error);
|
|
253
|
-
res
|
|
254
|
-
success: false,
|
|
255
|
-
error: error.message
|
|
256
|
-
});
|
|
269
|
+
return sendCapabilityError(res, error, 500);
|
|
257
270
|
}
|
|
258
271
|
});
|
|
259
272
|
|
|
@@ -3,9 +3,11 @@ const router = express.Router();
|
|
|
3
3
|
const {
|
|
4
4
|
MODEL_METADATA,
|
|
5
5
|
METADATA_LAST_UPDATED,
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
METADATA_SOURCE,
|
|
7
|
+
getModelIdsByToolType,
|
|
8
|
+
getDefaultSpeedTestModels
|
|
8
9
|
} = require('../../config/model-metadata');
|
|
10
|
+
const { getPlatformCatalog } = require('../services/platform-catalog');
|
|
9
11
|
const { loadConfig, saveConfig } = require('../../config/loader');
|
|
10
12
|
const {
|
|
11
13
|
MODEL_SCHEMA_VERSION,
|
|
@@ -34,6 +36,35 @@ function normalizeDefinitions(value) {
|
|
|
34
36
|
return isPlainObject(value) ? value : {};
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
function normalizeSpeedTestModels(value) {
|
|
40
|
+
if (!isPlainObject(value)) return {};
|
|
41
|
+
return Object.fromEntries(
|
|
42
|
+
Object.entries(value)
|
|
43
|
+
.map(([key, modelId]) => [String(key).trim(), typeof modelId === 'string' ? modelId.trim() : ''])
|
|
44
|
+
.filter(([key, modelId]) => key && modelId)
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getModelPlatformEntries(catalog = getPlatformCatalog()) {
|
|
49
|
+
return catalog.list({ capability: 'channels' }).map(manifest => ({
|
|
50
|
+
key: manifest.key,
|
|
51
|
+
catalogKey: manifest.modelConfig?.catalogKey || manifest.key
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function resolveDefaultSpeedTestModels(config = {}, catalog = getPlatformCatalog()) {
|
|
56
|
+
const configured = normalizeSpeedTestModels(config.defaultSpeedTestModels);
|
|
57
|
+
const staticDefaults = normalizeSpeedTestModels(getDefaultSpeedTestModels());
|
|
58
|
+
return Object.fromEntries(getModelPlatformEntries(catalog).map(({ key, catalogKey }) => [
|
|
59
|
+
key,
|
|
60
|
+
configured[key]
|
|
61
|
+
|| configured[catalogKey]
|
|
62
|
+
|| staticDefaults[catalogKey]
|
|
63
|
+
|| staticDefaults[key]
|
|
64
|
+
|| null
|
|
65
|
+
]));
|
|
66
|
+
}
|
|
67
|
+
|
|
37
68
|
function buildResolvedModelSettings(definitions, overrides) {
|
|
38
69
|
const ids = new Set([
|
|
39
70
|
...Object.keys(MODEL_METADATA),
|
|
@@ -62,7 +93,12 @@ function handleGetModelSettings(req, res) {
|
|
|
62
93
|
const config = loadConfig();
|
|
63
94
|
const overrides = config.modelMetadataOverrides || {};
|
|
64
95
|
const definitions = normalizeDefinitions(config.modelDefinitions);
|
|
65
|
-
const
|
|
96
|
+
const catalog = getPlatformCatalog();
|
|
97
|
+
const platformEntries = getModelPlatformEntries(catalog);
|
|
98
|
+
const defaultSpeedTestModels = resolveDefaultSpeedTestModels(config, catalog);
|
|
99
|
+
const toolModels = Object.fromEntries(
|
|
100
|
+
platformEntries.map(({ key, catalogKey }) => [key, getModelIdsByToolType(catalogKey)])
|
|
101
|
+
);
|
|
66
102
|
|
|
67
103
|
// Build merged table: built-in + user overrides
|
|
68
104
|
const merged = {};
|
|
@@ -91,6 +127,8 @@ function handleGetModelSettings(req, res) {
|
|
|
91
127
|
warnings: resolved.warnings,
|
|
92
128
|
builtinModelIds: Object.keys(MODEL_METADATA),
|
|
93
129
|
lastUpdated: METADATA_LAST_UPDATED,
|
|
130
|
+
metadataSource: METADATA_SOURCE,
|
|
131
|
+
toolModels,
|
|
94
132
|
defaultSpeedTestModels
|
|
95
133
|
});
|
|
96
134
|
} catch (error) {
|
|
@@ -110,6 +148,9 @@ function handleSaveModelSettings(req, res) {
|
|
|
110
148
|
if (overrides !== undefined && (typeof overrides !== 'object' || overrides === null || Array.isArray(overrides))) {
|
|
111
149
|
return res.status(400).json({ error: 'overrides must be an object' });
|
|
112
150
|
}
|
|
151
|
+
if (defaultSpeedTestModels !== undefined && !isPlainObject(defaultSpeedTestModels)) {
|
|
152
|
+
return res.status(400).json({ error: 'defaultSpeedTestModels must be an object' });
|
|
153
|
+
}
|
|
113
154
|
|
|
114
155
|
// Validate each override entry
|
|
115
156
|
if (overrides && typeof overrides === 'object') {
|
|
@@ -121,7 +162,7 @@ function handleSaveModelSettings(req, res) {
|
|
|
121
162
|
return res.status(400).json({ error: `${modelId}: metadata must be an object` });
|
|
122
163
|
}
|
|
123
164
|
if (meta.limit !== undefined) {
|
|
124
|
-
if (
|
|
165
|
+
if (!isPlainObject(meta.limit)) {
|
|
125
166
|
return res.status(400).json({ error: `${modelId}: limit must be an object` });
|
|
126
167
|
}
|
|
127
168
|
if (meta.limit.context !== undefined && (typeof meta.limit.context !== 'number' || meta.limit.context <= 0)) {
|
|
@@ -132,10 +173,10 @@ function handleSaveModelSettings(req, res) {
|
|
|
132
173
|
}
|
|
133
174
|
}
|
|
134
175
|
if (meta.pricing !== undefined) {
|
|
135
|
-
if (
|
|
176
|
+
if (!isPlainObject(meta.pricing)) {
|
|
136
177
|
return res.status(400).json({ error: `${modelId}: pricing must be an object` });
|
|
137
178
|
}
|
|
138
|
-
for (const field of ['input', 'output']) {
|
|
179
|
+
for (const field of ['input', 'output', 'cacheCreation', 'cacheRead']) {
|
|
139
180
|
if (meta.pricing[field] !== undefined && (typeof meta.pricing[field] !== 'number' || meta.pricing[field] < 0)) {
|
|
140
181
|
return res.status(400).json({ error: `${modelId}: pricing.${field} must be a non-negative number` });
|
|
141
182
|
}
|
|
@@ -166,6 +207,12 @@ function handleSaveModelSettings(req, res) {
|
|
|
166
207
|
}
|
|
167
208
|
|
|
168
209
|
const config = loadConfig();
|
|
210
|
+
const catalog = getPlatformCatalog();
|
|
211
|
+
const persistedDefaultSpeedTestModels = {
|
|
212
|
+
...normalizeSpeedTestModels(getDefaultSpeedTestModels()),
|
|
213
|
+
...normalizeSpeedTestModels(config.defaultSpeedTestModels),
|
|
214
|
+
...normalizeSpeedTestModels(defaultSpeedTestModels)
|
|
215
|
+
};
|
|
169
216
|
const newConfig = {
|
|
170
217
|
...config,
|
|
171
218
|
modelMetadataOverrides: overrides && typeof overrides === 'object'
|
|
@@ -174,17 +221,17 @@ function handleSaveModelSettings(req, res) {
|
|
|
174
221
|
modelDefinitions: normalizedDefinitions === undefined
|
|
175
222
|
? (config.modelDefinitions || {})
|
|
176
223
|
: normalizedDefinitions,
|
|
224
|
+
defaultSpeedTestModels: persistedDefaultSpeedTestModels,
|
|
177
225
|
modelMetadataSchemaVersion: MODEL_SCHEMA_VERSION
|
|
178
226
|
};
|
|
179
227
|
saveConfig(newConfig);
|
|
180
|
-
const persistedDefaultSpeedTestModels = saveDefaultSpeedTestModels(defaultSpeedTestModels);
|
|
181
228
|
|
|
182
229
|
res.json({
|
|
183
230
|
success: true,
|
|
184
231
|
schemaVersion: MODEL_SCHEMA_VERSION,
|
|
185
232
|
overrides: redactSensitiveFields(newConfig.modelMetadataOverrides),
|
|
186
233
|
definitions: redactSensitiveFields(newConfig.modelDefinitions),
|
|
187
|
-
defaultSpeedTestModels:
|
|
234
|
+
defaultSpeedTestModels: resolveDefaultSpeedTestModels(newConfig, catalog)
|
|
188
235
|
});
|
|
189
236
|
} catch (error) {
|
|
190
237
|
console.error('Error saving model metadata:', error);
|