dsh-plugin-pwsh7
Manifest validReplaces the Windows pwsh executor row so the model-facing pwsh tool runs PowerShell 7, with a shell_router tool for status, diagnosis, and per-user portable installation.
dsh-plugin-pwsh7
Windows DeepSeek Harness (DSH) bundle that routes the model-facing pwsh tool to PowerShell 7
(pwsh.exe, major version >= 7) instead of falling back to Windows PowerShell 5.1.
- The executor inherits every behavior of the stock
dsh-pwsh-sandboxexecutor: sandbox modes,sandbox_permissionsescalation, denial/runner-failure facts, background jobs, output caps, and exit markers. It only replaces executable resolution. - When PowerShell 7 is missing, a model-facing
shell_routertool reports status, diagnoses sandbox problems, and installs PowerShell 7 for the current user or the system, with matching PATH updates. - In the Web GUI, a setup dialog opens whenever PowerShell 7 is missing — on load and again on
every
pwshrun — with a download button and live progress (bytes, percent, phase). Closing it never cancels an install, and the next failed run re-opens it.
English | 中文说明
Why
On Windows, DSH mounts pwsh-sandbox as ctx.shell, but the resolved executable can end up being
Windows PowerShell 5.1 in some environments. This bundle keeps the stock PowerShell executor and
overrides only its pwshPath resolution:
- Take over the
pwsh-sandboxslot: a DSH patch entry'snameasserts the targeted row, it does not replace it, so the stock row is disabled by id and aRouterPwshExecutor extends SandboxPwshExecutorrow (id: pwsh7-executor) is inserted. An explicitconfig.pwshPathstill wins; otherwise the plugin-resolved PowerShell 7 is used. - Insert the bare
dsh-plugin-pwsh7row, which registers theshell_routertool (status/diagnose/install), a small system-prompt section, and the Web setup routes. That row's name is also what DSH's client-module scanner uses to discoverclient.js; the executor row's./pwsh-executorsubpath is not a client-bundle source.
Requirements
- Windows 10/11.
- A DSH profile that supports bundles (
@deepseek-ai/dsh-base/ Web profile). Tested against DSH desktop 0.2.1-rc.2. - Node.js >= 22 is only needed to run the repository test suite.
Installation
Install from npm through the DSH plugin manager:
plugin_manager action=install_bundle target=dsh-plugin-pwsh7@0.2.2
Or install from a local checkout (a directory install links the checkout, which is convenient while developing):
plugin_manager action=install_bundle target=D:\path\to\dsh-plugin-pwsh7
The new bundle is applied through HMR immediately. After changing the plugin's source, restart DSH to load a fresh module generation.
Usage
The model-facing shell_router tool:
| Action | What it does |
|---|---|
status (default) | Resolved PowerShell 7 path and version, config file, current sandbox policy, shipped-package resolution. |
diagnose | Runs real PowerShell 7 commands under the current sandbox policy (version + workspace write) and reports exit codes, stdout/stderr, denial/runner-failure classification, and concrete hints. |
install | Ensures PowerShell 7 exists. method: "auto" (default) prefers the portable zip for the selected scope, then falls back to winget; portable/winget force one strategy. Existing working installations within the selected scope are reused and their PATH is repaired. |
Setup dialog (Web)
The browser half renders into DSH's root shell.overlay slot, so it works in the ordinary Web GUI
and in the desktop shell without a second window:
- When it opens: on first load when
pwsh.execannot be found, and again every time apwshtool run fails for that reason (missingSeq). "Not now" hides it until the next failed run; a page reload opens it again while PowerShell 7 is still missing. - What it does:
Download and installstarts the same scoped installation job asshell_router install. The dialog showsdownloading → extracting → verifying, transferred bytes, total, and percent.Cancel downloadaborts it. - Why one job: the dialog and the tool share one coordinator, so a model-triggered install is
visible in the dialog (with progress) and a dialog-triggered install is awaited by the tool.
Concurrent installs would race on the same archive under
%LOCALAPPDATA%\dsh\pwsh7\tmp. - Transport:
GET /pwsh7/state(snapshot),GET /pwsh7/events(SSE, progress coalesced to ~7 frames/s),POST /pwsh7/install,POST /pwsh7/cancel. SSE drives smooth progress; a 3 s/pwsh7/statepoll stays active as the fallback for carriers that buffer event streams. These routes are same-origin and accept POST bodies only asapplication/json. - Failure: the dialog keeps the installer's message, offers
Retry, and links to the official PowerShell releases page. A failed install does not affectpwshrouting until one succeeds. - Scope: the dialog belongs to the Web GUI. A headless/CLI composition still gets the
shell_routertool and the same installer, just without a window.
Explicit paths
Resolution order for the pwsh executable:
DSH_PWSH_PATHenvironment variablepwshPathin%LOCALAPPDATA%\dsh\pwsh7\config.json%ProgramFiles%\PowerShell\7\pwsh.exe%LOCALAPPDATA%\dsh\pwsh7\powershell7\…\pwsh.exe(portable installs, newest first)%LOCALAPPDATA%\Programs\PowerShell\7\pwsh.exe- every
PATHentry %LOCALAPPDATA%\Microsoft\WindowsApps\pwsh.exe(Store alias)%ProgramFiles(x86)%\PowerShell\7\pwsh.exe
The stock pwsh-sandbox row still accepts its official pwshPath config field; an explicit config
value takes precedence over automatic detection.
Config file
%LOCALAPPDATA%\dsh\pwsh7\config.json:
{
"version": 1,
"pwshPath": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"installed": {
"pwsh": {
"path": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"version": "7.6.7",
"method": "existing",
"at": "2026-10-17T00:00:00.000Z"
}
},
"updatedAt": "2026-10-17T00:00:00.000Z"
}
Automatic installation
Choose scope: "user" (default) or scope: "system" in shell_router install, or select the scope in the Web dialog.
| Scope | Destination | Persistent PATH |
|---|---|---|
user | %LOCALAPPDATA%\dsh\pwsh7\powershell7\<version> | Current user (HKCU\Environment) |
system | %ProgramFiles%\PowerShell\7 | System (HKLM environment) |
System installation requires starting the DSH host as administrator; an unelevated host fails before downloading. User installation needs no elevation. Both preserve existing PATH entries and registry value types, avoid duplicate entries, refresh the host process PATH, and notify Windows. Already running terminals may need reopening. PATH write failures are reported as installation failures.
shell_router action=install scope=user
shell_router action=install scope=system
Portable download source:
| Component | Source | Destination |
|---|---|---|
| PowerShell 7 | Latest PowerShell/PowerShell GitHub release, PowerShell-*-win-x64.zip | %LOCALAPPDATA%\dsh\pwsh7\powershell7\<version>\ |
- HTTPS streaming download into
%LOCALAPPDATA%\dsh\pwsh7\tmp, with progress callbacks and cancellation. - Extraction uses the Windows built-in
tar.exe(bsdtar). No downloaded installer is ever executed. - After extraction the new
pwsh.exeis executed once to verify a major version >= 7 before it is written intoconfig.json. autofalls back towinget install Microsoft.PowerShell; when elevation would be required the result carries the exact manual elevated command instead of hanging on UAC.- winget receives
--scope useror--scope machine; fallback never changes the selected scope. - Live-tested on Windows: 106,364,316-byte zip downloaded in ~31 s, extracted to 244.8 MB, verified
7.6.7.
Sandbox behavior
- The executor runs through
ctx.sandbox.confine()and the Windows ACL restricted-token runner, with the sameworkspace-write/read-only/danger-full-accesssemantics as the stock executor. - PowerShell 7 works in all three modes (verified:
workspace-writecan write inside the workspace and is denied outside it;danger-full-accessis unconfined). - If the Windows sandbox reports
SetNamedSecurityInfoW failed (Win32 5)/grantWrite(<workspace>), the workspace DACL is missing rights. Run DSH's bundleddiagnose-windows-sandbox-aclskill against the workspace root (it backs up and verifies), or temporarily switch the session to full access.
Troubleshooting
- Run
shell_router action="status"and check the resolved path/version. - Run
shell_router action="diagnose"to execute real commands under the current sandbox policy. - Common causes:
- Still Windows PowerShell 5.1 — detection did not find PowerShell 7. Set
DSH_PWSH_PATHor thepwshPathconfig entry, then checkstatusagain. - PowerShell 7 installed in a custom location — set
DSH_PWSH_PATHorconfig.json. - Sandbox/ACL failure — see the sandbox section above.
- Still Windows PowerShell 5.1 — detection did not find PowerShell 7. Set
Architecture
| Path | Role |
|---|---|
index.js | Bare package row: installs shell_router, the system-prompt section, setup routes, and the reload hook |
client.js | Browser half: shell.overlay setup dialog, SSE + polling, download/cancel actions, en/zh copy |
lib/shipped.mjs | Loads the shipped @deepseek-ai/* packages from the running DSH installation (app.asar) |
lib/paths.mjs | PowerShell 7 detection, version probing, config.json IO |
lib/install.mjs | Per-user portable install (official zip) + winget fallback; progress and phase callbacks |
lib/state.mjs | Process-wide resolution cache shared by the executor and the tool; missing-run signal |
lib/router-features.mjs | Installs shell_router, the system-prompt section, the setup coordinator, and routes from the bare package row |
lib/setup-service.mjs | Single install coordinator: one job, progress snapshots, cancel, missingSeq |
lib/setup-routes.mjs | /pwsh7/state, /pwsh7/events (SSE), /pwsh7/install, /pwsh7/cancel |
lib/status.mjs | status / diagnose implementations |
lib/executors/pwsh.mjs | PowerShell 7 executor (extends the official SandboxPwshExecutor) |
cordis.patch.yml | Bundle patch: disables the stock pwsh-sandbox, inserts the executor and bare package rows (Windows only) |
locale/en.json, locale/zh.json, icon.svg | Plugin-manager display metadata |
package.json files ships only the runtime pieces; test/ stays in the repository.
Development
# Plain Node tests (no running DSH required)
node --test test/paths.test.mjs test/install.test.mjs test/setup.test.mjs test/client.test.mjs
- 72 tests: 71 pass, 0 fail, 1 skipped (network-gated by default).
DSH_PWSH7_NETWORK_TESTS=1enables the live GitHub release / HEAD checks: 30/30 pass.- The environment override prefix is
DSH_PWSH7_*(APP_ROOT,TAR,NETWORK_TESTS).
Publishing (maintainers)
Releases are published by GitHub Actions through npm Trusted Publishing (OIDC) — no npm token, OTP or repository secret is involved.
- Bump
versioninpackage.json, commit and push tomain. - Create and push a matching tag and publish a GitHub Release (for example
v0.2.0). .github/workflows/publish.ymlruns onrelease: published, verifies the tag matchespackage.json, runs the test suite, and publishes with provenance (npm publish --access public --provenance).
One-time npm-side setup (already configured for this repository):
npx npm@12 trust github dsh-plugin-pwsh7 `
--file publish.yml `
--repo drliuhuan/dsh-plugin-pwsh7 `
--allow-publish --yes
Manual dry run: Actions → Publish to npm → Run workflow, keep dry_run checked. The workflow
then runs npm publish --dry-run --provenance without publishing.
Only publish.yml in drliuhuan/dsh-plugin-pwsh7 is authorized to publish. Inspect or revoke the
relationship with:
npx npm@12 trust list dsh-plugin-pwsh7
npx npm@12 trust revoke dsh-plugin-pwsh7 --id <trust-id>
Versioning note
0.1.0 was the first public release. 0.1.1 is the first release published through npm
Trusted Publishing (OIDC) by GitHub Actions, and fixes the npm-hosted README cross-links.
0.2.0 adds the Web setup dialog and moves installation into one shared coordinator.
Earlier internal iterations (0.2.x/0.3.x) included MSYS2 bash routing and used a different package
name; that scope was removed because MSYS2/Cygwin cannot start under the DSH Windows ACL sandbox.
The historical evidence stays in the build workspace (sandbox-recon/FINDINGS.md), not in this
package.
Uninstall
plugin_manager action=remove_bundle target=dsh-plugin-pwsh7
The native Windows preset is restored and pwsh returns to DSH's default resolution. The per-user
directory %LOCALAPPDATA%\dsh\pwsh7\ is not deleted automatically.
License
MIT — see LICENSE.
Comments
Loading…
Similar plugins
by xinspark
PowerShell 7 for the DSH `pwsh` tool on Windows: detect, validate, and install the self-updating Microsoft Store package — one install path, with the connection checked first.
★ 0
MIT
JavaScript
Oct 13, 2026
dsh plugin --profile web add dsh-win-pwsh7by Saikel-Orado-Liu
Windows-adapted DSH coding agent preset with persistent PowerShell 7 (pwsh) and str_replace_editor, mirroring the official minimal preset.
★ 3
MIT
JavaScript
Aug 21, 2026
dsh plugin --profile web add @gamegeek-saikel/dsh-coding-presetby 0x1a27
Fixes the DSH Desktop built-in pwsh/shell silent empty-result bug by self-healing the Electron sandbox runner (injects ELECTRON_RUN_AS_NODE=1) on every boot, and provides the pwsh_direct rescue tool that spawns PowerShell directly via node:child_process (pwsh 7 preferred, Windows PowerShell 5.1 fallback), optionally gated by the dsh-powershell-check pitfall checker.
★ 0
MIT
JavaScript
Aug 19, 2026
dsh plugin --profile web add dsh-pwsh-directby MAXeaglet
DSH plugin: one shell tool that runs commands through PowerShell, Git Bash, or WSL on Windows, with a user-chosen default terminal in the Web UI settings.
★ 23
↓ 218/wk
MIT
JavaScript
Sep 11, 2026
dsh plugin --profile web add dsh-bash-terminalDSH plugin: one shell tool that runs commands through PowerShell, Git Bash, MSYS2, or WSL on Windows, with a user-chosen default terminal in the Web UI settings. TypeScript rewrite of MAXeaglet/dsh-bash-terminal with working MSYS2/MINGW64 support.
★ 0
dsh plugin --profile web add dsh-bash-terminal-tsby yanglaofish
Routes model requests, web fetches/searches and spawned tools through the Windows system proxy or a custom address — idempotent kernel (reads never rebuild the dispatcher), header one-click toggle, pe
★ 4
↓ 322/wk
MIT
JavaScript
Sep 23, 2026
dsh plugin --profile web add @yanglaofish/dsh-proxy-pro