dsh-plugin-pwsh7 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,33 @@
1
+ # Changelog
2
+
3
+ All notable changes to `dsh-plugin-pwsh7` are documented here.
4
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.1.1] - 2026-10-17
8
+
9
+ ### Changed
10
+
11
+ - Published through npm **Trusted Publishing** (OIDC) from GitHub Actions — no npm token, OTP, or
12
+ repository secret is used.
13
+ - Added `.github/workflows/publish.yml`: runs on a published GitHub Release, verifies the release
14
+ tag matches `package.json`, runs the test suite, and publishes with npm provenance.
15
+ - `publishConfig.provenance` is enabled.
16
+ - README cross-links were made absolute so they render correctly on npm.
17
+ - Added this changelog and included it in the npm package.
18
+
19
+ ## [0.1.0] - 2026-10-17
20
+
21
+ ### Added
22
+
23
+ - First public release.
24
+ - Windows DSH bundle that replaces the `pwsh-sandbox` executor row with a PowerShell 7 resolver,
25
+ keeping the stock sandbox, escalation, job, and rendering behavior.
26
+ - Model-facing `shell_router` tool with `status`, `diagnose`, and `install` actions.
27
+ - Per-user automatic PowerShell 7 installation from the official GitHub release zip, with a
28
+ winget fallback and no administrator rights.
29
+ - Bilingual README (English/Chinese), bilingual plugin-manager locale, and a PowerShell 7 icon.
30
+ - 49 unit tests (48 pass, 1 network-gated skip).
31
+
32
+ [0.1.1]: https://github.com/drliuhuan/dsh-plugin-pwsh7/compare/v0.1.0...v0.1.1
33
+ [0.1.0]: https://github.com/drliuhuan/dsh-plugin-pwsh7/releases/tag/v0.1.0
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 dsh-plugin-pwsh7 contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-plugin-pwsh7 contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,186 +1,219 @@
1
- # dsh-plugin-pwsh7
2
-
3
- [![npm version](https://img.shields.io/npm/v/dsh-plugin-pwsh7.svg)](https://www.npmjs.com/package/dsh-plugin-pwsh7)
4
- [![license](https://img.shields.io/npm/l/dsh-plugin-pwsh7.svg)](LICENSE)
5
-
6
- Windows DeepSeek Harness (DSH) bundle that routes the model-facing **`pwsh` tool to PowerShell 7**
7
- (`pwsh.exe`, major version >= 7) instead of falling back to Windows PowerShell 5.1.
8
-
9
- - The executor inherits every behavior of the stock `dsh-pwsh-sandbox` executor: sandbox modes,
10
- `sandbox_permissions` escalation, denial/runner-failure facts, background jobs, output caps, and
11
- exit markers. It only replaces executable resolution.
12
- - When PowerShell 7 is missing, a model-facing **`shell_router`** tool reports status, diagnoses
13
- sandbox problems, and installs PowerShell 7 per-user (no administrator required).
14
-
15
- English | [中文说明](README.zh.md)
16
-
17
- ---
18
-
19
- ## Why
20
-
21
- On Windows, DSH mounts `pwsh-sandbox` as `ctx.shell`, but the resolved executable can end up being
22
- Windows PowerShell 5.1 in some environments. This bundle keeps the stock PowerShell executor and
23
- overrides only its `pwshPath` resolution:
24
-
25
- 1. **Replace the `pwsh-sandbox` row** with `RouterPwshExecutor extends SandboxPwshExecutor`. An
26
- explicit `config.pwshPath` still wins; otherwise the plugin-resolved PowerShell 7 is used.
27
- 2. **Register the `shell_router` tool** (`status` / `diagnose` / `install`) plus a small system-prompt
28
- section describing the routing.
29
-
30
- ## Requirements
31
-
32
- - Windows 10/11.
33
- - A DSH profile that supports bundles (`@deepseek-ai/dsh-base` / Web profile). Tested against
34
- DSH desktop 0.2.1-rc.2.
35
- - Node.js >= 22 is only needed to run the repository test suite.
36
-
37
- ## Installation
38
-
39
- Install from npm through the DSH plugin manager:
40
-
41
- ```
42
- plugin_manager action=install_bundle target=dsh-plugin-pwsh7@0.1.0
43
- ```
44
-
45
- Or install from a local checkout (a directory install links the checkout, which is convenient while
46
- developing):
47
-
48
- ```
49
- plugin_manager action=install_bundle target=D:\path\to\dsh-plugin-pwsh7
50
- ```
51
-
52
- The new bundle is applied through HMR immediately. After changing the plugin's source, restart DSH
53
- to load a fresh module generation.
54
-
55
- ## Usage
56
-
57
- The model-facing `shell_router` tool:
58
-
59
- | Action | What it does |
60
- |---|---|
61
- | `status` (default) | Resolved PowerShell 7 path and version, config file, current sandbox policy, shipped-package resolution. |
62
- | `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. |
63
- | `install` | Ensures PowerShell 7 exists. `method: "auto"` (default) prefers the per-user portable zip, then falls back to winget; `portable`/`winget` force one strategy. Existing working installations are reused instead of downloading again. |
64
-
65
- ### Explicit paths
66
-
67
- Resolution order for the pwsh executable:
68
-
69
- 1. `DSH_PWSH_PATH` environment variable
70
- 2. `pwshPath` in `%LOCALAPPDATA%\dsh\pwsh7\config.json`
71
- 3. `%ProgramFiles%\PowerShell\7\pwsh.exe`
72
- 4. `%LOCALAPPDATA%\dsh\pwsh7\powershell7\…\pwsh.exe` (portable installs, newest first)
73
- 5. `%LOCALAPPDATA%\Programs\PowerShell\7\pwsh.exe`
74
- 6. every `PATH` entry
75
- 7. `%LOCALAPPDATA%\Microsoft\WindowsApps\pwsh.exe` (Store alias)
76
- 8. `%ProgramFiles(x86)%\PowerShell\7\pwsh.exe`
77
-
78
- The stock `pwsh-sandbox` row still accepts its official `pwshPath` config field; an explicit config
79
- value takes precedence over automatic detection.
80
-
81
- ### Config file
82
-
83
- `%LOCALAPPDATA%\dsh\pwsh7\config.json`:
84
-
85
- ```json
86
- {
87
- "version": 1,
88
- "pwshPath": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
89
- "installed": {
90
- "pwsh": {
91
- "path": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
92
- "version": "7.6.7",
93
- "method": "existing",
94
- "at": "2026-10-17T00:00:00.000Z"
95
- }
96
- },
97
- "updatedAt": "2026-10-17T00:00:00.000Z"
98
- }
99
- ```
100
-
101
- ## Automatic installation
102
-
103
- Per-user, no administrator rights:
104
-
105
- | Component | Source | Destination |
106
- |---|---|---|
107
- | PowerShell 7 | Latest `PowerShell/PowerShell` GitHub release, `PowerShell-*-win-x64.zip` | `%LOCALAPPDATA%\dsh\pwsh7\powershell7\<version>\` |
108
-
109
- - HTTPS streaming download into `%LOCALAPPDATA%\dsh\pwsh7\tmp`, with progress callbacks and
110
- cancellation.
111
- - Extraction uses the Windows built-in `tar.exe` (bsdtar). No downloaded installer is ever executed.
112
- - After extraction the new `pwsh.exe` is executed once to verify a major version >= 7 before it is
113
- written into `config.json`.
114
- - `auto` falls back to `winget install Microsoft.PowerShell`; when elevation would be required the
115
- result carries the exact manual elevated command instead of hanging on UAC.
116
- - No writes outside the router root and its temp directory.
117
- - Live-tested on Windows: 106,364,316-byte zip downloaded in ~31 s, extracted to 244.8 MB, verified
118
- `7.6.7`.
119
-
120
- ## Sandbox behavior
121
-
122
- - The executor runs through `ctx.sandbox.confine()` and the Windows ACL restricted-token runner, with
123
- the same `workspace-write` / `read-only` / `danger-full-access` semantics as the stock executor.
124
- - PowerShell 7 works in all three modes (verified: `workspace-write` can write inside the workspace
125
- and is denied outside it; `danger-full-access` is unconfined).
126
- - If the Windows sandbox reports `SetNamedSecurityInfoW failed (Win32 5)` / `grantWrite(<workspace>)`,
127
- the workspace DACL is missing rights. Run DSH's bundled **`diagnose-windows-sandbox-acl`** skill
128
- against the workspace root (it backs up and verifies), or temporarily switch the session to full
129
- access.
130
-
131
- ## Troubleshooting
132
-
133
- 1. Run `shell_router action="status"` and check the resolved path/version.
134
- 2. Run `shell_router action="diagnose"` to execute real commands under the current sandbox policy.
135
- 3. Common causes:
136
- - **Still Windows PowerShell 5.1** — detection did not find PowerShell 7. Set `DSH_PWSH_PATH` or
137
- the `pwshPath` config entry, then check `status` again.
138
- - **PowerShell 7 installed in a custom location** — set `DSH_PWSH_PATH` or `config.json`.
139
- - **Sandbox/ACL failure** — see the sandbox section above.
140
-
141
- ## Architecture
142
-
143
- | Path | Role |
144
- |---|---|
145
- | `index.js` | Plugin entry: `shell_router` tool, system-prompt section, state refresh on config reload |
146
- | `lib/shipped.mjs` | Loads the shipped `@deepseek-ai/*` packages from the running DSH installation (`app.asar`) |
147
- | `lib/paths.mjs` | PowerShell 7 detection, version probing, `config.json` IO |
148
- | `lib/install.mjs` | Per-user portable install (official zip) + winget fallback |
149
- | `lib/state.mjs` | Process-wide resolution cache shared by the executor and the tool |
150
- | `lib/status.mjs` | `status` / `diagnose` implementations |
151
- | `lib/executors/pwsh.mjs` | PowerShell 7 executor (extends the official `SandboxPwshExecutor`) |
152
- | `cordis.patch.yml` | Bundle patch: replaces `pwsh-sandbox` and inserts the plugin row (Windows only) |
153
- | `locale/en.json`, `locale/zh.json`, `icon.svg` | Plugin-manager display metadata |
154
-
155
- `package.json` `files` ships only the runtime pieces; `test/` stays in the repository.
156
-
157
- ## Development
158
-
159
- ```powershell
160
- # Plain Node tests (no running DSH required)
161
- node --test test/paths.test.mjs test/install.test.mjs
162
- ```
163
-
164
- - 49 tests: 48 pass, 0 fail, 1 skipped (network-gated by default).
165
- - `DSH_PWSH7_NETWORK_TESTS=1` enables the live GitHub release / HEAD checks: 30/30 pass.
166
- - The environment override prefix is `DSH_PWSH7_*` (`APP_ROOT`, `TAR`, `NETWORK_TESTS`).
167
-
168
- ## Versioning note
169
-
170
- `0.1.0` is the first public release. Earlier internal iterations (0.2.x/0.3.x) included MSYS2 bash
171
- routing and used a different package name; that scope was removed because MSYS2/Cygwin cannot start
172
- under the DSH Windows ACL sandbox. The historical evidence stays in the build workspace
173
- (`sandbox-recon/FINDINGS.md`), not in this package.
174
-
175
- ## Uninstall
176
-
177
- ```
178
- plugin_manager action=remove_bundle target=dsh-plugin-pwsh7
179
- ```
180
-
181
- The native Windows preset is restored and `pwsh` returns to DSH's default resolution. The per-user
182
- directory `%LOCALAPPDATA%\dsh\pwsh7\` is not deleted automatically.
183
-
184
- ## License
185
-
186
- MIT — see [LICENSE](LICENSE).
1
+ # dsh-plugin-pwsh7
2
+
3
+ [![npm version](https://img.shields.io/npm/v/dsh-plugin-pwsh7.svg)](https://www.npmjs.com/package/dsh-plugin-pwsh7)
4
+ [![license](https://img.shields.io/npm/l/dsh-plugin-pwsh7.svg)](https://github.com/drliuhuan/dsh-plugin-pwsh7/blob/main/LICENSE)
5
+
6
+ Windows DeepSeek Harness (DSH) bundle that routes the model-facing **`pwsh` tool to PowerShell 7**
7
+ (`pwsh.exe`, major version >= 7) instead of falling back to Windows PowerShell 5.1.
8
+
9
+ - The executor inherits every behavior of the stock `dsh-pwsh-sandbox` executor: sandbox modes,
10
+ `sandbox_permissions` escalation, denial/runner-failure facts, background jobs, output caps, and
11
+ exit markers. It only replaces executable resolution.
12
+ - When PowerShell 7 is missing, a model-facing **`shell_router`** tool reports status, diagnoses
13
+ sandbox problems, and installs PowerShell 7 per-user (no administrator required).
14
+
15
+ English | [中文说明](https://github.com/drliuhuan/dsh-plugin-pwsh7/blob/main/README.zh.md)
16
+
17
+ ---
18
+
19
+ ## Why
20
+
21
+ On Windows, DSH mounts `pwsh-sandbox` as `ctx.shell`, but the resolved executable can end up being
22
+ Windows PowerShell 5.1 in some environments. This bundle keeps the stock PowerShell executor and
23
+ overrides only its `pwshPath` resolution:
24
+
25
+ 1. **Replace the `pwsh-sandbox` row** with `RouterPwshExecutor extends SandboxPwshExecutor`. An
26
+ explicit `config.pwshPath` still wins; otherwise the plugin-resolved PowerShell 7 is used.
27
+ 2. **Register the `shell_router` tool** (`status` / `diagnose` / `install`) plus a small system-prompt
28
+ section describing the routing.
29
+
30
+ ## Requirements
31
+
32
+ - Windows 10/11.
33
+ - A DSH profile that supports bundles (`@deepseek-ai/dsh-base` / Web profile). Tested against
34
+ DSH desktop 0.2.1-rc.2.
35
+ - Node.js >= 22 is only needed to run the repository test suite.
36
+
37
+ ## Installation
38
+
39
+ Install from npm through the DSH plugin manager:
40
+
41
+ ```
42
+ plugin_manager action=install_bundle target=dsh-plugin-pwsh7@0.1.0
43
+ ```
44
+
45
+ Or install from a local checkout (a directory install links the checkout, which is convenient while
46
+ developing):
47
+
48
+ ```
49
+ plugin_manager action=install_bundle target=D:\path\to\dsh-plugin-pwsh7
50
+ ```
51
+
52
+ The new bundle is applied through HMR immediately. After changing the plugin's source, restart DSH
53
+ to load a fresh module generation.
54
+
55
+ ## Usage
56
+
57
+ The model-facing `shell_router` tool:
58
+
59
+ | Action | What it does |
60
+ |---|---|
61
+ | `status` (default) | Resolved PowerShell 7 path and version, config file, current sandbox policy, shipped-package resolution. |
62
+ | `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. |
63
+ | `install` | Ensures PowerShell 7 exists. `method: "auto"` (default) prefers the per-user portable zip, then falls back to winget; `portable`/`winget` force one strategy. Existing working installations are reused instead of downloading again. |
64
+
65
+ ### Explicit paths
66
+
67
+ Resolution order for the pwsh executable:
68
+
69
+ 1. `DSH_PWSH_PATH` environment variable
70
+ 2. `pwshPath` in `%LOCALAPPDATA%\dsh\pwsh7\config.json`
71
+ 3. `%ProgramFiles%\PowerShell\7\pwsh.exe`
72
+ 4. `%LOCALAPPDATA%\dsh\pwsh7\powershell7\…\pwsh.exe` (portable installs, newest first)
73
+ 5. `%LOCALAPPDATA%\Programs\PowerShell\7\pwsh.exe`
74
+ 6. every `PATH` entry
75
+ 7. `%LOCALAPPDATA%\Microsoft\WindowsApps\pwsh.exe` (Store alias)
76
+ 8. `%ProgramFiles(x86)%\PowerShell\7\pwsh.exe`
77
+
78
+ The stock `pwsh-sandbox` row still accepts its official `pwshPath` config field; an explicit config
79
+ value takes precedence over automatic detection.
80
+
81
+ ### Config file
82
+
83
+ `%LOCALAPPDATA%\dsh\pwsh7\config.json`:
84
+
85
+ ```json
86
+ {
87
+ "version": 1,
88
+ "pwshPath": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
89
+ "installed": {
90
+ "pwsh": {
91
+ "path": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
92
+ "version": "7.6.7",
93
+ "method": "existing",
94
+ "at": "2026-10-17T00:00:00.000Z"
95
+ }
96
+ },
97
+ "updatedAt": "2026-10-17T00:00:00.000Z"
98
+ }
99
+ ```
100
+
101
+ ## Automatic installation
102
+
103
+ Per-user, no administrator rights:
104
+
105
+ | Component | Source | Destination |
106
+ |---|---|---|
107
+ | PowerShell 7 | Latest `PowerShell/PowerShell` GitHub release, `PowerShell-*-win-x64.zip` | `%LOCALAPPDATA%\dsh\pwsh7\powershell7\<version>\` |
108
+
109
+ - HTTPS streaming download into `%LOCALAPPDATA%\dsh\pwsh7\tmp`, with progress callbacks and
110
+ cancellation.
111
+ - Extraction uses the Windows built-in `tar.exe` (bsdtar). No downloaded installer is ever executed.
112
+ - After extraction the new `pwsh.exe` is executed once to verify a major version >= 7 before it is
113
+ written into `config.json`.
114
+ - `auto` falls back to `winget install Microsoft.PowerShell`; when elevation would be required the
115
+ result carries the exact manual elevated command instead of hanging on UAC.
116
+ - No writes outside the router root and its temp directory.
117
+ - Live-tested on Windows: 106,364,316-byte zip downloaded in ~31 s, extracted to 244.8 MB, verified
118
+ `7.6.7`.
119
+
120
+ ## Sandbox behavior
121
+
122
+ - The executor runs through `ctx.sandbox.confine()` and the Windows ACL restricted-token runner, with
123
+ the same `workspace-write` / `read-only` / `danger-full-access` semantics as the stock executor.
124
+ - PowerShell 7 works in all three modes (verified: `workspace-write` can write inside the workspace
125
+ and is denied outside it; `danger-full-access` is unconfined).
126
+ - If the Windows sandbox reports `SetNamedSecurityInfoW failed (Win32 5)` / `grantWrite(<workspace>)`,
127
+ the workspace DACL is missing rights. Run DSH's bundled **`diagnose-windows-sandbox-acl`** skill
128
+ against the workspace root (it backs up and verifies), or temporarily switch the session to full
129
+ access.
130
+
131
+ ## Troubleshooting
132
+
133
+ 1. Run `shell_router action="status"` and check the resolved path/version.
134
+ 2. Run `shell_router action="diagnose"` to execute real commands under the current sandbox policy.
135
+ 3. Common causes:
136
+ - **Still Windows PowerShell 5.1** — detection did not find PowerShell 7. Set `DSH_PWSH_PATH` or
137
+ the `pwshPath` config entry, then check `status` again.
138
+ - **PowerShell 7 installed in a custom location** — set `DSH_PWSH_PATH` or `config.json`.
139
+ - **Sandbox/ACL failure** — see the sandbox section above.
140
+
141
+ ## Architecture
142
+
143
+ | Path | Role |
144
+ |---|---|
145
+ | `index.js` | Plugin entry: `shell_router` tool, system-prompt section, state refresh on config reload |
146
+ | `lib/shipped.mjs` | Loads the shipped `@deepseek-ai/*` packages from the running DSH installation (`app.asar`) |
147
+ | `lib/paths.mjs` | PowerShell 7 detection, version probing, `config.json` IO |
148
+ | `lib/install.mjs` | Per-user portable install (official zip) + winget fallback |
149
+ | `lib/state.mjs` | Process-wide resolution cache shared by the executor and the tool |
150
+ | `lib/status.mjs` | `status` / `diagnose` implementations |
151
+ | `lib/executors/pwsh.mjs` | PowerShell 7 executor (extends the official `SandboxPwshExecutor`) |
152
+ | `cordis.patch.yml` | Bundle patch: replaces `pwsh-sandbox` and inserts the plugin row (Windows only) |
153
+ | `locale/en.json`, `locale/zh.json`, `icon.svg` | Plugin-manager display metadata |
154
+
155
+ `package.json` `files` ships only the runtime pieces; `test/` stays in the repository.
156
+
157
+ ## Development
158
+
159
+ ```powershell
160
+ # Plain Node tests (no running DSH required)
161
+ node --test test/paths.test.mjs test/install.test.mjs
162
+ ```
163
+
164
+ - 49 tests: 48 pass, 0 fail, 1 skipped (network-gated by default).
165
+ - `DSH_PWSH7_NETWORK_TESTS=1` enables the live GitHub release / HEAD checks: 30/30 pass.
166
+ - The environment override prefix is `DSH_PWSH7_*` (`APP_ROOT`, `TAR`, `NETWORK_TESTS`).
167
+
168
+ ## Publishing (maintainers)
169
+
170
+ Releases are published by GitHub Actions through npm **Trusted Publishing** (OIDC) — no npm token,
171
+ OTP or repository secret is involved.
172
+
173
+ 1. Bump `version` in `package.json`, commit and push to `main`.
174
+ 2. Create and push a matching tag and publish a GitHub Release (for example `v0.2.0`).
175
+ 3. [`.github/workflows/publish.yml`](.github/workflows/publish.yml) runs on
176
+ `release: published`, verifies the tag matches `package.json`, runs the test suite, and publishes
177
+ with provenance (`npm publish --access public --provenance`).
178
+
179
+ One-time npm-side setup (already configured for this repository):
180
+
181
+ ```powershell
182
+ npx npm@12 trust github dsh-plugin-pwsh7 `
183
+ --file publish.yml `
184
+ --repo drliuhuan/dsh-plugin-pwsh7 `
185
+ --allow-publish --yes
186
+ ```
187
+
188
+ Manual dry run: **Actions → Publish to npm → Run workflow**, keep `dry_run` checked. The workflow
189
+ then runs `npm publish --dry-run --provenance` without publishing.
190
+
191
+ Only `publish.yml` in `drliuhuan/dsh-plugin-pwsh7` is authorized to publish. Inspect or revoke the
192
+ relationship with:
193
+
194
+ ```powershell
195
+ npx npm@12 trust list dsh-plugin-pwsh7
196
+ npx npm@12 trust revoke dsh-plugin-pwsh7 --id <trust-id>
197
+ ```
198
+
199
+ ## Versioning note
200
+
201
+ `0.1.0` was the first public release. `0.1.1` is the first release published through npm
202
+ **Trusted Publishing** (OIDC) by GitHub Actions, and fixes the npm-hosted README cross-links.
203
+ Earlier internal iterations (0.2.x/0.3.x) included MSYS2 bash routing and used a different package
204
+ name; that scope was removed because MSYS2/Cygwin cannot start under the DSH Windows ACL sandbox.
205
+ The historical evidence stays in the build workspace (`sandbox-recon/FINDINGS.md`), not in this
206
+ package.
207
+
208
+ ## Uninstall
209
+
210
+ ```
211
+ plugin_manager action=remove_bundle target=dsh-plugin-pwsh7
212
+ ```
213
+
214
+ The native Windows preset is restored and `pwsh` returns to DSH's default resolution. The per-user
215
+ directory `%LOCALAPPDATA%\dsh\pwsh7\` is not deleted automatically.
216
+
217
+ ## License
218
+
219
+ MIT — see [LICENSE](https://github.com/drliuhuan/dsh-plugin-pwsh7/blob/main/LICENSE).