dsh-win-pwsh7 0.0.0-stage → 0.2.3
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 +426 -0
- package/LICENSE +21 -0
- package/README.en.md +171 -0
- package/README.md +141 -2
- package/client.js +542 -0
- package/cordis.patch.yml +12 -0
- package/icon.svg +5 -0
- package/index.js +1572 -0
- package/lib/dsh-ops-bridge.js +329 -0
- package/lib/typert.host.js +94 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +71 -4
- package/tools/check-client.mjs +426 -0
- package/tools/check-host.mjs +842 -0
- package/tools/check-native-contracts.mjs +216 -0
- package/tools/dsh-app-modules.mjs +208 -0
- package/tools/node-app-modules-hook.mjs +56 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.3 — removable dsh-ops coexistence bridge
|
|
4
|
+
|
|
5
|
+
- Moved the bridge, profile-patch ownership, and pure name planning into `lib/dsh-ops-bridge.js`.
|
|
6
|
+
`index.js` now mounts it in one place; `package.json` ships the module.
|
|
7
|
+
- Enabled coexistence declaratively from `cordis.patch.yml`; the plugin no longer writes an
|
|
8
|
+
enable override into the profile. Turning the switch off writes only a marked disable override.
|
|
9
|
+
- Removal contract: delete the module, the mount line, the config field, the client switch, and its
|
|
10
|
+
gate; the bundle patch disappears with the package. A switch-off override is the only possible
|
|
11
|
+
profile residue and is removed by the plugin's cleanup when it runs.
|
|
12
|
+
- The bundle patch must come after `dsh-ops` in `dsh.profile.bundles`; otherwise the loader warns
|
|
13
|
+
and skips it. The profile keeps `dsh-ops` before `dsh-win-pwsh7`.
|
|
14
|
+
|
|
15
|
+
## 0.2.2 — fix the dsh-ops bridge freeze
|
|
16
|
+
|
|
17
|
+
- Fixed the 0.2.1 hide/unhide oscillation that could pin the Host main thread when many sessions
|
|
18
|
+
were restored. The bridge now plans from the host's **pre-restriction** `knownNames` /
|
|
19
|
+
`restrictableNames` instead of the post-restriction `visible` set, and filters the deny list to
|
|
20
|
+
names `tools.restrict()` actually accepts. The fallback path latches names it already hid.
|
|
21
|
+
- Added regression checks for the stable plan, the older-host fallback, and the scope-local
|
|
22
|
+
`ops_bash` case that used to throw an unknown-global-tool warning.
|
|
23
|
+
- Restored `dshOpsCompat` to default-on after multi-session validation of the fixed bridge.
|
|
24
|
+
- The configuration page now uses the native `Switch` primitive and native setting-row layout for
|
|
25
|
+
the coexistence toggle; labels and hints no longer expose raw config keys.
|
|
26
|
+
|
|
27
|
+
## 0.2.1 — dsh-ops coexistence bridge
|
|
28
|
+
|
|
29
|
+
- Added a default-on `dshOpsCompat` configuration row. When dsh-ops is installed, pwsh7 writes
|
|
30
|
+
a marked `dsh-ops-compat` override into the active profile patch and enables it, so the native
|
|
31
|
+
`pwsh` tool is visible again alongside `ops_bash`.
|
|
32
|
+
- The agent bridge re-hides the official `read` / `glob` / `grep` tools when their OPS
|
|
33
|
+
counterparts are visible, plus the duplicate official `bash` / `pwsh_persistent` shell. It
|
|
34
|
+
keeps `pwsh` and `ops_bash` and does nothing when dsh-ops is absent.
|
|
35
|
+
- The compatibility patch needs a DSH restart; turning the switch off removes only the block this
|
|
36
|
+
plugin wrote. Uninstall cleanup is best-effort and leaves at most a harmless compatibility row.
|
|
37
|
+
- Added the plugin-page toggle with its own localized row and hint.
|
|
38
|
+
|
|
39
|
+
## 0.2.0 — 优化 Store 版 pwsh7 安装方式
|
|
40
|
+
|
|
41
|
+
优化store版pwsh7安装方式,重构项目前端设计和工程设计,使其符合原生DSH工程习惯和界面风格。
|
|
42
|
+
|
|
43
|
+
- Removed the retired internal `method: 'store'` / winget install route. `pwsh7_install` has only
|
|
44
|
+
the Store-page script path plus the manual path; the tool schema never exposed the winget route.
|
|
45
|
+
- Removed the winget-only job spec, log follower, download measurement, failure-code translation,
|
|
46
|
+
inline fallback, constants, imports, and their test fixtures. The host gate now drives only the
|
|
47
|
+
Store-UI job, the VPN confirmation, the breaker, the disabled-row report, and activation.
|
|
48
|
+
- Deleted `docs/acceptance-0.13.0.md`, which described the retired metered/winget behaviour.
|
|
49
|
+
- READMEs no longer mention `installIfMissing`, the winget installer, or a "configuration card";
|
|
50
|
+
they describe the current two install paths and the status card.
|
|
51
|
+
- Declared `engines.dsh` (`>=0.2.1-rc.3 <0.2.2-0`) so an untested DSH line is rejected at install.
|
|
52
|
+
|
|
53
|
+
## 0.16.6 — status card matching the official provider card
|
|
54
|
+
|
|
55
|
+
- The status section is now a native bordered card with an inner estimate/facts surface, matching
|
|
56
|
+
the official speech-to-text provider card: card title, three facts (status, runtime, executor),
|
|
57
|
+
footnote, and the compact Re-detect action.
|
|
58
|
+
- The Remote `status` endpoint now also returns the Host gate snapshot, so the card renders facts
|
|
59
|
+
instead of the model-facing report. The client falls back to the report when an older Host
|
|
60
|
+
answers without it.
|
|
61
|
+
- When the gate is present the raw report is no longer shown; the pasteable wiring patch remains
|
|
62
|
+
available in the card.
|
|
63
|
+
|
|
64
|
+
## 0.16.5 — native plugin detail page
|
|
65
|
+
|
|
66
|
+
- The plugin page's two sections now match the native detail page instead of drawing their own
|
|
67
|
+
cards: flat sections, 14px/500 section titles, the page's 32px section rhythm, 34px native inputs,
|
|
68
|
+
28px outline actions for Re-detect and Copy, and the native settings-form Save/Reset with matching
|
|
69
|
+
focus rings.
|
|
70
|
+
- The status report is native body text rather than a scrollable log box; the pasteable patch keeps
|
|
71
|
+
a compact native code block and copy action.
|
|
72
|
+
- Removed the stale metered-network warning and its dictionary entries — the feature was already
|
|
73
|
+
gone, but the client still carried its copy.
|
|
74
|
+
- The plugin card/detail description now describes the current behaviour (script or manual Store
|
|
75
|
+
install; no metered preflight).
|
|
76
|
+
|
|
77
|
+
## 0.16.4 — make the companion recommendation an instruction to the model
|
|
78
|
+
|
|
79
|
+
- The completed script-install verdict now begins the companion text with `ACTION REQUIRED:`: the
|
|
80
|
+
model must tell the user that dsh-win-pwsh7 is best paired with the dsh-ops plugin, offer to install
|
|
81
|
+
it, and not install it without consent. The repository link and install command stay included.
|
|
82
|
+
- READMEs describe it as an instruction, not a passive recommendation.
|
|
83
|
+
- It is still emitted only in the completed script-install result.
|
|
84
|
+
|
|
85
|
+
## 0.16.3 — link the dsh-ops companion
|
|
86
|
+
|
|
87
|
+
- The completed script-install recommendation now includes the companion repository link:
|
|
88
|
+
https://github.com/T-Auto/dsh-ops.
|
|
89
|
+
- Both READMEs link the same repository.
|
|
90
|
+
|
|
91
|
+
## 0.16.2 — recommend the companion only after the script install completes
|
|
92
|
+
|
|
93
|
+
- 0.16.1 appended the dsh-ops recommendation to every healthy `pwsh7_status` report. That was too
|
|
94
|
+
broad: the request is a **one-time recommendation to the model after the script install
|
|
95
|
+
completes**.
|
|
96
|
+
- The recommendation now appears only in the successful Store-UI job verdict, after the runtime is
|
|
97
|
+
detected. `pwsh7_status`, manual installs, and the plugin page do not advertise it.
|
|
98
|
+
- READMEs and the host gate assert the narrower behavior.
|
|
99
|
+
|
|
100
|
+
## 0.16.1 — recommend dsh-ops after a working runtime appears
|
|
101
|
+
|
|
102
|
+
- `pwsh7_status` appends a companion recommendation once a usable PowerShell 7 is detected, and a
|
|
103
|
+
successful Store-UI install includes it in the job verdict: **dsh-ops** — native file/PTC tools
|
|
104
|
+
plus Windows host PowerShell integration — pairs well with this plugin. It is explicitly not
|
|
105
|
+
installed automatically; the suggested command is
|
|
106
|
+
`dsh plugin --profile <profile> add dsh-ops`.
|
|
107
|
+
- Both READMEs document the recommendation.
|
|
108
|
+
- Host gate asserts a healthy status report names `dsh-ops` and says it is not installed
|
|
109
|
+
automatically.
|
|
110
|
+
|
|
111
|
+
## 0.16.0 — no startup auto-install, three-failure breaker
|
|
112
|
+
|
|
113
|
+
- **`installIfMissing` is gone.** The config field, its activation branch, the install-attempt report
|
|
114
|
+
text and the client switch are removed. Starting the Host only detects and reports; installing is
|
|
115
|
+
always an explicit `pwsh7_install` (or the manual Win+R path). This also removes the old winget
|
|
116
|
+
startup route, so the only user-facing install methods are script install and manual install.
|
|
117
|
+
- **Three-failure breaker, per Host process.** Consecutive failed script installs are counted
|
|
118
|
+
(exit 2/3/4/5 and job/spawn errors; a started-but-not-yet-installed click does not count). After
|
|
119
|
+
3, `pwsh7_install` starts no job: it asks the user to check the network/VPN, and only accepts
|
|
120
|
+
`userConfirmedFixed: true` after the user explicitly says it is fixed. That resets the counter and
|
|
121
|
+
allows one retry; three more failures open the breaker again. Success and an already-installed
|
|
122
|
+
runtime reset it. The failure text now begins by asking whether a VPN is active.
|
|
123
|
+
- **Tool schema** gains `userConfirmedFixed`; the block is enforced before the VPN confirmation, so
|
|
124
|
+
repeating `vpnOffConfirmed: true` cannot bypass it.
|
|
125
|
+
- **Docs** rewritten to the current behavior: two install paths, VPN confirmation, Store notice,
|
|
126
|
+
breaker, no metered preflight, three gates, no `installIfMissing`.
|
|
127
|
+
- **Tests.** Host gate covers the breaker/no-job path and the explicit-fix reset; activation must
|
|
128
|
+
not start an install; client gate no longer expects the removed switch; all old config-driven
|
|
129
|
+
install tests use `method: 'store'` internally.
|
|
130
|
+
|
|
131
|
+
## 0.15.1 — the Store script survives 5.1 encoding, and only two install paths
|
|
132
|
+
|
|
133
|
+
The 0.15.0 Store-UI script failed before opening the page with a parser error, not a VPN problem:
|
|
134
|
+
Windows PowerShell 5.1 decoded the inline text in the host's ANSI code page, and characters inside
|
|
135
|
+
the Chinese notice string became illegal tokens.
|
|
136
|
+
|
|
137
|
+
- **The script is a UTF-8 BOM file, not inline text.** `spawnStoreUi` writes it to a temporary
|
|
138
|
+
`.ps1` with a BOM and launches `powershell.exe -File`; 5.1 reads BOM-prefixed files as UTF-8
|
|
139
|
+
regardless of the console code page. The temporary directory is removed when the job settles.
|
|
140
|
+
- **Smart quotes are gone.** The Store notice uses 「安装」/「取消」 instead of curly quotes, which
|
|
141
|
+
PowerShell 7 itself treats as string delimiters. The generated script now parses under both
|
|
142
|
+
Windows PowerShell 5.1 and PowerShell 7.
|
|
143
|
+
- **Only two install paths are exposed.** The `pwsh7_install` schema no longer has a `method`
|
|
144
|
+
parameter and the status/report text no longer offers a winget command: the tool is the script
|
|
145
|
+
install (open Store, notice, click Install), and the other path is manual Win+R. The manual
|
|
146
|
+
instructions remain in every report and failure message.
|
|
147
|
+
- **Tests.** The host gate still drives the Store-UI click/failure jobs and no longer expects a
|
|
148
|
+
winget command in the report.
|
|
149
|
+
|
|
150
|
+
## 0.15.0 — VPN confirmation, Store notice, no metered probe, no context injection
|
|
151
|
+
|
|
152
|
+
The 2026-10-27 run exposed three usability gaps around the Store-UI install and one unnecessary
|
|
153
|
+
mechanism: the model could start an install without asking about the VPN; the Store window could be
|
|
154
|
+
closed because nothing explained it; the metered preflight was no longer relevant to the manual
|
|
155
|
+
Store page; and the injected status note was unwanted.
|
|
156
|
+
|
|
157
|
+
- **VPN is now a question, not a probe.** `pwsh7_install` requires `vpnOffConfirmed: true`. Without
|
|
158
|
+
it the tool starts nothing and returns: ask the user whether a VPN is active, have them
|
|
159
|
+
disconnect it and restart Microsoft Store, then call again. There is no adapter/default-route
|
|
160
|
+
detection anywhere.
|
|
161
|
+
- **The Store window explains itself.** Before opening the page, the UI script shows a modal
|
|
162
|
+
`MessageBox`: dsh-win-pwsh7 is about to open Microsoft Store and click Install; do not close the
|
|
163
|
+
Store window; if a VPN is active, cancel, disconnect it, fully quit/restart Store, then retry.
|
|
164
|
+
Closing the notice with Cancel exits cleanly and the job reports "cancelled at the Store notice".
|
|
165
|
+
- **Metered/network preflight removed.** `METERED_COST`, `NETWORK_COST_SCRIPT`, `networkCost`,
|
|
166
|
+
`networkWarning`, the metered status warning and the install preflight are gone. `store-ui` is
|
|
167
|
+
the manual Store page, where the metered queue behaviour does not apply; `method: 'store'` keeps
|
|
168
|
+
the winget job but no longer probes the connection.
|
|
169
|
+
- **Context injection removed.** `agent.inject`, `createUserMessage`, the settled-state note and the
|
|
170
|
+
related contract check are gone; the job output and `pwsh7_status` remain the sources of truth.
|
|
171
|
+
- **Tests.** The host gate asserts the confirmation gate starts no job, a store-ui click job, a
|
|
172
|
+
page-not-loaded failure with VPN/manual guidance, and no network preflight; the probe environment
|
|
173
|
+
stays isolated from the host's real PowerShell.
|
|
174
|
+
|
|
175
|
+
## 0.14.0 — open the Store page and click Install
|
|
176
|
+
|
|
177
|
+
The 2026-10-27 test proved that the manual Store page is the path that works, and that a script can
|
|
178
|
+
open it and invoke the same Install button with Windows UI Automation. `pwsh7_install` now defaults
|
|
179
|
+
to that route; winget remains available as `method: 'store'`.
|
|
180
|
+
|
|
181
|
+
- **`store-ui` (default).** It opens
|
|
182
|
+
`ms-windows-store://pdp/?ProductId=9MZ1SNWT0N5D`, waits up to 90 seconds for the Store window, then
|
|
183
|
+
invokes the localized Install / 获取 / Get / 更新 / Update button through `UIAutomationClient` and
|
|
184
|
+
falls back to `LegacyIAccessiblePattern`. This is the same Store page and button a human uses.
|
|
185
|
+
- **A click is not a failed install.** The job reports "Store page opened and Install was clicked —
|
|
186
|
+
downloading/installing in the background", tells the model not to retry, and asks it to poll
|
|
187
|
+
`pwsh7_status`; a runtime found within the bounded re-check is reported as installed.
|
|
188
|
+
- **Page-load failure asks about the VPN.** If no Install button appears within the timeout — or the
|
|
189
|
+
page cannot be opened/invoked — the report says the Store page did not load, and tells the user:
|
|
190
|
+
disconnect any VPN, fully quit and restart Microsoft Store, then retry; manual Win+R steps remain.
|
|
191
|
+
- **VPN auto-detection is gone.** The 0.13.4 adapter/default-route heuristic was removed; the
|
|
192
|
+
network probe is back to `<cost>|<profile>` and the only automatic connection gate is metering.
|
|
193
|
+
The VPN question is asked only when the Store page fails to load, as the user requested.
|
|
194
|
+
- **`store` remains.** `pwsh7_install` with `method: 'store'` runs the existing winget background job
|
|
195
|
+
with its queue hints and 30-second polling guidance.
|
|
196
|
+
- **Tests.** The host gate drives a successful Store-UI click, a page-not-loaded failure with VPN
|
|
197
|
+
and manual guidance, and keeps all winget tests on `method: 'store'`; the probe environment is
|
|
198
|
+
isolated from the host's real PowerShell so the gate is reproducible with PowerShell 7 installed.
|
|
199
|
+
|
|
200
|
+
## 0.13.4 — configure-it guidance, manual Store steps, VPN preflight
|
|
201
|
+
|
|
202
|
+
Two gaps from the 2026-10-27 run: the blocked `pwsh` call mentioned install and disable but not the
|
|
203
|
+
case where PowerShell 7 is already installed and only needs wiring, and the automatic install was
|
|
204
|
+
also blocked by an active VPN while the plugin only understood metering.
|
|
205
|
+
|
|
206
|
+
- **The denial and status now offer three ways.** When a usable PowerShell 7 is detectable, the
|
|
207
|
+
first answer is "configure the executor": call `pwsh7_status` for the exact
|
|
208
|
+
`pwsh-sandbox.pwshPath` patch, apply it to the active profile and reload DSH. Installing
|
|
209
|
+
(`pwsh7_install` or manual) and disabling stay available. The status report says
|
|
210
|
+
"Three ways forward" with the same split.
|
|
211
|
+
- **Manual Store install is spelled out.** Every install path prints:
|
|
212
|
+
press Win+R, paste `ms-windows-store://pdp/?ProductId=9MZ1SNWT0N5D`, press Enter; outside a VPN the
|
|
213
|
+
Store page for PowerShell 7 opens — click Install. A manual install is auto-detected; no pin.
|
|
214
|
+
(The product id in the text is generated from `STORE_PRODUCT_ID`.)
|
|
215
|
+
- **VPN is detected and intercepted.** The Windows PowerShell 5.1 probe now also inspects active
|
|
216
|
+
adapters whose name/description match common VPN/TUN clients, a default route through such an
|
|
217
|
+
adapter, and `Get-VpnConnection`. A reading of `Unrestricted|<profile>|WireGuard` (or any active
|
|
218
|
+
VPN) makes the install preflight refuse to start and returns: disconnect the VPN, fully quit and
|
|
219
|
+
restart Microsoft Store, retry; or use the manual Store steps. `pwsh7_status` shows the same
|
|
220
|
+
warning; a failed install re-checks and names the VPN if it appeared after the preflight.
|
|
221
|
+
The adapter-name match is a heuristic — a false positive still leaves the manual Store install.
|
|
222
|
+
- **Tests.** The host gate asserts manual/configure text in the denial, a VPN preflight that starts
|
|
223
|
+
no job and names the adapter, and the VPN status warning.
|
|
224
|
+
|
|
225
|
+
## 0.13.3 — queued Store, VPN, 30-second polling, context injection
|
|
226
|
+
|
|
227
|
+
The automatic Store download can sit in "Queued" indefinitely; the reports confirmed the cause is
|
|
228
|
+
the Store client/queue, not the plugin's preflight. This release makes that state actionable and
|
|
229
|
+
stops the model from waiting on one long `job_output` call.
|
|
230
|
+
|
|
231
|
+
- **The queue is a first-class recovery path.** The install start report, the 2-minute progress
|
|
232
|
+
hint, and the failure verdict all say: pause/resume the PowerShell entry in Microsoft Store →
|
|
233
|
+
Downloads/Library; if the Store itself is stuck, disable any VPN, fully quit and restart Microsoft
|
|
234
|
+
Store; or install manually from `ms-windows-store://pdp/?ProductId=9MZ1SNWT0N5D`. A manual Store
|
|
235
|
+
install is detected automatically, no `pwshPath` pin.
|
|
236
|
+
- **The model is told to poll in 30-second rounds.** `pwsh7_install` now says
|
|
237
|
+
`job_output(wait:true, timeout_ms:30000)` then `job_list`; a `wait aborted` is not an install
|
|
238
|
+
failure. This is guidance for the model, not a change to the job's own 15-second progress tick.
|
|
239
|
+
- **The settled state is injected into the agent context.** When the background job finishes, the
|
|
240
|
+
owning agent receives a short `agent.inject()` note (feature-detected): runtime now effective,
|
|
241
|
+
install failed with the queue/VPN/manual options, or installed-but-still-pinned. The prompt
|
|
242
|
+
section alone could not tell a model that stopped looking.
|
|
243
|
+
- **The queue hint names VPN.** The progress line after `Started MSStore package execution` now
|
|
244
|
+
includes pause/resume, VPN off + restart Store, and the Windows Update pause check.
|
|
245
|
+
- **Tests.** The install start report carries the 30-second/`timeout_ms:30000`/VPN text; the
|
|
246
|
+
settled failure injects a note into a stub agent.
|
|
247
|
+
|
|
248
|
+
## 0.13.2 — the Store handoff is named correctly
|
|
249
|
+
|
|
250
|
+
The 2026-10-27 work-exp reports showed the automatic install failing on a **non-metered**
|
|
251
|
+
connection while the plugin still told the user to turn metering off. The failure path now re-reads
|
|
252
|
+
the connection, translates the Store error codes, and offers the recovery that actually worked:
|
|
253
|
+
the Store entry was parked in "Queued", and pause → resume started the download.
|
|
254
|
+
|
|
255
|
+
- **Failure attribution re-reads the connection.** `installVerdict` calls `networkCost` again;
|
|
256
|
+
metered advice appears only for `Fixed` / `Variable`. An unreadable cost is explicitly not
|
|
257
|
+
attributed to metering.
|
|
258
|
+
- **Store error codes are translated.** `wingetFailureCode` normalizes decimal exit codes to
|
|
259
|
+
`0x…`, and `describeWingetFailure` explains `0x80D03801` (download/deployment), `0x80004004`
|
|
260
|
+
(E_ABORT) and `0x80072EFD` (WinHTTP 12029).
|
|
261
|
+
- **Non-metered failures point at the queue and the manual fallback.** The verdict says to open
|
|
262
|
+
Microsoft Store → Downloads/Library, pause and resume a "Queued" PowerShell entry, check Windows
|
|
263
|
+
Update is not paused, and gives `ms-windows-store://pdp/?ProductId=9MZ1SNWT0N5D`. A manual Store
|
|
264
|
+
install is detected automatically — no `pwshPath` pin is needed.
|
|
265
|
+
- **The handoff is visible in progress.** `Started MSStore package execution` is now a named phase;
|
|
266
|
+
after `DSH_WIN_PWSH7_STORE_QUEUE_HINT_MS` (default 2 minutes) the progress line says the entry may
|
|
267
|
+
be queued, and the stall line names both the queue and metering instead of only metering.
|
|
268
|
+
- **The gate stub formats `%s`** (OBS-01), so the host gate no longer prints the placeholder.
|
|
269
|
+
- **Tests.** A non-metered failure must not give metering advice; `0x80D03801` must be translated and
|
|
270
|
+
keep the manual Store path; the metered preflight still starts no job.
|
|
271
|
+
|
|
272
|
+
## 0.13.1 — install, then actually usable
|
|
273
|
+
|
|
274
|
+
The 0.13.0 gate read the executor correctly but inherited the executor's own cache: `pwsh7_install`
|
|
275
|
+
could install PowerShell 7.6.9 while the running `PwshLocalExecutor` still resolved to 5.1, so the
|
|
276
|
+
tool stayed blocked and `pwsh7_status` could even answer "Nothing to configure". Both are fixed.
|
|
277
|
+
|
|
278
|
+
- **The install now nudges the executor cache.** `PwshLocalExecutor.pwshPath` re-resolves only when
|
|
279
|
+
its declared config changes. After a successful install the plugin writes a sentinel into that
|
|
280
|
+
cache and re-reads the getter, so the same running process resolves the new Store alias. No
|
|
281
|
+
profile patch and no restart are needed when the concrete executor exposes the cache.
|
|
282
|
+
- **The nudge is feature-detected.** If a composition does not expose `declaredPwshPath` /
|
|
283
|
+
`resolvedPwshPath`, the install report says so and prints the pin + reload patch instead of
|
|
284
|
+
pretending the tool is ready. `tools/check-native-contracts.mjs` now guards both fields.
|
|
285
|
+
- **The status can no longer call a stale executor "native".** When the live executor still reports
|
|
286
|
+
5.1, the report keeps the `running executor still resolves to Windows PowerShell 5.1` warning,
|
|
287
|
+
prints the pin patch, and never says "Nothing to configure" just because the standalone resolver
|
|
288
|
+
now finds a Store alias.
|
|
289
|
+
- **Failures that cannot be nudged are explicit.** `installVerdict` distinguishes "the running
|
|
290
|
+
executor now resolves to 7.6.9" from "it still resolves to 5.1; pin pwsh-sandbox.pwshPath and
|
|
291
|
+
reload DSH", so the user is not left with a contradictory success message.
|
|
292
|
+
- **The Re-detect button moved into the status section.** It used to sit in the detail page's
|
|
293
|
+
head actions, away from the text it refreshes; it now renders beside the status title, where a
|
|
294
|
+
reader looks for it. `plugins.detail.actions` no longer carries a second copy.
|
|
295
|
+
- **Tests.** A stale live 5.1 + resolver 7 case must not render "Nothing to configure"; a stubbed
|
|
296
|
+
executor cache must be refreshed by the nudge; the contract gate asserts the cache fields exist;
|
|
297
|
+
the client gate renders the section's own Re-detect and drives the Remote flow through it.
|
|
298
|
+
|
|
299
|
+
Measured against the 2026-10-27 work-exp report: install landed 7.6.9, the tool remained blocked
|
|
300
|
+
until a manual `pwsh-sandbox.pwshPath` pin, and status said "Nothing to configure" in the same
|
|
301
|
+
window. This release removes that manual step on the normal path and makes the fallback honest.
|
|
302
|
+
|
|
303
|
+
## 0.13.0 — enabled means gated
|
|
304
|
+
|
|
305
|
+
The plugin was observational: with only Windows PowerShell 5.1 it warned the model and let the
|
|
306
|
+
command run. This release makes the enabled state a contract. The model sees a call-time error
|
|
307
|
+
before dispatch, the user sees the install/configure/disable choices, and no PowerShell process is
|
|
308
|
+
started for a denied call.
|
|
309
|
+
|
|
310
|
+
- **The gate reads the executor, not a reconstruction.** `ctx.shell.pwshPath` is the exact
|
|
311
|
+
executable `dsh-tool-pwsh` will spawn (`PwshLocalExecutor.argv()` uses it). The read
|
|
312
|
+
feature-detects that concrete getter and falls back to `shell.config.pwshPath.get()` +
|
|
313
|
+
`resolvePwshPath()`, then to the default resolver. `configEditor.entries()` only exposes
|
|
314
|
+
`include`-owned rows, so a Desktop-generated live row could be missed; the report still lists the
|
|
315
|
+
rows for diagnosis.
|
|
316
|
+
- **`ctx.tools.guard` denies `pwsh` before dispatch.** A per-context snapshot drives the guard; a
|
|
317
|
+
`tools/pre-execute` listener refreshes it when the snapshot is unknown or older than
|
|
318
|
+
`DSH_WIN_PWSH7_GATE_TTL_MS`, and `app-boot/config-reload` / `plugin-manager/changed` refresh it
|
|
319
|
+
after profile changes. `pwsh7_status` and `pwsh7_install` are never gated.
|
|
320
|
+
- **The denial is self-contained.** It names the reason (5.1, broken pin, no PowerShell 7, unknown),
|
|
321
|
+
says not to retry, and offers `pwsh7_status` (exact patch), `pwsh7_install` (after the user
|
|
322
|
+
agrees), or disabling the plugin. The 5.1 prompt section now says the tool is blocked instead of
|
|
323
|
+
advising the `;` workaround.
|
|
324
|
+
- **Install preflight.** `resolveWinget()` then `networkCost()`: the install starts only for
|
|
325
|
+
`Unrestricted` with a readable profile. `Fixed` / `Variable` / `Unknown` / an unreadable probe /
|
|
326
|
+
a missing winget returns a report naming the network and the setting to turn off, and registers
|
|
327
|
+
**no job**. `installIfMissing` skips with the same reason instead of starting a doomed install.
|
|
328
|
+
- **Configuration guidance.** The report keeps the row's existing config fields (the `config` block
|
|
329
|
+
is replaced wholesale), distinguishes add vs update, and states that `overridePath` only changes
|
|
330
|
+
probing and recommendations — not executor wiring.
|
|
331
|
+
- **Client.** The diagnostics section derives a metered-network line and a fix block with the
|
|
332
|
+
profile patch and a copy button from the report it already receives.
|
|
333
|
+
- **Native contracts.** `docs/native-contracts.md` records the 0.2.1-rc.3 package table and the
|
|
334
|
+
symbols the plugin relies on; `tools/check-native-contracts.mjs` (36 checks over 12 packages)
|
|
335
|
+
runs after the host and client gates and fails when a symbol or prototype disappears.
|
|
336
|
+
- **Tests.** Gate allow/deny, broken pin, own tools, pre-execute refresh, config reload, add/update
|
|
337
|
+
patch, wholesale-config warning, overridePath-not-wiring, metered/unknown/no-winget starting no
|
|
338
|
+
job, and the client's network line and copyable patch.
|
|
339
|
+
|
|
340
|
+
This is a breaking behavioral change for anyone who relied on the 5.1 fallback while the plugin was
|
|
341
|
+
enabled. Disabling the plugin restores the previous behavior; the plugin still never writes
|
|
342
|
+
`pwshPath` and never uninstalls PowerShell.
|
|
343
|
+
|
|
344
|
+
## 0.12.3 — the gates read the desktop build's nested harness
|
|
345
|
+
|
|
346
|
+
The desktop build (`DeepSeek Harness.exe` 0.2.1-rc.2) packs a different layout than 2.0.19-next: the
|
|
347
|
+
archive root carries only a shell — `dsh`, `node_modules`, `lib`, `package.json`, `renderer` — and its
|
|
348
|
+
`node_modules/@deepseek-ai` holds eight packages (cordis, cosmokit, dsh-api-gateway, dsh-brand,
|
|
349
|
+
dsh-deque, dsh-timeout, dsh-typert-protocol, schemastery), while all 306 harness packages sit under
|
|
350
|
+
`dsh/`. `0.12.2` accepted any root carrying `cordis`, so it picked the shell and the Host gate died
|
|
351
|
+
with `ERR_MODULE_NOT_FOUND: Cannot find package '@deepseek-ai/dsh-tools'`.
|
|
352
|
+
|
|
353
|
+
- **The harness is recognised by carrying both `cordis` and `dsh-tools`**, not `cordis` alone, and a
|
|
354
|
+
root or its `dsh`/`app` subdirectory is searched for it — `harnessAt()` in
|
|
355
|
+
`tools/dsh-app-modules.mjs`.
|
|
356
|
+
- **The unpack now also takes `dsh/`**, so a packed desktop archive yields `<cache>\dsh`, and the
|
|
357
|
+
`note — the harness packages come from an asar archive, unpacked for this run into …` line names it.
|
|
358
|
+
- **A cache created by an older release is not trusted**: it is reused only when the full harness is
|
|
359
|
+
inside it, so upgrading the plugin repairs the stale unpack instead of failing again.
|
|
360
|
+
- **Measured**: new desktop install 30 s cold / 6 s cached, previous 2.0.19-next install 6 s cached,
|
|
361
|
+
both gates green; no installation at all still prints the actionable note and exits 1.
|
|
362
|
+
- **The READMEs now describe all three layouts** and the "Releasing" sections explain that the tag
|
|
363
|
+
publishes through CI (trusted publishing, OIDC) and that provenance requires `repository.url` to be
|
|
364
|
+
byte-identical to the GitHub context.
|
|
365
|
+
|
|
366
|
+
## 0.12.2 — the gates read a packed DSH 2.0 install
|
|
367
|
+
|
|
368
|
+
DSH 2.0.19-next ships its packages inside `resources/app.asar`, and the Host gate could not find them
|
|
369
|
+
there: Node resolves nothing inside an archive, and the sibling `app.asar.unpacked` holds only five
|
|
370
|
+
packages (cordis is not among them), so the run ended in
|
|
371
|
+
`ERR_MODULE_NOT_FOUND: Cannot find package '@deepseek-ai/cordis'`. The plugin's own halves were never
|
|
372
|
+
affected — both load and run on 2.0.19-next — but nobody could re-run the gates on a 2.0 machine,
|
|
373
|
+
which is exactly when they are wanted.
|
|
374
|
+
|
|
375
|
+
- **`tools/dsh-app-modules.mjs` (new)** resolves the harness: `DSH_APP_DIR` first, then the nearest
|
|
376
|
+
ancestor of the tools directory or the working directory that carries
|
|
377
|
+
`node_modules/@deepseek-ai/cordis`. `DSH_APP_DIR` now accepts an install root, `resources/app`
|
|
378
|
+
(an unpacked install), or `resources/app.asar` (a packed one).
|
|
379
|
+
- **A packed installation is unpacked once** into `%TEMP%\dsh-app-modules-<archive>-<size>-<mtime>` —
|
|
380
|
+
only `node_modules` and `package.json`, staged under `<cache>.<pid>` and renamed into place, reused
|
|
381
|
+
by later runs. Unpacking the real tree instead of re-implementing Node's resolution over the archive
|
|
382
|
+
is deliberate: a hand-written resolver can disagree with Node on `exports` maps, conditions, and
|
|
383
|
+
CJS/ESM, and that disagreement would show up as a green gate that proves nothing.
|
|
384
|
+
- **The hook and the Host gate use it**, and the gate says where the packages came from. A machine
|
|
385
|
+
with no installation at all still fails the gate — with one actionable line naming the three
|
|
386
|
+
accepted hand-offs, instead of a bare `ERR_MODULE_NOT_FOUND`.
|
|
387
|
+
- **Measured on 2.0.19-next**: 38 s cold (the unpack is most of it), 6 s on the cached second run,
|
|
388
|
+
both gates green.
|
|
389
|
+
|
|
390
|
+
## 0.12.1 — first public release
|
|
391
|
+
|
|
392
|
+
`dsh-win-pwsh7` puts a real PowerShell 7 under the Harness `pwsh` tool on Windows. This is the first
|
|
393
|
+
release published outside its author's machine, and it is the behaviour the README documents:
|
|
394
|
+
|
|
395
|
+
- **Detection and reporting** — `pwsh7_status` reads the executor rows, validates an explicit path,
|
|
396
|
+
refuses a version-numbered Store path as un-pinnable, and prints a pasteable profile patch for the
|
|
397
|
+
version-stable Store family alias.
|
|
398
|
+
- **One install path** — `pwsh7_install` installs the Microsoft Store package as a background job.
|
|
399
|
+
It reads the connection cost first, because Windows defers Store downloads on a connection marked
|
|
400
|
+
as metered, and the remedy it offers is that setting — never a second installer. When PowerShell 7
|
|
401
|
+
is not wanted at all, the other answer is to disable the plugin.
|
|
402
|
+
- **A failed exit is evidence, not a verdict** — the runtime is re-probed before a failure is
|
|
403
|
+
reported, because the Store can finish an install after winget has already exited non-zero.
|
|
404
|
+
- **Progress that is measured** — the job follows winget's own diagnostic log for named phases
|
|
405
|
+
(downloading, deploying, registering) and measures the installer download from the bytes on disk,
|
|
406
|
+
because winget reports no numeric progress of its own.
|
|
407
|
+
- **A prompt section** — the model is told which PowerShell the executor actually runs, so it knows
|
|
408
|
+
whether `&&` and `||` work before it writes a command.
|
|
409
|
+
- **Two offline gates** under `tools/`, shipped with the package so anyone can re-run them. They run
|
|
410
|
+
unconditionally — the behaviour half is fixture-pinned (`PATH`, `LOCALAPPDATA`, `ProgramFiles`)
|
|
411
|
+
rather than skipped on a machine that has the per-machine MSI — they cover job cancellation and
|
|
412
|
+
both inline install fallbacks, and every assertion has been shown to fail under a deliberate
|
|
413
|
+
mutation.
|
|
414
|
+
- **Reviewed independently before release** — three Open Code Review passes, 36 findings triaged.
|
|
415
|
+
30 were confirmed and fixed. The material ones: a gate that silently skipped half its checks; all
|
|
416
|
+
inline install paths taking a single-shot verdict instead of the bounded re-probe; a stall warning
|
|
417
|
+
that had become unreachable; a cancelled job that kept working (twice — the re-probe loop was the
|
|
418
|
+
second half); an activation-time install that reported nothing because it waited forever; a report
|
|
419
|
+
that could name a disabled row as the runtime. 4 findings were refuted with citations (the harness's
|
|
420
|
+
own schema dialect, the ecosystem's client descriptor shape, the optional `jobs` service, and the
|
|
421
|
+
string-error envelope), and 1 is recorded as backlog: the module-level state a second application
|
|
422
|
+
in one process would share.
|
|
423
|
+
- **Confirmed on the machine that found it** — the "a disabled row is never named as the runtime" fix
|
|
424
|
+
is not theoretical. This profile carries `pwsh-sandbox` (disabled) beside
|
|
425
|
+
`desktop-windows-pwsh-sandbox` (enabled), both pinning the same Store family alias; the report named
|
|
426
|
+
the *disabled* row until the fix, and after the restart it names the enabled one instead.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 XinSpark
|
|
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.en.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# dsh-win-pwsh7
|
|
2
|
+
|
|
3
|
+
<p align="center"><sub><a href="README.md">简体中文</a> · English</sub></p>
|
|
4
|
+
|
|
5
|
+
Give the Harness `pwsh` tool a real PowerShell 7 on Windows instead of silently falling back to
|
|
6
|
+
Windows PowerShell 5.1.
|
|
7
|
+
|
|
8
|
+
1. **Detect** PowerShell 7 on the machine (plus an optional `overridePath`);
|
|
9
|
+
2. **Validate** an explicit path (`pwsh7_status`'s `path` argument);
|
|
10
|
+
3. **Install** via the script path (`pwsh7_install` opens the Microsoft Store page and clicks
|
|
11
|
+
Install) or the manual path (Win+R, same Store link). There is no automatic startup install.
|
|
12
|
+
|
|
13
|
+
While enabled, the `pwsh` tool is allowed **only when the live executor resolves to PowerShell 7+**.
|
|
14
|
+
Otherwise every call is denied by `ctx.tools.guard` before dispatch, the model is told to configure /
|
|
15
|
+
install / disable, and no PowerShell process starts. Disabling the plugin removes the gate; the
|
|
16
|
+
default executor then chooses the runtime itself, and the plugin still never writes `pwshPath`.
|
|
17
|
+
|
|
18
|
+
## Verified environment
|
|
19
|
+
|
|
20
|
+
- Windows 10/11.
|
|
21
|
+
- Verified on DSH **0.2.1-rc.3** (see `dsh.verifiedAgainst` in `package.json`).
|
|
22
|
+
- The script path needs Microsoft Store; the manual path only needs the Store page.
|
|
23
|
+
- No administrator rights are required.
|
|
24
|
+
|
|
25
|
+
## What it does not do
|
|
26
|
+
|
|
27
|
+
- It does not install anything at startup.
|
|
28
|
+
- It does not write the executor's `pwshPath`; it only writes a marked dsh-ops compatibility override when coexistence is on.
|
|
29
|
+
- It does not uninstall a Store-installed PowerShell 7.
|
|
30
|
+
- It does not auto-detect VPNs or preflight metered connections.
|
|
31
|
+
|
|
32
|
+
## Coexistence with dsh-ops
|
|
33
|
+
|
|
34
|
+
On by default. The `dsh-ops-compat` override in `cordis.patch.yml` owns the enabled state: while
|
|
35
|
+
the dsh-win-pwsh7 bundle is installed and comes after dsh-ops, a DSH restart restores the native
|
|
36
|
+
`pwsh` tool and keeps `ops_bash`. Turning the switch off writes only a marked disable override;
|
|
37
|
+
removing the bundle removes the enable override, and cleanup best-effort removes the disable one.
|
|
38
|
+
|
|
39
|
+
The 0.2.1 bridge planned from the post-restriction visible set, which made it hide and restore the
|
|
40
|
+
same tools in a loop and starved the Host main thread. 0.2.2 plans from the pre-restriction
|
|
41
|
+
`knownNames` / `restrictableNames` and filters names `tools.restrict()` does not accept. The
|
|
42
|
+
multi-session validation passed, so the switch is default-on again.
|
|
43
|
+
|
|
44
|
+
## Install this plugin
|
|
45
|
+
|
|
46
|
+
```powershell
|
|
47
|
+
dsh plugin --profile desktop add github:XinSpark/dsh-win-pwsh7#v0.2.3
|
|
48
|
+
# or
|
|
49
|
+
dsh plugin --profile desktop add dsh-win-pwsh7
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Restart DSH after installing. To wire a path, paste the exact profile patch printed by
|
|
53
|
+
`pwsh7_status` into `~\.dsh\profiles\<profile>\cordis.patch.yml` and restart; the plugin never writes
|
|
54
|
+
the executor's `pwshPath` itself.
|
|
55
|
+
|
|
56
|
+
## Two install paths
|
|
57
|
+
|
|
58
|
+
| Path | Behavior |
|
|
59
|
+
|---|---|
|
|
60
|
+
| **Script install** | Call `pwsh7_install`. The tool first requires the user to confirm no VPN is active (`vpnOffConfirmed: true`). It then opens the Microsoft Store page for PowerShell 7, shows a notice (do not close the Store window; cancel if a VPN is on), and invokes the localized Install / Get / 获取 / 安装 button with Windows UI Automation. |
|
|
61
|
+
| **Manual install** | Win+R → paste `ms-windows-store://pdp/?ProductId=9MZ1SNWT0N5D` → Enter → click Install. A manual install is detected automatically; no pin is needed. |
|
|
62
|
+
|
|
63
|
+
If the Store page exposes no Install button within 90 seconds, the report asks the user to confirm
|
|
64
|
+
the VPN first: disconnect it, fully quit and restart Microsoft Store, then retry or use the manual
|
|
65
|
+
path.
|
|
66
|
+
|
|
67
|
+
### Three-failure breaker
|
|
68
|
+
|
|
69
|
+
Within one Host process, after **3 consecutive failed script installs**:
|
|
70
|
+
|
|
71
|
+
- the next `pwsh7_install` starts no job;
|
|
72
|
+
- it first asks the user to check the network, especially the VPN;
|
|
73
|
+
- only after the user explicitly says it is fixed may the model call with
|
|
74
|
+
`userConfirmedFixed: true`; that resets the counter and allows one retry;
|
|
75
|
+
- three more failures open the breaker again;
|
|
76
|
+
- otherwise the report points at the manual install.
|
|
77
|
+
|
|
78
|
+
The count lives in the current process and resets when DSH restarts.
|
|
79
|
+
|
|
80
|
+
## Configuration
|
|
81
|
+
|
|
82
|
+
| Key | Default | Meaning |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `overridePath` | unset | Priority ① explicit `pwsh.exe`. It must spawn and report PowerShell 7+; a failed validation falls back to auto-detection. **It only changes probing and recommendations, not executor wiring.** |
|
|
85
|
+
| `dshOpsCompat` | `true` | Coexist with dsh-ops (on by default): writes and enables its Compatibility mode, hides duplicate official tools, and keeps `pwsh` + `ops_bash`. Requires a restart. |
|
|
86
|
+
|
|
87
|
+
`overridePath` is `volatile()`: the plugin-page configuration section saves it live; it can also be
|
|
88
|
+
set in the profile patch:
|
|
89
|
+
|
|
90
|
+
```yaml
|
|
91
|
+
- id: win-pwsh7
|
|
92
|
+
config:
|
|
93
|
+
overridePath: 'D:\tools\pwsh\pwsh.exe'
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Recommended companion
|
|
97
|
+
|
|
98
|
+
When the script install completes, its job verdict contains an **instruction to the model**: tell the
|
|
99
|
+
user that dsh-win-pwsh7 works best paired with the **dsh-ops** plugin
|
|
100
|
+
([https://github.com/T-Auto/dsh-ops](https://github.com/T-Auto/dsh-ops)); ask before installing it and
|
|
101
|
+
never install it without the user's consent. Command:
|
|
102
|
+
|
|
103
|
+
```powershell
|
|
104
|
+
dsh plugin --profile <profile> add dsh-ops
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The recommendation appears only in the completed script-install result; `pwsh7_status` and manual
|
|
108
|
+
installs do not advertise it repeatedly.
|
|
109
|
+
|
|
110
|
+
## Report example
|
|
111
|
+
|
|
112
|
+
`pwsh7_status` returns the text report below; the plugin page renders the same state as a card
|
|
113
|
+
rather than showing the whole report.
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
Executor rows:
|
|
117
|
+
pwsh-sandbox : pwshPath = C:\Users\...\WindowsApps\Microsoft.PowerShell_8wekyb3d8bbwe\pwsh.exe (PowerShell 7.6.9, Store family alias)
|
|
118
|
+
|
|
119
|
+
The pwsh tool currently runs on PowerShell 7.6.9 via the executor (…).
|
|
120
|
+
The executor resolves to the version-stable Store family alias: … Nothing to configure.
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
When nothing usable exists, the report ends with `Three ways forward:`: install / configure the
|
|
124
|
+
executor / disable the plugin.
|
|
125
|
+
|
|
126
|
+
## Plugin page
|
|
127
|
+
|
|
128
|
+
The status section is a native card showing the state, runtime and executor path, with Re-detect
|
|
129
|
+
at the top right; the configuration section exposes `overridePath` and the default-on "Keep native
|
|
130
|
+
pwsh alongside dsh-ops" native switch.
|
|
131
|
+
|
|
132
|
+
## Disable or uninstall
|
|
133
|
+
|
|
134
|
+
Disabling the plugin removes the `pwsh` gate and the plugin page; it does not uninstall PowerShell 7.
|
|
135
|
+
As long as `pwsh.exe` remains on the machine, the default executor still prefers it (normally the
|
|
136
|
+
Store build); Windows PowerShell 5.1 is used only when no `pwsh.exe` can be found. To truly return
|
|
137
|
+
to 5.1, uninstall the Store build or pin the executor to `powershell.exe` (not recommended).
|
|
138
|
+
|
|
139
|
+
## Troubleshooting
|
|
140
|
+
|
|
141
|
+
| Symptom | What to do |
|
|
142
|
+
|---|---|
|
|
143
|
+
| The Store page opens without an Install button | Confirm the VPN is off, fully quit and restart Microsoft Store, then retry; or use the manual path. |
|
|
144
|
+
| `pwsh` still runs 5.1 | Run `pwsh7_status`, paste the reported `pwshPath` patch into the profile, and restart; or install the Store build. |
|
|
145
|
+
| The plugin page is missing | Confirm `dsh-win-pwsh7` is enabled in the current profile, then restart DSH. |
|
|
146
|
+
|
|
147
|
+
## Verification
|
|
148
|
+
|
|
149
|
+
```powershell
|
|
150
|
+
$env:DSH_APP_DIR = 'E:\FXS\APP\DSH NEXT\resources\app.asar'
|
|
151
|
+
node tools/check-host.mjs
|
|
152
|
+
node tools/check-client.mjs
|
|
153
|
+
node tools/check-native-contracts.mjs
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
All three gates run offline against a packed installation (`resources/app.asar`); `DSH_APP_DIR`
|
|
157
|
+
accepts the install root, `resources/app`, or `resources/app.asar`.
|
|
158
|
+
|
|
159
|
+
## Design constraints
|
|
160
|
+
|
|
161
|
+
- The reading comes from the executor's own `ctx.shell.pwshPath`, not from config rows;
|
|
162
|
+
`overridePath` only changes probing and recommendations.
|
|
163
|
+
- No VPN auto-detection and no metered-connection preflight: the user confirms the VPN before an
|
|
164
|
+
install, and a page-load failure asks again.
|
|
165
|
+
- No automatic retries; the three-failure breaker ends the loop.
|
|
166
|
+
- Run all three gates before publishing; end-to-end installation is release evidence, not part of
|
|
167
|
+
the automated gate.
|
|
168
|
+
|
|
169
|
+
## License
|
|
170
|
+
|
|
171
|
+
[MIT](LICENSE)
|