coding-tool-x 3.8.4 → 3.8.6
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-Db9wAyaZ.js +1 -0
- package/dist/web/assets/AgentsDrawer-Pw2k-ZAa.css +1 -0
- package/dist/web/assets/Analytics-C4gMzv7g.js +1 -0
- package/dist/web/assets/Analytics-CyHhR126.css +1 -0
- package/dist/web/assets/AssetPathField-Bd_nMFu3.js +1 -0
- package/dist/web/assets/ChatHistoryDrawer-B2qBQs9L.css +1 -0
- package/dist/web/assets/ChatHistoryDrawer-CwzJHyNP.js +1 -0
- package/dist/web/assets/CollapseItem-CTCfSiue.js +1 -0
- package/dist/web/assets/CommandsDrawer-BZJxlPvV.css +1 -0
- package/dist/web/assets/CommandsDrawer-vDghB1U9.js +1 -0
- package/dist/web/assets/ConfigExportDrawer-C-XDvlHc.js +1 -0
- package/dist/web/assets/ConfigExportDrawer-dwruRKWr.css +1 -0
- package/dist/web/assets/ConfigTemplates-CYY8XRED.js +1 -0
- package/dist/web/assets/ConfigTemplatesDrawer-BfDi8yO3.css +1 -0
- package/dist/web/assets/ConfigTemplatesDrawer-CbsJp76X.js +1 -0
- package/dist/web/assets/ConfigTemplatesPanel-CWyPtk67.css +1 -0
- package/dist/web/assets/ConfigTemplatesPanel-liMSTh7s.js +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-D6QSiYaL.js +1 -0
- package/dist/web/assets/GatewayConvertDrawer-CuNlf7AC.css +1 -0
- package/dist/web/assets/GatewayConvertDrawer-RvET6iNG.js +1 -0
- package/dist/web/assets/Home-CSuFuJ9Y.css +1 -0
- package/dist/web/assets/Home-P8eseZcf.js +1 -0
- package/dist/web/assets/MarkdownEditor-CYmLGYju.js +1 -0
- package/dist/web/assets/MarkdownEditor-qfVgSre_.css +1 -0
- package/dist/web/assets/McpDrawer-C0dnsZhQ.css +1 -0
- package/dist/web/assets/McpDrawer-Ch3bkKIq.js +1 -0
- package/dist/web/assets/McpFormDrawer-BRbDcawn.css +1 -0
- package/dist/web/assets/McpFormDrawer-BcTlgSpN.js +1 -0
- package/dist/web/assets/PluginManager-Dh2o0xkZ.js +1 -0
- package/dist/web/assets/PluginsDrawer-DM3QjprE.css +1 -0
- package/dist/web/assets/PluginsDrawer-deKQ5u3I.js +1 -0
- package/dist/web/assets/PluginsPanel-BofsgQgj.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-DhSWJHTA.js +1 -0
- package/dist/web/assets/PromptsDrawer-BIgiYCEQ.css +1 -0
- package/dist/web/assets/PromptsDrawer-Cfb2FeeU.js +1 -0
- package/dist/web/assets/RecentSessionsDrawer-3eXamJhr.js +1 -0
- package/dist/web/assets/RecentSessionsDrawer-CKFsOYDM.css +1 -0
- package/dist/web/assets/SessionCard-CW0eHURI.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-DQfyDGWU.js +1 -0
- package/dist/web/assets/SettingsDrawer-Dw5NUgHC.css +1 -0
- package/dist/web/assets/SettingsDrawer-u_vwUuPS.js +1 -0
- package/dist/web/assets/SkillManager-C0GCT2Kb.css +1 -0
- package/dist/web/assets/SkillManager-DHMprJLA.js +1 -0
- package/dist/web/assets/SkillsDrawer-BCNme-aJ.css +1 -0
- package/dist/web/assets/SkillsDrawer-CkF3BpyC.js +1 -0
- package/dist/web/assets/SkillsPanel-B3Nm5j32.css +1 -0
- package/dist/web/assets/SkillsPanel-DWE4pFGx.js +1 -0
- package/dist/web/assets/SpeedTestDrawer-BgfG1Ked.js +1 -0
- package/dist/web/assets/SpeedTestDrawer-Dc0WToJ_.css +1 -0
- package/dist/web/assets/Upload-CNwaGOws.js +1 -0
- package/dist/web/assets/WorkspaceDrawer-Br5CeCzL.js +1 -0
- package/dist/web/assets/WorkspaceDrawer-CGnMu9p1.css +1 -0
- package/dist/web/assets/WorkspaceManager-B2O8-qIw.js +1 -0
- package/dist/web/assets/WorkspacePanel-5oDKit3c.js +1 -0
- package/dist/web/assets/WorkspacePanel-D0-zHTHP.css +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-BMAUPq5K.js +2 -0
- package/dist/web/assets/index-Bi1MQHYX.css +1 -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-jbmqZuJs.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 +104 -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 +165 -0
- package/src/platforms/channel-auth-service.js +107 -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 +98 -418
- package/src/{server/services → platforms}/notification-hooks.js +190 -1023
- package/src/platforms/oauth-credentials-service.js +635 -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 +133 -24
- 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 +12 -2
- 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 +876 -214
- 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
|
@@ -3,6 +3,24 @@ const path = require('path');
|
|
|
3
3
|
const archiver = require('archiver');
|
|
4
4
|
const chalk = require('chalk');
|
|
5
5
|
const { HOME_DIR } = require('../config/paths');
|
|
6
|
+
const { getPlatformContext } = require('../server/platform-context');
|
|
7
|
+
|
|
8
|
+
function resolveClaudeExportPaths(options = {}) {
|
|
9
|
+
const registry = options.registry || getPlatformContext().registry;
|
|
10
|
+
const pathContext = options.pathContext
|
|
11
|
+
|| registry?.resolvePathContext?.('claude', options.pathOptions || {});
|
|
12
|
+
const homeDir = pathContext?.home || HOME_DIR;
|
|
13
|
+
const native = pathContext?.native || {};
|
|
14
|
+
const claudeDir = native.dir || path.join(homeDir, '.claude');
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
homeDir,
|
|
18
|
+
claudeDir,
|
|
19
|
+
prompt: native.prompt || path.join(claudeDir, 'CLAUDE.md'),
|
|
20
|
+
settings: native.settings || path.join(claudeDir, 'settings.json'),
|
|
21
|
+
skills: native.skills || path.join(claudeDir, 'skills')
|
|
22
|
+
};
|
|
23
|
+
}
|
|
6
24
|
|
|
7
25
|
/**
|
|
8
26
|
* 导出 Claude Code 配置为 ZIP 压缩包
|
|
@@ -14,8 +32,8 @@ async function exportConfig(options = {}) {
|
|
|
14
32
|
try {
|
|
15
33
|
console.log(chalk.blue('[START] 开始导出 Claude Code 配置...'));
|
|
16
34
|
|
|
17
|
-
const
|
|
18
|
-
const claudeDir =
|
|
35
|
+
const exportPaths = resolveClaudeExportPaths(options);
|
|
36
|
+
const { homeDir, claudeDir } = exportPaths;
|
|
19
37
|
const currentDir = process.cwd();
|
|
20
38
|
|
|
21
39
|
// 检查 .claude 目录是否存在
|
|
@@ -54,7 +72,7 @@ async function exportConfig(options = {}) {
|
|
|
54
72
|
};
|
|
55
73
|
|
|
56
74
|
// 1. 导出全局 CLAUDE.md
|
|
57
|
-
const globalClaudeMd =
|
|
75
|
+
const globalClaudeMd = exportPaths.prompt;
|
|
58
76
|
if (fs.existsSync(globalClaudeMd)) {
|
|
59
77
|
archive.file(globalClaudeMd, { name: 'global/CLAUDE.md' });
|
|
60
78
|
manifest.globalConfig.claudeMd = true;
|
|
@@ -63,7 +81,7 @@ async function exportConfig(options = {}) {
|
|
|
63
81
|
}
|
|
64
82
|
|
|
65
83
|
// 2. 导出 settings.json
|
|
66
|
-
const settingsJson =
|
|
84
|
+
const settingsJson = exportPaths.settings;
|
|
67
85
|
if (fs.existsSync(settingsJson)) {
|
|
68
86
|
archive.file(settingsJson, { name: 'global/settings.json' });
|
|
69
87
|
manifest.globalConfig.settings = true;
|
|
@@ -89,7 +107,7 @@ async function exportConfig(options = {}) {
|
|
|
89
107
|
}
|
|
90
108
|
|
|
91
109
|
// 3. 导出 Skills
|
|
92
|
-
const skillsDir =
|
|
110
|
+
const skillsDir = exportPaths.skills;
|
|
93
111
|
if (fs.existsSync(skillsDir)) {
|
|
94
112
|
const skills = fs.readdirSync(skillsDir).filter(f => !f.startsWith('.'));
|
|
95
113
|
if (skills.length > 0) {
|
package/src/commands/list.js
CHANGED
|
@@ -2,22 +2,101 @@
|
|
|
2
2
|
const chalk = require('chalk');
|
|
3
3
|
const ora = require('ora');
|
|
4
4
|
const inquirer = require('inquirer');
|
|
5
|
-
const { getAllSessions, parseSessionInfoFast } = require('../utils/session');
|
|
6
5
|
const { formatTime, formatSize, truncate } = require('../utils/format');
|
|
7
6
|
const { promptSelectSession, promptForkConfirm } = require('../ui/prompts');
|
|
8
7
|
const { resumeSession } = require('./resume');
|
|
9
8
|
const { loadAliases } = require('../server/services/alias');
|
|
10
|
-
const {
|
|
9
|
+
const { resolveOperation } = require('../platforms/access');
|
|
10
|
+
|
|
11
|
+
function isDriverResult(value) {
|
|
12
|
+
return value && typeof value === 'object' && typeof value.status === 'string';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function unwrapDriverResult(value) {
|
|
16
|
+
if (!isDriverResult(value) || value.status !== 'ok') return value;
|
|
17
|
+
return value.data;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function createFailureResult(error, platform, operation) {
|
|
21
|
+
const result = {
|
|
22
|
+
status: error?.code || 'failed',
|
|
23
|
+
platform: error?.platform || platform || 'claude',
|
|
24
|
+
capability: 'sessions',
|
|
25
|
+
operation,
|
|
26
|
+
error: error?.message || String(error)
|
|
27
|
+
};
|
|
28
|
+
if (error?.cause) {
|
|
29
|
+
Object.defineProperty(result, 'cause', { value: error.cause, enumerable: false });
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function invokeSessionOperation(config, operation, args, options = {}) {
|
|
35
|
+
const platform = options.platform || config.currentCliType || '';
|
|
36
|
+
let resolved;
|
|
37
|
+
try {
|
|
38
|
+
resolved = resolveOperation(platform, 'sessions', operation, {
|
|
39
|
+
...options,
|
|
40
|
+
fallback: 'claude'
|
|
41
|
+
});
|
|
42
|
+
} catch (error) {
|
|
43
|
+
return createFailureResult(error, platform, operation);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const result = await resolved.operation(...args);
|
|
48
|
+
return unwrapDriverResult(result);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
return createFailureResult(error, resolved.key, operation);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function normalizeSessionCollection(value) {
|
|
55
|
+
const unwrapped = unwrapDriverResult(value);
|
|
56
|
+
if (isDriverResult(unwrapped)) return unwrapped;
|
|
57
|
+
if (Array.isArray(unwrapped)) return unwrapped;
|
|
58
|
+
return Array.isArray(unwrapped?.sessions) ? unwrapped.sessions : [];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function normalizeSession(session = {}) {
|
|
62
|
+
const metadata = session.meta || session.metadata || {};
|
|
63
|
+
return {
|
|
64
|
+
...session,
|
|
65
|
+
sessionId: String(session.sessionId || session.id || ''),
|
|
66
|
+
mtime: session.mtime || session.updatedAt || session.timestamp || Date.now(),
|
|
67
|
+
size: Number(session.size ?? session.fileSize ?? metadata.size ?? 0) || 0,
|
|
68
|
+
gitBranch: session.gitBranch || metadata.gitBranch || null,
|
|
69
|
+
firstMessage: session.firstMessage || session.preview || session.summary || metadata.firstMessage || null
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function reportDriverFailure(result) {
|
|
74
|
+
if (!isDriverResult(result)) return;
|
|
75
|
+
const message = result.error || `会话操作 ${result.operation || 'unknown'} 不可用`;
|
|
76
|
+
console.log(chalk.yellow(`\n[WARN] ${message}\n`));
|
|
77
|
+
}
|
|
11
78
|
|
|
12
79
|
/**
|
|
13
80
|
* 列出会话
|
|
14
81
|
*/
|
|
15
|
-
async function listSessions(config, limit = null) {
|
|
16
|
-
const maxSessions = limit || config.maxDisplaySessions;
|
|
82
|
+
async function listSessions(config = {}, limit = null, options = {}) {
|
|
83
|
+
const maxSessions = limit || config.maxDisplaySessions || 15;
|
|
17
84
|
const spinner = ora('加载会话列表...').start();
|
|
85
|
+
const result = await invokeSessionOperation(
|
|
86
|
+
config,
|
|
87
|
+
'listSessions',
|
|
88
|
+
[config.currentProject, { config }],
|
|
89
|
+
options
|
|
90
|
+
);
|
|
91
|
+
const collection = normalizeSessionCollection(result);
|
|
92
|
+
|
|
93
|
+
if (isDriverResult(collection)) {
|
|
94
|
+
spinner.stop();
|
|
95
|
+
spinner.clear();
|
|
96
|
+
return collection;
|
|
97
|
+
}
|
|
18
98
|
|
|
19
|
-
const sessions =
|
|
20
|
-
|
|
99
|
+
const sessions = collection.slice(0, maxSessions).map(normalizeSession);
|
|
21
100
|
if (sessions.length === 0) {
|
|
22
101
|
spinner.fail('暂无会话记录');
|
|
23
102
|
return [];
|
|
@@ -25,22 +104,15 @@ async function listSessions(config, limit = null) {
|
|
|
25
104
|
|
|
26
105
|
spinner.text = '解析会话信息...';
|
|
27
106
|
|
|
28
|
-
// 加载别名
|
|
29
107
|
const aliases = loadAliases();
|
|
30
|
-
|
|
31
108
|
const choices = sessions.map((session, index) => {
|
|
32
|
-
const info = parseSessionInfoFast(session.filePath);
|
|
33
109
|
const time = formatTime(session.mtime);
|
|
34
110
|
const size = formatSize(session.size);
|
|
35
|
-
const alias = aliases[session.sessionId];
|
|
111
|
+
const alias = session.alias || aliases[session.sessionId];
|
|
36
112
|
|
|
37
|
-
// 构建显示名称 - 清爽的单行布局
|
|
38
113
|
let displayName = '';
|
|
39
|
-
|
|
40
|
-
// 格式:序号. [别名] 时间 │ 大小 │ 分支 │ 第一条消息
|
|
41
114
|
displayName += chalk.bold.white(`${index + 1}. `);
|
|
42
115
|
|
|
43
|
-
// 如果有别名,优先显示别名
|
|
44
116
|
if (alias) {
|
|
45
117
|
displayName += chalk.yellow.bold(`[${alias}] `);
|
|
46
118
|
}
|
|
@@ -48,8 +120,8 @@ async function listSessions(config, limit = null) {
|
|
|
48
120
|
displayName += chalk.cyan(`${time.padEnd(10)}`);
|
|
49
121
|
displayName += chalk.gray(` │ ${size.padEnd(9)}`);
|
|
50
122
|
|
|
51
|
-
if (
|
|
52
|
-
const branchName =
|
|
123
|
+
if (session.gitBranch) {
|
|
124
|
+
const branchName = session.gitBranch
|
|
53
125
|
.replace('feature/', '')
|
|
54
126
|
.replace('feat/', '')
|
|
55
127
|
.replace('fix/', '')
|
|
@@ -59,23 +131,21 @@ async function listSessions(config, limit = null) {
|
|
|
59
131
|
displayName += chalk.gray(` │ ${''.padEnd(25)}`);
|
|
60
132
|
}
|
|
61
133
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const firstMsg = truncate(info.firstMessage, 50);
|
|
134
|
+
if (session.firstMessage && session.firstMessage !== 'Warmup') {
|
|
135
|
+
const firstMsg = truncate(String(session.firstMessage), 50);
|
|
65
136
|
displayName += chalk.gray(' │ ') + chalk.white(firstMsg);
|
|
66
137
|
}
|
|
67
138
|
|
|
68
139
|
return {
|
|
69
140
|
name: displayName,
|
|
70
141
|
value: session.sessionId,
|
|
71
|
-
short: alias ? `${alias} (${session.sessionId.substring(0, 8)})` : `会话 ${session.sessionId.substring(0, 8)}
|
|
142
|
+
short: alias ? `${alias} (${session.sessionId.substring(0, 8)})` : `会话 ${session.sessionId.substring(0, 8)}`
|
|
72
143
|
};
|
|
73
144
|
});
|
|
74
145
|
|
|
75
146
|
spinner.stop();
|
|
76
147
|
spinner.clear();
|
|
77
148
|
|
|
78
|
-
// 清屏并重新显示,避免之前的输出干扰
|
|
79
149
|
console.clear();
|
|
80
150
|
console.log(chalk.green(`\n[NEW] 找到 ${sessions.length} 个会话\n`));
|
|
81
151
|
|
|
@@ -85,12 +155,24 @@ async function listSessions(config, limit = null) {
|
|
|
85
155
|
/**
|
|
86
156
|
* 列出跨项目的最近会话
|
|
87
157
|
*/
|
|
88
|
-
async function listRecentSessionsAcrossProjects(config, limit = null) {
|
|
89
|
-
const maxSessions = limit || 15;
|
|
158
|
+
async function listRecentSessionsAcrossProjects(config = {}, limit = null, options = {}) {
|
|
159
|
+
const maxSessions = limit || 15;
|
|
90
160
|
const spinner = ora('加载最新对话...').start();
|
|
161
|
+
const result = await invokeSessionOperation(
|
|
162
|
+
config,
|
|
163
|
+
'recent',
|
|
164
|
+
[maxSessions, { config }],
|
|
165
|
+
options
|
|
166
|
+
);
|
|
167
|
+
const collection = normalizeSessionCollection(result);
|
|
168
|
+
|
|
169
|
+
if (isDriverResult(collection)) {
|
|
170
|
+
spinner.stop();
|
|
171
|
+
spinner.clear();
|
|
172
|
+
return collection;
|
|
173
|
+
}
|
|
91
174
|
|
|
92
|
-
const sessions =
|
|
93
|
-
|
|
175
|
+
const sessions = collection.slice(0, maxSessions).map(normalizeSession);
|
|
94
176
|
if (sessions.length === 0) {
|
|
95
177
|
spinner.fail('暂无会话记录');
|
|
96
178
|
return [];
|
|
@@ -98,22 +180,18 @@ async function listRecentSessionsAcrossProjects(config, limit = null) {
|
|
|
98
180
|
|
|
99
181
|
spinner.text = '解析会话信息...';
|
|
100
182
|
|
|
183
|
+
const aliases = loadAliases();
|
|
101
184
|
const choices = sessions.map((session, index) => {
|
|
102
185
|
const time = formatTime(session.mtime);
|
|
103
186
|
const size = formatSize(session.size);
|
|
104
|
-
const alias = session.alias;
|
|
187
|
+
const alias = session.alias || aliases[session.sessionId];
|
|
105
188
|
|
|
106
|
-
// 构建显示名称 - 清爽的单行布局
|
|
107
189
|
let displayName = '';
|
|
108
|
-
|
|
109
|
-
// 格式:序号. [项目名] [别名] 时间 │ 大小 │ 分支 │ 第一条消息
|
|
110
190
|
displayName += chalk.bold.white(`${index + 1}. `);
|
|
111
191
|
|
|
112
|
-
|
|
113
|
-
const projectName = session.projectDisplayName || session.projectName;
|
|
192
|
+
const projectName = session.projectDisplayName || session.projectName || '未知项目';
|
|
114
193
|
displayName += chalk.magenta.bold(`[${projectName}] `);
|
|
115
194
|
|
|
116
|
-
// 如果有别名,显示别名
|
|
117
195
|
if (alias) {
|
|
118
196
|
displayName += chalk.yellow.bold(`[${alias}] `);
|
|
119
197
|
}
|
|
@@ -132,23 +210,21 @@ async function listRecentSessionsAcrossProjects(config, limit = null) {
|
|
|
132
210
|
displayName += chalk.gray(` │ ${''.padEnd(25)}`);
|
|
133
211
|
}
|
|
134
212
|
|
|
135
|
-
// 只显示第一条用户消息
|
|
136
213
|
if (session.firstMessage && session.firstMessage !== 'Warmup') {
|
|
137
|
-
const firstMsg = truncate(session.firstMessage, 50);
|
|
214
|
+
const firstMsg = truncate(String(session.firstMessage), 50);
|
|
138
215
|
displayName += chalk.gray(' │ ') + chalk.white(firstMsg);
|
|
139
216
|
}
|
|
140
217
|
|
|
141
218
|
return {
|
|
142
219
|
name: displayName,
|
|
143
220
|
value: { sessionId: session.sessionId, projectName: session.projectName },
|
|
144
|
-
short: alias ? `${alias} (${session.sessionId.substring(0, 8)})` : `会话 ${session.sessionId.substring(0, 8)}
|
|
221
|
+
short: alias ? `${alias} (${session.sessionId.substring(0, 8)})` : `会话 ${session.sessionId.substring(0, 8)}`
|
|
145
222
|
};
|
|
146
223
|
});
|
|
147
224
|
|
|
148
225
|
spinner.stop();
|
|
149
226
|
spinner.clear();
|
|
150
227
|
|
|
151
|
-
// 清屏并重新显示,避免之前的输出干扰
|
|
152
228
|
console.clear();
|
|
153
229
|
console.log(chalk.green(`\n[NEW] 找到 ${sessions.length} 个最新对话(跨所有项目)\n`));
|
|
154
230
|
|
|
@@ -158,22 +234,25 @@ async function listRecentSessionsAcrossProjects(config, limit = null) {
|
|
|
158
234
|
/**
|
|
159
235
|
* 处理列出会话
|
|
160
236
|
*/
|
|
161
|
-
async function handleList(config, switchProjectCallback, crossProject = false) {
|
|
237
|
+
async function handleList(config, switchProjectCallback, crossProject = false, options = {}) {
|
|
162
238
|
while (true) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
239
|
+
const result = crossProject
|
|
240
|
+
? await listRecentSessionsAcrossProjects(config, null, options)
|
|
241
|
+
: await listSessions(config, null, options);
|
|
242
|
+
|
|
243
|
+
if (isDriverResult(result)) {
|
|
244
|
+
reportDriverFailure(result);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
167
247
|
|
|
248
|
+
const choices = Array.isArray(result) ? result : [];
|
|
168
249
|
if (choices.length === 0) {
|
|
169
250
|
return;
|
|
170
251
|
}
|
|
171
252
|
|
|
172
|
-
// 添加操作选项
|
|
173
253
|
choices.push(new inquirer.Separator(chalk.gray('─'.repeat(50))));
|
|
174
254
|
choices.push({ name: chalk.blue('[<-] 返回主菜单'), value: 'back' });
|
|
175
255
|
|
|
176
|
-
// 跨项目模式不显示切换项目选项(因为已经是跨所有项目了)
|
|
177
256
|
if (!crossProject) {
|
|
178
257
|
choices.push({ name: chalk.magenta('[SWITCH] 切换项目'), value: 'switch' });
|
|
179
258
|
}
|
|
@@ -187,36 +266,35 @@ async function handleList(config, switchProjectCallback, crossProject = false) {
|
|
|
187
266
|
if (selected === 'switch') {
|
|
188
267
|
const switched = await switchProjectCallback();
|
|
189
268
|
if (!switched) {
|
|
190
|
-
return;
|
|
269
|
+
return;
|
|
191
270
|
}
|
|
192
|
-
continue;
|
|
271
|
+
continue;
|
|
193
272
|
}
|
|
194
273
|
|
|
195
|
-
// 跨项目模式:selected 是 { sessionId, projectName }
|
|
196
|
-
// 单项目模式:selected 是 sessionId
|
|
197
274
|
let sessionId, projectName;
|
|
198
275
|
if (crossProject) {
|
|
199
276
|
sessionId = selected.sessionId;
|
|
200
277
|
projectName = selected.projectName;
|
|
201
|
-
// 切换到该项目
|
|
202
278
|
config.currentProject = projectName;
|
|
203
279
|
} else {
|
|
204
280
|
sessionId = selected;
|
|
205
281
|
}
|
|
206
282
|
|
|
207
|
-
// 询问是否 fork
|
|
208
283
|
const action = await promptForkConfirm();
|
|
209
284
|
|
|
210
285
|
if (action === 'back') {
|
|
211
|
-
continue;
|
|
286
|
+
continue;
|
|
212
287
|
}
|
|
213
288
|
|
|
214
289
|
const fork = action === 'fork';
|
|
215
|
-
await resumeSession(config, sessionId, fork
|
|
290
|
+
await resumeSession(config, sessionId, fork, {
|
|
291
|
+
...options,
|
|
292
|
+
platform: options.platform || config.currentCliType || ''
|
|
293
|
+
});
|
|
216
294
|
}
|
|
217
295
|
}
|
|
218
296
|
|
|
219
297
|
module.exports = {
|
|
220
298
|
listSessions,
|
|
221
|
-
|
|
299
|
+
listRecentSessionsAcrossProjects,
|
|
222
300
|
};
|
package/src/commands/logs.js
CHANGED
|
@@ -6,23 +6,40 @@ const { PATHS } = require('../config/paths');
|
|
|
6
6
|
const { normalizePlatformKey } = require('../shared/platforms');
|
|
7
7
|
|
|
8
8
|
const LOGS_DIR = PATHS.logs;
|
|
9
|
+
const UI_LOG_FILE = 'cc-tool-out.log';
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
function getCommandRegistry() {
|
|
12
|
+
return require('./platform-command-registry').createPlatformCommandRegistry();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getLogDefinitions() {
|
|
16
|
+
return getCommandRegistry().list().filter(platform => platform.logFile || platform.logAliases?.length);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getLogFiles() {
|
|
20
|
+
return {
|
|
21
|
+
ui: UI_LOG_FILE,
|
|
22
|
+
...Object.fromEntries(getLogDefinitions()
|
|
23
|
+
.filter(platform => platform.logFile && !(platform.logAliases || []).includes('ui'))
|
|
24
|
+
.map(platform => [platform.key, platform.logFile]))
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getLogAliases() {
|
|
29
|
+
return Object.fromEntries(getLogDefinitions()
|
|
30
|
+
.flatMap(platform => (platform.logAliases || []).map(alias => [platform.key, alias])));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getLogAliasNotes() {
|
|
34
|
+
return Object.fromEntries(getLogDefinitions()
|
|
35
|
+
.filter(platform => platform.logNote)
|
|
36
|
+
.map(platform => [platform.key, platform.logNote]));
|
|
37
|
+
}
|
|
23
38
|
|
|
24
39
|
function getSupportedLogTypes() {
|
|
25
|
-
|
|
40
|
+
const files = getLogFiles();
|
|
41
|
+
const platformKeys = getLogDefinitions().map(platform => platform.key);
|
|
42
|
+
return [...new Set([...Object.keys(files), ...platformKeys])];
|
|
26
43
|
}
|
|
27
44
|
|
|
28
45
|
function resolveLogType(type) {
|
|
@@ -30,14 +47,17 @@ function resolveLogType(type) {
|
|
|
30
47
|
if (!normalized) {
|
|
31
48
|
return { requestedType: type, type: null, file: null, note: null };
|
|
32
49
|
}
|
|
33
|
-
const
|
|
50
|
+
const aliases = getLogAliases();
|
|
51
|
+
const files = getLogFiles();
|
|
52
|
+
const notes = getLogAliasNotes();
|
|
53
|
+
const aliasTarget = aliases[normalized];
|
|
34
54
|
const resolvedType = aliasTarget || normalized;
|
|
35
55
|
return {
|
|
36
56
|
requestedType: type,
|
|
37
57
|
normalizedType: normalized,
|
|
38
58
|
type: resolvedType,
|
|
39
|
-
file:
|
|
40
|
-
note:
|
|
59
|
+
file: files[resolvedType] || null,
|
|
60
|
+
note: notes[normalized] || null
|
|
41
61
|
};
|
|
42
62
|
}
|
|
43
63
|
|
|
@@ -113,7 +133,7 @@ function showAllLogs(lines, follow) {
|
|
|
113
133
|
const allLogs = [];
|
|
114
134
|
|
|
115
135
|
// 读取所有日志文件
|
|
116
|
-
Object.entries(
|
|
136
|
+
Object.entries(getLogFiles()).forEach(([type, filename]) => {
|
|
117
137
|
const logPath = path.join(LOGS_DIR, filename);
|
|
118
138
|
if (fs.existsSync(logPath)) {
|
|
119
139
|
try {
|
|
@@ -241,7 +261,7 @@ function clearLogs(type) {
|
|
|
241
261
|
console.log(chalk.cyan('\n[DEL] 清空所有日志...\n'));
|
|
242
262
|
|
|
243
263
|
let cleared = 0;
|
|
244
|
-
Object.entries(
|
|
264
|
+
Object.entries(getLogFiles()).forEach(([logType, filename]) => {
|
|
245
265
|
const logPath = path.join(LOGS_DIR, filename);
|
|
246
266
|
if (fs.existsSync(logPath)) {
|
|
247
267
|
try {
|
|
@@ -314,14 +334,11 @@ function extractTimestamp(line) {
|
|
|
314
334
|
* 获取类型颜色
|
|
315
335
|
*/
|
|
316
336
|
function getTypeColor(type) {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
opencode: chalk.yellow
|
|
323
|
-
};
|
|
324
|
-
return colors[type] || chalk.gray;
|
|
337
|
+
if (type === 'ui') return chalk.blue;
|
|
338
|
+
const normalized = normalizePlatformKey(type);
|
|
339
|
+
const platform = getLogDefinitions().find(item => item.key === normalized);
|
|
340
|
+
const color = platform?.logColor || platform?.terminalColor;
|
|
341
|
+
return color && typeof chalk[color] === 'function' ? chalk[color] : chalk.gray;
|
|
325
342
|
}
|
|
326
343
|
|
|
327
344
|
module.exports = {
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { normalizePlatformKey } = require('../shared/platforms');
|
|
4
|
+
const platformRuntime = require('../platforms/runtime');
|
|
5
|
+
|
|
6
|
+
function normalizePlatformDefinition(platform) {
|
|
7
|
+
if (!platform || typeof platform !== 'object' || !platform.key) return null;
|
|
8
|
+
return platform;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function createPlatformCommandRegistry({ registry = platformRuntime.getPlatformRegistry(), platforms } = {}) {
|
|
12
|
+
const source = Array.isArray(platforms)
|
|
13
|
+
? platforms
|
|
14
|
+
: (registry && typeof registry.list === 'function' ? registry.list({ enabledOnly: true }) : []);
|
|
15
|
+
const definitions = new Map(
|
|
16
|
+
source
|
|
17
|
+
.map(normalizePlatformDefinition)
|
|
18
|
+
.filter(Boolean)
|
|
19
|
+
.map(platform => [normalizePlatformKey(platform.key), platform])
|
|
20
|
+
);
|
|
21
|
+
const commands = new Map(
|
|
22
|
+
[...definitions.values()]
|
|
23
|
+
.filter(platform => platform.command)
|
|
24
|
+
.map(platform => [normalizePlatformKey(platform.command), platform])
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const list = () => [...definitions.values()];
|
|
28
|
+
const hasCapability = (platform, capability) => {
|
|
29
|
+
const value = platform?.capabilities?.[capability];
|
|
30
|
+
return value !== undefined && value !== null && value !== 'unsupported';
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
resolve(key) {
|
|
34
|
+
const normalized = normalizePlatformKey(key);
|
|
35
|
+
return definitions.get(normalized) || commands.get(normalized) || null;
|
|
36
|
+
},
|
|
37
|
+
platformKeys() {
|
|
38
|
+
return list().map(platform => platform.key);
|
|
39
|
+
},
|
|
40
|
+
list() {
|
|
41
|
+
return list().map(platform => ({ ...platform }));
|
|
42
|
+
},
|
|
43
|
+
logTypes() {
|
|
44
|
+
return list()
|
|
45
|
+
.filter(platform => platform.logFile || platform.logAliases?.length)
|
|
46
|
+
.map(platform => platform.key);
|
|
47
|
+
},
|
|
48
|
+
portKeys() {
|
|
49
|
+
return list()
|
|
50
|
+
.filter(platform => platform.portKey && platform.defaultPort)
|
|
51
|
+
.map(platform => platform.portKey);
|
|
52
|
+
},
|
|
53
|
+
statsTypes() {
|
|
54
|
+
return list().filter(platform => hasCapability(platform, 'statistics')).map(platform => platform.key);
|
|
55
|
+
},
|
|
56
|
+
selectableTypes() {
|
|
57
|
+
return list()
|
|
58
|
+
.filter(platform => platform.cliSelectable !== false)
|
|
59
|
+
.map(platform => platform.key);
|
|
60
|
+
},
|
|
61
|
+
helpEntries() {
|
|
62
|
+
return list().map(platform => ({
|
|
63
|
+
key: platform.key,
|
|
64
|
+
command: platform.command || platform.key,
|
|
65
|
+
label: platform.helpLabel || platform.label || platform.title || platform.key,
|
|
66
|
+
proxyLabel: platform.proxyLabels?.proxyLabel || '代理',
|
|
67
|
+
proxy: hasCapability(platform, 'proxy'),
|
|
68
|
+
log: Boolean(platform.logFile || platform.logAliases?.length),
|
|
69
|
+
stats: hasCapability(platform, 'statistics'),
|
|
70
|
+
portKey: platform.portKey || null
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = {
|
|
77
|
+
createPlatformCommandRegistry
|
|
78
|
+
};
|
package/src/commands/plugin.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
function getInquirer() {
|
|
3
|
+
return require('inquirer');
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function getPluginInstaller() {
|
|
7
|
+
return require('../plugins/plugin-installer');
|
|
8
|
+
}
|
|
4
9
|
const { listPlugins, getPlugin, updatePlugin: updatePluginRegistry } = require('../plugins/registry');
|
|
5
|
-
const { createPluginContext } = require('../plugins/plugin-api');
|
|
6
10
|
const fs = require('fs');
|
|
7
11
|
const path = require('path');
|
|
8
12
|
const { INSTALLED_DIR } = require('../plugins/constants');
|
|
@@ -70,6 +74,7 @@ async function handleInstall(args) {
|
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
console.log(chalk.cyan(`\n[PKG] Installing plugin from ${url}...\n`));
|
|
77
|
+
const { installPlugin } = getPluginInstaller();
|
|
73
78
|
|
|
74
79
|
const result = await installPlugin(url);
|
|
75
80
|
|
|
@@ -111,8 +116,7 @@ async function handleRemove(args) {
|
|
|
111
116
|
process.exit(1);
|
|
112
117
|
}
|
|
113
118
|
|
|
114
|
-
|
|
115
|
-
const { confirmed } = await inquirer.prompt([
|
|
119
|
+
const { confirmed } = await getInquirer().prompt([
|
|
116
120
|
{
|
|
117
121
|
type: 'confirm',
|
|
118
122
|
name: 'confirmed',
|
|
@@ -126,6 +130,7 @@ async function handleRemove(args) {
|
|
|
126
130
|
return;
|
|
127
131
|
}
|
|
128
132
|
|
|
133
|
+
const { uninstallPlugin } = getPluginInstaller();
|
|
129
134
|
console.log(chalk.cyan(`\n[DEL] Uninstalling plugin "${name}"...\n`));
|
|
130
135
|
|
|
131
136
|
const result = uninstallPlugin(name);
|
|
@@ -477,6 +482,7 @@ async function handleUpdate(args) {
|
|
|
477
482
|
console.log(chalk.gray(' ctx plugin update --all\n'));
|
|
478
483
|
process.exit(1);
|
|
479
484
|
}
|
|
485
|
+
const { updatePlugin, updateAllPlugins } = getPluginInstaller();
|
|
480
486
|
|
|
481
487
|
if (isUpdateAll) {
|
|
482
488
|
console.log(chalk.cyan('\n[SYNC] Updating all plugins...\n'));
|