dsh-plugin-wsl-env 0.15.0 → 0.17.0
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 +144 -15
- package/CONTRIBUTING.md +25 -33
- package/README.md +10 -10
- package/SECURITY.md +6 -4
- package/SUPPORT.md +8 -8
- package/agent/native/linux-aarch64/dsh-wsl-agent +0 -0
- package/agent/native/linux-x86_64/dsh-wsl-agent +0 -0
- package/agent/wsl-agent.sh +51 -12
- package/cordis.patch.yml +23 -10
- package/docs/ARCHITECTURE.md +56 -41
- package/docs/COMPATIBILITY.md +121 -0
- package/docs/CONFIGURATION.md +275 -273
- package/docs/LIMITATIONS.md +114 -38
- package/docs/MIGRATION.md +16 -13
- package/docs/PARITY.md +4 -3
- package/docs/PERFORMANCE.md +11 -9
- package/docs/QUICKSTART.md +46 -21
- package/docs/README.zh.md +7 -7
- package/docs/RELEASING.md +257 -0
- package/docs/REQUIREMENTS.zh.md +77 -0
- package/docs/ROADMAP-1.0.md +105 -61
- package/docs/ROADMAP.md +15 -9
- package/docs/UPSTREAM-FILE-REFERENCE-SEAM.md +3 -3
- package/docs/UPSTREAM-FSIO-EXPORT.md +7 -7
- package/docs/UPSTREAM-OPEN-IN-APP.md +57 -0
- package/docs/UPSTREAM-SESSION-NOTICE.md +4 -4
- package/docs/UPSTREAM-TERMINAL-TITLE.md +10 -12
- package/docs/VALUE.zh.md +144 -0
- package/docs/adr/0002-native-agent.md +348 -0
- package/docs/root-fs-routing.md +186 -0
- package/docs/screenshots/picker.png +0 -0
- package/docs/screenshots/preview.png +0 -0
- package/docs/screenshots/sandbox.png +0 -0
- package/docs/screenshots/terminal.png +0 -0
- package/lib/agent-exec.d.ts +7 -3
- package/lib/agent-protocol.d.ts +18 -5
- package/lib/agent-protocol.js +11 -6
- package/lib/agent-shared.js +1 -0
- package/lib/agent.d.ts +28 -9
- package/lib/agent.js +74 -14
- package/lib/fs-routing.d.ts +2 -1
- package/lib/fs-routing.js +13 -1
- package/lib/fs-substrate.d.ts +11 -9
- package/lib/fs-substrate.js +6 -9
- package/lib/fsio-agent.d.ts +2 -3
- package/lib/fsio-agent.js +2 -3
- package/lib/git-exec.d.ts +117 -0
- package/lib/git-exec.js +105 -0
- package/lib/git-route.d.ts +43 -13
- package/lib/git-route.js +54 -15
- package/lib/index.d.ts +20 -13
- package/lib/index.js +18 -11
- package/lib/session-runtime.d.ts +5 -3
- package/lib/session-runtime.js +5 -4
- package/lib/subprocess.d.ts +21 -7
- package/lib/subprocess.js +63 -9
- package/locale/en.json +1 -1
- package/locale/zh.json +1 -1
- package/package.json +13 -4
- package/scripts/diagnose.sh +1 -1
- package/scripts/doctor.mjs +23 -3
package/docs/ROADMAP-1.0.md
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
# Roadmap 1.0: the WSL plugin the DSH ecosystem should have
|
|
2
2
|
|
|
3
|
-
Status: working plan, 2026-10-
|
|
3
|
+
Status: working plan, last refreshed 2026-10-31 against `0.15.0`.
|
|
4
|
+
The 0.12.0 baseline that motivated the plan is kept below as history.
|
|
4
5
|
Audience: maintainers and contributors. This is a plan, not a release promise.
|
|
5
6
|
The short version: **from "the only WSL plugin" to "the default WSL plugin"** —
|
|
6
7
|
first run works, every distro and workspace is served by its own environment,
|
|
7
8
|
every DSH surface has a story, and every claim has a test or a probe.
|
|
8
9
|
|
|
10
|
+
## 0. 核心价值(需求裁决标准)
|
|
11
|
+
|
|
12
|
+
本插件只做两件事,其余一切都是为这两件事服务的适配:
|
|
13
|
+
|
|
14
|
+
1. **原生 Linux 工具链,LLM 生成的质量更高。** 模型在正确的生态里生成与执行——bash 而非 PowerShell、GNU 工具链、项目真实的构建系统。凡能让 distro 内工具链更完整、对模型更可见的,直接服务此价值(doctor 工具链检查、bootstrap-import、六发行版矩阵)。
|
|
15
|
+
2. **避开 Windows 与 WSL 的跨环境文件操作,大幅提升性能。** 每一次跨 9p/UNC 边界的文件操作都是性能税。凡消除或减少跨界往返的,直接服务此价值(picker 的 agent 化、#31 批量读、workspace-changes 的 git 经 `ctx.subprocess` 在 distro 内原生运行——已与上游实现对账)。
|
|
16
|
+
|
|
17
|
+
任何新提案先用这两条裁决:不服务者不进路线图。
|
|
18
|
+
|
|
9
19
|
## 1. What "must-have" means
|
|
10
20
|
|
|
11
21
|
"Best" is not "most features". It is five acceptance lines:
|
|
@@ -34,25 +44,41 @@ North-star metrics:
|
|
|
34
44
|
| Real-machine probe suite | 100% on Tier 1, nightly |
|
|
35
45
|
| Known documentation drift | 0 |
|
|
36
46
|
|
|
37
|
-
## 2. Where 0.
|
|
47
|
+
## 2. Where 0.15.0 stands
|
|
48
|
+
|
|
49
|
+
> WSL-101 landed on 2026-10-19: the distro follows the workspace and the
|
|
50
|
+
> per-distro caches are in place. 0.15.0 (2026-10-27) shipped the compatibility
|
|
51
|
+
> matrix, container legs, qemu aarch64, doctor, preset helper, and
|
|
52
|
+
> `interopVisibility`. The table that *motivated* the plan is frozen as the
|
|
53
|
+
> 0.12.0 baseline; the 0.15.0 row is what a reader should act on.
|
|
38
54
|
|
|
39
|
-
|
|
40
|
-
> workspace and the per-distro caches are in place. The table below records the
|
|
41
|
-
> 0.12.0 baseline that motivated the plan.
|
|
55
|
+
### 0.15.0 (current)
|
|
42
56
|
|
|
43
|
-
| Area | Strong today |
|
|
57
|
+
| Area | Strong today | Remaining gap |
|
|
44
58
|
|---|---|---|
|
|
45
|
-
| Execution | Native agent
|
|
46
|
-
| Files |
|
|
47
|
-
| Sandbox | `bubblewrap`, fail-closed,
|
|
48
|
-
| Onboarding | `
|
|
49
|
-
| Configuration | Every shipped key
|
|
50
|
-
| Quality |
|
|
51
|
-
| Ecosystem | npm package, bundle patch, bilingual locale,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
| Execution | Native agent default; systemd session scope; `distro: auto` coordinate routing; concurrent distros | Physical aarch64 WSL (out of scope); non-systemd real-machine session probe unrun |
|
|
60
|
+
| Files | in-distro agent substrate, root-plane `fs-routing` in unit+coverage, kernel-enforced confined writes | GUI previews still extra agent round trips (measured, deferred); `@` completion still 9p until the upstream seam |
|
|
61
|
+
| Sandbox | `bubblewrap`, fail-closed, `enforcement: partial`, `interopVisibility` / `maskWindowsDrive` | Plugin keys do not disable WSL interop; distro `[interop] enabled=false` must be configured separately |
|
|
62
|
+
| Onboarding | `doctor`, `bootstrap` / `bootstrap-import`, session preflight, `profile-preset` helper | Clean-machine first-run timing still unmeasured; session UI has no toast seam |
|
|
63
|
+
| Configuration | Every shipped key documented; nested `preset-wsl` rows edited through the helper | An id patch of `wsl-shell` / `wsl-fs` still only warns |
|
|
64
|
+
| Quality | Unit files including `fs-routing`; coverage 85/84/70; qemu aarch64 18-check; five-family container agent; COMPATIBILITY.md | Nightly `probes` job is GitHub-hosted `windows-latest` (skips without WSL); physical aarch64 out of scope |
|
|
65
|
+
| Ecosystem | npm package, bundle patch, bilingual locale, issue templates | Upstream seams remain: `ensureSession` monkey patch, argv-shape search interception, missing `FileReferenceTraversal` |
|
|
66
|
+
|
|
67
|
+
### 0.12.0 baseline (historical)
|
|
68
|
+
|
|
69
|
+
| Area | Strong then | Gap that motivated the plan |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| Execution | Native agent is the default; systemd session scope; background processes survive | Distro pinned by configuration; non-default workspace hit the cross-distro guard |
|
|
72
|
+
| Files | ext4 substrate, root-plane `fs-routing`, kernel-enforced confined writes | GUI extra round trips; `@` completion through 9p |
|
|
73
|
+
| Sandbox | `bubblewrap`, fail-closed, honest `enforcement: partial`, `maskWindowsDrive` | systemd and Linger unchecked by diagnose/bootstrap |
|
|
74
|
+
| Onboarding | `bootstrap`, `diagnose`, session-start preflight | No single doctor; preflight only probed bwrap; preset override trap |
|
|
75
|
+
| Configuration | Every shipped key documented | Nested `preset-wsl` rows; an id patch warned and changed nothing |
|
|
76
|
+
| Quality | 33 unit-test files, 12 real-machine probes, build/type/coverage gates | Probes manual; aarch64 build-only; `fs-routing` outside `test:unit` / `test:coverage` |
|
|
77
|
+
| Ecosystem | npm package, bundle patch, bilingual locale | Fragile upstream seams (same three as today) |
|
|
78
|
+
|
|
79
|
+
The remaining gap after 0.15.0 is **upstream seams, honest probe collection,
|
|
80
|
+
and 1.0 empirical legs** (clean-machine timing, 30 days without a P0) — not
|
|
81
|
+
the 0.12.0 productization list.
|
|
56
82
|
|
|
57
83
|
## 3. Design principles
|
|
58
84
|
|
|
@@ -141,12 +167,12 @@ may move if the compatibility matrix exposes a higher-severity failure.
|
|
|
141
167
|
|---|---|---|---|
|
|
142
168
|
| Time to first command | Not systematically measured | p50 <= 5 min, p90 <= 15 min | Ten clean-machine runs |
|
|
143
169
|
| Tier 1 first-run success | Not measured | >= 95% | Compatibility matrix |
|
|
144
|
-
| Real-machine probes | 14
|
|
170
|
+
| Real-machine probes | 15 with `--include-fs` (14 base scripts incl. `fs-routing.sh`, plus `run.sh`); nightly job on hosted `windows-latest` skips without WSL | 100% on a Windows+WSL runner | Dispatch or a self-hosted runner that actually has WSL |
|
|
145
171
|
| FS single-op p95 | ~22ms host round trip | <= 30ms | `fs-queue.mjs` |
|
|
146
172
|
| 16 concurrent reads p95 | 2.4-8.2ms | <= 20ms | `fs-queue.mjs` |
|
|
147
173
|
| GUI preview p95 | Backend 63.5 ms/MiB (service round trips on top) | <= 1s/MiB | `probe:gui-preview` |
|
|
148
174
|
| Agent recovery | One rebuild | < 2s | Fault injection |
|
|
149
|
-
| Documentation drift |
|
|
175
|
+
| Documentation drift | Closed 2026-10-30 (aarch64 qemu, 0.15 baseline, WSL-202 boxes) | 0 | Release checklist |
|
|
150
176
|
| Release cadence | Ad hoc | Every 2-4 weeks | Calendar |
|
|
151
177
|
| Adoption (lagging) | Not established | +50% per quarter | npm download stats |
|
|
152
178
|
|
|
@@ -187,8 +213,13 @@ acceptance list in each issue is the contract; filter by priority:
|
|
|
187
213
|
|
|
188
214
|
### WSL-101 — Multi-distro coordinate routing
|
|
189
215
|
|
|
190
|
-
**Status:**
|
|
191
|
-
|
|
216
|
+
**Status:** shipped in 0.13.0 (2026-10-19), unit-covered. The
|
|
217
|
+
`fs-routing.sh` probe (added with P0.4) runs on the real machine: it serves a
|
|
218
|
+
workspace in its own distro, reads a drive-letter path on the host plane, and
|
|
219
|
+
refuses another distro's UNC — one leg of the acceptance below has real-machine
|
|
220
|
+
evidence (a 2026-10-31 run passed all 15 probes on one machine; not a matrix
|
|
221
|
+
result). The concurrent two-distro leg still has no dedicated probe and has
|
|
222
|
+
not been run; the checkboxes stay unchecked until that leg exists.
|
|
192
223
|
|
|
193
224
|
**Priority:** P0 · **Size:** L · **Labels:** `area:multi-distro`,
|
|
194
225
|
`type:feature`, `priority:P0`
|
|
@@ -245,7 +276,7 @@ current diagnostics do not cover the second.
|
|
|
245
276
|
run on this single configured machine).
|
|
246
277
|
|
|
247
278
|
**Tests/probes:** process-level tests against fake `wsl.exe` outputs
|
|
248
|
-
([`test/doctor.test.mjs`](
|
|
279
|
+
([`test/doctor.test.mjs`](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/test/doctor.test.mjs)); real-machine run on the
|
|
249
280
|
Tier 1 image; `diagnose` remains a read-only alias.
|
|
250
281
|
|
|
251
282
|
**Depends on:** none.
|
|
@@ -279,7 +310,7 @@ failure.
|
|
|
279
310
|
|
|
280
311
|
**Tests/probes:** generated YAML compared byte-for-byte against the shipped
|
|
281
312
|
block (the row the real composition loads); the CLI's print/write/check paths
|
|
282
|
-
run in [`test/profile-preset.test.mjs`](
|
|
313
|
+
run in [`test/profile-preset.test.mjs`](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/test/profile-preset.test.mjs).
|
|
283
314
|
|
|
284
315
|
**Depends on:** none.
|
|
285
316
|
|
|
@@ -288,8 +319,10 @@ run in [`test/profile-preset.test.mjs`](../test/profile-preset.test.mjs).
|
|
|
288
319
|
**Status:** implemented (2026-10-19): the three drifts are fixed, `fs-routing`
|
|
289
320
|
and `distro-route` are in both test lists, `scripts/check-links.mjs` gates
|
|
290
321
|
relative links from `pnpm test`, and `probe:fs-routing` is written and wired
|
|
291
|
-
into the real-machine suite. The routing probe
|
|
292
|
-
|
|
322
|
+
into the real-machine suite. The routing probe's first real-machine run
|
|
323
|
+
happened by 2026-10-31 (a user-supplied log shows the full `--include-fs`
|
|
324
|
+
suite, 15 probes, 0 failures on one machine — an environment-specific result,
|
|
325
|
+
not a matrix).
|
|
293
326
|
|
|
294
327
|
**Priority:** P0 · **Size:** S · **Labels:** `area:docs`, `area:quality`,
|
|
295
328
|
`priority:P0`
|
|
@@ -323,15 +356,15 @@ remedy for `no-systemd`, `no-user-manager`, `no-systemd-run` and `no-linger`
|
|
|
323
356
|
(`sessionSandbox: false` on the row skips the session half). The advisory is
|
|
324
357
|
logged **and** published as a session-scoped `wsl-preflight` runtime-context
|
|
325
358
|
entry, so it is visible in the session transcript rather than only in the app
|
|
326
|
-
log. DSH 0.2.1 has no toast/banner seam; the exact ask
|
|
327
|
-
|
|
359
|
+
log. DSH 0.2.1 has no toast/banner seam; the exact ask was filed as
|
|
360
|
+
[#10263](https://github.com/deepseek-ai/deepseek-harness/discussions/10263) and is recorded in
|
|
328
361
|
[UPSTREAM-SESSION-NOTICE.md](UPSTREAM-SESSION-NOTICE.md), and
|
|
329
362
|
[LIMITATIONS.md](LIMITATIONS.md#session-start-advisories) records the boundary.
|
|
330
363
|
Unit coverage drives every probe verdict through a fake `wsl.exe`; the
|
|
331
364
|
real-machine missing-bwrap and non-systemd legs are still manual.
|
|
332
365
|
|
|
333
|
-
**Why:**
|
|
334
|
-
`logger.warn`; the other default prerequisite
|
|
366
|
+
**Why:** Before this work, session-start preflight only probed bwrap and wrote
|
|
367
|
+
to `logger.warn`; the other default prerequisite was discovered at the first
|
|
335
368
|
command.
|
|
336
369
|
|
|
337
370
|
**Acceptance:**
|
|
@@ -391,20 +424,30 @@ probe remains unrun (no non-systemd distro here).
|
|
|
391
424
|
**Priority:** P1 · **Size:** L · **Labels:** `area:compatibility`,
|
|
392
425
|
`area:quality`, `priority:P1`
|
|
393
426
|
|
|
394
|
-
**
|
|
395
|
-
|
|
427
|
+
**Status:** implemented (0.15.0 / 2026-10-27) except the scope decisions in
|
|
428
|
+
[COMPATIBILITY.md](COMPATIBILITY.md#scope-decisions): physical aarch64 WSL and
|
|
429
|
+
a separate Windows 10 matrix are out of scope; the non-systemd real WSL
|
|
430
|
+
terminal-session legs remain unrun (Alpine is covered for the in-distro
|
|
431
|
+
suite and `sessionSandbox: auto`).
|
|
432
|
+
|
|
433
|
+
**Why:** The support matrix used to be prose, and the aarch64 binary was built
|
|
434
|
+
but never executed.
|
|
396
435
|
|
|
397
436
|
**Acceptance:**
|
|
398
437
|
|
|
399
|
-
- [
|
|
400
|
-
Fedora, Arch, Alpine (musl), openSUSE; systemd
|
|
401
|
-
|
|
402
|
-
- [
|
|
403
|
-
|
|
404
|
-
- [
|
|
405
|
-
|
|
438
|
+
- [x] Tier 1 and Tier 2 are defined and tested on x86_64 WSL2 / Windows 11:
|
|
439
|
+
Ubuntu, Debian stable, Fedora, Arch, Alpine (musl), openSUSE; systemd
|
|
440
|
+
and non-systemd (Alpine). Evidence: [COMPATIBILITY.md](COMPATIBILITY.md).
|
|
441
|
+
- [x] The native 18-check suite runs for aarch64 under qemu in CI (built
|
|
442
|
+
artifact and committed `linux-aarch64` binary).
|
|
443
|
+
- [x] The shell agent runs in Linux containers for the non-Ubuntu families
|
|
444
|
+
(`agent-containers` job, 35/35).
|
|
445
|
+
- [x] The support table states "supported", "partial" and "unsupported" with
|
|
446
|
+
evidence (COMPATIBILITY.md). Physical aarch64 and Windows 10 are
|
|
447
|
+
documented as out of scope rather than untested claims.
|
|
406
448
|
|
|
407
|
-
**Tests/probes:** container matrix, qemu spike,
|
|
449
|
+
**Tests/probes:** container matrix, qemu spike, COMPATIBILITY.md; nightly
|
|
450
|
+
`probes` job is GitHub-hosted `windows-latest` and skips without WSL.
|
|
408
451
|
|
|
409
452
|
**Depends on:** WSL-201 for non-systemd; WSL-203 for packaging.
|
|
410
453
|
|
|
@@ -413,7 +456,7 @@ executed.
|
|
|
413
456
|
**Priority:** P1 · **Size:** M · **Labels:** `area:release`,
|
|
414
457
|
`area:quality`, `priority:P1`
|
|
415
458
|
|
|
416
|
-
**Status:** implemented (2026-10-19): [`test/e2e/install.sh`](
|
|
459
|
+
**Status:** implemented (2026-10-19): [`test/e2e/install.sh`](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/test/e2e/install.sh)
|
|
417
460
|
(`pnpm run e2e:install`) packs the tree, creates a fresh `DSH_HOME` under
|
|
418
461
|
`%TEMP%`, initializes a profile from the shipped `web` template, installs the
|
|
419
462
|
tarball, asserts `--dump-config` composes the plugin rows with no skipped-patch
|
|
@@ -422,7 +465,7 @@ installs the previous minor (0.11.0), plants a marker in the profile layer,
|
|
|
422
465
|
upgrades to the packed version, and asserts the marker survives, the installed
|
|
423
466
|
version is current, and the installed CHANGELOG carries the migration note.
|
|
424
467
|
The run passed 10/10 on this machine (the app may stay running: plugin
|
|
425
|
-
management is local). [`test/packaging.test.mjs`](
|
|
468
|
+
management is local). [`test/packaging.test.mjs`](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/test/packaging.test.mjs)
|
|
426
469
|
guards the packed file list in `pnpm test`. A self-hosted Windows runner job is
|
|
427
470
|
still unconfigured; the local command is the documented path.
|
|
428
471
|
|
|
@@ -453,8 +496,8 @@ silently leave an obsolete workaround behind.
|
|
|
453
496
|
cost (20 dirs / 520 files: 9p walk median 84.7 ms vs ext4 1.5 ms, ~56×; 9p
|
|
454
497
|
samples 63–192 ms) measured by `pnpm run probe:file-reference`. The seam
|
|
455
498
|
contract (three functions, Dirent/error/coordinate semantics) is already
|
|
456
|
-
written in [rfc-wsl-workspaces.md](upstream/rfc-wsl-workspaces.md); the
|
|
457
|
-
consumer [`src/file-reference-wsl.ts`](
|
|
499
|
+
written in [rfc-wsl-workspaces.md](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/docs/upstream/rfc-wsl-workspaces.md); the
|
|
500
|
+
consumer [`src/file-reference-wsl.ts`](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/src/file-reference-wsl.ts) is built
|
|
458
501
|
and unit-tested but deliberately unwired. The fallback is to keep the 9p walk
|
|
459
502
|
until upstream exposes the funnel; the trigger and the follow-up probe are
|
|
460
503
|
recorded.
|
|
@@ -511,7 +554,7 @@ no prototype while the trigger is unmet.
|
|
|
511
554
|
**Priority:** P1 · **Size:** M · **Labels:** `area:performance`,
|
|
512
555
|
`area:gui`, `priority:P1`
|
|
513
556
|
|
|
514
|
-
**Status:** implemented (2026-10-19): [`test/probe/gui-preview.sh`](
|
|
557
|
+
**Status:** implemented (2026-10-19): [`test/probe/gui-preview.sh`](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/test/probe/gui-preview.sh)
|
|
515
558
|
(`pnpm run probe:gui-preview`) measures the three routed backend operations a
|
|
516
559
|
preview pays — `stat`, `listDir`, and a 1 MiB `readByteRange` — with p50/p95 and
|
|
517
560
|
budgets (stat 100 ms, listing 500 ms, page 1 s/MiB). Measured on this machine
|
|
@@ -578,7 +621,7 @@ mismatch); a real-machine kill/restart probe is still unrun.
|
|
|
578
621
|
`area:docs`, `priority:P1`
|
|
579
622
|
|
|
580
623
|
**Status:** implemented except the distro-disabled leg (2026-10-19):
|
|
581
|
-
[CONFIGURATION](../docs/CONFIGURATION.md#
|
|
624
|
+
[CONFIGURATION](../docs/CONFIGURATION.md#windows-interop) documents the strict
|
|
582
625
|
profile, its trade-offs and the visible/masked/disabled matrix;
|
|
583
626
|
`pnpm run probe:sandbox` now also runs the masked profile (14 expectations:
|
|
584
627
|
`/mnt` hidden, the Windows binary unreachable, the workspace still writable). The
|
|
@@ -620,8 +663,8 @@ workflow itself has not run in this environment (no Actions runner here), and
|
|
|
620
663
|
opening an issue on a red run was left out because the workflow has no issue
|
|
621
664
|
permission — the failing run plus its delta is the signal.
|
|
622
665
|
|
|
623
|
-
**Why:** The peer pins are exact
|
|
624
|
-
user reports it.
|
|
666
|
+
**Why:** The development peer pins are exact, while accepted peer ranges can
|
|
667
|
+
admit newer releases; a DSH release can break the plugin before a user reports it.
|
|
625
668
|
|
|
626
669
|
**Acceptance:**
|
|
627
670
|
|
|
@@ -647,7 +690,7 @@ user reports it.
|
|
|
647
690
|
fragile parts.
|
|
648
691
|
|
|
649
692
|
**Status:** packaging plan written (2026-10-19):
|
|
650
|
-
[docs/upstream/promotion-pack.md](upstream/promotion-pack.md) records the
|
|
693
|
+
[docs/upstream/promotion-pack.md](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/docs/upstream/promotion-pack.md) records the
|
|
651
694
|
`packages/wsl/*` layout (ten capability packages plus a thin integration
|
|
652
695
|
package, each with its existing tests), the seam/RFC index with the current
|
|
653
696
|
state of each seam, what `test/composition.test.mjs` boots today and the gaps a
|
|
@@ -683,18 +726,17 @@ install, first session, recipes for Node/Python/Rust/Go and a monorepo, an
|
|
|
683
726
|
honest Tier 1/Tier 2 table); [docs/PERFORMANCE.md](PERFORMANCE.md) is the
|
|
684
727
|
9p-vs-agent page with the A6/A7 numbers and the GUI-preview baseline, and
|
|
685
728
|
`pnpm run probe:gui-preview` / `fs-queue.mjs` reproduce the latter. No GIF or
|
|
686
|
-
screenshot
|
|
687
|
-
|
|
729
|
+
screenshot existed on 2026-10-19. Four screenshots were added on 2026-10-27;
|
|
730
|
+
a GIF remains open. No DSH plugin
|
|
688
731
|
marketplace was identified, so nothing was submitted.
|
|
689
732
|
|
|
690
733
|
**Why:** "Best" also means easy to find and evaluate.
|
|
691
734
|
|
|
692
735
|
**Acceptance:**
|
|
693
736
|
|
|
694
|
-
- [x] A one-page entry with a
|
|
695
|
-
|
|
696
|
-
- [ ] A
|
|
697
|
-
(not produced; recorded here and in QUICKSTART).
|
|
737
|
+
- [x] A one-page entry with a quickstart, compatibility table and screenshots.
|
|
738
|
+
The five-minute clean-machine target remains unmeasured.
|
|
739
|
+
- [ ] A GIF showing the picker, terminal, preview and sandbox fact.
|
|
698
740
|
- [x] Recipes for Node, Python, Rust/Go and a monorepo; a 9p-vs-plugin
|
|
699
741
|
benchmark page.
|
|
700
742
|
- [ ] The DSH plugin directory/marketplace is updated if one exists (none
|
|
@@ -741,17 +783,19 @@ removals need a boot-time refusal, meaning changes need a migration note; exact
|
|
|
741
783
|
peer pins are tested by the canary), the deprecation path with the
|
|
742
784
|
`substrate: "share"` and `distro: ''` cases, and the release-gate table with the
|
|
743
785
|
manual legs marked unrun. RELEASING and SUPPORT link it. The empirical legs
|
|
744
|
-
(
|
|
745
|
-
release notes remain open.
|
|
786
|
+
(clean-machine first-run timing, 30 days without a P0) and the final `1.0.0`
|
|
787
|
+
release notes remain open. The Tier 1 matrix and aarch64 qemu execution
|
|
788
|
+
closed in 0.15.0.
|
|
746
789
|
|
|
747
790
|
**Acceptance:**
|
|
748
791
|
|
|
749
792
|
- [x] Configuration schema frozen; new keys require a minor.
|
|
750
793
|
- [x] Migration and deprecation policy documented.
|
|
751
|
-
- [
|
|
752
|
-
|
|
794
|
+
- [x] Tier 1 matrix green and aarch64 executed under qemu (0.15.0);
|
|
795
|
+
install E2E is 10/10. Physical aarch64 WSL is out of scope.
|
|
796
|
+
- [ ] No P0 bugs for 30 days; clean-machine first-run timing still unrun.
|
|
753
797
|
- [ ] `1.0.0` release notes list the supported matrix and the known
|
|
754
|
-
limitations (
|
|
798
|
+
limitations (COMPATIBILITY.md + LIMITATIONS.md are the draft).
|
|
755
799
|
|
|
756
800
|
**Tests/probes:** [MIGRATION.md](MIGRATION.md#gates-a-release-must-clear);
|
|
757
801
|
release gate; full probe suite.
|
|
@@ -776,5 +820,5 @@ A 1.0 release additionally requires the WSL-304 checklist.
|
|
|
776
820
|
- Known boundaries: [LIMITATIONS.md](LIMITATIONS.md)
|
|
777
821
|
- Current technical roadmap: [ROADMAP.md](ROADMAP.md)
|
|
778
822
|
- Requirements traceability: [REQUIREMENTS.zh.md](REQUIREMENTS.zh.md)
|
|
779
|
-
- Upstream mapping: [upstream/promotion-map.md](upstream/promotion-map.md)
|
|
780
|
-
- Real-machine suite: [`test/probe/run-all-when-closed.sh`](
|
|
823
|
+
- Upstream mapping: [upstream/promotion-map.md](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/docs/upstream/promotion-map.md)
|
|
824
|
+
- Real-machine suite: [`test/probe/run-all-when-closed.sh`](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/test/probe/run-all-when-closed.sh)
|
package/docs/ROADMAP.md
CHANGED
|
@@ -20,6 +20,8 @@ section.
|
|
|
20
20
|
| A4 | the native-session probe (scope, EXEC, FS, KILL, digest, teardown, 8/8) in the real-machine suite; the warm-cache and stdin-EPIPE fixes |
|
|
21
21
|
| A5 | the native agent is the documented default; 0.10.0 published (npm + GitHub Release) |
|
|
22
22
|
| A6 | `WslAgent.metrics()` and `test/probe/fs-queue.mjs`; the shared shell read agent is the measured batch bottleneck |
|
|
23
|
+
| A7 | native shared read agent (v5); 16 concurrent shared reads 2.4–4.1 ms; shell remains the fallback |
|
|
24
|
+
| A8 | aarch64 18-check under qemu-user in CI (built binary and committed `linux-aarch64` artifact); physical aarch64 WSL out of scope, see COMPATIBILITY.md |
|
|
23
25
|
|
|
24
26
|
## Next
|
|
25
27
|
|
|
@@ -30,9 +32,10 @@ The shared unconfined read agent was the only remaining measured bottleneck
|
|
|
30
32
|
0.2-0.3 ms). A7 swaps its shell for the native binary (v5) while keeping the
|
|
31
33
|
shell as the fallback:
|
|
32
34
|
|
|
33
|
-
- **selection:**
|
|
34
|
-
packaged binary for the distro's architecture
|
|
35
|
-
|
|
35
|
+
- **selection:** `shell` forces the shell; otherwise the shared agent tries
|
|
36
|
+
the packaged binary for the distro's architecture (or the dev override).
|
|
37
|
+
Unlike session-runtime preparation with `agentBackend: native`, shared reads
|
|
38
|
+
fall back to the shell when native preparation fails;
|
|
36
39
|
- **preparation:** `ensureNativeBackend` once per distro (cache/digest/exec
|
|
37
40
|
probe); the `WslAgent` with `expectedDigest` and `signalable: false`; on a
|
|
38
41
|
preparation or HELLO failure the shell agent serves the reads — fail-open to
|
|
@@ -46,11 +49,13 @@ shell as the fallback:
|
|
|
46
49
|
pays the ensure/cache cost (~70 ms once). The shell still serves the reads
|
|
47
50
|
under `agentBackend: shell` and after a native failure.
|
|
48
51
|
|
|
49
|
-
### A8 — aarch64 functional validation
|
|
52
|
+
### A8 — aarch64 functional validation — done
|
|
50
53
|
|
|
51
|
-
The
|
|
52
|
-
spike suite
|
|
53
|
-
the
|
|
54
|
+
The `native packages` job in CI builds static-musl aarch64 and runs the
|
|
55
|
+
18-check spike suite under qemu-user against both the freshly built binary
|
|
56
|
+
and the committed `agent/native/linux-aarch64/dsh-wsl-agent`. Physical
|
|
57
|
+
aarch64 WSL is out of scope (COMPATIBILITY.md). The native-session probe on
|
|
58
|
+
real aarch64 hardware is not planned.
|
|
54
59
|
|
|
55
60
|
### A9 — maintenance
|
|
56
61
|
|
|
@@ -66,8 +71,9 @@ the result in the ADR.
|
|
|
66
71
|
measurably or the ERR/env framing is needed for another reason.
|
|
67
72
|
- **Event stream.** No current consumer: the `fs.watch` contract is coarse and
|
|
68
73
|
the inotify watcher satisfies it; terminal activity and ports poll.
|
|
69
|
-
- **Shell retirement.** Not planned. The shell agent remains the fallback
|
|
70
|
-
|
|
74
|
+
- **Shell retirement.** Not planned. The shell agent remains the fallback
|
|
75
|
+
(`agentBackend: shell`, and after a native HELLO/prepare failure) and the
|
|
76
|
+
protocol/script stays supported.
|
|
71
77
|
|
|
72
78
|
## Not planned
|
|
73
79
|
|
|
@@ -10,7 +10,7 @@ decision.
|
|
|
10
10
|
|
|
11
11
|
## The measured cost
|
|
12
12
|
|
|
13
|
-
Probe: [`test/probe/file-reference-9p.sh`](
|
|
13
|
+
Probe: [`test/probe/file-reference-9p.sh`](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/test/probe/file-reference-9p.sh)
|
|
14
14
|
(three runs, `node:fs` readdir walk, no ranking engine). Tree: 20 directories,
|
|
15
15
|
520 files, one level of subdirectories; the same tree walked from Windows over
|
|
16
16
|
`\\wsl.localhost\<distro>` and from inside the distro on ext4.
|
|
@@ -31,7 +31,7 @@ seam must keep.
|
|
|
31
31
|
|
|
32
32
|
## The seam
|
|
33
33
|
|
|
34
|
-
RFC addendum ① (in [rfc-wsl-workspaces.md](upstream/rfc-wsl-workspaces.md))
|
|
34
|
+
RFC addendum ① (in [rfc-wsl-workspaces.md](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/docs/upstream/rfc-wsl-workspaces.md))
|
|
35
35
|
proposes exposing the three module-internal funnels as an injectable strategy:
|
|
36
36
|
|
|
37
37
|
```ts
|
|
@@ -55,7 +55,7 @@ with three semantics that matter for a remote world:
|
|
|
55
55
|
|
|
56
56
|
## The plugin side is ready
|
|
57
57
|
|
|
58
|
-
[`src/file-reference-wsl.ts`](
|
|
58
|
+
[`src/file-reference-wsl.ts`](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/src/file-reference-wsl.ts) implements that
|
|
59
59
|
interface over the resident agent: one `find -printf` per directory, a
|
|
60
60
|
single-exec segment walk for `resolveDisplayDirectory` (instead of N sequential
|
|
61
61
|
`lstat`s), and the UNC/POSIX conversions. It is unit-tested against a fake
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
Status: filed upstream as
|
|
4
4
|
[deepseek-ai/deepseek-harness#10262](https://github.com/deepseek-ai/deepseek-harness/discussions/10262)
|
|
5
5
|
(Ideas); the filing convention is [UPSTREAM-TERMINAL-TITLE.md](UPSTREAM-TERMINAL-TITLE.md).
|
|
6
|
-
Targeting `deepseek-harness` @ `packages/fs/fs-local`, the `0.2.1-rc.x` line
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
Targeting `deepseek-harness` @ `packages/fs/fs-local`, the `0.2.1-rc.x` line.
|
|
7
|
+
The proposal was measured against `@deepseek-ai/dsh-fs-local@0.2.1-rc.2`;
|
|
8
|
+
the current development pin and peer range are in `package.json`. This is the Shape-A
|
|
9
9
|
upstream half of the in-distro I/O refactor: with the fsio text mechanics
|
|
10
10
|
importable, `dsh-plugin-wsl-env` deletes its copies of them.
|
|
11
11
|
|
|
@@ -146,13 +146,13 @@ import("koffi")`, `:25`), so no native dependency is evaluated at import time.
|
|
|
146
146
|
layer maps the `code` token and the message, not the error class.
|
|
147
147
|
- Semver: an additive export. On the `0.2.0-rc.x` line it ships in the next
|
|
148
148
|
pre-release — the `0.2` position does not move, so this is not a minor bump
|
|
149
|
-
of a released line
|
|
150
|
-
|
|
149
|
+
of a released line. Adoption by the plugin requires an explicitly verified
|
|
150
|
+
development pin and a peer minimum that includes the export.
|
|
151
151
|
|
|
152
152
|
## Landing it (consumer side)
|
|
153
153
|
|
|
154
|
-
1.
|
|
155
|
-
|
|
154
|
+
1. Update the development pin and peer minimum in `package.json` to a verified
|
|
155
|
+
version that carries the export.
|
|
156
156
|
2. `pnpm run build` — `lib/` is committed, and `test/build-freshness.mjs`
|
|
157
157
|
enforces that it is a byte-identical, closed image of `src/`.
|
|
158
158
|
3. Re-run the comparison in [PEER-PARITY.md](PEER-PARITY.md) (its Maintenance
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Upstream: Host "Open in app" inherits `ELECTRON_RUN_AS_NODE`
|
|
2
|
+
|
|
3
|
+
Status: observed on DSH Desktop `0.2.1-rc.3` (Windows x64, 2026-10-30);
|
|
4
|
+
**not a defect of this plugin.** The Host process's open-in-app launcher
|
|
5
|
+
inherits `ELECTRON_RUN_AS_NODE=1`, so Electron editors (VS Code, Cursor)
|
|
6
|
+
start as Node, exit 1, and the UI reports launch-failed. File Explorer and
|
|
7
|
+
other non-Electron launchers work. The failure is the same on a Windows
|
|
8
|
+
folder and on a WSL UNC workspace.
|
|
9
|
+
|
|
10
|
+
User-facing note: [LIMITATIONS.md](LIMITATIONS.md#host-open-in-app).
|
|
11
|
+
|
|
12
|
+
## Environment
|
|
13
|
+
|
|
14
|
+
- DSH Desktop 0.2.1-rc.3, Windows 11
|
|
15
|
+
- Reproduced on both `\\wsl.localhost\...` workspaces and plain Windows
|
|
16
|
+
paths; 100% of VS Code launches failed
|
|
17
|
+
|
|
18
|
+
## What happens
|
|
19
|
+
|
|
20
|
+
The desktop window's overflow menu "Open in app" → VS Code shows an "打开失败"
|
|
21
|
+
/ launch-failed toast. VS Code never opens.
|
|
22
|
+
|
|
23
|
+
## Cause
|
|
24
|
+
|
|
25
|
+
1. The desktop app starts the backend Host through
|
|
26
|
+
`desktopNodeEnvironment()` (`lib/main.js`) with
|
|
27
|
+
`ELECTRON_RUN_AS_NODE: "1"`.
|
|
28
|
+
2. Open-in-app's `launchDetachedApp()` (`@deepseek-ai/dsh-host-open-in-app`)
|
|
29
|
+
builds the child environment with `scrubbedParentEnv()`, which strips
|
|
30
|
+
keys matching `/KEY|PASSWORD|SECRET|TOKEN/i` and `DSH_*`.
|
|
31
|
+
`ELECTRON_RUN_AS_NODE` is left in place.
|
|
32
|
+
3. Host then spawn's `Code.exe <workspace>`. VS Code (Electron) sees
|
|
33
|
+
`ELECTRON_RUN_AS_NODE=1`, runs as plain Node, opens no window, and
|
|
34
|
+
exits 1 inside the launch watch window → `POST /open-in-app/open`
|
|
35
|
+
returns 502 `launch-failed`.
|
|
36
|
+
|
|
37
|
+
`dsh-subprocess-local` already clears `ELECTRON_RUN_AS_NODE` when it
|
|
38
|
+
spawns the PTC runtime, so the Host carrying that variable is a known
|
|
39
|
+
fact; open-in-app's scrub list does not follow it.
|
|
40
|
+
|
|
41
|
+
## Reproduction
|
|
42
|
+
|
|
43
|
+
Using the app's bundled `node.exe`, spawn `Code.exe` detached with stdio
|
|
44
|
+
ignored and a scrubbed parent env:
|
|
45
|
+
|
|
46
|
+
- without `ELECTRON_RUN_AS_NODE`: `Code.exe` stays running → launched
|
|
47
|
+
- with `ELECTRON_RUN_AS_NODE=1`: process exits quickly, code 1 → 502
|
|
48
|
+
|
|
49
|
+
## Ask
|
|
50
|
+
|
|
51
|
+
Drop `ELECTRON_RUN_AS_NODE` in `launchDetachedApp()` (or in the shared
|
|
52
|
+
`scrubbedParentEnv()`), matching `dsh-subprocess-local`. Any Electron
|
|
53
|
+
target (VS Code, Cursor, …) hits the same path.
|
|
54
|
+
|
|
55
|
+
This repository will not work around the Host spawn: the plugin does not
|
|
56
|
+
own that launcher, and a WSL-specific env filter would not help Windows
|
|
57
|
+
workspaces.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Upstream proposal: a session-visible notice seam for plugin advisories
|
|
2
2
|
|
|
3
|
-
Status:
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Status: filed upstream as
|
|
4
|
+
[deepseek-ai/deepseek-harness#10263](https://github.com/deepseek-ai/deepseek-harness/discussions/10263)
|
|
5
|
+
(version line `0.2.1-rc.x`; the gap was checked
|
|
6
6
|
against `dsh-v0.2.1-rc.2` on 2026-10-19). The exact filing payload (title, body,
|
|
7
|
-
command) is [proposal-session-notice.md](upstream/proposal-session-notice.md). The plugin ships the workaround
|
|
7
|
+
command) is [proposal-session-notice.md](https://github.com/Big-Dao/dsh-plugin-wsl-env/blob/main/docs/upstream/proposal-session-notice.md). The plugin ships the workaround
|
|
8
8
|
described at the end: the advisory goes to the log **and** into the session's
|
|
9
9
|
runtime context, which is model-visible and appears in the session transcript,
|
|
10
10
|
but is not a dedicated banner.
|
|
@@ -107,17 +107,15 @@ next touched:
|
|
|
107
107
|
|
|
108
108
|
## Workarounds until then
|
|
109
109
|
|
|
110
|
+
- The plugin now ships the candidate list itself: `shellCandidates` is
|
|
111
|
+
`[wsl.exe, powershell, cmd]` in [`cordis.patch.yml`](../cordis.patch.yml),
|
|
112
|
+
with the `shell` block kept verbatim. `wsl.exe` dedupes into the default's
|
|
113
|
+
`wsl` kind; selecting `powershell` or `cmd` starts a shell the terminal
|
|
114
|
+
really launches (host sessions do outright) and titles the tab after itself.
|
|
115
|
+
Nothing remains for a user layer to add unless it wants different entries.
|
|
110
116
|
- Double-click a tab's title to rename it (a shipped client feature; the
|
|
111
117
|
controller's `rename` Remote API accepts 1–120 characters).
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
to carry this plugin's `shell` block verbatim — `path: wsl.exe`, `name: WSL`,
|
|
117
|
-
`args: []` — or the terminal stops being a distro terminal. Expect the menu
|
|
118
|
-
to grow the host shells discovery finds on the root provider, which receives
|
|
119
|
-
no directory: executables this terminal never starts (the second bullet of
|
|
120
|
-
the GUI-terminal comment in [`cordis.patch.yml`](../cordis.patch.yml)).
|
|
121
|
-
[LIMITATIONS.md](LIMITATIONS.md) still carries the older one-line form of
|
|
122
|
-
this tip, which drops the `shell` block; the version above is the one that
|
|
123
|
-
works.
|
|
118
|
+
|
|
119
|
+
Both cover only manually selected shells. The DEFAULT entry — what a new tab
|
|
120
|
+
gets before anyone chooses — is still titled from the static profile, which is
|
|
121
|
+
exactly the gap the upstream change closes.
|