@toddzheng024/dscode-desktop 0.0.0-stage → 0.7.34
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/LICENSE +21 -0
- package/README.md +120 -2
- package/THIRD_PARTY_NOTICES.md +30 -0
- package/bin/apply_patch +9 -0
- package/cordis.patch.yml +433 -0
- package/docs/CHANGELOG.md +649 -0
- package/docs/account-login.md +44 -0
- package/docs/auto-review.md +128 -0
- package/docs/browser-use.md +784 -0
- package/docs/computer-use.md +81 -0
- package/docs/custom-providers.md +88 -0
- package/docs/demo.md +158 -0
- package/docs/distribution.md +58 -0
- package/docs/dscode-ultra.md +75 -0
- package/docs/email.md +296 -0
- package/docs/exec.md +40 -0
- package/docs/hub-distribution.md +212 -0
- package/docs/memory.md +121 -0
- package/docs/opencode-go.md +61 -0
- package/docs/plugin-hub.md +68 -0
- package/docs/releases/0.2.0.md +28 -0
- package/docs/releases/0.3.0.md +21 -0
- package/docs/releases/0.4.0.md +20 -0
- package/docs/releases/0.5.0.md +19 -0
- package/docs/releases/0.6.0.md +20 -0
- package/docs/releases/0.7.0.md +22 -0
- package/docs/releases/0.7.1.md +20 -0
- package/docs/releases/0.7.10.md +10 -0
- package/docs/releases/0.7.11.md +17 -0
- package/docs/releases/0.7.12.md +11 -0
- package/docs/releases/0.7.13.md +12 -0
- package/docs/releases/0.7.14.md +11 -0
- package/docs/releases/0.7.15.md +11 -0
- package/docs/releases/0.7.16.md +10 -0
- package/docs/releases/0.7.17.md +12 -0
- package/docs/releases/0.7.18.md +13 -0
- package/docs/releases/0.7.19.md +8 -0
- package/docs/releases/0.7.2.md +19 -0
- package/docs/releases/0.7.20.md +10 -0
- package/docs/releases/0.7.21.md +9 -0
- package/docs/releases/0.7.22.md +11 -0
- package/docs/releases/0.7.23.md +14 -0
- package/docs/releases/0.7.24.md +11 -0
- package/docs/releases/0.7.25.md +8 -0
- package/docs/releases/0.7.26.md +18 -0
- package/docs/releases/0.7.27.md +8 -0
- package/docs/releases/0.7.28.md +22 -0
- package/docs/releases/0.7.29.md +12 -0
- package/docs/releases/0.7.3.md +23 -0
- package/docs/releases/0.7.30.md +19 -0
- package/docs/releases/0.7.31.md +14 -0
- package/docs/releases/0.7.32.md +14 -0
- package/docs/releases/0.7.33.md +37 -0
- package/docs/releases/0.7.34.md +24 -0
- package/docs/releases/0.7.4.md +16 -0
- package/docs/releases/0.7.5.md +18 -0
- package/docs/releases/0.7.6.md +29 -0
- package/docs/releases/0.7.7.md +36 -0
- package/docs/releases/0.7.8.md +14 -0
- package/docs/releases/0.7.9.md +15 -0
- package/docs/session-bridge.md +80 -0
- package/docs/session-cards.md +53 -0
- package/docs/session-communication.md +186 -0
- package/docs/session-metrics.md +41 -0
- package/docs/skills.md +81 -0
- package/docs/triggers.md +338 -0
- package/docs/tui-commands.md +204 -0
- package/extensions/browser/manifest.json +22 -0
- package/extensions/browser/popup.css +6 -0
- package/extensions/browser/popup.html +11 -0
- package/extensions/browser/popup.mjs +47 -0
- package/extensions/browser/protocol.mjs +168 -0
- package/extensions/browser/worker.mjs +94 -0
- package/icon.svg +7 -0
- package/locale/en.json +6 -0
- package/locale/zh-cn.json +6 -0
- package/node_modules/@deepseek-ai/node-addon-system/LICENSE +21 -0
- package/node_modules/@deepseek-ai/node-addon-system/README.i18n.yaml +6 -0
- package/node_modules/@deepseek-ai/node-addon-system/README.md +15 -0
- package/node_modules/@deepseek-ai/node-addon-system/README.zh.md +15 -0
- package/node_modules/@deepseek-ai/node-addon-system/lib/flock.d.ts +13 -0
- package/node_modules/@deepseek-ai/node-addon-system/lib/flock.js +51 -0
- package/node_modules/@deepseek-ai/node-addon-system/lib/index.d.ts +73 -0
- package/node_modules/@deepseek-ai/node-addon-system/lib/index.js +98 -0
- package/node_modules/@deepseek-ai/node-addon-system/package.json +45 -0
- package/node_modules/@deepseek-ai/node-addon-system/src/flock.c +164 -0
- package/node_modules/@deepseek-ai/node-addon-system/src/main.c +298 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-arm64/LICENSE +28 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-arm64/README.i18n.yaml +6 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-arm64/README.md +9 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-arm64/README.zh.md +9 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-arm64/bin/system.node +0 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-arm64/package.json +31 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-arm64/prebuilds.json +6 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-x64/LICENSE +28 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-x64/README.i18n.yaml +6 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-x64/README.md +9 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-x64/README.zh.md +9 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-x64/bin/system.node +0 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-x64/package.json +31 -0
- package/node_modules/@deepseek-ai/node-addon-system-darwin-x64/prebuilds.json +6 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-arm64/LICENSE +28 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-arm64/README.i18n.yaml +6 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-arm64/README.md +11 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-arm64/README.zh.md +11 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-arm64/bin/glibc/system.node +0 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-arm64/bin/landlock-run +0 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-arm64/bin/musl/system.node +0 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-arm64/package.json +31 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-arm64/prebuilds.json +24 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-x64/LICENSE +28 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-x64/README.i18n.yaml +6 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-x64/README.md +11 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-x64/README.zh.md +11 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-x64/bin/glibc/system.node +0 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-x64/bin/landlock-run +0 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-x64/bin/musl/system.node +0 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-x64/package.json +31 -0
- package/node_modules/@deepseek-ai/node-addon-system-linux-x64/prebuilds.json +24 -0
- package/package.json +156 -4
- package/plugins/account/index.mjs +178 -0
- package/plugins/account/state.mjs +123 -0
- package/plugins/auto-review/audit.mjs +24 -0
- package/plugins/auto-review/index.mjs +267 -0
- package/plugins/auto-review/policy.mjs +92 -0
- package/plugins/browser/SKILL.md +158 -0
- package/plugins/browser/access.mjs +143 -0
- package/plugins/browser/config.mjs +60 -0
- package/plugins/browser/connection.mjs +385 -0
- package/plugins/browser/desktop-client.mjs +282 -0
- package/plugins/browser/desktop-host.mjs +74 -0
- package/plugins/browser/document-identity.mjs +57 -0
- package/plugins/browser/extension-relay.mjs +66 -0
- package/plugins/browser/files.mjs +32 -0
- package/plugins/browser/index.mjs +235 -0
- package/plugins/browser/mcp-entry.mjs +18 -0
- package/plugins/browser/mcp-tools.mjs +21 -0
- package/plugins/browser/presentation.mjs +45 -0
- package/plugins/browser/preview.mjs +77 -0
- package/plugins/browser/review.mjs +20 -0
- package/plugins/browser/screenshots.mjs +35 -0
- package/plugins/clipboard-image/clipboard-image.swift +56 -0
- package/plugins/clipboard-image/index.mjs +70 -0
- package/plugins/code-review/baseline.mjs +143 -0
- package/plugins/code-review/git.mjs +163 -0
- package/plugins/code-review/index.mjs +236 -0
- package/plugins/compaction/engine.mjs +304 -0
- package/plugins/compaction/tetris.mjs +65 -0
- package/plugins/compaction/threshold.mjs +99 -0
- package/plugins/computer-use/DESKTOP-SKILL.md +64 -0
- package/plugins/computer-use/desktop-host.mjs +75 -0
- package/plugins/computer-use/desktop-skill.mjs +28 -0
- package/plugins/computer-use/desktop-upstream.mjs +3 -0
- package/plugins/computer-use/index.mjs +37 -0
- package/plugins/cordis-config/plain.mjs +31 -0
- package/plugins/credentials/index.mjs +73 -0
- package/plugins/custom/adapter.mjs +110 -0
- package/plugins/custom/config.mjs +85 -0
- package/plugins/custom/desktop-client.mjs +150 -0
- package/plugins/custom/desktop-host.mjs +78 -0
- package/plugins/custom/images.mjs +32 -0
- package/plugins/custom/index.mjs +145 -0
- package/plugins/custom/wire.mjs +179 -0
- package/plugins/desktop/client.mjs +1041 -0
- package/plugins/desktop/index.mjs +10 -0
- package/plugins/desktop/shell-environment.mjs +9 -0
- package/plugins/desktop-workspace/hooks.mjs +29 -0
- package/plugins/desktop-workspace/index.mjs +37 -0
- package/plugins/dscode/board.mjs +260 -0
- package/plugins/dscode/child-target.mjs +11 -0
- package/plugins/dscode/control.mjs +17 -0
- package/plugins/dscode/desktop-client.mjs +55 -0
- package/plugins/dscode/desktop-host.mjs +37 -0
- package/plugins/dscode/index.mjs +270 -0
- package/plugins/email/cli.mjs +32 -0
- package/plugins/email/contacts.mjs +36 -0
- package/plugins/email/desktop-client.mjs +117 -0
- package/plugins/email/desktop-host.mjs +54 -0
- package/plugins/email/desktop-service.mjs +106 -0
- package/plugins/email/gmail-oauth.mjs +69 -0
- package/plugins/email/gmail-store.mjs +2 -0
- package/plugins/email/gmail.mjs +194 -0
- package/plugins/email/imap.mjs +136 -0
- package/plugins/email/inbox.d.mts +25 -0
- package/plugins/email/inbox.mjs +76 -0
- package/plugins/email/smtp.mjs +70 -0
- package/plugins/email/store.mjs +32 -0
- package/plugins/email-tools/index.mjs +46 -0
- package/plugins/exec/cli.mjs +64 -0
- package/plugins/exec/index.mjs +112 -0
- package/plugins/grok/adapter.mjs +114 -0
- package/plugins/grok/auth.mjs +76 -0
- package/plugins/grok/billing.mjs +147 -0
- package/plugins/grok/index.mjs +123 -0
- package/plugins/grok/models.mjs +129 -0
- package/plugins/grok/status.mjs +29 -0
- package/plugins/grok/wire.mjs +268 -0
- package/plugins/hub/catalog.mjs +82 -0
- package/plugins/hub/desktop-client.mjs +114 -0
- package/plugins/hub/desktop-host.mjs +129 -0
- package/plugins/i18n/messages.d.mts +21 -0
- package/plugins/i18n/messages.mjs +537 -0
- package/plugins/jev/approval.mjs +131 -0
- package/plugins/jev/client.mjs +74 -0
- package/plugins/jev/index.mjs +100 -0
- package/plugins/memory/content.mjs +57 -0
- package/plugins/memory/desktop-host.mjs +3 -0
- package/plugins/memory/index.mjs +168 -0
- package/plugins/memory/pipeline.mjs +79 -0
- package/plugins/memory/store.mjs +93 -0
- package/plugins/message-source/kind.mjs +20 -0
- package/plugins/opencode-go/adapter.mjs +96 -0
- package/plugins/opencode-go/command.mjs +128 -0
- package/plugins/opencode-go/index.mjs +121 -0
- package/plugins/opencode-go/models.mjs +58 -0
- package/plugins/opencode-go/oauth.mjs +194 -0
- package/plugins/opencode-go/search.mjs +86 -0
- package/plugins/opencode-go/usage.mjs +120 -0
- package/plugins/opencode-go/version.mjs +10 -0
- package/plugins/opencode-go/wire.mjs +73 -0
- package/plugins/openrouter/adapter.mjs +232 -0
- package/plugins/openrouter/index.mjs +124 -0
- package/plugins/openrouter/models.mjs +157 -0
- package/plugins/openrouter/search.mjs +113 -0
- package/plugins/openrouter/wire.mjs +101 -0
- package/plugins/providers/catalog.mjs +160 -0
- package/plugins/providers/chat-messages.mjs +120 -0
- package/plugins/providers/chat-stream.mjs +174 -0
- package/plugins/providers/desktop-client.mjs +84 -0
- package/plugins/providers/desktop-host.mjs +63 -0
- package/plugins/providers/effort.mjs +35 -0
- package/plugins/providers/http-errors.mjs +50 -0
- package/plugins/providers/openrouter-account.mjs +171 -0
- package/plugins/session-bridge/client.mjs +106 -0
- package/plugins/session-bridge/communication.mjs +260 -0
- package/plugins/session-bridge/index.mjs +67 -0
- package/plugins/session-bridge/mailbox.mjs +267 -0
- package/plugins/session-bridge/paths.mjs +21 -0
- package/plugins/session-bridge/server.mjs +172 -0
- package/plugins/session-bridge/tasks.mjs +229 -0
- package/plugins/session-cards/content.mjs +64 -0
- package/plugins/session-cards/index.mjs +38 -0
- package/plugins/session-cards/manager.mjs +140 -0
- package/plugins/session-metrics/attribution.mjs +30 -0
- package/plugins/session-metrics/balance.mjs +81 -0
- package/plugins/session-metrics/desktop-client.mjs +62 -0
- package/plugins/session-metrics/desktop-host.mjs +46 -0
- package/plugins/session-metrics/index.mjs +97 -0
- package/plugins/session-metrics/pricing.mjs +84 -0
- package/plugins/session-metrics/rate.mjs +59 -0
- package/plugins/session-metrics/store.mjs +75 -0
- package/plugins/session-metrics/turns.mjs +134 -0
- package/plugins/session-metrics/view.mjs +272 -0
- package/plugins/time-marks/desktop-host.mjs +2 -0
- package/plugins/time-marks/index.mjs +116 -0
- package/plugins/time-marks/marks.mjs +152 -0
- package/plugins/triggers/cli.mjs +558 -0
- package/plugins/triggers/commands.mjs +143 -0
- package/plugins/triggers/config.mjs +264 -0
- package/plugins/triggers/desktop-client.mjs +155 -0
- package/plugins/triggers/desktop-host.mjs +88 -0
- package/plugins/triggers/desktop-management.mjs +97 -0
- package/plugins/triggers/desktop-scheduler.mjs +125 -0
- package/plugins/triggers/host.mjs +24 -0
- package/plugins/triggers/index.mjs +27 -0
- package/plugins/triggers/job-cli.mjs +110 -0
- package/plugins/triggers/jobs.mjs +156 -0
- package/plugins/triggers/launchd.mjs +101 -0
- package/plugins/triggers/lease.mjs +24 -0
- package/plugins/triggers/log.mjs +104 -0
- package/plugins/triggers/management.mjs +181 -0
- package/plugins/triggers/options.mjs +117 -0
- package/plugins/triggers/overlay.mjs +7 -0
- package/plugins/triggers/poll.mjs +65 -0
- package/plugins/triggers/run.mjs +157 -0
- package/plugins/triggers/schedule.mjs +40 -0
- package/plugins/triggers/scheduler-service.mjs +46 -0
- package/plugins/triggers/scheduler.mjs +92 -0
- package/plugins/triggers/session-run.mjs +125 -0
- package/plugins/triggers/session.mjs +48 -0
- package/plugins/triggers/source-emit.mjs +19 -0
- package/plugins/triggers/source-host.mjs +78 -0
- package/plugins/triggers/source-ingress.mjs +70 -0
- package/plugins/triggers/source-sandbox.mjs +35 -0
- package/plugins/triggers/sources.mjs +45 -0
- package/plugins/triggers/spool.mjs +145 -0
- package/plugins/triggers/tools.mjs +67 -0
- package/plugins/triggers/unattended.mjs +18 -0
- package/plugins/tui-tools/composition.mjs +28 -0
- package/plugins/tui-tools/desktop-host.mjs +2 -0
- package/plugins/tui-tools/doctor-cli.mjs +22 -0
- package/plugins/tui-tools/doctor.mjs +149 -0
- package/plugins/tui-tools/hook-sources.mjs +113 -0
- package/plugins/tui-tools/hooks.mjs +23 -0
- package/plugins/tui-tools/index.mjs +269 -0
- package/plugins/tui-tools/sandbox-runner.mjs +123 -0
- package/plugins/tui-tools/shell.mjs +27 -0
- package/plugins/tui-tools/update.mjs +111 -0
- package/plugins/tui-tools/workspace-discovery.mjs +129 -0
- package/plugins/ultra/policy.mjs +42 -0
- package/plugins/worktree-subagent/worktree.mjs +56 -0
- package/runtime-sources.json +94 -0
- package/vendor/bash/LICENSE +21 -0
- package/vendor/bash/index.js +717 -0
- package/vendor/bash/types/background.d.ts +50 -0
- package/vendor/bash/types/index.d.ts +38 -0
- package/vendor/bash/types/render.d.ts +57 -0
- package/vendor/command-goal/LICENSE +21 -0
- package/vendor/command-goal/index.js +210 -0
- package/vendor/command-goal/types/index.d.ts +10 -0
- package/vendor/computer-use/LICENSE +21 -0
- package/vendor/computer-use/lib/approval-policy.js +12 -0
- package/vendor/computer-use/lib/approval-policy.js.map +1 -0
- package/vendor/computer-use/lib/artifacts.js +79 -0
- package/vendor/computer-use/lib/artifacts.js.map +1 -0
- package/vendor/computer-use/lib/backend.js +3 -0
- package/vendor/computer-use/lib/backend.js.map +1 -0
- package/vendor/computer-use/lib/client.js +369 -0
- package/vendor/computer-use/lib/client.js.map +1 -0
- package/vendor/computer-use/lib/config.js +159 -0
- package/vendor/computer-use/lib/config.js.map +1 -0
- package/vendor/computer-use/lib/confirmations.js +99 -0
- package/vendor/computer-use/lib/confirmations.js.map +1 -0
- package/vendor/computer-use/lib/diff.js +58 -0
- package/vendor/computer-use/lib/diff.js.map +1 -0
- package/vendor/computer-use/lib/errors.js +22 -0
- package/vendor/computer-use/lib/errors.js.map +1 -0
- package/vendor/computer-use/lib/exposure.js +244 -0
- package/vendor/computer-use/lib/exposure.js.map +1 -0
- package/vendor/computer-use/lib/index.js +66 -0
- package/vendor/computer-use/lib/index.js.map +1 -0
- package/vendor/computer-use/lib/leases.js +262 -0
- package/vendor/computer-use/lib/leases.js.map +1 -0
- package/vendor/computer-use/lib/providers/macos.js +243 -0
- package/vendor/computer-use/lib/providers/macos.js.map +1 -0
- package/vendor/computer-use/lib/providers/native-helper.js +726 -0
- package/vendor/computer-use/lib/providers/native-helper.js.map +1 -0
- package/vendor/computer-use/lib/providers/unsupported.js +51 -0
- package/vendor/computer-use/lib/providers/unsupported.js.map +1 -0
- package/vendor/computer-use/lib/service.js +608 -0
- package/vendor/computer-use/lib/service.js.map +1 -0
- package/vendor/computer-use/lib/skill.js +136 -0
- package/vendor/computer-use/lib/skill.js.map +1 -0
- package/vendor/computer-use/lib/target-resolver.js +180 -0
- package/vendor/computer-use/lib/target-resolver.js.map +1 -0
- package/vendor/computer-use/lib/tools.js +511 -0
- package/vendor/computer-use/lib/tools.js.map +1 -0
- package/vendor/computer-use/lib/types/approval-policy.d.ts +13 -0
- package/vendor/computer-use/lib/types/approval-policy.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/artifacts.d.ts +10 -0
- package/vendor/computer-use/lib/types/artifacts.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/backend.d.ts +124 -0
- package/vendor/computer-use/lib/types/backend.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/client/index.d.ts +83 -0
- package/vendor/computer-use/lib/types/client/index.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/config.d.ts +94 -0
- package/vendor/computer-use/lib/types/config.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/confirmations.d.ts +23 -0
- package/vendor/computer-use/lib/types/confirmations.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/diff.d.ts +5 -0
- package/vendor/computer-use/lib/types/diff.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/errors.d.ts +15 -0
- package/vendor/computer-use/lib/types/errors.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/exposure.d.ts +30 -0
- package/vendor/computer-use/lib/types/exposure.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/index.d.ts +21 -0
- package/vendor/computer-use/lib/types/index.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/leases.d.ts +81 -0
- package/vendor/computer-use/lib/types/leases.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/providers/macos.d.ts +39 -0
- package/vendor/computer-use/lib/types/providers/macos.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/providers/native-helper.d.ts +48 -0
- package/vendor/computer-use/lib/types/providers/native-helper.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/providers/unsupported.d.ts +23 -0
- package/vendor/computer-use/lib/types/providers/unsupported.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/service.d.ts +58 -0
- package/vendor/computer-use/lib/types/service.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/skill.d.ts +14 -0
- package/vendor/computer-use/lib/types/skill.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/target-resolver.d.ts +38 -0
- package/vendor/computer-use/lib/types/target-resolver.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/tools.d.ts +6 -0
- package/vendor/computer-use/lib/types/tools.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/types.d.ts +270 -0
- package/vendor/computer-use/lib/types/types.d.ts.map +1 -0
- package/vendor/computer-use/lib/types/web.d.ts +33 -0
- package/vendor/computer-use/lib/types/web.d.ts.map +1 -0
- package/vendor/computer-use/lib/types.js +9 -0
- package/vendor/computer-use/lib/types.js.map +1 -0
- package/vendor/computer-use/lib/web.js +188 -0
- package/vendor/computer-use/lib/web.js.map +1 -0
- package/vendor/computer-use/native/macos/Sources/Fixture/main.swift +412 -0
- package/vendor/computer-use/native/macos/Sources/Helper/CursorImage.swift +11 -0
- package/vendor/computer-use/native/macos/Sources/Helper/CursorMotion.swift +67 -0
- package/vendor/computer-use/native/macos/Sources/Helper/CursorOverlay.swift +840 -0
- package/vendor/computer-use/native/macos/Sources/Helper/TargetedPointer.swift +327 -0
- package/vendor/computer-use/native/macos/Sources/Helper/WindowNumberMatcher.swift +29 -0
- package/vendor/computer-use/native/macos/Sources/Helper/main.swift +1244 -0
- package/vendor/computer-use/native/macos/Sources/Monitor/main.swift +153 -0
- package/vendor/computer-use/native/macos/bin/dsh-computer-use-helper +0 -0
- package/vendor/computer-use/native/macos/manifest.json +14 -0
- package/vendor/persistent/LICENSE +21 -0
- package/vendor/persistent/index.js +411 -0
- package/vendor/persistent/types/index.d.ts +24 -0
- package/vendor/subagent/LICENSE +21 -0
- package/vendor/subagent/index.js +694 -0
- package/vendor/subagent/invariant.js +52 -0
- package/vendor/subagent/model-selection-settings.js +68 -0
- package/vendor/subagent/types/index.d.ts +82 -0
- package/vendor/subagent/types/invariant.d.ts +16 -0
- package/vendor/subagent/types/list-models.d.ts +10 -0
- package/vendor/subagent/types/model-selection-settings.d.ts +45 -0
- package/vendor/subagent/types/model-selection-state.d.ts +48 -0
- package/vendor/subagent/types/model-selection.d.ts +81 -0
- package/vendor/subagent-core/LICENSE +21 -0
- package/vendor/subagent-core/index.js +3202 -0
- package/vendor/subagent-core/invariant.js +76 -0
- package/vendor/subagent-core/typert.host.d.ts +3 -0
- package/vendor/subagent-core/typert.host.js +978 -0
- package/vendor/subagent-core/typert.remote-client.d.ts +25 -0
- package/vendor/subagent-core/typert.remote-client.js +114 -0
- package/vendor/subagent-core/types/archive-admission.d.ts +16 -0
- package/vendor/subagent-core/types/archive-admission.js +151 -0
- package/vendor/subagent-core/types/assistant-output.d.ts +48 -0
- package/vendor/subagent-core/types/assistant-output.js +73 -0
- package/vendor/subagent-core/types/catalog.d.ts +84 -0
- package/vendor/subagent-core/types/catalog.js +109 -0
- package/vendor/subagent-core/types/child-agent.d.ts +156 -0
- package/vendor/subagent-core/types/child-agent.js +213 -0
- package/vendor/subagent-core/types/client.d.ts +8 -0
- package/vendor/subagent-core/types/client.js +7 -0
- package/vendor/subagent-core/types/continuation-activation.d.ts +267 -0
- package/vendor/subagent-core/types/continuation-activation.js +700 -0
- package/vendor/subagent-core/types/continuation-messages.d.ts +62 -0
- package/vendor/subagent-core/types/continuation-messages.js +106 -0
- package/vendor/subagent-core/types/continuation.d.ts +124 -0
- package/vendor/subagent-core/types/continuation.js +455 -0
- package/vendor/subagent-core/types/control-types.d.ts +135 -0
- package/vendor/subagent-core/types/control-types.js +8 -0
- package/vendor/subagent-core/types/control.d.ts +45 -0
- package/vendor/subagent-core/types/control.js +79 -0
- package/vendor/subagent-core/types/depth.d.ts +31 -0
- package/vendor/subagent-core/types/depth.js +39 -0
- package/vendor/subagent-core/types/descriptor.d.ts +144 -0
- package/vendor/subagent-core/types/descriptor.js +193 -0
- package/vendor/subagent-core/types/error.d.ts +11 -0
- package/vendor/subagent-core/types/error.js +14 -0
- package/vendor/subagent-core/types/inbox.d.ts +43 -0
- package/vendor/subagent-core/types/inbox.js +61 -0
- package/vendor/subagent-core/types/index.d.ts +320 -0
- package/vendor/subagent-core/types/index.js +475 -0
- package/vendor/subagent-core/types/internal.d.ts +58 -0
- package/vendor/subagent-core/types/internal.js +58 -0
- package/vendor/subagent-core/types/invariant.d.ts +13 -0
- package/vendor/subagent-core/types/invariant.js +91 -0
- package/vendor/subagent-core/types/lifecycle.d.ts +113 -0
- package/vendor/subagent-core/types/lifecycle.js +180 -0
- package/vendor/subagent-core/types/list-children.d.ts +36 -0
- package/vendor/subagent-core/types/list-children.js +166 -0
- package/vendor/subagent-core/types/out-of-process.d.ts +118 -0
- package/vendor/subagent-core/types/out-of-process.js +219 -0
- package/vendor/subagent-core/types/projection-types.d.ts +82 -0
- package/vendor/subagent-core/types/projection-types.js +7 -0
- package/vendor/subagent-core/types/projection.d.ts +100 -0
- package/vendor/subagent-core/types/projection.js +157 -0
- package/vendor/subagent-core/types/run-settlement.d.ts +17 -0
- package/vendor/subagent-core/types/run-settlement.js +70 -0
- package/vendor/subagent-core/types/types.d.ts +377 -0
- package/vendor/subagent-core/types/types.js +19 -0
- package/vendor/subagent-driver/LICENSE +21 -0
- package/vendor/subagent-driver/index.js +255 -0
- package/vendor/subagent-driver/types/index.d.ts +33 -0
- package/vendor/subagent-driver/types/structured.d.ts +42 -0
- package/vendor/subagent-fork/LICENSE +21 -0
- package/vendor/subagent-fork/index.js +61 -0
- package/vendor/subagent-fork/types/index.d.ts +20 -0
- package/vendor/subagent-spawn/LICENSE +21 -0
- package/vendor/subagent-spawn/index.js +45 -0
- package/vendor/subagent-spawn/types/index.d.ts +19 -0
- package/vendor/terminal/LICENSE +21 -0
- package/vendor/terminal/index.js +1093 -0
- package/vendor/terminal/types/config.d.ts +82 -0
- package/vendor/terminal/types/index.d.ts +36 -0
- package/vendor/terminal/types/sanitize.d.ts +47 -0
- package/vendor/terminal/types/session.d.ts +87 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
import { mkdirSync, writeFileSync, renameSync, rmSync, chmodSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import { digest, redact } from './content.mjs';
|
|
6
|
+
|
|
7
|
+
export class MemoryStore {
|
|
8
|
+
constructor(root) {
|
|
9
|
+
this.root = root;
|
|
10
|
+
mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
11
|
+
this.db = new DatabaseSync(join(root, 'state.sqlite'));
|
|
12
|
+
chmodSync(join(root, 'state.sqlite'), 0o600);
|
|
13
|
+
this.db.exec(`PRAGMA busy_timeout=3000; PRAGMA journal_mode=WAL;
|
|
14
|
+
CREATE TABLE IF NOT EXISTS kv (key TEXT PRIMARY KEY, value TEXT NOT NULL);
|
|
15
|
+
CREATE TABLE IF NOT EXISTS leases (key TEXT PRIMARY KEY, owner TEXT NOT NULL, expires INTEGER NOT NULL);
|
|
16
|
+
CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, enabled INTEGER NOT NULL DEFAULT 1);
|
|
17
|
+
CREATE TABLE IF NOT EXISTS jobs (id TEXT PRIMARY KEY, revision TEXT NOT NULL, retry INTEGER NOT NULL DEFAULT 0, failures INTEGER NOT NULL DEFAULT 0);
|
|
18
|
+
CREATE TABLE IF NOT EXISTS memories (id TEXT PRIMARY KEY, revision TEXT NOT NULL, cwd TEXT NOT NULL, value TEXT NOT NULL, generated INTEGER NOT NULL, used INTEGER NOT NULL, uses INTEGER NOT NULL DEFAULT 0);
|
|
19
|
+
CREATE TABLE IF NOT EXISTS notes (id TEXT PRIMARY KEY, text TEXT NOT NULL, created INTEGER NOT NULL);`);
|
|
20
|
+
}
|
|
21
|
+
get(key, fallback = null) { const row = this.db.prepare('SELECT value FROM kv WHERE key=?').get(key); return row ? JSON.parse(row.value) : fallback; }
|
|
22
|
+
set(key, value) { this.db.prepare('INSERT OR REPLACE INTO kv VALUES (?,?)').run(key, JSON.stringify(value)); }
|
|
23
|
+
acquire(key, owner, ttl, now = Date.now()) {
|
|
24
|
+
return this.db.prepare(`INSERT INTO leases VALUES (?,?,?) ON CONFLICT(key) DO UPDATE SET owner=excluded.owner,expires=excluded.expires WHERE leases.expires < ? OR leases.owner=excluded.owner`).run(key, owner, now + ttl, now).changes > 0;
|
|
25
|
+
}
|
|
26
|
+
owns(key, owner) { return !!this.db.prepare('SELECT 1 FROM leases WHERE key=? AND owner=? AND expires>=?').get(key, owner, Date.now()); }
|
|
27
|
+
release(key, owner) { this.db.prepare('DELETE FROM leases WHERE key=? AND owner=?').run(key, owner); }
|
|
28
|
+
cancelPipeline() { this.db.prepare('DELETE FROM leases WHERE key=?').run('pipeline'); }
|
|
29
|
+
active(id) { return !!this.db.prepare('SELECT 1 FROM leases WHERE key=? AND expires>=?').get(`session:${id}`, Date.now()); }
|
|
30
|
+
enabled(id) { return this.db.prepare('SELECT enabled FROM sessions WHERE id=?').get(id)?.enabled !== 0; }
|
|
31
|
+
enable(id, enabled) { this.db.prepare('INSERT OR REPLACE INTO sessions VALUES (?,?)').run(id, +enabled); }
|
|
32
|
+
pending(id, revision) { const job = this.db.prepare('SELECT * FROM jobs WHERE id=?').get(id); return !job || job.revision !== revision || job.retry > 0 && job.retry < Date.now(); }
|
|
33
|
+
failed(id, revision) {
|
|
34
|
+
const count = (this.db.prepare('SELECT failures FROM jobs WHERE id=?').get(id)?.failures ?? 0) + 1;
|
|
35
|
+
this.db.prepare('INSERT OR REPLACE INTO jobs VALUES (?,?,?,?)').run(id, revision, Date.now() + Math.min(86400000, 60000 * 2 ** Math.min(count, 10)), count);
|
|
36
|
+
}
|
|
37
|
+
save(id, revision, cwd, value) {
|
|
38
|
+
this.db.exec('BEGIN IMMEDIATE');
|
|
39
|
+
try {
|
|
40
|
+
this.db.prepare('INSERT OR REPLACE INTO jobs VALUES (?,?,0,0)').run(id, revision);
|
|
41
|
+
if (value.raw_memory.trim()) this.db.prepare(`INSERT INTO memories VALUES (?,?,?,?,?,?,0) ON CONFLICT(id) DO UPDATE SET revision=excluded.revision,cwd=excluded.cwd,value=excluded.value,generated=excluded.generated`).run(id, revision, cwd, JSON.stringify(value), Date.now(), Date.now());
|
|
42
|
+
else this.db.prepare('DELETE FROM memories WHERE id=?').run(id);
|
|
43
|
+
this.db.exec('COMMIT');
|
|
44
|
+
} catch (error) { this.db.exec('ROLLBACK'); throw error; }
|
|
45
|
+
}
|
|
46
|
+
candidates(days, limit) {
|
|
47
|
+
return this.db.prepare(`SELECT m.* FROM memories m LEFT JOIN sessions s ON s.id=m.id WHERE COALESCE(s.enabled,1)=1 AND MAX(m.used,m.generated)>=? ORDER BY m.uses DESC,MAX(m.used,m.generated) DESC LIMIT ?`).all(Date.now() - days * 86400000, limit).map(row => ({ ...row, value: JSON.parse(row.value) }));
|
|
48
|
+
}
|
|
49
|
+
prune(days) { this.db.prepare('DELETE FROM memories WHERE MAX(used,generated)<?').run(Date.now() - days * 86400000); }
|
|
50
|
+
recordCall(call) {
|
|
51
|
+
const stats = this.get('usage', { calls: 0, inputTokens: 0, outputTokens: 0, unknownUsage: 0 });
|
|
52
|
+
stats.calls++; stats.inputTokens += call.usage?.inputTokens ?? 0; stats.outputTokens += call.usage?.outputTokens ?? 0;
|
|
53
|
+
if (!call.usage) stats.unknownUsage++;
|
|
54
|
+
this.set('usage', { ...stats, last: call });
|
|
55
|
+
}
|
|
56
|
+
touch(ids) { for (const id of ids) this.db.prepare('UPDATE memories SET used=?,uses=uses+1 WHERE id=?').run(Date.now(), id); }
|
|
57
|
+
note(text) { const id = `note:${randomUUID()}`; this.db.prepare('INSERT INTO notes VALUES (?,?,?)').run(id, redact(text.slice(0, 4000)), Date.now()); return id; }
|
|
58
|
+
notes() { return this.db.prepare('SELECT * FROM notes ORDER BY created DESC LIMIT 32').all(); }
|
|
59
|
+
publish(snapshot, fingerprint) {
|
|
60
|
+
this.db.exec('BEGIN IMMEDIATE');
|
|
61
|
+
try { this.set('snapshot', snapshot); this.set('fingerprint', fingerprint); this.db.exec('COMMIT'); }
|
|
62
|
+
catch (error) { this.db.exec('ROLLBACK'); throw error; }
|
|
63
|
+
this.materialize(snapshot);
|
|
64
|
+
}
|
|
65
|
+
materialize(snapshot = this.get('snapshot')) {
|
|
66
|
+
if (!snapshot) return;
|
|
67
|
+
const write = (path, text) => {
|
|
68
|
+
const tmp = `${path}.${randomUUID()}.tmp`;
|
|
69
|
+
writeFileSync(tmp, text, { mode: 0o600 }); renameSync(tmp, path);
|
|
70
|
+
};
|
|
71
|
+
const cite = ids => ids.map(id => `source: ${id}`).join(', ');
|
|
72
|
+
write(join(this.root, 'memory_summary.md'), snapshot.summary + '\n');
|
|
73
|
+
write(join(this.root, 'MEMORY.md'), snapshot.entries.map(e => `## ${e.title}\n\n${e.body}\n\n${cite(e.sources)}`).join('\n\n') + '\n');
|
|
74
|
+
write(join(this.root, 'raw_memories.md'), snapshot.candidates.map(c => `## ${c.id}\nWorkspace: ${c.cwd}\n\n${c.value.raw_memory}`).join('\n\n'));
|
|
75
|
+
// These two directories contain generated files only. The DB snapshot is
|
|
76
|
+
// authoritative; interrupted materialization is repaired on the next run.
|
|
77
|
+
for (const dir of ['rollout_summaries', 'skills']) { rmSync(join(this.root, dir), { recursive: true, force: true }); mkdirSync(join(this.root, dir), { mode: 0o700 }); }
|
|
78
|
+
for (const c of snapshot.candidates) write(join(this.root, 'rollout_summaries', digest(c.id) + '.md'), `Session: ${c.id}\nWorkspace: ${c.cwd}\nMessage sequences: ${c.value.evidence.join(', ')}\n\n${c.value.rollout_summary}\n`);
|
|
79
|
+
for (const skill of snapshot.skills) {
|
|
80
|
+
const dir = join(this.root, 'skills', digest(skill.title).slice(0, 16)); mkdirSync(dir, { mode: 0o700 });
|
|
81
|
+
write(join(dir, 'SKILL.md'), `# ${skill.title}\n\n${skill.body}\n\n${cite(skill.sources)}\n`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
clear() {
|
|
85
|
+
this.db.exec('BEGIN IMMEDIATE');
|
|
86
|
+
try {
|
|
87
|
+
this.db.exec("DELETE FROM memories; DELETE FROM notes; DELETE FROM jobs; DELETE FROM kv WHERE key NOT IN ('use','generate'); DELETE FROM leases WHERE key='pipeline';");
|
|
88
|
+
this.set('clearedAt', Date.now()); this.db.exec('COMMIT');
|
|
89
|
+
} catch (error) { this.db.exec('ROLLBACK'); throw error; }
|
|
90
|
+
for (const file of ['MEMORY.md', 'memory_summary.md', 'raw_memories.md', 'rollout_summaries', 'skills']) rmSync(join(this.root, file), { recursive: true, force: true });
|
|
91
|
+
}
|
|
92
|
+
close() { this.db.close(); }
|
|
93
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Producer identity of one message source.
|
|
3
|
+
*
|
|
4
|
+
* DSH 0.1.7 retired the shared `plugin` kind: every producer now declares its own
|
|
5
|
+
* `kind`, and DSCODE's plugins name themselves the same way. Durable history carries two
|
|
6
|
+
* older shapes — the raw `{ kind: 'plugin', plugin: '<producer>' }` of a session written
|
|
7
|
+
* before the upgrade, and the `plugin:<producer>` kind the session format's v3-to-v4
|
|
8
|
+
* migration writes for a producer it does not know — so every reader of history resolves
|
|
9
|
+
* all three through this one function.
|
|
10
|
+
*
|
|
11
|
+
* @param source - a message source from any release.
|
|
12
|
+
* @returns the producing subsystem's name, or `''` when the source names none.
|
|
13
|
+
*/
|
|
14
|
+
export function producerKind(source) {
|
|
15
|
+
if (source === null || typeof source !== 'object') return '';
|
|
16
|
+
const { kind, plugin } = source;
|
|
17
|
+
if (kind === 'plugin') return typeof plugin === 'string' ? plugin : '';
|
|
18
|
+
if (typeof kind !== 'string') return '';
|
|
19
|
+
return kind.startsWith('plugin:') ? kind.slice('plugin:'.length) : kind;
|
|
20
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { LlmError, ReasoningEffortId, attributionHeaders } from '@deepseek-ai/dsh-llm';
|
|
2
|
+
import { OpenRouterAdapter } from '../openrouter/adapter.mjs';
|
|
3
|
+
import { effortInfo } from '../openrouter/wire.mjs';
|
|
4
|
+
import { DEFAULT_CONTEXT_WINDOW, GO_MODELS, OTHER_PROTOCOL_MODELS, goModel } from './models.mjs';
|
|
5
|
+
import { LABEL, PROVIDER, REPLAY_KIND, explainError, modelReasoning, requestBody } from './wire.mjs';
|
|
6
|
+
|
|
7
|
+
export { PROVIDER };
|
|
8
|
+
/** Output cap materialized when a caller names none. */
|
|
9
|
+
export const DEFAULT_OUTPUT_CAP = 131072;
|
|
10
|
+
const APP_URL = 'https://github.com/qiz029/dscode';
|
|
11
|
+
|
|
12
|
+
function modelInfo(provider, id, entry) {
|
|
13
|
+
return { provider, id, name: entry?.name ?? id, inputModalities: entry?.inputModalities?.length ? [...entry.inputModalities] : ['text'] };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* OpenCode Go chat completions as a harness adapter. The request loop, image handling and
|
|
18
|
+
* stream translation are OpenRouter's; this route supplies its own catalog, body, headers
|
|
19
|
+
* and the account login's endpoint. Go asks each client to name itself in the user agent and to send one stable
|
|
20
|
+
* `x-opencode-session` per conversation.
|
|
21
|
+
*/
|
|
22
|
+
export class OpenCodeGoAdapter extends OpenRouterAdapter {
|
|
23
|
+
/**
|
|
24
|
+
* @param config - `options()` connection facts, `resolveAccount()` (request auth from the account
|
|
25
|
+
* login; throws when signed out), `version`, optional `resolveAttachments()`,
|
|
26
|
+
* `resolveImageAccess(attachments, ref)` and `fetch`.
|
|
27
|
+
*/
|
|
28
|
+
constructor(config) {
|
|
29
|
+
super({ ensureModels: async () => {}, ...config });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get label() {
|
|
33
|
+
return LABEL;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
providerInfo(provider) {
|
|
37
|
+
return { id: provider, name: this.config.displayName ?? LABEL };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async listModels(provider) {
|
|
41
|
+
return [...GO_MODELS].map(([id, entry]) => modelInfo(provider, id, entry));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async resolveModel(provider, model) {
|
|
45
|
+
const entry = goModel(model);
|
|
46
|
+
const reasoning = modelReasoning(entry);
|
|
47
|
+
return {
|
|
48
|
+
...modelInfo(provider, model, entry),
|
|
49
|
+
context: { contextWindow: entry?.contextWindow ?? DEFAULT_CONTEXT_WINDOW },
|
|
50
|
+
defaultMaxTokens: DEFAULT_OUTPUT_CAP,
|
|
51
|
+
...(reasoning ? { reasoning: {
|
|
52
|
+
efforts: reasoning.levels.map(id => ({ ...effortInfo(id), id: ReasoningEffortId(id) })),
|
|
53
|
+
defaultEffort: ReasoningEffortId(reasoning.defaultEffort),
|
|
54
|
+
} } : {}),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async modelEntry(model) {
|
|
59
|
+
const protocol = OTHER_PROTOCOL_MODELS.get(model);
|
|
60
|
+
if (protocol !== undefined) {
|
|
61
|
+
throw new LlmError(`${LABEL} serves "${model}" over its ${protocol} endpoint, which DSCODE does not support yet; pick a model from /model`, 'INVALID_REQUEST');
|
|
62
|
+
}
|
|
63
|
+
return goModel(model);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
requestBody(options, context) {
|
|
67
|
+
return requestBody(options, context);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The OpenCode account login: the endpoint it names, its token and its organisation header. */
|
|
71
|
+
async resolveAuth() {
|
|
72
|
+
return this.config.resolveAccount();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
requestHeaders(options) {
|
|
76
|
+
return {
|
|
77
|
+
...attributionHeaders({ product: 'dscode', version: this.config.version ?? '0.0.0', url: APP_URL }),
|
|
78
|
+
...(options.sessionId !== undefined ? { 'x-opencode-session': String(options.sessionId).slice(0, 256) } : {}),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
translateOptions(options) {
|
|
83
|
+
return { model: options.model, kind: REPLAY_KIND, label: LABEL };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async *stream(options) {
|
|
87
|
+
try {
|
|
88
|
+
yield* super.stream(options);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
const explained = error instanceof LlmError ? explainError(error.message) : undefined;
|
|
91
|
+
if (explained === undefined || explained === error.message) throw error;
|
|
92
|
+
const status = error.failure?.status;
|
|
93
|
+
throw new LlmError(explained, error.code, { cause: error, ...(status === undefined ? {} : { status }) });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { t } from '../i18n/messages.mjs';
|
|
2
|
+
import { openBrowser } from '../account/index.mjs';
|
|
3
|
+
import { completeGrant, grantSummary, pollDeviceToken, startDeviceLogin } from './oauth.mjs';
|
|
4
|
+
|
|
5
|
+
// `/opencode`: sign in to OpenCode Go with an OpenCode account. A command settles with one
|
|
6
|
+
// result and cannot print while it waits, and the device flow needs the code in front of the
|
|
7
|
+
// user before approval, so `login` answers at once with the code and URL and keeps polling
|
|
8
|
+
// in the background; `/opencode` reports how it ended.
|
|
9
|
+
|
|
10
|
+
const ok = text => ({ kind: 'success', text });
|
|
11
|
+
const fail = text => ({ kind: 'error', text });
|
|
12
|
+
const who = summary => [summary.email, summary.orgName].filter(Boolean).join(' · ') || 'OpenCode account';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The login state machine behind the command, kept apart so a test can drive it with fakes.
|
|
16
|
+
* @param deps - `store` (`write`, `remove`), `grant()` for the stored grant, optional `onSignedIn()`,
|
|
17
|
+
* `fetch`, `open(url)`, `sleep(ms)`, `now()` and `log(message)`.
|
|
18
|
+
*/
|
|
19
|
+
export class OpenCodeLogin {
|
|
20
|
+
constructor(deps) {
|
|
21
|
+
this.deps = deps;
|
|
22
|
+
this.attempt = undefined;
|
|
23
|
+
this.outcome = undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
now() {
|
|
27
|
+
return this.deps.now?.() ?? Date.now();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Status lines: the stored login, an attempt in flight, the last outcome. */
|
|
31
|
+
async status(locale) {
|
|
32
|
+
const lines = [];
|
|
33
|
+
if (this.attempt !== undefined) lines.push(t(locale, 'opencode.pending', { code: this.attempt.device.userCode }), this.attempt.device.url);
|
|
34
|
+
else if (this.outcome !== undefined) lines.push(this.outcome);
|
|
35
|
+
const grant = await this.deps.grant();
|
|
36
|
+
if (grant !== undefined) {
|
|
37
|
+
const summary = grantSummary(grant, this.now());
|
|
38
|
+
lines.push(t(locale, 'opencode.signedIn', { who: who(summary), days: summary.expiresInDays }));
|
|
39
|
+
} else if (this.attempt === undefined) lines.push(t(locale, 'opencode.signedOut'));
|
|
40
|
+
return lines;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Start a login, or show the one already waiting. */
|
|
44
|
+
async login(locale) {
|
|
45
|
+
if (this.attempt !== undefined) return { ok: true, lines: await this.status(locale) };
|
|
46
|
+
let device;
|
|
47
|
+
try {
|
|
48
|
+
device = await startDeviceLogin({ ...(this.deps.fetch ? { fetch: this.deps.fetch } : {}), now: this.now() });
|
|
49
|
+
} catch (error) {
|
|
50
|
+
return { ok: false, lines: [t(locale, 'opencode.startFailed', { reason: error.message })] };
|
|
51
|
+
}
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
const attempt = { device, controller };
|
|
54
|
+
this.attempt = attempt;
|
|
55
|
+
this.outcome = undefined;
|
|
56
|
+
attempt.done = this.follow(attempt, locale);
|
|
57
|
+
const opened = await (this.deps.open ?? openBrowser)(device.url);
|
|
58
|
+
return {
|
|
59
|
+
ok: true,
|
|
60
|
+
lines: [
|
|
61
|
+
t(locale, 'opencode.started', { code: device.userCode, minutes: Math.max(1, Math.round((device.expiresAt - this.now()) / 60000)) }),
|
|
62
|
+
t(locale, opened ? 'opencode.browserOpened' : 'opencode.browserManual'),
|
|
63
|
+
device.url,
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Poll to the end, store the grant on approval, and record how it ended. */
|
|
69
|
+
async follow(attempt, locale) {
|
|
70
|
+
const options = { ...(this.deps.fetch ? { fetch: this.deps.fetch } : {}), signal: attempt.controller.signal, ...(this.deps.sleep ? { sleep: this.deps.sleep } : {}), now: () => this.now() };
|
|
71
|
+
try {
|
|
72
|
+
const token = await pollDeviceToken(attempt.device, options);
|
|
73
|
+
const grant = await completeGrant(token, { ...(this.deps.fetch ? { fetch: this.deps.fetch } : {}), now: this.now() });
|
|
74
|
+
await this.deps.store.write(JSON.stringify(grant));
|
|
75
|
+
this.outcome = t(locale, 'opencode.succeeded', { who: who(grantSummary(grant, this.now())) });
|
|
76
|
+
this.deps.log?.('signed in');
|
|
77
|
+
this.deps.onSignedIn?.();
|
|
78
|
+
} catch (error) {
|
|
79
|
+
this.outcome = attempt.controller.signal.aborted ? t(locale, 'opencode.cancelled') : t(locale, 'opencode.failed', { reason: error.message });
|
|
80
|
+
this.deps.log?.(`sign-in did not complete: ${error.message}`);
|
|
81
|
+
} finally {
|
|
82
|
+
if (this.attempt === attempt) this.attempt = undefined;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
cancel(locale) {
|
|
87
|
+
const attempt = this.attempt;
|
|
88
|
+
if (attempt === undefined) return t(locale, 'opencode.nothingToCancel');
|
|
89
|
+
attempt.controller.abort(new Error('cancelled'));
|
|
90
|
+
this.attempt = undefined;
|
|
91
|
+
this.outcome = t(locale, 'opencode.cancelled');
|
|
92
|
+
return this.outcome;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async logout(locale) {
|
|
96
|
+
this.attempt?.controller.abort(new Error('signed out'));
|
|
97
|
+
this.attempt = undefined;
|
|
98
|
+
this.outcome = undefined;
|
|
99
|
+
await this.deps.store.remove();
|
|
100
|
+
return t(locale, 'opencode.loggedOut');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
dispose() {
|
|
104
|
+
this.attempt?.controller.abort(new Error('disposed'));
|
|
105
|
+
this.attempt = undefined;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** The `/opencode` command descriptor over one login machine. */
|
|
110
|
+
export function openCodeCommand(login, language) {
|
|
111
|
+
return {
|
|
112
|
+
name: 'opencode',
|
|
113
|
+
description: 'Sign in to OpenCode Go with an OpenCode account, or read the login (/opencode [login|cancel|logout])',
|
|
114
|
+
input: { hint: '[login|cancel|logout]' },
|
|
115
|
+
handler: async ({ rawInput }) => {
|
|
116
|
+
const locale = language();
|
|
117
|
+
const argument = String(rawInput ?? '').trim().toLowerCase();
|
|
118
|
+
if (argument === '' || argument === 'status') return ok((await login.status(locale)).join('\n'));
|
|
119
|
+
if (argument === 'login' || argument === 'signin' || argument === 'sign-in') {
|
|
120
|
+
const result = await login.login(locale);
|
|
121
|
+
return (result.ok ? ok : fail)(result.lines.join('\n'));
|
|
122
|
+
}
|
|
123
|
+
if (argument === 'cancel') return ok(login.cancel(locale));
|
|
124
|
+
if (argument === 'logout' || argument === 'signout' || argument === 'sign-out') return ok(await login.logout(locale));
|
|
125
|
+
return fail(t(locale, 'opencode.usage'));
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { resolveDshHome } from '@deepseek-ai/dsh-home-paths';
|
|
2
|
+
import z from '@deepseek-ai/schemastery';
|
|
3
|
+
import { LlmError, RetryPolicySchema, resolveImageAttachmentAccess, resolveRetryPolicy } from '@deepseek-ai/dsh-llm';
|
|
4
|
+
import { credentialRef } from '@deepseek-ai/dsh-credentials';
|
|
5
|
+
import { deepEqualJson } from '@deepseek-ai/dsh-util-values';
|
|
6
|
+
import { plainConfig } from '../cordis-config/plain.mjs';
|
|
7
|
+
import { OpenCodeGoAdapter, PROVIDER } from './adapter.mjs';
|
|
8
|
+
import { dscodeVersion } from './version.mjs';
|
|
9
|
+
import { GRANT_REF, GrantSession } from './oauth.mjs';
|
|
10
|
+
import { OpenCodeLogin, openCodeCommand } from './command.mjs';
|
|
11
|
+
import { GO_USAGE_TTL_MS, clearGoUsage, currentGoUsage } from './usage.mjs';
|
|
12
|
+
import { readLanguage } from '../i18n/messages.mjs';
|
|
13
|
+
|
|
14
|
+
// The `opencode-go` route: the OpenCode Go subscription's chat-completions models through
|
|
15
|
+
// DSCODE's OpenRouter request loop, authorised only by an OpenCode account login
|
|
16
|
+
// (`/opencode login`, see oauth.mjs). The login names the account's own inference endpoint,
|
|
17
|
+
// which also answers the subscription's usage for the status line (usage.mjs).
|
|
18
|
+
export const name = 'dscode-opencode-go';
|
|
19
|
+
export const inject = ['llm'];
|
|
20
|
+
const NS = 'llm-opencode-go';
|
|
21
|
+
/** Where requests go before a login names the account's endpoint; used only in messages. */
|
|
22
|
+
const DEFAULT_BASE_URL = 'https://opencode.ai/inference/go/openai/v1';
|
|
23
|
+
|
|
24
|
+
// The route's credential reference is the login itself: `/provider` reads its status from
|
|
25
|
+
// here, and the credential store describes it as read-only so no key form is ever offered.
|
|
26
|
+
// Each `.volatile()` field arrives as a reference the Settings form and a profile edit both
|
|
27
|
+
// write, so every read below sees the current value.
|
|
28
|
+
export const Config = z.object({
|
|
29
|
+
providerName: z.union(['opencode-go', 'dscode-opencode-go']).default('opencode-go'),
|
|
30
|
+
apiKeyEnv: z.string().role('credential-ref').default(GRANT_REF).volatile(),
|
|
31
|
+
streamIdleTimeoutMs: z.number().min(1).default(300000).volatile(),
|
|
32
|
+
maxRequestImageBytes: z.number().step(1).min(1).default(20 * 1024 * 1024).volatile(),
|
|
33
|
+
retryPolicy: RetryPolicySchema.volatile(),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
/** Validated connection facts from one config snapshot. */
|
|
37
|
+
export function resolveOptions(config = {}) {
|
|
38
|
+
const streamIdleTimeoutMs = config.streamIdleTimeoutMs ?? 300000;
|
|
39
|
+
if (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0) throw new Error(`${name}: streamIdleTimeoutMs must be a positive number`);
|
|
40
|
+
return {
|
|
41
|
+
apiKeyEnv: credentialRef(config.apiKeyEnv || GRANT_REF),
|
|
42
|
+
baseURL: DEFAULT_BASE_URL,
|
|
43
|
+
streamIdleTimeoutMs,
|
|
44
|
+
maxRequestImageBytes: config.maxRequestImageBytes ?? 20 * 1024 * 1024,
|
|
45
|
+
retryPolicy: resolveRetryPolicy(config.retryPolicy, `${name}: retryPolicy`),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function apply(ctx, config = {}) {
|
|
50
|
+
const provider = config.providerName ?? PROVIDER;
|
|
51
|
+
const displayName = provider === 'dscode-opencode-go' ? 'DSCODE OpenCode Go' : 'OpenCode Go';
|
|
52
|
+
// `/opencode` owns the login, so Settings must not generate a form for this entry.
|
|
53
|
+
ctx.inject(['settings'], settingsCtx => {
|
|
54
|
+
settingsCtx.effect(() => settingsCtx.settings.configure({ auto: false }, ctx.fiber));
|
|
55
|
+
});
|
|
56
|
+
let lastGood;
|
|
57
|
+
const options = () => {
|
|
58
|
+
try {
|
|
59
|
+
lastGood = resolveOptions(plainConfig(config));
|
|
60
|
+
return lastGood;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
if (lastGood === undefined) throw error;
|
|
63
|
+
ctx.logger.error(`${name}: keeping the last good configuration after an invalid edit`);
|
|
64
|
+
ctx.logger.error(error);
|
|
65
|
+
return lastGood;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
options();
|
|
69
|
+
const home = resolveDshHome();
|
|
70
|
+
// The login lives in the shared credential store beside the provider keys.
|
|
71
|
+
const grants = {
|
|
72
|
+
read: async () => (await ctx.get('credentials')?.resolve(GRANT_REF))?.value || undefined,
|
|
73
|
+
write: value => ctx.get('credentials').set(GRANT_REF, value),
|
|
74
|
+
remove: async () => {
|
|
75
|
+
await ctx.get('credentials')?.unset(GRANT_REF);
|
|
76
|
+
clearGoUsage(home);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
const session = new GrantSession(grants);
|
|
80
|
+
const signedIn = async () => {
|
|
81
|
+
const auth = await session.auth();
|
|
82
|
+
if (auth !== undefined) return auth;
|
|
83
|
+
throw new LlmError(`${name}: not signed in to OpenCode Go; run /opencode login`, 'MISSING_CREDENTIAL');
|
|
84
|
+
};
|
|
85
|
+
const adapter = new OpenCodeGoAdapter({
|
|
86
|
+
displayName,
|
|
87
|
+
options,
|
|
88
|
+
version: dscodeVersion(),
|
|
89
|
+
resolveAccount: signedIn,
|
|
90
|
+
resolveAttachments: () => ctx.get('attachments'),
|
|
91
|
+
resolveImageAccess: (attachments, ref) => resolveImageAttachmentAccess(attachments, hostPath => ctx.get('fs')?.processPathFromHostPath(hostPath), ref),
|
|
92
|
+
});
|
|
93
|
+
// Keep the subscription's usage fresh for the status line while signed in.
|
|
94
|
+
const refreshUsage = () => currentGoUsage({ home, resolveAuth: () => session.auth() });
|
|
95
|
+
const login = new OpenCodeLogin({
|
|
96
|
+
store: grants,
|
|
97
|
+
grant: () => session.current(),
|
|
98
|
+
onSignedIn: () => { void refreshUsage().catch(() => {}); },
|
|
99
|
+
log: message => ctx.logger.info(`${name}: ${message}`),
|
|
100
|
+
});
|
|
101
|
+
ctx.provide('dscodeOpenCodeLogin', login);
|
|
102
|
+
ctx.effect(() => () => login.dispose());
|
|
103
|
+
ctx.inject(['commands'], commandsCtx => {
|
|
104
|
+
commandsCtx.commands.register(openCodeCommand(login, () => readLanguage()));
|
|
105
|
+
});
|
|
106
|
+
ctx.llm.registerConfigurableProviders([{ provider, displayName, settingsNs: ctx.fiber.entry?.options.id ?? NS, settingsPath: [] }]);
|
|
107
|
+
const registration = ctx.llm.registerAdapter([provider], adapter);
|
|
108
|
+
// The retry policy is captured at registration: re-register when an edit changes it.
|
|
109
|
+
let registeredPolicy = options().retryPolicy;
|
|
110
|
+
ctx.on('loader/volatile-update', () => {
|
|
111
|
+
let policy;
|
|
112
|
+
try { policy = options().retryPolicy; } catch (error) { ctx.logger.warn(error); return; }
|
|
113
|
+
if (deepEqualJson(policy, registeredPolicy)) return;
|
|
114
|
+
registration.replace([provider]);
|
|
115
|
+
registeredPolicy = policy;
|
|
116
|
+
});
|
|
117
|
+
void refreshUsage().catch(() => {});
|
|
118
|
+
const timer = setInterval(() => { void refreshUsage().catch(() => {}); }, GO_USAGE_TTL_MS);
|
|
119
|
+
timer.unref?.();
|
|
120
|
+
ctx.effect(() => () => clearInterval(timer));
|
|
121
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// The OpenCode Go catalog DSCODE serves. Go's `/models` listing names ids only, with no
|
|
2
|
+
// context size, modalities or reasoning controls, and Go passes request fields through to
|
|
3
|
+
// each upstream, so every fact below was probed against the live gateway (2026-09): which
|
|
4
|
+
// `reasoning_effort` values each model accepts, whether it can switch thinking off, and
|
|
5
|
+
// whether it accepts image input (a text-only model answers an image with HTTP 404).
|
|
6
|
+
// Context windows follow each lab's published figure. DeepSeek needs the workspace's
|
|
7
|
+
// Global region, so its rows follow DeepSeek's own API rather than a probe.
|
|
8
|
+
|
|
9
|
+
/** Context assumed for a model the catalog does not size. */
|
|
10
|
+
export const DEFAULT_CONTEXT_WINDOW = 262144;
|
|
11
|
+
|
|
12
|
+
// Reasoning shapes: the harness efforts a model offers. `off` sends `none`; Ultra rides `max`.
|
|
13
|
+
const SWITCHABLE = Object.freeze(['off', 'low', 'high', 'max', 'ultra']);
|
|
14
|
+
const MANDATORY = Object.freeze(['low', 'high', 'max', 'ultra']);
|
|
15
|
+
const NO_MAX = Object.freeze(['off', 'low', 'high']);
|
|
16
|
+
const DEEPSEEK = Object.freeze(['high', 'max', 'ultra']);
|
|
17
|
+
|
|
18
|
+
const model = (id, name, contextWindow, efforts, image = false) => [id, Object.freeze({ name, contextWindow, efforts, inputModalities: image ? ['text', 'image'] : ['text'] })];
|
|
19
|
+
|
|
20
|
+
/** Chat-completions models in picker order. */
|
|
21
|
+
export const GO_MODELS = new Map([
|
|
22
|
+
model('deepseek-v4-pro', 'DeepSeek V4 Pro', 1048576, DEEPSEEK),
|
|
23
|
+
model('deepseek-v4-flash', 'DeepSeek V4 Flash', 1048576, DEEPSEEK),
|
|
24
|
+
model('deepseek-v4.1-flash', 'DeepSeek V4.1 Flash', 1048576, DEEPSEEK, true),
|
|
25
|
+
model('deepseek-v4-flash-vision-exp', 'DeepSeek V4 Flash Vision Exp', 1048576, DEEPSEEK, true),
|
|
26
|
+
// GLM is thinking-only: `none` is refused.
|
|
27
|
+
model('glm-5.3', 'GLM-5.3', 1048576, MANDATORY),
|
|
28
|
+
model('glm-5.3-flash', 'GLM-5.3-Flash', 1048576, MANDATORY, true),
|
|
29
|
+
model('glm-5.2', 'GLM-5.2', 1048576, MANDATORY),
|
|
30
|
+
model('glm-5.1', 'GLM-5.1', 204800, MANDATORY),
|
|
31
|
+
model('kimi-k3', 'Kimi K3', 1048576, SWITCHABLE, true),
|
|
32
|
+
model('kimi-k2.7-code', 'Kimi K2.7 Code', 262144, MANDATORY, true),
|
|
33
|
+
model('kimi-k2.6', 'Kimi K2.6', 262144, SWITCHABLE, true),
|
|
34
|
+
// MiMo V2.6 refuses `max`.
|
|
35
|
+
model('mimo-v2.6-pro', 'MiMo-V2.6-Pro', 1048576, NO_MAX, true),
|
|
36
|
+
model('mimo-v2.6-flash', 'MiMo-V2.6-Flash', 1048576, NO_MAX, true),
|
|
37
|
+
model('mimo-v2.5-pro', 'MiMo-V2.5-Pro', 1048576, SWITCHABLE),
|
|
38
|
+
model('mimo-v2.5', 'MiMo-V2.5', 1048576, SWITCHABLE, true),
|
|
39
|
+
// LongCat accepts `none` but keeps thinking, so it offers no Off.
|
|
40
|
+
model('longcat-2.0', 'LongCat-2.0', 1048576, MANDATORY),
|
|
41
|
+
model('hy4-preview', 'Hy4 preview', 1048576, SWITCHABLE),
|
|
42
|
+
model('hy3', 'Hy3', 262144, SWITCHABLE),
|
|
43
|
+
model('space-bunny-free', 'Space Bunny Free', DEFAULT_CONTEXT_WINDOW, MANDATORY, true),
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Go models served over another protocol (Anthropic messages or OpenAI responses), which
|
|
48
|
+
* this route does not speak yet; asking for one fails before any request.
|
|
49
|
+
*/
|
|
50
|
+
export const OTHER_PROTOCOL_MODELS = Object.freeze(new Map([
|
|
51
|
+
...['grok-4.7', 'grok-4.6', 'gpt-6-luna', 'gpt-5.6-luna', 'muse-spark-1.3-contributor', 'muse-spark-1.2-contributor'].map(id => [id, 'responses']),
|
|
52
|
+
...['minimax-m3', 'minimax-m2.7', 'minimax-m2.5', 'qwen3.8-max', 'qwen3.8-flash', 'qwen3.7-max', 'qwen3.7-plus', 'qwen3.6-plus'].map(id => [id, 'messages']),
|
|
53
|
+
]));
|
|
54
|
+
|
|
55
|
+
/** One model's catalog entry, or undefined for an id the catalog does not describe. */
|
|
56
|
+
export function goModel(id) {
|
|
57
|
+
return GO_MODELS.get(id);
|
|
58
|
+
}
|