@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
package/docs/email.md
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# Email inbox
|
|
2
|
+
|
|
3
|
+
`/email` opens a local inbox in the TUI. The right-hand list is sorted by
|
|
4
|
+
`updatedAt`, newest first; the left side previews the selected message.
|
|
5
|
+
On narrow terminals, Tab switches between list and preview.
|
|
6
|
+
|
|
7
|
+
- ↑/↓ selects a message; PgUp/PgDn scrolls its preview.
|
|
8
|
+
- Enter immediately steers the full message, sender, subject and source into
|
|
9
|
+
the current session. A running agent receives it at the next step; an idle
|
|
10
|
+
agent starts a turn. No second Enter is needed.
|
|
11
|
+
- Esc closes the inbox without sending. Receipt and browsing never start a model turn.
|
|
12
|
+
- The open inbox refreshes every two seconds; `r` refreshes immediately. Selection
|
|
13
|
+
stays on the same message when newer messages arrive.
|
|
14
|
+
|
|
15
|
+
The inbox belongs to the local user and is shared across sessions. Its default
|
|
16
|
+
directory is `~/.dscode/email`; `DSCODE_EMAIL_DIR` overrides it. New directories
|
|
17
|
+
use mode 0700 and messages use 0600. Message content enters session history only
|
|
18
|
+
when selected with Enter. Existing composer drafts and attachments are preserved.
|
|
19
|
+
|
|
20
|
+
## Experimental Desktop inbox
|
|
21
|
+
|
|
22
|
+
The combined Desktop package adds **Open right sidebar → Email inbox**. It reads
|
|
23
|
+
the same local inbox as the terminal. Select a message to preview its plain text;
|
|
24
|
+
**Add email to this session** steers it into the selected DSCODE session, starting
|
|
25
|
+
a turn if idle. The message is explicitly marked as external context. Reading,
|
|
26
|
+
refreshing and syncing never start a turn. Standard sessions can browse the human
|
|
27
|
+
inbox interface but cannot receive a DSCODE email injection or access DSCODE's
|
|
28
|
+
email sender/contact tools.
|
|
29
|
+
|
|
30
|
+
The Host checks that the selected message revision still matches its preview.
|
|
31
|
+
A changed message must be previewed again. A request retried with the same ID is
|
|
32
|
+
recognized in the persisted session admission history, including after restart;
|
|
33
|
+
it is not inserted or used to wake the agent again. The result acknowledges
|
|
34
|
+
admission, not successful model processing. Cancellation can discard pending
|
|
35
|
+
steering. Reopening and selecting the message again creates a new request if you
|
|
36
|
+
explicitly want to add it again. Switching sessions or hiding the pane clears
|
|
37
|
+
the preview and connection drafts; existing composer text is untouched.
|
|
38
|
+
|
|
39
|
+
Expand **Mailbox connection** to connect IMAP using a masked application password
|
|
40
|
+
or import a Google Desktop OAuth client by its absolute local path and authorize
|
|
41
|
+
Gmail. These actions use the connectors described below and share their account,
|
|
42
|
+
folder, TLS, filtering and credential-storage rules. Gmail authorization creates
|
|
43
|
+
or reuses the ToAgent label and filter and requests the same three scopes. The
|
|
44
|
+
interface allows an in-flight connection or sync to be cancelled. Passwords never
|
|
45
|
+
enter session history and are cleared from the form after submission.
|
|
46
|
+
|
|
47
|
+
**Sync now** performs one sync. **Sync in the background while Desktop is open**
|
|
48
|
+
is off by default; enabling it polls every 30 seconds, with IMAP taking precedence
|
|
49
|
+
over Gmail OAuth. The preference is stored under `$DSH_HOME/desktop-email/` and
|
|
50
|
+
survives restart and package removal. Existing mailbox credentials and local
|
|
51
|
+
messages are retained when the package is removed; reinstalling it resumes sync
|
|
52
|
+
if this preference was enabled. Disable it before removal to prevent that resume.
|
|
53
|
+
Enabling sync before connecting a mailbox preserves the preference and shows a
|
|
54
|
+
connection setup hint. A throttled poll reports that it is waiting for the next
|
|
55
|
+
interval; neither state is shown as a completed sync.
|
|
56
|
+
Unloading the plugin cancels connector work, stops its timer and removes the
|
|
57
|
+
interface and scoped tools. An already-started SMTP send is allowed to settle its
|
|
58
|
+
durable receipt; cancelling a task cannot recall submitted mail.
|
|
59
|
+
|
|
60
|
+
DSCODE sessions receive the existing `send_email`, receipt and contact-alias
|
|
61
|
+
tools. Their authorization and SMTP limitations below still apply. Previewing an incoming message grants no permission to reply. The Desktop email
|
|
62
|
+
RPC has no send action. Mail receipt does not automatically send a message to an
|
|
63
|
+
agent, and the UI has no mailbox deletion or retention controls.
|
|
64
|
+
|
|
65
|
+
## Connector boundary
|
|
66
|
+
|
|
67
|
+
The exported `createEmailInbox()` provides `receive(value)` and `list()`;
|
|
68
|
+
`EmailReceiver` in `plugins/email/inbox.d.mts` is the connector's destination
|
|
69
|
+
interface. This is an in-process/local-filesystem interface, not an HTTP endpoint.
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
import { createEmailInbox } from '../plugins/email/inbox.mjs';
|
|
73
|
+
// Published bundle export: @toddzheng024/dscode-bundle/email
|
|
74
|
+
const receiver = createEmailInbox();
|
|
75
|
+
receiver.receive({
|
|
76
|
+
format: 'dscode.email.v1',
|
|
77
|
+
connector: 'example',
|
|
78
|
+
account: 'developer@example.com',
|
|
79
|
+
id: 'provider-message-id',
|
|
80
|
+
from: 'Sender <sender@example.com>',
|
|
81
|
+
subject: 'Investigate a failing build',
|
|
82
|
+
body: 'Please inspect the test failure in the attached report URL.',
|
|
83
|
+
receivedAt: '2026-09-12T10:00:00Z',
|
|
84
|
+
updatedAt: '2026-09-12T10:00:00Z',
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Dates must include a timezone. `updatedAt` cannot precede `receivedAt`. Body is
|
|
89
|
+
nonempty plain text, limited to 256 KiB. HTML and attachments must be handled by
|
|
90
|
+
the connector before receipt. Unknown formats and malformed fields are rejected.
|
|
91
|
+
Terminal controls are removed from display and insertion. Mail is inserted as a
|
|
92
|
+
JSON envelope with `type: "user_injected_email_context"`, `injectedBy: "user"`,
|
|
93
|
+
`purpose: "supplement_session_context"`, explicit context-only instructions, and
|
|
94
|
+
a nested `email` object. The email is external reference material, not a new
|
|
95
|
+
user instruction or authorization to act. Enter directly injects this envelope
|
|
96
|
+
in both idle and running sessions.
|
|
97
|
+
|
|
98
|
+
Identity is `(connector, account, id)`. Exact repeats are idempotent; immutable,
|
|
99
|
+
atomically written revisions ensure a late delivery cannot replace a newer
|
|
100
|
+
revision, including when multiple processes receive mail. For the same identity,
|
|
101
|
+
changed content should have a strictly newer `updatedAt`; equal timestamps use a
|
|
102
|
+
stable content-hash tie break. Corrupt records are skipped with a visible count.
|
|
103
|
+
Revisions are retained locally; this first version has no deletion/retention UI.
|
|
104
|
+
|
|
105
|
+
## IMAP connection (no Google OAuth client required)
|
|
106
|
+
|
|
107
|
+
Restart the local TUI, enter `/email`, and press **i**. The setup walks through:
|
|
108
|
+
|
|
109
|
+
1. Mailbox login address.
|
|
110
|
+
2. IMAP host (default `imap.gmail.com`).
|
|
111
|
+
3. TLS port (default `993`).
|
|
112
|
+
4. Folder (default `INBOX`; an existing `ToAgent` folder may be used).
|
|
113
|
+
5. Application password, entered in a masked private field.
|
|
114
|
+
|
|
115
|
+
Enter accepts each field; Tab revisits fields; Ctrl+U clears the current field.
|
|
116
|
+
Esc cancels, including an in-flight connection. Credentials are saved only after
|
|
117
|
+
TLS login and opening the chosen folder succeed. They are never submitted to
|
|
118
|
+
the agent, recorded in composer history, or printed in status/error messages.
|
|
119
|
+
To update a password, press **i** and reconnect the same account and folder.
|
|
120
|
+
|
|
121
|
+
For Gmail, first enable 2-Step Verification and generate an application password
|
|
122
|
+
in [Google Account settings](https://support.google.com/mail/answer/185833?hl=en).
|
|
123
|
+
Some organization or Advanced Protection accounts do not offer this option.
|
|
124
|
+
Use that password in the TUI, not the ordinary Google account password. No Google
|
|
125
|
+
Cloud project or client JSON is needed for this IMAP path.
|
|
126
|
+
|
|
127
|
+
The default directly filters `INBOX` by the exact `[ToAgent]` subject prefix.
|
|
128
|
+
It does not require or create a Gmail label/filter. If a custom `ToAgent` folder
|
|
129
|
+
is selected, create and route mail to that folder in the mail provider first.
|
|
130
|
+
Only the selected folder is checked; mail auto-archived elsewhere is not picked
|
|
131
|
+
up from `INBOX`. App passwords grant mailbox access, not per-folder access; the
|
|
132
|
+
connector enforces the selected folder and subject checks.
|
|
133
|
+
|
|
134
|
+
Connections require TLS with certificate verification. The client opens the
|
|
135
|
+
folder read-only and uses `BODY.PEEK`; it never marks mail read, changes flags,
|
|
136
|
+
sends mail, or deletes messages. Strict subject checks happen before retrieving
|
|
137
|
+
a full message. Plain-text MIME bodies are accepted, including multipart
|
|
138
|
+
alternatives; HTML-only and attachment-only messages are skipped. Raw messages
|
|
139
|
+
are capped at 2 MiB and the decoded text at 256 KiB, so larger messages are skipped.
|
|
140
|
+
|
|
141
|
+
The first successful connection records UIDVALIDITY and UIDNEXT without importing
|
|
142
|
+
existing mail. Subsequent polls use bounded UID ranges, process at most 50 matching
|
|
143
|
+
candidates per poll, and checkpoint only after persistence. Retries deduplicate
|
|
144
|
+
by source content. UIDVALIDITY changes trigger recovery using the original
|
|
145
|
+
connection timestamp (at IMAP's second precision) and content identity, instead
|
|
146
|
+
of trusting old UIDs or importing the whole historical inbox.
|
|
147
|
+
|
|
148
|
+
All sessions share `~/.dscode/email/imap/connection.json` (or
|
|
149
|
+
`$DSCODE_EMAIL_DIR/imap/connection.json`). It contains the credentials and cursor,
|
|
150
|
+
is written atomically with mode 0600 inside a new 0700 directory, and is guarded
|
|
151
|
+
by a kernel lock. A running TUI polls every 30 seconds even with `/email` closed;
|
|
152
|
+
there is no daemon after all TUIs exit. Press **r** for an immediate sync.
|
|
153
|
+
|
|
154
|
+
IMAP takes precedence over the earlier Gmail OAuth connector when both are
|
|
155
|
+
configured, avoiding two background connectors polling the same mailbox. The
|
|
156
|
+
existing OAuth configuration is retained. Previously imported messages remain
|
|
157
|
+
in the shared inbox; cross-connector imports are not merged automatically.
|
|
158
|
+
|
|
159
|
+
Development diagnostics (no passwords accepted as CLI arguments):
|
|
160
|
+
|
|
161
|
+
```sh
|
|
162
|
+
node bin/dscode.mjs email imap-status
|
|
163
|
+
node bin/dscode.mjs email imap-sync
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The packaged launcher supports `dscode email imap-status` and `imap-sync` after
|
|
167
|
+
release. The current implementation is local and has not been publicly released.
|
|
168
|
+
|
|
169
|
+
## Gmail OAuth connection (optional)
|
|
170
|
+
|
|
171
|
+
The Gmail connector is implemented locally. It requires a Google Cloud Desktop
|
|
172
|
+
OAuth client and the user's browser authorization before real mail can sync.
|
|
173
|
+
|
|
174
|
+
1. In Google Cloud, enable **Gmail API**, configure the OAuth consent screen, and
|
|
175
|
+
create an OAuth client with application type **Desktop app**. Download its
|
|
176
|
+
JSON file. See [Google's setup instructions](https://developers.google.com/workspace/gmail/api/quickstart/nodejs).
|
|
177
|
+
2. Import the downloaded file using its path (never paste its contents into chat):
|
|
178
|
+
|
|
179
|
+
```sh
|
|
180
|
+
node bin/dscode.mjs email configure /absolute/path/to/client.json
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
3. Restart the local TUI, open `/email`, and press **g**. Choose the Gmail account
|
|
184
|
+
and grant the requested permissions in the system browser. Esc cancels.
|
|
185
|
+
Alternatively, run `node bin/dscode.mjs email connect`.
|
|
186
|
+
4. After connection succeeds, new incoming mail must have a subject beginning
|
|
187
|
+
with `[ToAgent]` followed by whitespace or the end of the subject, and a
|
|
188
|
+
nonempty `text/plain` body. For example, `[ToAgent] Check the login module`.
|
|
189
|
+
|
|
190
|
+
The distributed launcher supports the same commands as `dscode email configure`,
|
|
191
|
+
`connect`, `status`, and `sync` when this version is released. Development commands
|
|
192
|
+
above run the current checkout. `status` reports no secrets; `sync` performs one
|
|
193
|
+
explicit sync. `/email` shows the connection status; **r** requests an immediate
|
|
194
|
+
sync and **g** reauthorizes the same account if access expires.
|
|
195
|
+
|
|
196
|
+
The connector creates or reuses the **ToAgent** label and an incoming-mail
|
|
197
|
+
subject filter. Gmail's subject search is a candidate filter; the connector
|
|
198
|
+
independently checks the exact `[ToAgent]` prefix, current label and receipt date
|
|
199
|
+
before fetching a full body. Replies prefixed `Re:`, HTML-only messages, drafts,
|
|
200
|
+
sent mail, trash and spam are not imported. A `text/plain` alternative within a
|
|
201
|
+
multipart message is accepted; ordinary attachments and nested forwarded-message
|
|
202
|
+
attachments are not imported. Plain-text MIME bodies stored separately by Gmail
|
|
203
|
+
are fetched using the body attachment endpoint. No messages are sent, marked
|
|
204
|
+
read, deleted or automatically submitted to an agent.
|
|
205
|
+
|
|
206
|
+
OAuth requests `gmail.readonly`, `gmail.labels`, and `gmail.settings.basic` for
|
|
207
|
+
reading mail and setting up the agreed label/filter. These are Google account
|
|
208
|
+
permissions, not a Google-enforced per-label grant; DSCODE's connector enforces
|
|
209
|
+
the mail filter. See Google's [label](https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.labels/create)
|
|
210
|
+
and [filter](https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings.filters/create)
|
|
211
|
+
permission documentation. Login uses [desktop loopback OAuth with PKCE and state validation](https://developers.google.com/identity/protocols/oauth2/native-app).
|
|
212
|
+
|
|
213
|
+
The client JSON, tokens and sync state are stored privately under
|
|
214
|
+
`~/.dscode/email/gmail/` (or `$DSCODE_EMAIL_DIR/gmail/`). Files are atomic 0600
|
|
215
|
+
writes inside a new 0700 directory. `DSCODE_GMAIL_CLIENT_FILE` optionally points
|
|
216
|
+
at an existing client JSON instead of importing it. Keep that file available
|
|
217
|
+
for token refresh. Only one account is supported; reconnecting another account
|
|
218
|
+
is rejected without replacing the current credentials.
|
|
219
|
+
|
|
220
|
+
After first connection, this connector records a Gmail history cursor and does
|
|
221
|
+
not import old mail. A running TUI syncs every 30 seconds, even with the inbox
|
|
222
|
+
panel closed, provided IMAP is not configured. There is no always-on daemon: when all TUIs are closed, the next
|
|
223
|
+
launch catches up. Multiple sessions share a kernel lock and a polling timestamp.
|
|
224
|
+
The cursor advances only after all accepted messages are persisted. Retries are
|
|
225
|
+
idempotent. If [Gmail history expires](https://developers.google.com/workspace/gmail/api/guides/sync),
|
|
226
|
+
recovery lists labelled messages since the original connection date and retains
|
|
227
|
+
that date boundary. Reauthorization of the same account also retains it.
|
|
228
|
+
|
|
229
|
+
This first connector has no account-switch or disconnect UI. Revocation is
|
|
230
|
+
available through the Google account's app-access settings. Provisioned labels
|
|
231
|
+
and filters are not removed automatically.
|
|
232
|
+
|
|
233
|
+
Validation: `npm test` includes deterministic Gmail transport fixtures, real
|
|
234
|
+
local OAuth callback/PKCE/cancellation tests, shared-lock and cursor recovery
|
|
235
|
+
checks, a local TLS server exercising the real IMAP library, MIME parsing, masked
|
|
236
|
+
IMAP credential entry, and the real Ink `/email` keyboard flow. Callback tests require local
|
|
237
|
+
loopback listeners. Real Google authorization and mail delivery are separate
|
|
238
|
+
verification steps; automated tests use no actual Gmail credentials or messages.
|
|
239
|
+
|
|
240
|
+
## Send email from the agent
|
|
241
|
+
|
|
242
|
+
After configuring Gmail with an application password, restart DSCODE to load
|
|
243
|
+
`send_email` and `email_send_status`. Ask, for example: “Send a [ToAgent] email
|
|
244
|
+
to colleague@example.com summarizing this change and asking them to review it.”
|
|
245
|
+
The agent uses the existing approval flow to check recipient and content against
|
|
246
|
+
your authorization. Incoming mail does not authorize automatic replies.
|
|
247
|
+
|
|
248
|
+
`send_email` accepts `to` (one address), `subject`, `body` (plain text, up to
|
|
249
|
+
256 KiB), and a globally unique `idempotency_key`. It automatically adds
|
|
250
|
+
`[ToAgent]` unless already present. The sender is your configured Gmail account;
|
|
251
|
+
SMTP uses `smtp.gmail.com:465` with verified TLS and the existing local app
|
|
252
|
+
password. No OAuth client JSON or separate password is needed. This initial
|
|
253
|
+
sender supports Gmail app-password connections, not custom IMAP hosts or the
|
|
254
|
+
optional OAuth connector. Attachments, CC/BCC and automatic replies are not part
|
|
255
|
+
of this tool.
|
|
256
|
+
|
|
257
|
+
Receipts are shared across sessions under `~/.dscode/email/outbox` (or
|
|
258
|
+
`DSCODE_EMAIL_DIR/outbox`), with private file permissions. `accepted` means the
|
|
259
|
+
SMTP server accepted the mail; it does not prove delivery or that someone read
|
|
260
|
+
it. `uncertain` means the send may have succeeded despite an interrupted
|
|
261
|
+
response. Check with `email_send_status`; never use a new key to blindly retry.
|
|
262
|
+
Repeating the same key and content returns the existing receipt without sending.
|
|
263
|
+
A key reused for different content is rejected.
|
|
264
|
+
|
|
265
|
+
## Contact aliases
|
|
266
|
+
|
|
267
|
+
Save a recipient once, then say "email congkai and tell him this change is done":
|
|
268
|
+
|
|
269
|
+
```sh
|
|
270
|
+
dscode email alias set congkai actual-address@example.com
|
|
271
|
+
dscode email alias list
|
|
272
|
+
dscode email alias remove congkai
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Replace the example address with the person's real email. Aliases are shared
|
|
276
|
+
across sessions in the local email directory (`contacts/aliases.json`), are
|
|
277
|
+
case-insensitive, and contain 1–64 letters, digits, underscores or hyphens.
|
|
278
|
+
`set` also updates an existing alias. Changes take effect without restarting;
|
|
279
|
+
restart once after installing this version to load the new agent tool.
|
|
280
|
+
|
|
281
|
+
The agent calls `resolve_email_recipient`, then supplies both `to: "congkai"`
|
|
282
|
+
and `resolved_to: "actual-address@example.com"` to `send_email`. Approval sees
|
|
283
|
+
both the alias and the real address. Unknown aliases fail without guessing an
|
|
284
|
+
address; a changed mapping is rejected at send time until resolved and reviewed
|
|
285
|
+
again. Configuring an alias does not send mail or enable automatic replies.
|
|
286
|
+
|
|
287
|
+
You can also manage aliases by asking the agent directly:
|
|
288
|
+
|
|
289
|
+
- "set congkai's email to person@example.com" creates or updates the mapping.
|
|
290
|
+
- "list my email aliases" lists contacts.
|
|
291
|
+
- "remove congkai's email alias" removes it.
|
|
292
|
+
|
|
293
|
+
The tools are `set_email_alias`, `list_email_aliases`, and `remove_email_alias`.
|
|
294
|
+
They use the same shared contact store as the CLI. The agent asks for the real
|
|
295
|
+
email address if it is missing; it must not infer contact changes from incoming
|
|
296
|
+
mail. Saving a contact does not send any email.
|
package/docs/exec.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# dscode exec
|
|
2
|
+
|
|
3
|
+
`dscode exec` runs one prompt through the full dscode agent without the TUI, streams the reply to stdout and exits with the turn's outcome. It is the non-interactive counterpart of the TUI, in the spirit of `claude -p`.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
dscode exec "summarize the failing tests in this repo"
|
|
7
|
+
git diff | dscode exec "review this diff for bugs"
|
|
8
|
+
dscode exec --json --effort low "list the top-level directories" | jq -r 'select(.type=="result").text'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Both the source checkout (`bin/dscode.mjs`) and the npm launcher (`@toddzheng024/dscode`) provide the command; the launcher runs it against its installed Hub profile, installing it first when needed with the installer's output on stderr.
|
|
12
|
+
|
|
13
|
+
The prompt is taken from the arguments, or from stdin when it is omitted or given as `-`. The agent runs in the current directory (or `--cwd DIR`) with the same preset, tools, skills, MCP servers and memory as the TUI, so it can read and edit files and run commands.
|
|
14
|
+
|
|
15
|
+
## Output
|
|
16
|
+
|
|
17
|
+
- stdout receives only the assistant's text, streamed as it is produced.
|
|
18
|
+
- stderr receives tool activity (`→ bash …`), approval notices, errors and finally `session <id>`. `--quiet` drops the activity and the session line.
|
|
19
|
+
- `--json` switches stdout to JSON lines: `{"type":"session",…}` first, then `text`, `tool` and a final `result` object with `sessionId`, `reason` and the last assistant `text`.
|
|
20
|
+
|
|
21
|
+
Exit codes: 0 completed, 1 model or runtime error, 2 output-token ceiling, 3 blocked, 124 timeout, 130 aborted.
|
|
22
|
+
|
|
23
|
+
## Options
|
|
24
|
+
|
|
25
|
+
| Option | Meaning |
|
|
26
|
+
|---|---|
|
|
27
|
+
| `--cwd DIR` | Workspace for the agent. Default: current directory. |
|
|
28
|
+
| `--model PROVIDER/ID` | Model route. Default: the saved default model. |
|
|
29
|
+
| `--effort LEVEL` | `low`, `high`, `max` or `ultra`. Default: the saved default effort. |
|
|
30
|
+
| `--permission PRESET` | `auto-review`, `ask`, `workspace-write`, `read-only` or `danger-full-access`. Default: the profile default. |
|
|
31
|
+
| `--approve-all` | Answer every approval request with allow. Without it a request that reaches the human fallback is rejected, since nobody is watching. |
|
|
32
|
+
| `--resume SESSION_ID` | Continue an existing session; the id is printed at the end of every run. The session stays bound to the folder it was created in: a resume from another directory still writes the session's log there and reports it there, while this run's own working directory remains the one it was launched in, so run it from the session's folder (or pass `--cwd DIRECTORY`) when the turn must touch that folder. |
|
|
33
|
+
| `--timeout SECONDS` | Give up and exit 124. |
|
|
34
|
+
| `--patch FILE` | Extra dsh composition overlay, repeatable. |
|
|
35
|
+
|
|
36
|
+
## How it works
|
|
37
|
+
|
|
38
|
+
One prompt, one turn, started by you or by a script; a run started by an event instead is a [trigger](triggers.md), which keeps going toward a goal. The CLI half (argument parsing and the overlay in `plugins/exec/cli.mjs`, driven by `scripts/exec.mjs` in a checkout or `packages/launcher/manager.mjs` in the launcher) provisions the runtime like `dscode` does, then starts the same dsh Host with an overlay that disables the TUI rows and session cards and inserts `plugins/exec/index.mjs`. That plugin composes a `dscode` agent, applies the permission preset, forwards live text chunks and session events to stdout/stderr, answers approval requests, and asks the Host to exit when the turn ends. Sessions are ordinary dscode sessions: they appear in `/resume` and can be continued in the TUI.
|
|
39
|
+
|
|
40
|
+
`scripts/verify-exec.mjs` exercises the command end to end against a fixture model (`npm run test:integration`).
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# npm + Hub distribution
|
|
2
|
+
|
|
3
|
+
## Packages and responsibilities
|
|
4
|
+
|
|
5
|
+
- `@toddzheng024/dscode`: the global `dscode` command; the first launch applies the Hub's `dscode` profile and later runs the installed version directly. It ships its own install-tool shims on `PATH`: `pnpm` is pinned to 10.15.1 for the profile install, and the `npx` shim pins DSH together with pnpm for a Hub release that still spawns a pinned-DSH `npx` command. Hub CLI 0.5.0 prepares and verifies the pinned DSH runtime itself — an exact-version `npm install` into `$DSCODE_HOME/.hub/runtimes/<version>`, then launch with the current Node — so a rewritten `PATH` cannot pick up a system version by mistake.
|
|
6
|
+
- `@toddzheng024/dscode-bundle`: the complete Cordis composition, including the base layer, Computer Use, the modified TUI/runtime modules and this repository's plugins. Modified modules are generated at build time, and no third-party file is changed at install time.
|
|
7
|
+
- `@toddzheng024/dscode-desktop`: the extension for official Harness Desktop, published under the npm `preview` tag. It has its own exact runtime compatibility and Hub listing, and is not part of the terminal Hub profile.
|
|
8
|
+
- Hub profile `dscode`: the exact versions and integrity hashes of the bundle and the DSH runtime.
|
|
9
|
+
|
|
10
|
+
The complete bundle pins the shared DSH dependencies and the vendored terminal's runtime dependencies explicitly, using the repository lockfile. The terminal's workspace package is compiled into the bundle; its dependencies must still be installed, including `chalk` and `ink`. Do not stack it with another base/TUI bundle in one profile: installing several root bundles in Hub order resolves a wide transitive dependency to the other rc line first. A standalone profile's pnpm hoisted + autoInstallPeers=false is the verified installation path. A direct `npm install` of the bundle hits Computer Use's old peer range; end users install through the launcher.
|
|
11
|
+
|
|
12
|
+
## User
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install -g @toddzheng024/dscode
|
|
16
|
+
dscode
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The first install fetches the code from Hub/npm over the network. It needs macOS 14+, Node 22.19+ (22.x) or 24+, Git and Chrome. Dependencies install with ignore-scripts, matching the verified precompiled-module path, so no third-party install script runs automatically. A normal agent shell does not force this npm option.
|
|
20
|
+
|
|
21
|
+
DeepSeek and OpenRouter keys are stored locally through `/login` (`/login openrouter`), and `/provider` switches between them; other model keys are configured in `/model`, or set `DEEPSEEK_API_KEY` / `OPENROUTER_API_KEY`. Accessibility/Screen Recording permission is granted by macOS.
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
dscode update 0.7.8
|
|
25
|
+
dscode history
|
|
26
|
+
dscode rollback
|
|
27
|
+
dscode doctor
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`dscode update` first replaces the global launcher itself with npm at the target version, then moves the profile to the same version: an explicit version updates both to that exact version; with no version it asks npm for the latest launcher and updates both when there is a newer one, otherwise the profile only follows the current launcher's recommended version (the same fallback applies when npm is unreachable, so `latest` is never tracked implicitly). `npm install -g @toddzheng024/dscode@<version>` also works manually. One data directory can run several launchers/root sessions at once. Startup and version management serialise admission through a short-lived kernel lock, and each running Host holds its own version-protection lock; install/update/rollback has to wait for those Hosts to exit. When a launcher exits unexpectedly, the runtime or Hub child process inherits the lock descriptor so it does not lose protection while still running. A newer launcher notices an older one still alive and asks it to exit first. Session write exclusivity stays with the native Harness lock.
|
|
31
|
+
|
|
32
|
+
The default state directory is `~/.local/share/dscode-hub`, overridable with `DSCODE_HOME`; it is separate from the existing tar installation and this repository's `.runtime`. Sessions, credentials, review and cost records live in the data directory, not inside the npm package. Configuration lives in that directory's `.env` and `config/`, supporting `hooks.local.json`, `mcp.local.yml` and `harness.local.yml`. The profile lives in `profiles/dscode`. Hub manages upgrade and rollback directories; sessions do not roll back with the profile, but crossing a future incompatible session-format version still needs a migration.
|
|
33
|
+
|
|
34
|
+
A user who already has dsh-hub installed can apply directly, but must use pnpm 10.15.1, set a dedicated `DSH_HOME` and `DSH_AGENTS_HOME`, and set `npm_config_ignore_scripts=true` on the install command. The launcher is recommended because it unifies those conditions.
|
|
35
|
+
|
|
36
|
+
### Desktop users
|
|
37
|
+
|
|
38
|
+
Install the official Harness Desktop application with embedded runtime
|
|
39
|
+
0.2.0-rc.2. In **Plugins → Add plugin**, enter
|
|
40
|
+
`@toddzheng024/dscode-desktop@0.7.34`, review and install, then choose
|
|
41
|
+
**Enable now**. Select the DSCODE preset and configure your model account.
|
|
42
|
+
The Desktop preview is qualified on macOS Apple Silicon. See
|
|
43
|
+
[Desktop installation](browser-use.md#install-the-experimental-combined-desktop-package)
|
|
44
|
+
for archive checksums, migration and removal, and [Plugin Hub](plugin-hub.md)
|
|
45
|
+
for discovering community plugins after installation.
|
|
46
|
+
|
|
47
|
+
Version 0.7.34 fixes the 0.7.33 activation error “4 entries did not activate”
|
|
48
|
+
when Desktop starts without `DSH_HOME`. Update to the exact 0.7.34 package and
|
|
49
|
+
enable it again; exporting a shell variable is unnecessary. Default Desktop
|
|
50
|
+
state uses `~/.dsh`, as resolved by Harness. Publication now verifies installation
|
|
51
|
+
and the affected components with that default environment.
|
|
52
|
+
|
|
53
|
+
## Release checklist
|
|
54
|
+
|
|
55
|
+
Cutting a release from this repository, in order. The rule that matters most: **the git tag must equal `v<package.json version>`, and that version must not already be on npm from a different build.**
|
|
56
|
+
|
|
57
|
+
1. Decide the version and bump `package.json` `version`. Never re-tag a version that has already been published.
|
|
58
|
+
2. Ship the release documentation in the same commit: `docs/releases/<version>.md`, `docs/CHANGELOG.md` and both READMEs (see [AGENTS.md](https://github.com/qiz029/dscode/blob/main/AGENTS.md)).
|
|
59
|
+
3. Commit, then tag and push:
|
|
60
|
+
```sh
|
|
61
|
+
git tag v<version>
|
|
62
|
+
git push origin main --tags
|
|
63
|
+
```
|
|
64
|
+
The `build` job fails immediately when the tag and the manifest version disagree.
|
|
65
|
+
4. Watch the run:
|
|
66
|
+
```sh
|
|
67
|
+
gh run list --workflow=release.yml --limit 3
|
|
68
|
+
gh run view <run-id> # job and step status
|
|
69
|
+
gh run view --job=<job-id> --log-failed
|
|
70
|
+
```
|
|
71
|
+
5. On a tag push the `publish` job runs: credential check → bundle → profile sync → launcher → Desktop npm/Hub publication and public installation verification → attach the tarballs. **The launcher is published last on purpose**; a user's first launch fails when the launcher reaches npm before its bundle and its Hub profile. The order is enforced by the job, not by discipline.
|
|
72
|
+
6. Confirm the published result rather than the green check: the credential step prints `free to publish` (or `already on npm with the tested integrity` for a re-run), and the attach step either creates or updates the GitHub release the `dscode update` assets come from.
|
|
73
|
+
|
|
74
|
+
7. The Homebrew tap follows on its own: `qiz029/homebrew-tap` runs a scheduled (and manually dispatchable) workflow that reads `npm view @toddzheng024/dscode version`, recomputes the launcher tarball's sha256 and commits the formula change. It is deliberately not wired to this repository's tag push — the launcher is the last stage the publish job releases, so a formula bumped earlier would send a user to a Hub profile that is not there yet.
|
|
75
|
+
|
|
76
|
+
Before tagging, a dry run needs no publication: Actions → Release → Run workflow with both switches left `false` (build and verify only), or tick `verify_credentials` to check the tokens and whether the version is still free.
|
|
77
|
+
|
|
78
|
+
### Known failure modes
|
|
79
|
+
|
|
80
|
+
| Symptom | Cause | Fix |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| `publish` fails in about 30 seconds at *Check the publishing credentials* with `... is already on npm with a different build; bump the version before pushing a release tag` | That version was already published from a different build. An identical `dist.integrity` is treated as a skippable re-run; anything else is a conflict. | Bump `package.json` and cut a new tag. Do not re-tag, and do not force-push the tag. |
|
|
83
|
+
| `publish` fails at `test -n "$NPM_PUBLISH_TOKEN"` / `$DSH_HUB_TOKEN` | The repository secret is missing or empty. | Add it under Settings → Secrets and variables → Actions; see the table below. |
|
|
84
|
+
| A credential that is present but dead: `npm credential OK` or `Hub credential OK` never prints and the step dies inside `npm whoami` or the profile read | The token expired or lost its scope. | Regenerate the granular npm token (Read and write for the launcher, bundle and Desktop packages, bypass 2FA) and update the secret. |
|
|
85
|
+
| `build` fails in under a minute | A code or packaging problem, not credentials (0.7.14 failed this way on a missing bundle export). | Read that step's log, fix, and bump the version again if it was already published. |
|
|
86
|
+
| `make release`, `make verify` or `npm run doctor` fails inside a dscode session with `sandbox-exec: sandbox_apply: Operation not permitted` | The session's own sandbox refuses to apply a nested profile. | Run them from a normal terminal, or configure `plugins/tui-tools/sandbox-runner.mjs`; see [Verification](https://github.com/qiz029/dscode/blob/main/docs/verification.md). |
|
|
87
|
+
|
|
88
|
+
A tag push is the only thing that publishes. A manual run only publishes when `publish` is ticked, so a mis-typed dispatch cannot ship a release.
|
|
89
|
+
|
|
90
|
+
## Publisher
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
# Write the real GitHub repository into the release metadata; never a fabricated URL.
|
|
94
|
+
DSCODE_REPOSITORY=https://github.com/OWNER/REPO npm run build:packages
|
|
95
|
+
npm run release:hub
|
|
96
|
+
npm test
|
|
97
|
+
npm run verify:hub
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The same sequence is wrapped in Make targets: `make release` runs version-check, `npm run check`, `build:packages`, `release:hub`, `dist`, `verify:hub`, then Desktop preparation and exact-archive qualification in order and packs `release-candidates.tar.gz` (matching CI's build job); `make publish` runs the read-only credential check, then bundle, profile, launcher, Desktop publication/verification and release-asset upload (matching CI's publish job, requiring `NPM_PUBLISH_TOKEN`, `DSH_HUB_TOKEN` and, for attaching assets, `GH_TOKEN`). A single stage can be re-run with `make publish-bundle|publish-profile|publish-launcher`, and `make help` lists every target; the workflow itself does not call make.
|
|
101
|
+
|
|
102
|
+
Artifacts live in `artifacts/npm/`: two npm tgz files, the Hub draft/release JSON and the `.dshprofile`. A build copies only whitelisted files, never user configuration, credentials or sessions; a release carries the original MIT licence and the modification notice.
|
|
103
|
+
|
|
104
|
+
`verify:hub` installs a real launcher in a temporary directory and serves the not-yet-published bundle from a loopback npm registry. It checks the native locked Hub installer, imports the installed bundle's public `/startup` and `/tui` entries, checks launcher composition and Hub doctor, then uses separate external-executor fixtures for the agent loop, replacement and rollback. The import check resolves dependencies from that isolated profile so a developer checkout cannot supply missing terminal dependencies. Publication requires these results, including `terminalImports`, against the exact tarball hashes. It does not exercise interactive terminal rendering, public Hub discovery or a real npm publish. The tests request no remote model.
|
|
105
|
+
|
|
106
|
+
The launcher vendors Hub CLI 0.5.0 with a narrow compatibility fix for the empty `cordis.yml` generated by Harness composition. Only the exact generated content is excluded from dependency-input receipts, and only when package-manager hooks are absent. Custom root content, other configuration and dependency locks remain checked. The compatibility fix is applied to build copies; recipient dependencies are not patched during installation.
|
|
107
|
+
|
|
108
|
+
The publication order:
|
|
109
|
+
|
|
110
|
+
1. Validate the package metadata and the real public source repository with `dsh-hub validate artifacts/npm/bundle`.
|
|
111
|
+
2. Confirm `npm whoami` is `toddzheng024`, then publish the bundle tgz (`npm publish ... --access public`).
|
|
112
|
+
3. Register/claim `@toddzheng024/dscode-bundle` in the Hub publisher console and confirm the exact version resolves.
|
|
113
|
+
4. Save the generated profile draft, then publish the `dscode` release for the same version.
|
|
114
|
+
5. After verifying a public Hub apply/doctor under a fresh DSH_HOME, publish the launcher tgz.
|
|
115
|
+
6. Complete a first-launch verification in another clean directory using the launcher from public npm.
|
|
116
|
+
|
|
117
|
+
Never publish the launcher before the bundle/Hub release is available, or the user's first launch fails. A new version has to regenerate packages and the release; an old integrity hash cannot be reused. `build:packages` and `release:hub` produce the candidate artifacts; a release counts as done only after it is published and confirmed on the public registry. v0.1.0 has been distributed publicly through npm + Hub.
|
|
118
|
+
|
|
119
|
+
Hub calls retry in a bounded way (`scripts/hub-retry.mjs`): a 5xx or transport failure retries 5 times by default, 3 seconds apart, overridable with `DSCODE_HUB_RETRY_ATTEMPTS` / `DSCODE_HUB_RETRY_MS`; a 4xx (invalid token, missing package, immutable version) fails immediately. Exhausting the retries throws the last error, so a long Hub outage fails the release rather than continuing without verification.
|
|
120
|
+
|
|
121
|
+
The publish script runs per stage: `npm run publish:hub -- bundle`, `npm run publish:hub -- profile`, `npm run publish:hub -- launcher`. Each stage verifies the hashes of the tested artifacts; before publishing the launcher it checks the exact version and integrity of the public Hub release. The profile stage first calls the Hub's `sync` interface (available since dsh-hub CLI 0.3.0) so Hub pulls the bundle from npm immediately instead of waiting for the hourly sync; after the sync it still requires Hub to list that exact version. Claiming still needs the publisher console, and login uses `dsh-hub login`.
|
|
122
|
+
|
|
123
|
+
### Desktop release candidate and publication
|
|
124
|
+
|
|
125
|
+
The Desktop package is qualified separately from the terminal runtime. Build it
|
|
126
|
+
with Node 24 in an independent directory:
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
npm run prepare:desktop
|
|
130
|
+
DSCODE_TEST_CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
|
|
131
|
+
npm run release:desktop -- .research/desktop-release-runtime
|
|
132
|
+
node scripts/verify-desktop-registry.mjs .research/desktop-release-runtime --local
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`prepare:desktop` provisions exact direct dependencies with install scripts
|
|
136
|
+
disabled; it refuses to overwrite an unrelated project. `release:desktop`
|
|
137
|
+
builds a public candidate only for Harness 0.2.0-rc.2, then unpacks those exact
|
|
138
|
+
bytes for Host startup/restart, browser, annotation, isolation and authenticated
|
|
139
|
+
Hub RPC checks. The source runtime is checked for unintended changes. The
|
|
140
|
+
local install rehearsal additionally resolves dependencies in a new native
|
|
141
|
+
Harness profile and boots the installed package; it does not establish public
|
|
142
|
+
npm availability or drive the Electron UI.
|
|
143
|
+
|
|
144
|
+
Artifacts under `artifacts/desktop/release/` include the `.tgz`, SHA-256 file,
|
|
145
|
+
installation README, release notes, candidate receipt and qualification record.
|
|
146
|
+
This generated directory is replaced on each build. `make desktop` runs the
|
|
147
|
+
preparation and qualification steps; `make release` includes it and requires
|
|
148
|
+
`DSCODE_TEST_CHROME`.
|
|
149
|
+
|
|
150
|
+
After the release gates pass:
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
npm run publish:desktop -- credentials
|
|
154
|
+
npm run publish:desktop -- npm
|
|
155
|
+
npm run publish:desktop -- hub
|
|
156
|
+
npm run publish:desktop -- verify
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Each phase checks the archive and receipt again. The npm phase publishes with
|
|
160
|
+
`--tag preview`; an existing version is reusable only with identical integrity.
|
|
161
|
+
The Hub phase syncs the package and requires the exact version, integrity and
|
|
162
|
+
Desktop compatibility to resolve. A newly published package can appear on
|
|
163
|
+
the npm version endpoint before the Hub can fetch its package index. In this
|
|
164
|
+
post-publication phase, `package_not_found` and an index missing the exact
|
|
165
|
+
version retry up to 40 times, 15 seconds apart. Other rejections and credential
|
|
166
|
+
errors stop immediately; the final integrity and compatibility checks still
|
|
167
|
+
apply. The final phase downloads public bytes,
|
|
168
|
+
checks their SHA-256, and installs the exact npm version into a new native
|
|
169
|
+
Harness profile before booting it and checking the preset and Hub RPC. The
|
|
170
|
+
result is saved as `artifacts/local/desktop-public-install.json`. No model
|
|
171
|
+
account is used, and no real-model quality claim follows from these probes.
|
|
172
|
+
|
|
173
|
+
The existing npm token must permit the new Desktop package. Successful `whoami`
|
|
174
|
+
proves authentication only; the first publish establishes write permission.
|
|
175
|
+
Desktop publication does not replace the terminal profile, create a DMG, or
|
|
176
|
+
implement an automatic Desktop updater. GitHub Release attaches the Desktop
|
|
177
|
+
archive, checksum and instructions alongside the terminal assets. Follow the
|
|
178
|
+
[Plugin Hub guide](plugin-hub.md) for discovery and official management.
|
|
179
|
+
|
|
180
|
+
### Login-free publishing (local machine)
|
|
181
|
+
|
|
182
|
+
The account has auth-and-writes two-factor enabled, so `npm login`'s session token expires and every `npm publish` asks for a one-time code again. Use a **granular access token** instead, which the publish script picks up automatically:
|
|
183
|
+
|
|
184
|
+
1. Generate a granular token on npm's Access Tokens page: tick *Bypass two-factor authentication*, grant Read and write only to `@toddzheng024/dscode`, `@toddzheng024/dscode-bundle` and `@toddzheng024/dscode-desktop` under Packages and scopes, and pick an expiry that suits you (repeat this step when it expires). Granular tokens can currently only be created on the website.
|
|
185
|
+
2. `npm run publish:token store` and paste the token at the `security` password prompt. It goes into the login keychain (service `dscode-npm-publish`) and never into `~/.npmrc`, the command line or the shell history.
|
|
186
|
+
3. `npm run publish:token check` confirms the token authenticates as `toddzheng024`.
|
|
187
|
+
|
|
188
|
+
After that `npm run publish:hub -- bundle|launcher` takes the token from the keychain and hands it to npm through a one-off temporary `--userconfig`, so no login and no one-time code are needed. A temporary environment can override with `NPM_PUBLISH_TOKEN`; with neither present it falls back to the original interactive flow. `npm run publish:token remove` deletes the keychain token.
|
|
189
|
+
|
|
190
|
+
npm has announced that publishing directly with a bypass-2FA token is retired in January 2027; from then local publishing has to move to trusted publishing (OIDC) in CI.
|
|
191
|
+
|
|
192
|
+
### GitHub Actions
|
|
193
|
+
|
|
194
|
+
Two workflows:
|
|
195
|
+
|
|
196
|
+
- `.github/workflows/checks.yml`: runs `npm run check` on `macos-14` for every push/PR (a matrix of Node 22.19.0 and 24) and uploads the coverage artifacts; a newer push to the same ref cancels the previous run.
|
|
197
|
+
- `.github/workflows/release.yml`: on a `v*` tag push (or a manual `workflow_dispatch`) it runs the `build` job first — `npm run check` → `npm run build:packages` → `npm run release:hub` → `npm run verify:hub` — uploading `artifacts/npm` and `artifacts/local/hub-verification.json` as the `release-candidates` artifact. A separate `desktop` job prepares Harness 0.2.0-rc.2 and verifies the exact public Desktop archive with real Chrome, then uploads `desktop-candidate`. The `publish` job depends on both jobs and is attached to the `release` environment (add required reviewers under repository Settings → Environments for manual approval).
|
|
198
|
+
|
|
199
|
+
Publish credentials live in repository Secrets (Settings → Secrets and variables → Actions):
|
|
200
|
+
|
|
201
|
+
| Secret | Purpose |
|
|
202
|
+
| --- | --- |
|
|
203
|
+
| `DSH_HUB_TOKEN` | Hub CI credential. `@dsh-plugin-hub/cli`'s `getAccessToken()` prefers it, so the pipeline runs no device login and does not depend on a 5-minute WorkOS access token. |
|
|
204
|
+
| `NPM_PUBLISH_TOKEN` | npm granular token (tick *Bypass two-factor authentication*, granting Read and write to `@toddzheng024/dscode`, `@toddzheng024/dscode-bundle` and `@toddzheng024/dscode-desktop`, including permission to create the Desktop package on its first publication). `npm run publish:hub` writes it into a one-off `--userconfig` that never touches disk or the shell history. |
|
|
205
|
+
|
|
206
|
+
Publishing runs in the three documented stages, each re-verifying the hashes checked above: `publish:hub -- bundle` → `publish:hub -- profile` (sync Hub from npm first, then require that exact version to resolve) → `publish:hub -- launcher`. **The launcher always follows the bundle and the public Hub release**, or the user's first launch fails. Claiming a new package in the Hub console is still manual; when the tag and the `package.json` version disagree the `build` job fails outright and nothing is published.
|
|
207
|
+
|
|
208
|
+
Manual dry run: Actions → Release → Run workflow with both switches left at `false`, which only builds and verifies the candidate artifacts without publishing.
|
|
209
|
+
|
|
210
|
+
Credential check only: Actions → Release → Run workflow with `verify_credentials` ticked. It runs the full `build` job, then enters the `publish` job and uses `node scripts/check-publish-credentials.mjs` to do a **read-only** check — whether the npm token authenticates as `toddzheng024`, whether the Hub token can read the `dscode` profile, and whether the current version number is still free on npm — then stops without publishing anything. The check fails when the version is already on npm, which is exactly what blocks "push a tag after forgetting to bump the version".
|
|
211
|
+
|
|
212
|
+
The Hub stage (`profile`) uses the WorkOS session written by `dsh-hub login` into `~/.dsh/.hub/auth.json`; the access token lasts 5 minutes and the script refreshes it automatically with the refresh token, so `dsh-hub login` is only needed again once the refresh token expires.
|