coding-tool-x 3.8.3 → 3.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +86 -15
- package/dist/web/assets/AgentsDrawer-BG6P3DX-.js +1 -0
- package/dist/web/assets/AgentsDrawer-Pw2k-ZAa.css +1 -0
- package/dist/web/assets/Analytics--z_FmL5P.js +1 -0
- package/dist/web/assets/Analytics-CyHhR126.css +1 -0
- package/dist/web/assets/AssetPathField-CrJtRKHy.js +1 -0
- package/dist/web/assets/ChatHistoryDrawer-B2qBQs9L.css +1 -0
- package/dist/web/assets/ChatHistoryDrawer-BiuEryJj.js +1 -0
- package/dist/web/assets/CollapseItem-BAYEsL_Q.js +1 -0
- package/dist/web/assets/CommandsDrawer-BZJxlPvV.css +1 -0
- package/dist/web/assets/CommandsDrawer-YJ-U7BXN.js +1 -0
- package/dist/web/assets/ConfigExportDrawer-Ce_hAknW.js +1 -0
- package/dist/web/assets/ConfigExportDrawer-dwruRKWr.css +1 -0
- package/dist/web/assets/ConfigTemplates-Bvr1NN6K.js +1 -0
- package/dist/web/assets/ConfigTemplatesDrawer-BfDi8yO3.css +1 -0
- package/dist/web/assets/ConfigTemplatesDrawer-BjIeHfF-.js +1 -0
- package/dist/web/assets/ConfigTemplatesPanel-AV00tm_D.js +1 -0
- package/dist/web/assets/ConfigTemplatesPanel-CWyPtk67.css +1 -0
- package/dist/web/assets/Divider-D28g1gwj.js +1 -0
- package/dist/web/assets/DrawerContent-ChXgZ1Xm.js +1 -0
- package/dist/web/assets/FavoritesDrawer-CG9eI9Ay.css +1 -0
- package/dist/web/assets/FavoritesDrawer-Cz95o4CD.js +1 -0
- package/dist/web/assets/GatewayConvertDrawer-CuNlf7AC.css +1 -0
- package/dist/web/assets/GatewayConvertDrawer-DLlbMz27.js +1 -0
- package/dist/web/assets/Home-CSuFuJ9Y.css +1 -0
- package/dist/web/assets/Home-D7CCOFQC.js +1 -0
- package/dist/web/assets/MarkdownEditor-qfVgSre_.css +1 -0
- package/dist/web/assets/MarkdownEditor-rEZ-c72L.js +1 -0
- package/dist/web/assets/McpDrawer-C0dnsZhQ.css +1 -0
- package/dist/web/assets/McpDrawer-DfoCyxU2.js +1 -0
- package/dist/web/assets/McpFormDrawer-BRbDcawn.css +1 -0
- package/dist/web/assets/McpFormDrawer-SKu8HNUR.js +1 -0
- package/dist/web/assets/PluginManager-BbeK-3rV.js +1 -0
- package/dist/web/assets/PluginsDrawer-CWVJ7yjS.js +1 -0
- package/dist/web/assets/PluginsDrawer-DM3QjprE.css +1 -0
- package/dist/web/assets/PluginsPanel-Cm2N3StG.js +1 -0
- package/dist/web/assets/PluginsPanel-D6ZqITcR.css +1 -0
- package/dist/web/assets/ProjectList-677RLZ8O.css +1 -0
- package/dist/web/assets/ProjectList-CsjnsNPv.js +1 -0
- package/dist/web/assets/PromptsDrawer-BIgiYCEQ.css +1 -0
- package/dist/web/assets/PromptsDrawer-EGd3djFa.js +1 -0
- package/dist/web/assets/RecentSessionsDrawer-CKFsOYDM.css +1 -0
- package/dist/web/assets/RecentSessionsDrawer-D1vtoLAs.js +1 -0
- package/dist/web/assets/SessionCard-BgLg49U3.js +1 -0
- package/dist/web/assets/SessionCard-aM2NHu6i.css +1 -0
- package/dist/web/assets/SessionList-BpYRz1cX.css +1 -0
- package/dist/web/assets/SessionList-TRiTklWk.js +1 -0
- package/dist/web/assets/SettingsDrawer-d5liXjHq.css +1 -0
- package/dist/web/assets/SettingsDrawer-rz2WejGY.js +1 -0
- package/dist/web/assets/SkillManager-BTjTUbHq.js +1 -0
- package/dist/web/assets/SkillManager-C0GCT2Kb.css +1 -0
- package/dist/web/assets/SkillsDrawer-BCNme-aJ.css +1 -0
- package/dist/web/assets/SkillsDrawer-pN0hbkK3.js +1 -0
- package/dist/web/assets/SkillsPanel-B3Nm5j32.css +1 -0
- package/dist/web/assets/SkillsPanel-gmBWEoiF.js +1 -0
- package/dist/web/assets/SpeedTestDrawer-Dc0WToJ_.css +1 -0
- package/dist/web/assets/SpeedTestDrawer-DcNzuVJk.js +1 -0
- package/dist/web/assets/Upload-v5rV0qTT.js +1 -0
- package/dist/web/assets/WorkspaceDrawer-CGnMu9p1.css +1 -0
- package/dist/web/assets/WorkspaceDrawer-DxmicM4U.js +1 -0
- package/dist/web/assets/WorkspaceManager-CJHCjARN.js +1 -0
- package/dist/web/assets/WorkspacePanel-D0-zHTHP.css +1 -0
- package/dist/web/assets/WorkspacePanel-D8_Zq-du.js +1 -0
- package/dist/web/assets/_plugin-vue_export-helper-BeLZJZij.js +1 -0
- package/dist/web/assets/client-UDwXBP9i.js +1 -0
- package/dist/web/assets/clipboard-B46yyoz_.js +1 -0
- package/dist/web/assets/headers-cf-QapUq.js +1 -0
- package/dist/web/assets/icons-B2Vg-IOC.js +1 -0
- package/dist/web/assets/index-C0EHRym0.css +1 -0
- package/dist/web/assets/index-DnEocV0M.js +2 -0
- package/dist/web/assets/light-Cp0t7v32.js +1 -0
- package/dist/web/assets/markdown-u082bbtj.js +1 -0
- package/dist/web/assets/platforms-CBkB45JP.js +1 -0
- package/dist/web/assets/platforms-FTpjxAT6.js +1 -0
- package/dist/web/assets/project-config-B2baPzYL.js +1 -0
- package/dist/web/assets/sessions-Cmy31slD.js +1 -0
- package/dist/web/assets/sessions-yC_oVVh8.js +1 -0
- package/dist/web/assets/skill-repo-input-B_fkGlUK.js +1 -0
- package/dist/web/assets/use-lock-html-scroll-DXIqmUW4.js +1 -0
- package/dist/web/assets/use-message-DoLM8C1C.js +1 -0
- package/dist/web/assets/useResponsiveDrawer-B3uojyvV.js +1 -0
- package/dist/web/assets/vendors-D0c_0KLP.js +1 -0
- package/dist/web/assets/vue-vendor-BqZbbXHA.js +1 -0
- package/dist/web/assets/workspaces-mjyPVGS8.js +1 -0
- package/dist/web/assets/xml-CgY3RMlX.js +1 -0
- package/dist/web/index.html +12 -8
- package/docs/native-log-memory-2026-09-16.md +43 -0
- package/docs/superpowers/plans/2026-08-26-configuration-driven-cli-platform.md +1578 -0
- package/docs/superpowers/plans/2026-08-30-project-scoped-config-control.md +1260 -0
- package/docs/superpowers/plans/2026-09-01-omp-skill-refresh-boundary.md +213 -0
- package/docs/superpowers/plans/2026-09-01-realtime-logs-panel.md +125 -0
- package/docs/superpowers/plans/2026-09-02-config-driven-platform-boundary.md +86 -0
- package/docs/superpowers/plans/2026-09-02-platform-implementation-drivers.md +508 -0
- package/docs/superpowers/plans/2026-09-03-cli-platform-correctness-boundary.md +760 -0
- package/docs/superpowers/plans/2026-09-03-dependency-security-remediation.md +133 -0
- package/docs/superpowers/plans/2026-09-04-model-catalog-pricing-sync.md +1078 -0
- package/docs/superpowers/plans/2026-09-05-codex-project-scan-500.md +128 -0
- package/docs/superpowers/plans/2026-09-06-project-skill-path-fix.md +97 -0
- package/docs/superpowers/specs/2026-08-26-configuration-driven-cli-platform-design.md +408 -0
- package/docs/superpowers/specs/2026-08-30-project-scoped-config-control-design.md +467 -0
- package/docs/superpowers/specs/2026-09-01-claude-session-content-repair-design.md +111 -0
- package/docs/superpowers/specs/2026-09-01-omp-skill-refresh-boundary-design.md +83 -0
- package/docs/superpowers/specs/2026-09-01-realtime-logs-panel-design.md +27 -0
- package/docs/superpowers/specs/2026-09-02-config-driven-platform-boundary-design.md +64 -0
- package/docs/superpowers/specs/2026-09-02-platform-implementation-driver-boundary-design.md +123 -0
- package/docs/superpowers/specs/2026-09-03-cli-platform-correctness-boundary-design.md +249 -0
- package/docs/superpowers/specs/2026-09-03-dependency-security-remediation-design.md +87 -0
- package/docs/superpowers/specs/2026-09-04-model-catalog-pricing-sync-design.md +301 -0
- package/docs/superpowers/specs/2026-09-05-codex-project-scan-500-design.md +24 -0
- package/package.json +13 -8
- package/src/commands/channels.js +88 -191
- package/src/commands/cli-type.js +19 -11
- package/src/commands/daemon.js +94 -32
- package/src/commands/doctor.js +16 -9
- package/src/commands/export-config.js +23 -5
- package/src/commands/list.js +130 -52
- package/src/commands/logs.js +44 -27
- package/src/commands/platform-command-registry.js +78 -0
- package/src/commands/plugin.js +11 -5
- package/src/commands/port-config.js +34 -52
- package/src/commands/proxy-control.js +207 -145
- package/src/commands/proxy.js +2 -2
- package/src/commands/resume.js +87 -91
- package/src/commands/search.js +137 -67
- package/src/commands/stats.js +30 -22
- package/src/commands/switch.js +1 -1
- package/src/commands/toggle-proxy.js +94 -111
- package/src/commands/ui.js +67 -6
- package/src/commands/workspace.js +90 -8
- package/src/config/default.js +6 -53
- package/src/config/loader.js +61 -24
- package/src/config/model-metadata.js +49 -59
- package/src/config/model-metadata.json +4095 -99
- package/src/config/paths.js +181 -8
- package/src/index.js +134 -71
- package/src/platforms/access.js +196 -0
- package/src/{server/services → platforms}/agents-service.js +354 -197
- package/src/platforms/channel-auth-registry.js +162 -0
- package/src/platforms/channel-auth-service.js +82 -0
- package/src/{server/services → platforms}/commands-service.js +195 -115
- package/src/platforms/driver-registry.js +59 -0
- package/src/platforms/drivers/claude/api-operations.js +62 -0
- package/src/{server/services/channels.js → platforms/drivers/claude/channels-implementation.js} +131 -33
- package/src/platforms/drivers/claude/channels.js +39 -0
- package/src/{server/services/config-sync-service.js → platforms/drivers/claude/config-sync.js} +29 -5
- package/src/{server/services → platforms/drivers/claude}/health-check.js +4 -4
- package/src/platforms/drivers/claude/health.js +22 -0
- package/src/platforms/drivers/claude/mcp.js +9 -0
- package/src/{server/services/settings-manager.js → platforms/drivers/claude/native-config-implementation.js} +13 -4
- package/src/platforms/drivers/claude/native-config.js +46 -0
- package/src/platforms/drivers/claude/native-logs.js +72 -0
- package/src/{server/services/claude-openai-gateway.js → platforms/drivers/claude/openai-gateway.js} +8 -65
- package/src/platforms/drivers/claude/project-config.js +21 -0
- package/src/platforms/drivers/claude/projects.js +62 -0
- package/src/platforms/drivers/claude/prompts.js +9 -0
- package/src/{server/proxy-server.js → platforms/drivers/claude/proxy-implementation.js} +41 -278
- package/src/platforms/drivers/claude/proxy.js +16 -0
- package/src/platforms/drivers/claude/resource-sync.js +9 -0
- package/src/platforms/drivers/claude/session-history-adapter.js +313 -0
- package/src/{server/services/sessions.js → platforms/drivers/claude/sessions-implementation.js} +145 -35
- package/src/platforms/drivers/claude/sessions.js +76 -0
- package/src/{server/services/claude-statistics-service.js → platforms/drivers/claude/statistics-implementation.js} +2 -2
- package/src/platforms/drivers/claude/statistics.js +16 -0
- package/src/{server/services/claude-wire.js → platforms/drivers/claude/wire.js} +1 -1
- package/src/platforms/drivers/codex/api-operations.js +9 -0
- package/src/{server/services/codex-channels.js → platforms/drivers/codex/channels-implementation.js} +149 -14
- package/src/platforms/drivers/codex/channels.js +45 -0
- package/src/{server/services/codex-config.js → platforms/drivers/codex/config.js} +12 -2
- package/src/{server/services/codex-env-manager.js → platforms/drivers/codex/env-manager.js} +1 -1
- package/src/platforms/drivers/codex/mcp.js +9 -0
- package/src/{server/services/codex-settings-manager.js → platforms/drivers/codex/native-config-implementation.js} +15 -6
- package/src/platforms/drivers/codex/native-config.js +47 -0
- package/src/platforms/drivers/codex/native-logs.js +166 -0
- package/src/platforms/drivers/codex/project-config.js +21 -0
- package/src/platforms/drivers/codex/projects.js +26 -0
- package/src/platforms/drivers/codex/prompts.js +9 -0
- package/src/{server/codex-proxy-server.js → platforms/drivers/codex/proxy-implementation.js} +30 -233
- package/src/platforms/drivers/codex/proxy.js +16 -0
- package/src/platforms/drivers/codex/resource-sync.js +9 -0
- package/src/{server/services/session-history-adapters/codex.js → platforms/drivers/codex/session-history-adapter.js} +37 -23
- package/src/{server/services/codex-sessions.js → platforms/drivers/codex/sessions-implementation.js} +81 -75
- package/src/platforms/drivers/codex/sessions.js +36 -0
- package/src/{server/services/codex-statistics-service.js → platforms/drivers/codex/statistics-implementation.js} +2 -2
- package/src/platforms/drivers/codex/statistics.js +16 -0
- package/src/platforms/drivers/gemini/api-operations.js +9 -0
- package/src/{server/services/gemini-channels.js → platforms/drivers/gemini/channels-implementation.js} +202 -37
- package/src/platforms/drivers/gemini/channels.js +39 -0
- package/src/{server/services/gemini-config.js → platforms/drivers/gemini/config.js} +12 -2
- package/src/platforms/drivers/gemini/mcp.js +9 -0
- package/src/{server/services/gemini-settings-manager.js → platforms/drivers/gemini/native-config-implementation.js} +14 -5
- package/src/platforms/drivers/gemini/native-config.js +39 -0
- package/src/platforms/drivers/gemini/native-logs.js +180 -0
- package/src/platforms/drivers/gemini/project-config.js +21 -0
- package/src/platforms/drivers/gemini/projects.js +26 -0
- package/src/platforms/drivers/gemini/prompts.js +9 -0
- package/src/{server/gemini-proxy-server.js → platforms/drivers/gemini/proxy-implementation.js} +36 -267
- package/src/platforms/drivers/gemini/proxy.js +16 -0
- package/src/platforms/drivers/gemini/resource-sync.js +9 -0
- package/src/{server/services/session-history-adapters/gemini.js → platforms/drivers/gemini/session-history-adapter.js} +70 -18
- package/src/{server/services/gemini-sessions.js → platforms/drivers/gemini/sessions-implementation.js} +53 -37
- package/src/platforms/drivers/gemini/sessions.js +47 -0
- package/src/{server/services/gemini-statistics-service.js → platforms/drivers/gemini/statistics-implementation.js} +2 -2
- package/src/platforms/drivers/gemini/statistics.js +16 -0
- package/src/{server/services/gemini-wire.js → platforms/drivers/gemini/wire.js} +1 -1
- package/src/platforms/drivers/generic-filesystem.js +166 -0
- package/src/platforms/drivers/generic-jsonl.js +141 -0
- package/src/platforms/drivers/generic-mcp.js +44 -0
- package/src/platforms/drivers/generic-openai-compatible.js +45 -0
- package/src/platforms/drivers/generic-prompt.js +41 -0
- package/src/platforms/drivers/legacy.js +677 -0
- package/src/platforms/drivers/native-config-snapshot.js +125 -0
- package/src/platforms/drivers/native-log-utils.js +1292 -0
- package/src/platforms/drivers/notification-hooks.js +578 -0
- package/src/{server/api/omp-config.js → platforms/drivers/omp/api-operations.js} +52 -64
- package/src/{server/services/omp-auth-provider-worker.js → platforms/drivers/omp/auth-provider-worker.js} +1 -1
- package/src/{server/services/omp-auth-providers.js → platforms/drivers/omp/auth-providers.js} +1 -1
- package/src/{server/services/omp-channels.js → platforms/drivers/omp/channels-implementation.js} +166 -39
- package/src/platforms/drivers/omp/channels.js +58 -0
- package/src/{server/services/omp-config.js → platforms/drivers/omp/config.js} +53 -13
- package/src/{server/services/omp-gateway-routing.js → platforms/drivers/omp/gateway-routing.js} +14 -7
- package/src/{server/services/omp-gateway.js → platforms/drivers/omp/gateway.js} +4 -262
- package/src/platforms/drivers/omp/mcp.js +9 -0
- package/src/{server/services/omp-settings-manager.js → platforms/drivers/omp/native-config-implementation.js} +75 -10
- package/src/platforms/drivers/omp/native-config.js +46 -0
- package/src/platforms/drivers/omp/native-logs.js +52 -0
- package/src/{server/services/omp-native-plugin-adapter.js → platforms/drivers/omp/native-plugin-adapter.js} +91 -4
- package/src/platforms/drivers/omp/project-config.js +29 -0
- package/src/platforms/drivers/omp/projects.js +20 -0
- package/src/platforms/drivers/omp/prompts.js +9 -0
- package/src/{server/omp-proxy-server.js → platforms/drivers/omp/proxy-implementation.js} +6 -15
- package/src/platforms/drivers/omp/proxy.js +16 -0
- package/src/platforms/drivers/omp/resource-sync.js +9 -0
- package/src/{server/services/session-history-adapters/omp.js → platforms/drivers/omp/session-history-adapter.js} +42 -18
- package/src/{server/services/omp-sessions.js → platforms/drivers/omp/sessions-implementation.js} +130 -94
- package/src/platforms/drivers/omp/sessions.js +36 -0
- package/src/{server/services/omp-skill-discovery.js → platforms/drivers/omp/skill-discovery.js} +159 -32
- package/src/{server/services/omp-skill-settings-service.js → platforms/drivers/omp/skill-settings.js} +1 -1
- package/src/{server/services/omp-statistics-service.js → platforms/drivers/omp/statistics-implementation.js} +3 -3
- package/src/platforms/drivers/omp/statistics.js +16 -0
- package/src/platforms/drivers/opencode/api-operations.js +9 -0
- package/src/{server/services/opencode-channels.js → platforms/drivers/opencode/channels-implementation.js} +28 -9
- package/src/platforms/drivers/opencode/channels.js +40 -0
- package/src/platforms/drivers/opencode/conversion.js +41 -0
- package/src/{server/services/opencode-gateway-converter.js → platforms/drivers/opencode/gateway-converter.js} +1 -1
- package/src/platforms/drivers/opencode/mcp.js +9 -0
- package/src/{server/services/opencode-settings-manager.js → platforms/drivers/opencode/native-config-implementation.js} +17 -6
- package/src/platforms/drivers/opencode/native-config.js +26 -0
- package/src/platforms/drivers/opencode/native-logs.js +133 -0
- package/src/platforms/drivers/opencode/project-config.js +98 -0
- package/src/platforms/drivers/opencode/projects.js +20 -0
- package/src/platforms/drivers/opencode/prompts.js +9 -0
- package/src/{server/opencode-proxy-server.js → platforms/drivers/opencode/proxy-implementation.js} +27 -362
- package/src/platforms/drivers/opencode/proxy.js +16 -0
- package/src/platforms/drivers/opencode/resource-sync.js +9 -0
- package/src/{server/services/opencode-sessions.js → platforms/drivers/opencode/sessions-implementation.js} +211 -64
- package/src/platforms/drivers/opencode/sessions.js +48 -0
- package/src/{server/services/opencode-statistics-service.js → platforms/drivers/opencode/statistics-implementation.js} +2 -2
- package/src/platforms/drivers/opencode/statistics.js +16 -0
- package/src/platforms/drivers/secure-file-driver.js +272 -0
- package/src/platforms/drivers/unsupported.js +7 -0
- package/src/platforms/manifest-schema.js +398 -0
- package/src/platforms/manifests/claude.json +489 -0
- package/src/platforms/manifests/codex.json +448 -0
- package/src/platforms/manifests/gemini.json +447 -0
- package/src/platforms/manifests/omp.json +496 -0
- package/src/platforms/manifests/opencode.json +422 -0
- package/src/{server/services → platforms}/native-oauth-adapters.js +87 -417
- package/src/{server/services → platforms}/notification-hooks.js +140 -1023
- package/src/platforms/oauth-credentials-service.js +506 -0
- package/src/platforms/path-resolver.js +179 -0
- package/src/platforms/platform-path-context.js +305 -0
- package/src/platforms/registry.js +248 -0
- package/src/platforms/remote-notification-providers.js +678 -0
- package/src/platforms/runtime.js +259 -0
- package/src/{server/services/session-history-adapters/index.js → platforms/session-history-adapters.js} +8 -1
- package/src/plugins/plugin-loader.js +2 -2
- package/src/plugins/plugin-manager.js +2 -2
- package/src/plugins/registry.js +27 -10
- package/src/reset-config.js +21 -5
- package/src/server/api/agents.js +46 -72
- package/src/server/api/commands.js +16 -6
- package/src/server/api/config-registry.js +206 -59
- package/src/server/api/config-sync.js +3 -2
- package/src/server/api/config-templates.js +20 -4
- package/src/server/api/config.js +111 -102
- package/src/server/api/convert.js +54 -178
- package/src/server/api/dashboard.js +168 -102
- package/src/server/api/hooks.js +1 -1
- package/src/server/api/mcp.js +224 -84
- package/src/server/api/platform-api-config.js +102 -0
- package/src/server/api/platform-route-factory.js +215 -0
- package/src/server/api/platform-routes.js +26 -0
- package/src/server/api/platforms.js +110 -0
- package/src/server/api/plugins.js +57 -57
- package/src/server/api/project-config.js +168 -0
- package/src/server/api/prompts.js +58 -45
- package/src/server/api/settings.js +55 -8
- package/src/server/api/skills.js +262 -133
- package/src/server/api/ui-config.js +2 -2
- package/src/server/api/validation-errors.js +18 -4
- package/src/server/api/workspaces.js +47 -12
- package/src/server/index.js +164 -213
- package/src/server/platform-context.js +81 -0
- package/src/server/services/channel-balance.js +11 -20
- package/src/server/services/channel-health.js +21 -6
- package/src/server/services/channel-scheduler.js +29 -39
- package/src/server/services/channel-sync-utils.js +23 -13
- package/src/server/services/config-export-service.js +350 -319
- package/src/server/services/config-registry-service.js +280 -54
- package/src/server/services/config-sync-manager.js +172 -944
- package/src/server/services/config-templates-service.js +419 -353
- package/src/server/services/control-manifest-store.js +206 -0
- package/src/server/services/dashboard-snapshot-worker.js +656 -100
- package/src/server/services/effective-control-service.js +557 -0
- package/src/server/services/local-resource-index.js +314 -0
- package/src/server/services/mcp-service.js +607 -977
- package/src/server/services/model-detector.js +15 -10
- package/src/server/services/native-log-channel-resolver.js +214 -0
- package/src/server/services/native-log-observer.js +291 -0
- package/src/server/services/network-access.js +1 -1
- package/src/server/services/platform-catalog.js +82 -0
- package/src/server/services/platform-resolution.js +32 -29
- package/src/server/services/plugins-service.js +376 -122
- package/src/server/services/project-config-service.js +550 -0
- package/src/server/services/project-path-validation.js +31 -0
- package/src/server/services/prompts-service.js +267 -233
- package/src/server/services/proxy-runtime.js +7 -4
- package/src/server/services/remote-credential-cache.js +43 -0
- package/src/server/services/repo-scanner-base.js +182 -75
- package/src/server/services/request-logger.js +7 -4
- package/src/server/services/session-history-index.js +780 -213
- package/src/server/services/session-history-worker.js +228 -33
- package/src/server/services/session-snapshot-worker.js +124 -34
- package/src/server/services/session-snapshots.js +4 -2
- package/src/server/services/skill-artifact-store.js +355 -0
- package/src/server/services/skill-format-adapters.js +65 -0
- package/src/server/services/skill-projection-service.js +323 -0
- package/src/server/services/skill-refresh-task-service.js +275 -0
- package/src/server/services/skill-service.js +2020 -677
- package/src/server/services/snapshot-cache.js +30 -8
- package/src/server/services/speed-test.js +8 -8
- package/src/server/services/sqlite-connection.js +19 -3
- package/src/server/services/statistics-service.js +240 -57
- package/src/server/services/ui-config.js +107 -76
- package/src/server/services/usage-log-utils.js +98 -0
- package/src/server/services/web-build.js +1 -1
- package/src/server/services/workspace-service.js +59 -29
- package/src/server/utils/pricing.js +10 -19
- package/src/server/websocket-server.js +153 -28
- package/src/{server/services/base → shared}/base-channel-service.js +156 -28
- package/src/shared/capability-driver.js +104 -0
- package/src/shared/channel-auth-policy.js +27 -0
- package/src/shared/channel-driver.js +161 -0
- package/src/shared/driver-factories/api.js +180 -0
- package/src/shared/driver-factories/mcp.js +244 -0
- package/src/shared/driver-factories/projects.js +121 -0
- package/src/shared/driver-factories/prompts.js +58 -0
- package/src/shared/driver-factories/resource-sync.js +375 -0
- package/src/shared/driver-result.js +78 -0
- package/src/shared/mcp-format.js +189 -0
- package/src/shared/platforms.js +104 -167
- package/src/shared/project-config.js +512 -0
- package/src/shared/proxy-driver.js +57 -0
- package/src/{server/services/base → shared}/response-usage-parser.js +8 -4
- package/src/ui/menu.js +91 -67
- package/src/utils/port-helper.js +35 -19
- package/src/utils/session.js +1 -1
- package/dist/web/assets/Analytics-COEUXmd4.js +0 -25
- package/dist/web/assets/Analytics-RNn1BUbG.css +0 -1
- package/dist/web/assets/ConfigTemplates-DLLkS53H.js +0 -1
- package/dist/web/assets/Home-DCEyLzwX.js +0 -1
- package/dist/web/assets/Home-DYVy4cGZ.css +0 -1
- package/dist/web/assets/PluginManager-Oe1ZHoMO.js +0 -1
- package/dist/web/assets/ProjectList-CWjuAFof.js +0 -1
- package/dist/web/assets/ProjectList-VeMNXfgO.css +0 -1
- package/dist/web/assets/SessionList-C4chCPxK.css +0 -1
- package/dist/web/assets/SessionList-v3ehGg9U.js +0 -1
- package/dist/web/assets/SkillManager-BsX8Qpj0.css +0 -1
- package/dist/web/assets/SkillManager-DUF_qP5S.js +0 -1
- package/dist/web/assets/WorkspaceManager-CjAWBosO.js +0 -1
- package/dist/web/assets/icons-nGdSKQn2.js +0 -1
- package/dist/web/assets/index-D5hyHPj7.js +0 -2
- package/dist/web/assets/index-bJRG3RXH.css +0 -1
- package/dist/web/assets/markdown-BNJfEgCA.js +0 -1
- package/dist/web/assets/markdown-BfC0goYb.css +0 -10
- package/dist/web/assets/naive-ui-BALVpMgd.js +0 -1
- package/dist/web/assets/vendors-DQA4Hw9v.js +0 -7
- package/dist/web/assets/vue-vendor-B5RqjEjQ.js +0 -45
- package/src/config/model-pricing.js +0 -35
- package/src/server/api/channels.js +0 -439
- package/src/server/api/claude-hooks.js +0 -56
- package/src/server/api/claude-statistics.js +0 -57
- package/src/server/api/codex-channels.js +0 -491
- package/src/server/api/codex-projects.js +0 -117
- package/src/server/api/codex-proxy.js +0 -293
- package/src/server/api/codex-sessions.js +0 -652
- package/src/server/api/codex-statistics.js +0 -57
- package/src/server/api/gemini-channels.js +0 -392
- package/src/server/api/gemini-projects.js +0 -103
- package/src/server/api/gemini-proxy.js +0 -231
- package/src/server/api/gemini-sessions.js +0 -550
- package/src/server/api/gemini-statistics.js +0 -57
- package/src/server/api/health-check.js +0 -31
- package/src/server/api/oauth-credentials.js +0 -198
- package/src/server/api/omp-channels.js +0 -575
- package/src/server/api/omp-projects.js +0 -88
- package/src/server/api/omp-proxy.js +0 -125
- package/src/server/api/omp-sessions.js +0 -386
- package/src/server/api/omp-statistics.js +0 -40
- package/src/server/api/opencode-channels.js +0 -471
- package/src/server/api/opencode-projects.js +0 -110
- package/src/server/api/opencode-proxy.js +0 -354
- package/src/server/api/opencode-sessions.js +0 -466
- package/src/server/api/opencode-statistics.js +0 -57
- package/src/server/api/projects.js +0 -120
- package/src/server/api/proxy.js +0 -330
- package/src/server/api/sessions.js +0 -810
- package/src/server/services/oauth-credentials-service.js +0 -945
- package/src/server/services/omp-session-log-observer.js +0 -138
- package/src/server/services/opencode-gateway-adapters.js +0 -43
- package/src/server/services/project-snapshots.js +0 -59
- package/src/server/services/proxy-log-helper.js +0 -298
- package/src/server/services/session-cache.js +0 -127
- package/src/server/services/session-converter.js +0 -582
- package/src/server/services/session-history-adapters/claude.js +0 -235
- /package/src/{server/services/claude-token-recovery.js → platforms/drivers/claude/token-recovery.js} +0 -0
- /package/src/{server/services/codex-parser.js → platforms/drivers/codex/parser.js} +0 -0
- /package/src/{server/services/codex-speed-test-template.json → platforms/drivers/codex/speed-test-template.json} +0 -0
- /package/src/{server/services/codex-wire.js → platforms/drivers/codex/wire.js} +0 -0
- /package/src/{server/services/omp-auth-gateway-client.js → platforms/drivers/omp/auth-gateway-client.js} +0 -0
- /package/src/{server/services/opencode-normalization.js → platforms/drivers/opencode/normalization.js} +0 -0
- /package/src/{server/services → shared}/config-artifact-paths.js +0 -0
- /package/src/{server/services/base → shared}/proxy-utils.js +0 -0
|
@@ -2,7 +2,7 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const crypto = require('crypto');
|
|
4
4
|
const { DatabaseSync } = require('node:sqlite');
|
|
5
|
-
const { NATIVE_PATHS, PATHS } = require('
|
|
5
|
+
const { NATIVE_PATHS, PATHS } = require('../../../config/paths');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* OpenCode 会话服务
|
|
@@ -11,14 +11,35 @@ const { NATIVE_PATHS, PATHS } = require('../../config/paths');
|
|
|
11
11
|
|
|
12
12
|
const PROJECT_ORDER_FILE = PATHS.opencodeProjectOrder;
|
|
13
13
|
const SESSION_ORDER_FILE = PATHS.opencodeSessionOrder;
|
|
14
|
-
|
|
15
|
-
const COUNTS_CACHE_TTL_MS = 30 * 1000;
|
|
16
|
-
const EMPTY_COUNTS = Object.freeze({ projectCount: 0, sessionCount: 0 });
|
|
14
|
+
let opencodeDataDirOverride = null;
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
function configure({ pathContext } = {}) {
|
|
17
|
+
opencodeDataDirOverride = pathContext?.customized
|
|
18
|
+
? (pathContext.native?.data || null)
|
|
19
|
+
: null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getOpenCodeDbPath(dataDir = opencodeDataDirOverride || NATIVE_PATHS.opencode.data) {
|
|
23
|
+
const configuredPath = typeof process.env.OPENCODE_DB_PATH === 'string'
|
|
24
|
+
? process.env.OPENCODE_DB_PATH.trim()
|
|
25
|
+
: '';
|
|
26
|
+
if (configuredPath && fs.existsSync(configuredPath)) return configuredPath;
|
|
27
|
+
|
|
28
|
+
const defaultPath = path.join(dataDir, 'opencode.db');
|
|
29
|
+
if (fs.existsSync(defaultPath)) return defaultPath;
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
return fs.readdirSync(dataDir, { withFileTypes: true })
|
|
33
|
+
.filter(entry => entry.isFile() && /^opencode-.*\.db$/.test(entry.name))
|
|
34
|
+
.map(entry => {
|
|
35
|
+
const filePath = path.join(dataDir, entry.name);
|
|
36
|
+
return { filePath, mtimeMs: fs.statSync(filePath).mtimeMs };
|
|
37
|
+
})
|
|
38
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs)[0]?.filePath || defaultPath;
|
|
39
|
+
} catch (_) {
|
|
40
|
+
return defaultPath;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
22
43
|
|
|
23
44
|
function ensureParentDir(filePath) {
|
|
24
45
|
const dir = path.dirname(filePath);
|
|
@@ -71,6 +92,48 @@ function parseJsonMaybe(raw, fallback = null) {
|
|
|
71
92
|
}
|
|
72
93
|
}
|
|
73
94
|
|
|
95
|
+
function isAbsolutePath(value) {
|
|
96
|
+
return typeof value === 'string' && (
|
|
97
|
+
path.isAbsolute(value)
|
|
98
|
+
|| /^[a-zA-Z]:[\\/]/.test(value)
|
|
99
|
+
|| value.startsWith('\\\\')
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function getEmbeddedProjectMetadata(directory) {
|
|
104
|
+
if (!isAbsolutePath(directory)) return null;
|
|
105
|
+
|
|
106
|
+
const projectDirectory = path.normalize(directory);
|
|
107
|
+
const projectsDirectory = path.dirname(projectDirectory);
|
|
108
|
+
if (path.basename(projectsDirectory) !== 'projects') return null;
|
|
109
|
+
|
|
110
|
+
const hostDataDirectory = path.dirname(projectsDirectory);
|
|
111
|
+
const hostDatabasePath = path.join(hostDataDirectory, 'app.sqlite');
|
|
112
|
+
if (!fs.existsSync(hostDatabasePath)) return null;
|
|
113
|
+
|
|
114
|
+
let hostDb;
|
|
115
|
+
try {
|
|
116
|
+
hostDb = new DatabaseSync(hostDatabasePath, { readOnly: true, timeout: 1000 });
|
|
117
|
+
const project = hostDb.prepare(
|
|
118
|
+
'SELECT name, metadata_json FROM projects WHERE id = ? LIMIT 1'
|
|
119
|
+
).get(path.basename(projectDirectory));
|
|
120
|
+
if (!project) return null;
|
|
121
|
+
|
|
122
|
+
const metadata = parseJsonMaybe(project.metadata_json, {});
|
|
123
|
+
const linkedDirs = Array.isArray(metadata?.linkedDirs) ? metadata.linkedDirs : [];
|
|
124
|
+
const fullPath = linkedDirs.find(isAbsolutePath) || '';
|
|
125
|
+
const displayName = typeof project.name === 'string' && project.name.trim()
|
|
126
|
+
? project.name.trim()
|
|
127
|
+
: (fullPath ? path.basename(fullPath) : path.basename(projectDirectory));
|
|
128
|
+
|
|
129
|
+
return { displayName, fullPath };
|
|
130
|
+
} catch (_) {
|
|
131
|
+
return null;
|
|
132
|
+
} finally {
|
|
133
|
+
try { hostDb?.close(); } catch (_) {}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
74
137
|
function extractTextContent(content) {
|
|
75
138
|
if (typeof content === 'string') {
|
|
76
139
|
return content;
|
|
@@ -152,7 +215,7 @@ function toIsoTime(input) {
|
|
|
152
215
|
|
|
153
216
|
function _openCodeDb() {
|
|
154
217
|
if (!isOpenCodeInstalled()) return null;
|
|
155
|
-
const db = new DatabaseSync(
|
|
218
|
+
const db = new DatabaseSync(getOpenCodeDbPath(), { readOnly: false, timeout: 5000 });
|
|
156
219
|
db.exec('PRAGMA foreign_keys = ON');
|
|
157
220
|
return db;
|
|
158
221
|
}
|
|
@@ -193,12 +256,9 @@ function buildContext(text, keyword, contextLength = 35) {
|
|
|
193
256
|
|
|
194
257
|
// 检查 OpenCode 是否安装
|
|
195
258
|
function isOpenCodeInstalled() {
|
|
196
|
-
return fs.existsSync(
|
|
259
|
+
return fs.existsSync(getOpenCodeDbPath());
|
|
197
260
|
}
|
|
198
261
|
|
|
199
|
-
function invalidateProjectAndSessionCountsCache() {
|
|
200
|
-
countsCache = { expiresAt: 0, value: EMPTY_COUNTS };
|
|
201
|
-
}
|
|
202
262
|
|
|
203
263
|
// ---------------------------------------------------------------------------
|
|
204
264
|
// Project / session order (file-based)
|
|
@@ -239,6 +299,9 @@ function removeSessionFromOrder(projectId, sessionId) {
|
|
|
239
299
|
|
|
240
300
|
function getProjectDisplayName(project) {
|
|
241
301
|
if (!project) return 'Unknown';
|
|
302
|
+
if (typeof project.name === 'string' && project.name.trim()) {
|
|
303
|
+
return project.name.trim();
|
|
304
|
+
}
|
|
242
305
|
const worktree = project.worktree || '';
|
|
243
306
|
if (worktree) {
|
|
244
307
|
const parsed = parseJsonMaybe(project.data);
|
|
@@ -250,6 +313,14 @@ function getProjectDisplayName(project) {
|
|
|
250
313
|
return project.id || 'Unknown';
|
|
251
314
|
}
|
|
252
315
|
|
|
316
|
+
function getDisplayNameForPath(projectPath, fallback) {
|
|
317
|
+
if (typeof projectPath === 'string' && projectPath.trim() && projectPath !== '/') {
|
|
318
|
+
const name = path.basename(projectPath);
|
|
319
|
+
if (name) return name;
|
|
320
|
+
}
|
|
321
|
+
return fallback;
|
|
322
|
+
}
|
|
323
|
+
|
|
253
324
|
function getSessionLocation(sessionId) {
|
|
254
325
|
const row = getSessionRowById(sessionId);
|
|
255
326
|
if (!row) return null;
|
|
@@ -260,24 +331,15 @@ function getSessionLocation(sessionId) {
|
|
|
260
331
|
// Database query functions (parameterized)
|
|
261
332
|
// ---------------------------------------------------------------------------
|
|
262
333
|
|
|
263
|
-
function queryProjectAndSessionCounts() {
|
|
264
|
-
const rows = _query(`
|
|
265
|
-
SELECT
|
|
266
|
-
(SELECT COUNT(*) FROM project) AS project_count,
|
|
267
|
-
(SELECT COUNT(*) FROM session WHERE time_archived IS NULL) AS session_count
|
|
268
|
-
`);
|
|
269
|
-
return rows.length > 0 ? rows[0] : { project_count: 0, session_count: 0 };
|
|
270
|
-
}
|
|
271
334
|
|
|
272
335
|
function getProjectRows() {
|
|
273
336
|
return _query(`
|
|
274
337
|
SELECT
|
|
275
|
-
p
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
p.time_archived
|
|
280
|
-
p.data
|
|
338
|
+
p.*,
|
|
339
|
+
(SELECT s.directory FROM session s
|
|
340
|
+
WHERE s.project_id = p.id AND s.time_archived IS NULL
|
|
341
|
+
ORDER BY s.time_updated DESC LIMIT 1) AS session_directory,
|
|
342
|
+
(SELECT COUNT(*) FROM session s WHERE s.project_id = p.id AND s.time_archived IS NULL) AS session_count
|
|
281
343
|
FROM project p
|
|
282
344
|
ORDER BY p.time_updated DESC
|
|
283
345
|
`);
|
|
@@ -303,7 +365,22 @@ function getSessionRowsByProjectId(projectId) {
|
|
|
303
365
|
s.time_created,
|
|
304
366
|
s.time_updated,
|
|
305
367
|
s.time_compacting,
|
|
306
|
-
s.time_archived
|
|
368
|
+
s.time_archived,
|
|
369
|
+
(
|
|
370
|
+
COALESCE((
|
|
371
|
+
SELECT SUM(LENGTH(CAST(m.data AS BLOB)))
|
|
372
|
+
FROM message m
|
|
373
|
+
WHERE m.session_id = s.id
|
|
374
|
+
), 0)
|
|
375
|
+
+ COALESCE((
|
|
376
|
+
SELECT SUM(LENGTH(CAST(p.data AS BLOB)))
|
|
377
|
+
FROM part p
|
|
378
|
+
WHERE p.session_id = s.id
|
|
379
|
+
), 0)
|
|
380
|
+
+ COALESCE(LENGTH(CAST(s.title AS BLOB)), 0)
|
|
381
|
+
+ COALESCE(LENGTH(CAST(s.slug AS BLOB)), 0)
|
|
382
|
+
+ COALESCE(LENGTH(CAST(s.directory AS BLOB)), 0)
|
|
383
|
+
) AS storage_size
|
|
307
384
|
FROM session s
|
|
308
385
|
WHERE s.project_id = ?
|
|
309
386
|
AND s.time_archived IS NULL
|
|
@@ -331,7 +408,22 @@ function getSessionRowById(sessionId) {
|
|
|
331
408
|
s.time_created,
|
|
332
409
|
s.time_updated,
|
|
333
410
|
s.time_compacting,
|
|
334
|
-
s.time_archived
|
|
411
|
+
s.time_archived,
|
|
412
|
+
(
|
|
413
|
+
COALESCE((
|
|
414
|
+
SELECT SUM(LENGTH(CAST(m.data AS BLOB)))
|
|
415
|
+
FROM message m
|
|
416
|
+
WHERE m.session_id = s.id
|
|
417
|
+
), 0)
|
|
418
|
+
+ COALESCE((
|
|
419
|
+
SELECT SUM(LENGTH(CAST(p.data AS BLOB)))
|
|
420
|
+
FROM part p
|
|
421
|
+
WHERE p.session_id = s.id
|
|
422
|
+
), 0)
|
|
423
|
+
+ COALESCE(LENGTH(CAST(s.title AS BLOB)), 0)
|
|
424
|
+
+ COALESCE(LENGTH(CAST(s.slug AS BLOB)), 0)
|
|
425
|
+
+ COALESCE(LENGTH(CAST(s.directory AS BLOB)), 0)
|
|
426
|
+
) AS storage_size
|
|
335
427
|
FROM session s
|
|
336
428
|
WHERE s.id = ?
|
|
337
429
|
LIMIT 1
|
|
@@ -372,7 +464,8 @@ function normalizeSession(session, projectId) {
|
|
|
372
464
|
return {
|
|
373
465
|
sessionId: session.id,
|
|
374
466
|
mtime: toIsoTime(session.time_updated) || new Date().toISOString(),
|
|
375
|
-
|
|
467
|
+
// SQLite has no per-session file, so use the UTF-8 size of its stored payloads.
|
|
468
|
+
size: Number(session.storage_size) || 0,
|
|
376
469
|
filePath: `opencode://${projectId}/${session.id}`,
|
|
377
470
|
gitBranch: null,
|
|
378
471
|
firstMessage: session.title || null,
|
|
@@ -392,15 +485,26 @@ function normalizeSession(session, projectId) {
|
|
|
392
485
|
// ---------------------------------------------------------------------------
|
|
393
486
|
|
|
394
487
|
function getProjects(_options = {}) {
|
|
395
|
-
const projects = getProjectRows().map((project) =>
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
488
|
+
const projects = getProjectRows().map((project) => {
|
|
489
|
+
const fallbackPath = project.worktree && project.worktree !== '/'
|
|
490
|
+
? project.worktree
|
|
491
|
+
: project.session_directory || project.worktree || '/';
|
|
492
|
+
const embeddedProject = getEmbeddedProjectMetadata(fallbackPath);
|
|
493
|
+
const fullPath = embeddedProject?.fullPath || fallbackPath;
|
|
494
|
+
const fallbackDisplayName = embeddedProject?.displayName
|
|
495
|
+
|| getProjectDisplayName({ ...project, worktree: fullPath });
|
|
496
|
+
return {
|
|
497
|
+
name: project.id,
|
|
498
|
+
displayName: embeddedProject?.fullPath
|
|
499
|
+
? getDisplayNameForPath(fullPath, fallbackDisplayName)
|
|
500
|
+
: fallbackDisplayName,
|
|
501
|
+
fullPath,
|
|
502
|
+
path: fullPath,
|
|
503
|
+
sessionCount: Number(project.session_count) || 0,
|
|
504
|
+
lastUsed: toIsoTime(project.time_updated),
|
|
505
|
+
source: 'opencode'
|
|
506
|
+
};
|
|
507
|
+
});
|
|
404
508
|
|
|
405
509
|
const order = getProjectOrder();
|
|
406
510
|
return sortByOrder(projects, order, (a, b) => (b.lastUsed || '').localeCompare(a.lastUsed || ''));
|
|
@@ -446,7 +550,8 @@ function searchSessions(keyword) {
|
|
|
446
550
|
|
|
447
551
|
if (data && data.role === 'user') {
|
|
448
552
|
text = extractTextFromMessageData(data);
|
|
449
|
-
}
|
|
553
|
+
}
|
|
554
|
+
if (!text) {
|
|
450
555
|
const messageParts = partsByMessageId.get(message.id) || [];
|
|
451
556
|
for (const part of messageParts) {
|
|
452
557
|
const partData = parseJsonMaybe(part.data, null);
|
|
@@ -509,7 +614,7 @@ function getSessionById(sessionId) {
|
|
|
509
614
|
return {
|
|
510
615
|
sessionId,
|
|
511
616
|
mtime: toIsoTime(location.sessionData.time_updated) || new Date().toISOString(),
|
|
512
|
-
size: 0,
|
|
617
|
+
size: Number(location.sessionData.storage_size) || 0,
|
|
513
618
|
filePath: `opencode://${location.projectId}/${sessionId}`,
|
|
514
619
|
source: 'opencode',
|
|
515
620
|
directory: location.directory || null,
|
|
@@ -518,6 +623,56 @@ function getSessionById(sessionId) {
|
|
|
518
623
|
};
|
|
519
624
|
}
|
|
520
625
|
|
|
626
|
+
function getSessionStatus(sessionId) {
|
|
627
|
+
const session = getSessionById(sessionId);
|
|
628
|
+
if (!session) return null;
|
|
629
|
+
return {
|
|
630
|
+
sessionId,
|
|
631
|
+
lastModified: Date.parse(session.mtime) || null,
|
|
632
|
+
size: session.size || 0,
|
|
633
|
+
filePath: session.filePath
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
function getSessionMessages(sessionId, options = {}) {
|
|
638
|
+
const session = getSessionById(sessionId);
|
|
639
|
+
if (!session) return null;
|
|
640
|
+
const page = Math.max(1, Number.parseInt(options.page, 10) || 1);
|
|
641
|
+
const limit = Math.max(1, Math.min(200, Number.parseInt(options.limit, 10) || 50));
|
|
642
|
+
const order = String(options.order || 'desc').toLowerCase() === 'asc' ? 'asc' : 'desc';
|
|
643
|
+
const ordered = order === 'asc' ? [...session.messages] : [...session.messages].reverse();
|
|
644
|
+
const offset = (page - 1) * limit;
|
|
645
|
+
return {
|
|
646
|
+
messages: ordered.slice(offset, offset + limit),
|
|
647
|
+
metadata: { sessionId, messageCount: session.messages.length },
|
|
648
|
+
pagination: {
|
|
649
|
+
page,
|
|
650
|
+
limit,
|
|
651
|
+
total: session.messages.length,
|
|
652
|
+
hasMore: offset + limit < session.messages.length
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
function getSessionOutline(sessionId) {
|
|
658
|
+
const session = getSessionById(sessionId);
|
|
659
|
+
if (!session) return null;
|
|
660
|
+
let userMessageNumber = 0;
|
|
661
|
+
return {
|
|
662
|
+
sessionId,
|
|
663
|
+
items: session.messages.flatMap(message => {
|
|
664
|
+
if (message.role !== 'user') return [];
|
|
665
|
+
userMessageNumber += 1;
|
|
666
|
+
const firstLine = String(message.content || '').trim().split(/\r?\n/, 1)[0] || '(空消息)';
|
|
667
|
+
return [{
|
|
668
|
+
userMessageNumber,
|
|
669
|
+
preview: firstLine.length > 42 ? `${firstLine.slice(0, 42)}...` : firstLine,
|
|
670
|
+
timestamp: message.timestamp
|
|
671
|
+
}];
|
|
672
|
+
})
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
|
|
521
676
|
function buildSessionMessages(sessionId) {
|
|
522
677
|
const messages = getMessageRowsBySessionId(sessionId);
|
|
523
678
|
const parts = getPartRowsBySessionId(sessionId);
|
|
@@ -534,9 +689,8 @@ function buildSessionMessages(sessionId) {
|
|
|
534
689
|
const messageParts = partsByMessageId.get(message.id) || [];
|
|
535
690
|
|
|
536
691
|
let content = '';
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
} else if (messageParts.length > 0) {
|
|
692
|
+
content = extractTextFromMessageData(data);
|
|
693
|
+
if (!content && messageParts.length > 0) {
|
|
540
694
|
content = messageParts
|
|
541
695
|
.map(part => {
|
|
542
696
|
const partData = parseJsonMaybe(part.data, null);
|
|
@@ -574,7 +728,7 @@ function deleteSession(sessionId) {
|
|
|
574
728
|
);
|
|
575
729
|
|
|
576
730
|
try {
|
|
577
|
-
const { deleteAlias } = require('
|
|
731
|
+
const { deleteAlias } = require('../../../server/services/alias');
|
|
578
732
|
deleteAlias(sessionId);
|
|
579
733
|
} catch (err) {
|
|
580
734
|
// ignore alias cleanup errors
|
|
@@ -583,7 +737,7 @@ function deleteSession(sessionId) {
|
|
|
583
737
|
removeSessionFromOrder(location.projectId, sessionId);
|
|
584
738
|
|
|
585
739
|
try {
|
|
586
|
-
const { getForkRelations, saveForkRelations } = require('
|
|
740
|
+
const { getForkRelations, saveForkRelations } = require('../claude/sessions-implementation');
|
|
587
741
|
const relations = getForkRelations();
|
|
588
742
|
delete relations[sessionId];
|
|
589
743
|
Object.keys(relations).forEach((key) => {
|
|
@@ -596,7 +750,6 @@ function deleteSession(sessionId) {
|
|
|
596
750
|
// ignore fork relation cleanup errors
|
|
597
751
|
}
|
|
598
752
|
|
|
599
|
-
invalidateProjectAndSessionCountsCache();
|
|
600
753
|
return { success: true, projectName: location.projectId, sessionId };
|
|
601
754
|
}
|
|
602
755
|
|
|
@@ -700,7 +853,7 @@ function forkSession(sessionId) {
|
|
|
700
853
|
}
|
|
701
854
|
|
|
702
855
|
try {
|
|
703
|
-
const { getForkRelations, saveForkRelations } = require('
|
|
856
|
+
const { getForkRelations, saveForkRelations } = require('../claude/sessions-implementation');
|
|
704
857
|
const relations = getForkRelations();
|
|
705
858
|
relations[newSessionId] = sessionId;
|
|
706
859
|
saveForkRelations(relations);
|
|
@@ -708,7 +861,6 @@ function forkSession(sessionId) {
|
|
|
708
861
|
// ignore
|
|
709
862
|
}
|
|
710
863
|
|
|
711
|
-
invalidateProjectAndSessionCountsCache();
|
|
712
864
|
return { success: true, sessionId: newSessionId, forkedFrom: sessionId };
|
|
713
865
|
}
|
|
714
866
|
|
|
@@ -730,7 +882,7 @@ function deleteProject(projectId) {
|
|
|
730
882
|
const deletedSessionIds = sessionRows.map(row => row.id);
|
|
731
883
|
|
|
732
884
|
try {
|
|
733
|
-
const { deleteAlias } = require('
|
|
885
|
+
const { deleteAlias } = require('../../../server/services/alias');
|
|
734
886
|
deletedSessionIds.forEach(id => {
|
|
735
887
|
try { deleteAlias(id); } catch (_) {}
|
|
736
888
|
});
|
|
@@ -739,32 +891,27 @@ function deleteProject(projectId) {
|
|
|
739
891
|
_exec(`DELETE FROM project WHERE id = ?`, projectId);
|
|
740
892
|
|
|
741
893
|
removeProjectFromOrder(projectId);
|
|
742
|
-
invalidateProjectAndSessionCountsCache();
|
|
743
894
|
return { success: true, projectId, deletedSessions: deletedSessionIds.length };
|
|
744
895
|
}
|
|
745
896
|
|
|
746
897
|
function getProjectAndSessionCounts(options = {}) {
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
const row = queryProjectAndSessionCounts();
|
|
754
|
-
const result = {
|
|
755
|
-
projectCount: Number(row.project_count) || 0,
|
|
756
|
-
sessionCount: Number(row.session_count) || 0
|
|
898
|
+
const projects = getProjects(options);
|
|
899
|
+
return {
|
|
900
|
+
projectCount: projects.length,
|
|
901
|
+
sessionCount: projects.reduce((sum, project) => sum + project.sessionCount, 0)
|
|
757
902
|
};
|
|
758
|
-
|
|
759
|
-
countsCache = { expiresAt: Date.now() + COUNTS_CACHE_TTL_MS, value: result };
|
|
760
|
-
return result;
|
|
761
903
|
}
|
|
762
904
|
|
|
763
905
|
module.exports = {
|
|
906
|
+
configure,
|
|
907
|
+
getOpenCodeDbPath,
|
|
764
908
|
isOpenCodeInstalled,
|
|
765
909
|
getProjects,
|
|
766
910
|
getSessionsByProjectId,
|
|
767
911
|
getSessionById,
|
|
912
|
+
getSessionStatus,
|
|
913
|
+
getSessionMessages,
|
|
914
|
+
getSessionOutline,
|
|
768
915
|
searchSessions,
|
|
769
916
|
getRecentSessions,
|
|
770
917
|
deleteSession,
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { createCapabilityDriver } = require('../../../shared/capability-driver');
|
|
4
|
+
|
|
5
|
+
function createDriver(context = {}) {
|
|
6
|
+
return createCapabilityDriver({
|
|
7
|
+
...context,
|
|
8
|
+
platform: 'opencode',
|
|
9
|
+
capability: 'sessions',
|
|
10
|
+
servicePath: './opencode/sessions-implementation',
|
|
11
|
+
localServicePath: '../platforms/drivers/opencode/sessions-implementation',
|
|
12
|
+
methods: {
|
|
13
|
+
getProjects: 'getProjects',
|
|
14
|
+
recent: 'getRecentSessions',
|
|
15
|
+
search: 'searchSessions',
|
|
16
|
+
getSessionById: 'getSessionById',
|
|
17
|
+
delete: 'deleteSession',
|
|
18
|
+
fork: 'forkSession',
|
|
19
|
+
saveSessionOrder: 'saveSessionOrder',
|
|
20
|
+
status: 'getSessionStatus',
|
|
21
|
+
outline: 'getSessionOutline',
|
|
22
|
+
isAvailable: 'isOpenCodeInstalled'
|
|
23
|
+
},
|
|
24
|
+
customMethods: {
|
|
25
|
+
listSessions: (service, ...args) => {
|
|
26
|
+
const method = service.getSessionsByProjectId || service.getSessionsByProject;
|
|
27
|
+
if (typeof method !== 'function') return undefined;
|
|
28
|
+
return method.apply(service, args);
|
|
29
|
+
},
|
|
30
|
+
messages: (service, sessionId, options) => {
|
|
31
|
+
if (typeof service.getSessionMessages === 'function') {
|
|
32
|
+
return service.getSessionMessages(sessionId, options);
|
|
33
|
+
}
|
|
34
|
+
const session = typeof service.getSessionById === 'function'
|
|
35
|
+
? service.getSessionById(sessionId)
|
|
36
|
+
: null;
|
|
37
|
+
return session?.messages || [];
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
onSuccess: operation => {
|
|
41
|
+
if (['delete', 'fork', 'saveSessionOrder'].includes(operation)) {
|
|
42
|
+
context.sessionHistoryIndex?.invalidateSource('opencode');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = { createDriver };
|
|
@@ -3,8 +3,8 @@ const {
|
|
|
3
3
|
getStatistics: getSharedStatistics,
|
|
4
4
|
getDailyStatistics: getSharedDailyStatistics,
|
|
5
5
|
getTodayStatistics: getSharedTodayStatistics
|
|
6
|
-
} = require('
|
|
7
|
-
const { normalizeUsageTokens, toNumber } = require('
|
|
6
|
+
} = require('../../../server/services/statistics-service');
|
|
7
|
+
const { normalizeUsageTokens, toNumber } = require('../../../server/services/usage-log-utils');
|
|
8
8
|
|
|
9
9
|
const TOOL_TYPE = 'opencode';
|
|
10
10
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { createCapabilityDriver } = require('../../../shared/capability-driver');
|
|
4
|
+
|
|
5
|
+
function createDriver(context = {}) {
|
|
6
|
+
return createCapabilityDriver({
|
|
7
|
+
...context,
|
|
8
|
+
platform: 'opencode',
|
|
9
|
+
capability: 'statistics',
|
|
10
|
+
servicePath: './opencode/statistics-implementation',
|
|
11
|
+
localServicePath: '../opencode/statistics-implementation',
|
|
12
|
+
methods: {"getStatistics":"getStatistics","getDailyStatistics":"getDailyStatistics","getTodayStatistics":"getTodayStatistics","recordRequest":"recordRequest","resetStatistics":"resetStatistics"}
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = { createDriver };
|