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
|
@@ -6,35 +6,110 @@
|
|
|
6
6
|
|
|
7
7
|
const fs = require('fs');
|
|
8
8
|
const path = require('path');
|
|
9
|
-
const
|
|
10
|
-
const { NATIVE_PATHS, PATHS } = require('../../config/paths');
|
|
11
|
-
const { resolvePreferredHomeDir } = require('../../utils/home-dir');
|
|
12
|
-
|
|
13
|
-
const HOME_DIR = resolvePreferredHomeDir(process.platform, process.env, os.homedir());
|
|
9
|
+
const { PATHS } = require('../../config/paths');
|
|
14
10
|
|
|
15
11
|
// Prompts 配置文件路径
|
|
16
12
|
const PROMPTS_FILE = PATHS.prompts;
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|| path.join(NATIVE_PATHS.omp?.dir || path.join(HOME_DIR, '.omp', 'agent'), 'prompts');
|
|
26
|
-
const MANAGED_OMP_PROMPTS_DIR = path.join(OMP_PROMPTS_DIR, 'coding-tool-x');
|
|
27
|
-
|
|
28
|
-
function normalizeApps(apps = {}, defaults = { claude: true, codex: true, gemini: true, opencode: false, omp: false }) {
|
|
14
|
+
|
|
15
|
+
function normalizePlatformKey(platform) {
|
|
16
|
+
return String(platform || '').trim().toLowerCase();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getPlatformServices() {
|
|
20
|
+
const { registry, runtime } = require('../platform-context').getPlatformContext();
|
|
29
21
|
return {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
gemini: apps.gemini !== undefined ? !!apps.gemini : defaults.gemini,
|
|
33
|
-
opencode: apps.opencode !== undefined ? !!apps.opencode : defaults.opencode,
|
|
34
|
-
omp: apps.omp !== undefined ? !!apps.omp: defaults.omp
|
|
22
|
+
registry,
|
|
23
|
+
runtime
|
|
35
24
|
};
|
|
36
25
|
}
|
|
37
26
|
|
|
27
|
+
function getPromptPlatformKeys() {
|
|
28
|
+
const { registry } = getPlatformServices();
|
|
29
|
+
const keys = [];
|
|
30
|
+
const seen = new Set();
|
|
31
|
+
|
|
32
|
+
for (const platform of registry.list()) {
|
|
33
|
+
const key = normalizePlatformKey(platform.key);
|
|
34
|
+
if (!key || seen.has(key)) continue;
|
|
35
|
+
const driverId = registry.getCapability(key, 'prompts');
|
|
36
|
+
if (!driverId || driverId === 'unsupported') continue;
|
|
37
|
+
seen.add(key);
|
|
38
|
+
keys.push(key);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return keys;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function createPlatformCapabilityError(platform, capability, code) {
|
|
45
|
+
const key = normalizePlatformKey(platform);
|
|
46
|
+
const error = new Error(code === 'not_found'
|
|
47
|
+
? `无效的平台: ${key}`
|
|
48
|
+
: `平台 ${key} 未声明 ${capability} capability`);
|
|
49
|
+
error.status = 404;
|
|
50
|
+
error.code = code;
|
|
51
|
+
error.platform = key;
|
|
52
|
+
error.capability = capability;
|
|
53
|
+
return error;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function requirePromptCapability(platform) {
|
|
57
|
+
const key = normalizePlatformKey(platform);
|
|
58
|
+
const { registry, runtime } = getPlatformServices();
|
|
59
|
+
if (!registry.resolve(key)) {
|
|
60
|
+
throw createPlatformCapabilityError(key, 'prompts', 'not_found');
|
|
61
|
+
}
|
|
62
|
+
const driverId = registry.getCapability(key, 'prompts');
|
|
63
|
+
if (!driverId || driverId === 'unsupported') {
|
|
64
|
+
throw createPlatformCapabilityError(key, 'prompts', 'unsupported');
|
|
65
|
+
}
|
|
66
|
+
const driver = runtime.getDriver(key, 'prompts');
|
|
67
|
+
if (!driver) {
|
|
68
|
+
throw createPlatformCapabilityError(key, 'prompts', 'unsupported');
|
|
69
|
+
}
|
|
70
|
+
return { platform: key, driver, driverId };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function getDriverFailure(result, platform, operation) {
|
|
74
|
+
if (!result || result.status !== 'failed' || result.capability !== 'prompts') return null;
|
|
75
|
+
if (result.cause instanceof Error) return result.cause;
|
|
76
|
+
return new Error(result.error || `Prompt ${operation} failed for ${platform}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function assertPromptReadResult(result, platform) {
|
|
80
|
+
const failure = getDriverFailure(result, platform, 'read');
|
|
81
|
+
if (failure) throw failure;
|
|
82
|
+
const content = result?.status === 'ok' ? result.data : result;
|
|
83
|
+
if (typeof content !== 'string') throw new Error(`平台 ${platform} 的提示词内容无效`);
|
|
84
|
+
return content;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
function normalizeApps(apps = {}, defaults = {
|
|
89
|
+
claude: true,
|
|
90
|
+
codex: true,
|
|
91
|
+
gemini: true,
|
|
92
|
+
opencode: false,
|
|
93
|
+
omp: false
|
|
94
|
+
}) {
|
|
95
|
+
const source = apps && typeof apps === 'object' && !Array.isArray(apps) ? apps : {};
|
|
96
|
+
const fallback = defaults && typeof defaults === 'object' && !Array.isArray(defaults) ? defaults : {};
|
|
97
|
+
const platformKeys = new Set(getPromptPlatformKeys());
|
|
98
|
+
const normalized = {};
|
|
99
|
+
|
|
100
|
+
for (const platform of platformKeys) {
|
|
101
|
+
normalized[platform] = source[platform] !== undefined
|
|
102
|
+
? !!source[platform]
|
|
103
|
+
: !!fallback[platform];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Preserve historical flags for platforms absent from the current registry.
|
|
107
|
+
for (const [platform, enabled] of Object.entries(source)) {
|
|
108
|
+
if (!platformKeys.has(platform)) normalized[platform] = !!enabled;
|
|
109
|
+
}
|
|
110
|
+
return normalized;
|
|
111
|
+
}
|
|
112
|
+
|
|
38
113
|
// 内置模板(不是"默认",只是可选模板)
|
|
39
114
|
const BUILTIN_TEMPLATES = [
|
|
40
115
|
{
|
|
@@ -142,44 +217,6 @@ function writeJsonFile(filePath, data) {
|
|
|
142
217
|
fs.renameSync(tempPath, filePath);
|
|
143
218
|
}
|
|
144
219
|
|
|
145
|
-
/**
|
|
146
|
-
* 安全读取文本文件
|
|
147
|
-
*/
|
|
148
|
-
function readTextFile(filePath, defaultValue = '') {
|
|
149
|
-
try {
|
|
150
|
-
if (fs.existsSync(filePath)) {
|
|
151
|
-
return fs.readFileSync(filePath, 'utf-8');
|
|
152
|
-
}
|
|
153
|
-
} catch (err) {
|
|
154
|
-
console.error(`[Prompts] Failed to read ${filePath}:`, err.message);
|
|
155
|
-
}
|
|
156
|
-
return defaultValue;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* 安全写入文本文件(原子写入)
|
|
161
|
-
*/
|
|
162
|
-
function writeTextFile(filePath, content) {
|
|
163
|
-
ensureDir(path.dirname(filePath));
|
|
164
|
-
const tempPath = filePath + '.tmp';
|
|
165
|
-
fs.writeFileSync(tempPath, content, 'utf-8');
|
|
166
|
-
fs.renameSync(tempPath, filePath);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* 删除文件(如果存在)
|
|
171
|
-
*/
|
|
172
|
-
function deleteFile(filePath) {
|
|
173
|
-
try {
|
|
174
|
-
if (fs.existsSync(filePath)) {
|
|
175
|
-
fs.unlinkSync(filePath);
|
|
176
|
-
return true;
|
|
177
|
-
}
|
|
178
|
-
} catch (err) {
|
|
179
|
-
console.error(`[Prompts] Failed to delete ${filePath}:`, err.message);
|
|
180
|
-
}
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
220
|
|
|
184
221
|
// ============================================================================
|
|
185
222
|
// Prompts 数据管理
|
|
@@ -208,8 +245,9 @@ function initPromptsData() {
|
|
|
208
245
|
};
|
|
209
246
|
});
|
|
210
247
|
|
|
211
|
-
|
|
212
|
-
|
|
248
|
+
const existingContent = getPromptPlatformKeys().includes('claude')
|
|
249
|
+
? readPlatformPrompt('claude')
|
|
250
|
+
: '';
|
|
213
251
|
if (existingContent.trim()) {
|
|
214
252
|
const currentPreset = {
|
|
215
253
|
id: 'current',
|
|
@@ -233,14 +271,13 @@ function initPromptsData() {
|
|
|
233
271
|
let updated = false;
|
|
234
272
|
for (const preset of Object.values(data.presets || {})) {
|
|
235
273
|
const normalizedApps = normalizeApps(preset.apps);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
) {
|
|
274
|
+
const sourceApps = preset.apps && typeof preset.apps === 'object' && !Array.isArray(preset.apps)
|
|
275
|
+
? preset.apps
|
|
276
|
+
: {};
|
|
277
|
+
const needsNormalization = Object.entries(normalizedApps).some(
|
|
278
|
+
([platform, enabled]) => sourceApps[platform] !== enabled
|
|
279
|
+
);
|
|
280
|
+
if (needsNormalization) {
|
|
244
281
|
preset.apps = normalizedApps;
|
|
245
282
|
updated = true;
|
|
246
283
|
}
|
|
@@ -333,10 +370,10 @@ function savePreset(preset) {
|
|
|
333
370
|
writeJsonFile(PROMPTS_FILE, data);
|
|
334
371
|
|
|
335
372
|
if (wasActive) {
|
|
336
|
-
|
|
337
|
-
|
|
373
|
+
const syncResult = syncPresetToAllPlatforms(preset);
|
|
374
|
+
if (syncResult && typeof syncResult.then === 'function') {
|
|
375
|
+
return syncResult.then(() => preset);
|
|
338
376
|
}
|
|
339
|
-
syncPresetToAllPlatforms(preset);
|
|
340
377
|
}
|
|
341
378
|
|
|
342
379
|
return preset;
|
|
@@ -362,10 +399,6 @@ function deletePreset(id) {
|
|
|
362
399
|
data.activePresetId = null;
|
|
363
400
|
}
|
|
364
401
|
|
|
365
|
-
if (normalizeApps(preset.apps).omp) {
|
|
366
|
-
deleteOmpPromptTemplate(preset);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
402
|
delete data.presets[id];
|
|
370
403
|
writeJsonFile(PROMPTS_FILE, data);
|
|
371
404
|
|
|
@@ -378,7 +411,6 @@ function deletePreset(id) {
|
|
|
378
411
|
async function activatePreset(id) {
|
|
379
412
|
const data = initPromptsData();
|
|
380
413
|
const preset = data.presets[id];
|
|
381
|
-
const previousPreset = data.activePresetId ? data.presets[data.activePresetId] : null;
|
|
382
414
|
|
|
383
415
|
if (!preset) {
|
|
384
416
|
throw new Error(`预设 "${id}" 不存在`);
|
|
@@ -388,10 +420,6 @@ async function activatePreset(id) {
|
|
|
388
420
|
data.activePresetId = id;
|
|
389
421
|
writeJsonFile(PROMPTS_FILE, data);
|
|
390
422
|
|
|
391
|
-
if (previousPreset && previousPreset.id !== id && normalizeApps(previousPreset.apps).omp) {
|
|
392
|
-
deleteOmpPromptTemplate(previousPreset);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
423
|
// 同步到各平台
|
|
396
424
|
await syncPresetToAllPlatforms(preset);
|
|
397
425
|
|
|
@@ -403,25 +431,36 @@ async function activatePreset(id) {
|
|
|
403
431
|
*/
|
|
404
432
|
async function deactivatePrompt() {
|
|
405
433
|
const data = initPromptsData();
|
|
406
|
-
const activePreset = data.activePresetId ? data.presets[data.activePresetId] : null;
|
|
407
434
|
|
|
408
|
-
//
|
|
435
|
+
// Clear active state.
|
|
409
436
|
data.activePresetId = null;
|
|
410
437
|
writeJsonFile(PROMPTS_FILE, data);
|
|
411
438
|
|
|
412
|
-
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
439
|
+
const results = {};
|
|
440
|
+
const pending = [];
|
|
441
|
+
for (const platform of getPromptPlatformKeys()) {
|
|
442
|
+
const { driver } = requirePromptCapability(platform);
|
|
443
|
+
if (typeof driver.remove !== 'function') {
|
|
444
|
+
const error = createPlatformCapabilityError(platform, 'prompts', 'unsupported');
|
|
445
|
+
error.operation = 'remove';
|
|
446
|
+
throw error;
|
|
447
|
+
}
|
|
448
|
+
const result = driver.remove();
|
|
449
|
+
if (result && typeof result.then === 'function') {
|
|
450
|
+
pending.push(result.then(value => {
|
|
451
|
+
const failure = getDriverFailure(value, platform, 'remove');
|
|
452
|
+
if (failure) throw failure;
|
|
453
|
+
results[platform] = true;
|
|
454
|
+
}));
|
|
455
|
+
} else {
|
|
456
|
+
const failure = getDriverFailure(result, platform, 'remove');
|
|
457
|
+
if (failure) throw failure;
|
|
458
|
+
results[platform] = true;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
422
461
|
|
|
462
|
+
await Promise.all(pending);
|
|
423
463
|
console.log('[Prompts] Deactivated and removed prompt files:', results);
|
|
424
|
-
|
|
425
464
|
return results;
|
|
426
465
|
}
|
|
427
466
|
|
|
@@ -432,183 +471,176 @@ async function deactivatePrompt() {
|
|
|
432
471
|
/**
|
|
433
472
|
* 同步预设到所有已启用的平台
|
|
434
473
|
*/
|
|
435
|
-
function
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
console.log('[Prompts] Synced to Claude:', CLAUDE_PROMPT_PATH);
|
|
474
|
+
function syncPromptToPlatform(platform, content) {
|
|
475
|
+
const { driver } = requirePromptCapability(platform);
|
|
476
|
+
if (typeof driver.write !== 'function') {
|
|
477
|
+
const error = createPlatformCapabilityError(platform, 'prompts', 'unsupported');
|
|
478
|
+
error.operation = 'write';
|
|
479
|
+
throw error;
|
|
442
480
|
}
|
|
443
481
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
console.log('[Prompts] Synced to Gemini:', GEMINI_PROMPT_PATH);
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
if (apps.opencode) {
|
|
455
|
-
writeTextFile(OPENCODE_PROMPT_PATH, content);
|
|
456
|
-
console.log('[Prompts] Synced to OpenCode:', OPENCODE_PROMPT_PATH);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
if (apps.omp) {
|
|
460
|
-
const targetPath = writeOmpPromptTemplate(preset);
|
|
461
|
-
console.log('[Prompts] Synced to OMP:', targetPath);
|
|
482
|
+
const result = driver.write(content);
|
|
483
|
+
if (result && typeof result.then === 'function') {
|
|
484
|
+
return result.then(value => {
|
|
485
|
+
const failure = getDriverFailure(value, platform, 'write');
|
|
486
|
+
if (failure) throw failure;
|
|
487
|
+
return value;
|
|
488
|
+
});
|
|
462
489
|
}
|
|
490
|
+
return result;
|
|
463
491
|
}
|
|
464
492
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
493
|
+
/**
|
|
494
|
+
* 同步预设到所有已启用的平台
|
|
495
|
+
*/
|
|
496
|
+
function syncPresetToAllPlatforms(preset) {
|
|
497
|
+
const apps = normalizeApps(preset.apps);
|
|
498
|
+
const { content } = preset;
|
|
499
|
+
const pending = [];
|
|
500
|
+
|
|
501
|
+
for (const platform of getPromptPlatformKeys()) {
|
|
502
|
+
if (!apps[platform]) continue;
|
|
503
|
+
const result = syncPromptToPlatform(platform, content);
|
|
504
|
+
if (result && typeof result.then === 'function') {
|
|
505
|
+
pending.push(result.then(() => {
|
|
506
|
+
console.log(`[Prompts] Synced to ${platform}`);
|
|
507
|
+
}));
|
|
508
|
+
} else {
|
|
509
|
+
console.log(`[Prompts] Synced to ${platform}`);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
474
512
|
|
|
475
|
-
function escapeFrontmatterValue(value) {
|
|
476
|
-
return String(value || '')
|
|
477
|
-
.replace(/\\/g, '\\\\')
|
|
478
|
-
.replace(/"/g, '\\"')
|
|
479
|
-
.replace(/\r?\n/g, ' ');
|
|
480
|
-
}
|
|
481
513
|
|
|
482
|
-
|
|
483
|
-
const description = escapeFrontmatterValue(preset.description || preset.name || preset.id);
|
|
484
|
-
return `---\ndescription: "${description}"\n---\n\n${preset.content || ''}`;
|
|
514
|
+
return pending.length ? Promise.all(pending) : undefined;
|
|
485
515
|
}
|
|
486
516
|
|
|
487
|
-
function writeOmpPromptTemplate(preset) {
|
|
488
|
-
const filePath = getOmpPromptTemplatePath(preset);
|
|
489
|
-
writeTextFile(filePath, buildOmpPromptTemplateContent(preset));
|
|
490
|
-
return filePath;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
function deleteOmpPromptTemplate(preset) {
|
|
494
|
-
return deleteFile(getOmpPromptTemplatePath(preset));
|
|
495
|
-
}
|
|
496
517
|
|
|
497
518
|
/**
|
|
498
519
|
* 从平台读取当前提示词
|
|
499
520
|
*/
|
|
500
521
|
function readPlatformPrompt(platform) {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
throw new Error('OMP 使用 prompts/ 目录中的模板文件,请通过平台状态查看模板列表');
|
|
512
|
-
default:
|
|
513
|
-
throw new Error(`无效的平台: ${platform}`);
|
|
522
|
+
const { platform: normalizedPlatform, driver } = requirePromptCapability(platform);
|
|
523
|
+
if (typeof driver.read !== 'function') {
|
|
524
|
+
const error = createPlatformCapabilityError(normalizedPlatform, 'prompts', 'unsupported');
|
|
525
|
+
error.operation = 'read';
|
|
526
|
+
throw error;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
const result = driver.read();
|
|
530
|
+
if (result && typeof result.then === 'function') {
|
|
531
|
+
return result.then(value => assertPromptReadResult(value, normalizedPlatform));
|
|
514
532
|
}
|
|
533
|
+
return assertPromptReadResult(result, normalizedPlatform);
|
|
515
534
|
}
|
|
516
535
|
|
|
517
|
-
function
|
|
518
|
-
if (
|
|
519
|
-
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
const results = [];
|
|
523
|
-
const walk = (dir) => {
|
|
524
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
525
|
-
if (entry.name.startsWith('.')) continue;
|
|
526
|
-
const fullPath = path.join(dir, entry.name);
|
|
527
|
-
if (entry.isDirectory()) {
|
|
528
|
-
walk(fullPath);
|
|
529
|
-
} else if (entry.isFile() && path.extname(entry.name).toLowerCase() === '.md') {
|
|
530
|
-
const relativePath = path.relative(OMP_PROMPTS_DIR, fullPath);
|
|
531
|
-
results.push({
|
|
532
|
-
name: path.basename(entry.name, '.md'),
|
|
533
|
-
path: fullPath,
|
|
534
|
-
relativePath,
|
|
535
|
-
managed: relativePath.split(path.sep)[0] === 'coding-tool-x'
|
|
536
|
-
});
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
};
|
|
536
|
+
function writePlatformPrompt(platform, content) {
|
|
537
|
+
if (typeof content !== 'string') {
|
|
538
|
+
throw new Error('提示词内容必须是字符串');
|
|
539
|
+
}
|
|
540
540
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
541
|
+
const { platform: normalizedPlatform, driver } = requirePromptCapability(platform);
|
|
542
|
+
if (typeof driver.write !== 'function') {
|
|
543
|
+
const error = createPlatformCapabilityError(normalizedPlatform, 'prompts', 'unsupported');
|
|
544
|
+
error.operation = 'write';
|
|
545
|
+
throw error;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
const result = driver.write(content);
|
|
549
|
+
if (result && typeof result.then === 'function') {
|
|
550
|
+
return result.then(value => {
|
|
551
|
+
const failure = getDriverFailure(value, normalizedPlatform, 'write');
|
|
552
|
+
if (failure) throw failure;
|
|
553
|
+
return content;
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
return result;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
function removePlatformPrompt(platform) {
|
|
560
|
+
const { platform: normalizedPlatform, driver } = requirePromptCapability(platform);
|
|
561
|
+
if (typeof driver.remove !== 'function') {
|
|
562
|
+
const error = createPlatformCapabilityError(normalizedPlatform, 'prompts', 'unsupported');
|
|
563
|
+
error.operation = 'remove';
|
|
564
|
+
throw error;
|
|
545
565
|
}
|
|
546
566
|
|
|
547
|
-
|
|
567
|
+
const result = driver.remove();
|
|
568
|
+
if (result && typeof result.then === 'function') {
|
|
569
|
+
return result.then(value => {
|
|
570
|
+
const failure = getDriverFailure(value, normalizedPlatform, 'remove');
|
|
571
|
+
if (failure) throw failure;
|
|
572
|
+
return true;
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
return result;
|
|
548
576
|
}
|
|
549
577
|
|
|
578
|
+
|
|
550
579
|
/**
|
|
551
580
|
* 获取各平台当前的提示词状态
|
|
552
581
|
*/
|
|
553
582
|
function getPlatformStatus() {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
content: readTextFile(CODEX_PROMPT_PATH, '')
|
|
564
|
-
},
|
|
565
|
-
gemini: {
|
|
566
|
-
path: GEMINI_PROMPT_PATH,
|
|
567
|
-
exists: fs.existsSync(GEMINI_PROMPT_PATH),
|
|
568
|
-
content: readTextFile(GEMINI_PROMPT_PATH, '')
|
|
569
|
-
},
|
|
570
|
-
opencode: {
|
|
571
|
-
path: OPENCODE_PROMPT_PATH,
|
|
572
|
-
exists: fs.existsSync(OPENCODE_PROMPT_PATH),
|
|
573
|
-
content: readTextFile(OPENCODE_PROMPT_PATH, '')
|
|
574
|
-
},
|
|
575
|
-
omp: {
|
|
576
|
-
path: OMP_PROMPTS_DIR,
|
|
577
|
-
managedPath: MANAGED_OMP_PROMPTS_DIR,
|
|
578
|
-
exists: fs.existsSync(OMP_PROMPTS_DIR),
|
|
579
|
-
templates: listOmpPromptTemplates()
|
|
583
|
+
const statuses = {};
|
|
584
|
+
const pending = [];
|
|
585
|
+
|
|
586
|
+
for (const platform of getPromptPlatformKeys()) {
|
|
587
|
+
const { driver } = requirePromptCapability(platform);
|
|
588
|
+
if (typeof driver.read !== 'function') {
|
|
589
|
+
const error = createPlatformCapabilityError(platform, 'prompts', 'unsupported');
|
|
590
|
+
error.operation = 'read';
|
|
591
|
+
throw error;
|
|
580
592
|
}
|
|
581
|
-
|
|
593
|
+
const pathValue = typeof driver.path === 'string' ? driver.path : null;
|
|
594
|
+
const result = driver.read();
|
|
595
|
+
const apply = value => {
|
|
596
|
+
const failure = getDriverFailure(value, platform, 'read');
|
|
597
|
+
if (failure) throw failure;
|
|
598
|
+
const content = assertPromptReadResult(value, platform);
|
|
599
|
+
statuses[platform] = {
|
|
600
|
+
...(pathValue ? { path: pathValue } : {}),
|
|
601
|
+
exists: pathValue ? fs.existsSync(pathValue) : Boolean(content),
|
|
602
|
+
content
|
|
603
|
+
};
|
|
604
|
+
};
|
|
605
|
+
if (result && typeof result.then === 'function') pending.push(result.then(apply));
|
|
606
|
+
else apply(result);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
return pending.length ? Promise.all(pending).then(() => statuses) : statuses;
|
|
582
610
|
}
|
|
583
611
|
|
|
584
612
|
/**
|
|
585
613
|
* 从平台导入提示词作为新预设
|
|
586
614
|
*/
|
|
587
615
|
function importFromPlatform(platform, presetName) {
|
|
588
|
-
const
|
|
616
|
+
const normalizedPlatform = requirePromptCapability(platform).platform;
|
|
617
|
+
const contentResult = readPlatformPrompt(normalizedPlatform);
|
|
589
618
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
619
|
+
const createPreset = content => {
|
|
620
|
+
if (!content.trim()) {
|
|
621
|
+
throw new Error(`${normalizedPlatform} 的提示词文件为空`);
|
|
622
|
+
}
|
|
593
623
|
|
|
594
|
-
|
|
595
|
-
|
|
624
|
+
const id = `imported-${normalizedPlatform}-${Date.now()}`;
|
|
625
|
+
const emptyApps = Object.fromEntries(getPromptPlatformKeys().map(key => [key, false]));
|
|
626
|
+
const preset = {
|
|
627
|
+
id,
|
|
628
|
+
name: presetName || `从 ${normalizedPlatform} 导入`,
|
|
629
|
+
description: `从 ${normalizedPlatform} 导入的提示词`,
|
|
630
|
+
content,
|
|
631
|
+
apps: normalizeApps(emptyApps),
|
|
632
|
+
isBuiltin: false,
|
|
633
|
+
createdAt: Date.now(),
|
|
634
|
+
updatedAt: Date.now()
|
|
635
|
+
};
|
|
596
636
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
name: presetName || `从 ${platform} 导入`,
|
|
600
|
-
description: `从 ${platform} 导入的提示词`,
|
|
601
|
-
content,
|
|
602
|
-
apps: normalizeApps({ claude: false, codex: false, gemini: false, opencode: false, omp: false }),
|
|
603
|
-
isBuiltin: false,
|
|
604
|
-
createdAt: Date.now(),
|
|
605
|
-
updatedAt: Date.now()
|
|
637
|
+
preset.apps[normalizedPlatform] = true;
|
|
638
|
+
return savePreset(preset);
|
|
606
639
|
};
|
|
607
640
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
return savePreset(preset);
|
|
641
|
+
return contentResult && typeof contentResult.then === 'function'
|
|
642
|
+
? contentResult.then(createPreset)
|
|
643
|
+
: createPreset(contentResult);
|
|
612
644
|
}
|
|
613
645
|
|
|
614
646
|
/**
|
|
@@ -635,6 +667,8 @@ module.exports = {
|
|
|
635
667
|
activatePreset,
|
|
636
668
|
deactivatePrompt,
|
|
637
669
|
readPlatformPrompt,
|
|
670
|
+
writePlatformPrompt,
|
|
671
|
+
removePlatformPrompt,
|
|
638
672
|
getPlatformStatus,
|
|
639
673
|
importFromPlatform,
|
|
640
674
|
getStats
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const { PATHS } = require('../../config/paths');
|
|
3
|
+
const { PATHS, getPlatformStatePath } = require('../../config/paths');
|
|
4
4
|
|
|
5
5
|
const LOG_RECOVERY_BYTES = 1024 * 1024;
|
|
6
6
|
const LOG_FILE_PATH = path.join(PATHS.logs, 'cc-tool-out.log');
|
|
@@ -19,8 +19,8 @@ const PROXY_START_LOG_PATTERNS = {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
function getRuntimeFilePath(proxyType) {
|
|
22
|
-
const filePath =
|
|
23
|
-
|
|
22
|
+
const filePath = getPlatformStatePath('proxyRuntime', proxyType);
|
|
23
|
+
if (!filePath) return null;
|
|
24
24
|
const dir = path.dirname(filePath);
|
|
25
25
|
if (!fs.existsSync(dir)) {
|
|
26
26
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -31,6 +31,7 @@ function getRuntimeFilePath(proxyType) {
|
|
|
31
31
|
function saveProxyStartTime(proxyType, preserveExisting = false) {
|
|
32
32
|
try {
|
|
33
33
|
const filePath = getRuntimeFilePath(proxyType);
|
|
34
|
+
if (!filePath) return null;
|
|
34
35
|
if (preserveExisting && fs.existsSync(filePath)) {
|
|
35
36
|
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
36
37
|
}
|
|
@@ -58,6 +59,7 @@ function persistRecoveredStartTime(proxyType, startTime, recoveredFrom) {
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
const runtimeFilePath = getRuntimeFilePath(proxyType);
|
|
62
|
+
if (!runtimeFilePath) return null;
|
|
61
63
|
const data = {
|
|
62
64
|
startTime: validStartTime,
|
|
63
65
|
type: proxyType,
|
|
@@ -70,6 +72,7 @@ function persistRecoveredStartTime(proxyType, startTime, recoveredFrom) {
|
|
|
70
72
|
function readStoredProxyStartTime(proxyType) {
|
|
71
73
|
try {
|
|
72
74
|
const filePath = getRuntimeFilePath(proxyType);
|
|
75
|
+
if (!filePath) return null;
|
|
73
76
|
if (!fs.existsSync(filePath)) return null;
|
|
74
77
|
const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
75
78
|
return toValidStartTime(data.startTime);
|
|
@@ -136,7 +139,7 @@ function recoverProxyStartTime(proxyType) {
|
|
|
136
139
|
return logRecoveredStartTime;
|
|
137
140
|
}
|
|
138
141
|
|
|
139
|
-
const activeChannelPath =
|
|
142
|
+
const activeChannelPath = getPlatformStatePath('activeChannel', proxyType);
|
|
140
143
|
if (!activeChannelPath || !fs.existsSync(activeChannelPath)) {
|
|
141
144
|
return null;
|
|
142
145
|
}
|