dsh-plugin-wsl-env 0.7.5 → 0.9.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 +345 -8
- package/CONTRIBUTING.md +221 -68
- package/README.md +50 -35
- package/SECURITY.md +18 -2
- package/SUPPORT.md +23 -7
- package/cordis.patch.yml +9 -0
- package/docs/ARCHITECTURE.md +200 -57
- package/docs/CONFIGURATION.md +180 -16
- package/docs/LIMITATIONS.md +91 -33
- package/docs/PARITY.md +66 -38
- package/docs/PEER-PARITY.md +95 -32
- package/docs/README.zh.md +49 -31
- package/docs/UPSTREAM-FSIO-EXPORT.md +159 -50
- package/docs/UPSTREAM-TERMINAL-TITLE.md +49 -14
- package/lib/agent-confined.d.ts +42 -0
- package/lib/agent-confined.js +25 -41
- package/lib/agent-errors.d.ts +31 -0
- package/lib/agent-errors.js +19 -16
- package/lib/agent-exec.d.ts +159 -0
- package/lib/agent-exec.js +151 -165
- package/lib/agent-protocol.d.ts +192 -0
- package/lib/agent-protocol.js +76 -100
- package/lib/agent-shared.d.ts +27 -0
- package/lib/agent-shared.js +12 -12
- package/lib/agent.d.ts +353 -0
- package/lib/agent.js +536 -552
- package/lib/auto-preset.d.ts +110 -0
- package/lib/auto-preset.js +157 -141
- package/lib/bwrap.d.ts +90 -0
- package/lib/bwrap.js +18 -18
- package/lib/file-reference-wsl.d.ts +160 -0
- package/lib/file-reference-wsl.js +192 -173
- package/lib/fs-decisions.d.ts +107 -0
- package/lib/fs-decisions.js +64 -60
- package/lib/fs-routing.d.ts +182 -0
- package/lib/fs-routing.js +173 -116
- package/lib/fs-substrate.d.ts +258 -0
- package/lib/fs-substrate.js +248 -248
- package/lib/fs.d.ts +10 -0
- package/lib/fs.js +5 -0
- package/lib/fsio-agent.d.ts +307 -0
- package/lib/fsio-agent.js +414 -410
- package/lib/fsio-text.d.ts +115 -0
- package/lib/fsio-text.js +104 -84
- package/lib/git-route.d.ts +100 -0
- package/lib/git-route.js +46 -47
- package/lib/index.d.ts +1003 -0
- package/lib/index.js +1106 -1003
- package/lib/listing.d.ts +114 -0
- package/lib/listing.js +68 -55
- package/lib/paths.d.ts +182 -0
- package/lib/paths.js +134 -109
- package/lib/picker.d.ts +266 -0
- package/lib/picker.js +371 -351
- package/lib/ports.d.ts +44 -0
- package/lib/ports.js +39 -29
- package/lib/preflight.d.ts +91 -0
- package/lib/preflight.js +94 -0
- package/lib/preset-choice.d.ts +33 -0
- package/lib/preset-choice.js +15 -7
- package/lib/probe-cache.d.ts +51 -0
- package/lib/probe-cache.js +43 -29
- package/lib/sandbox-core.d.ts +149 -0
- package/lib/sandbox-core.js +239 -87
- package/lib/sandbox.d.ts +48 -0
- package/lib/sandbox.js +4 -4
- package/lib/search-exec.d.ts +96 -0
- package/lib/search-exec.js +52 -79
- package/lib/search-route.d.ts +75 -0
- package/lib/search-route.js +30 -31
- package/lib/shell-env.d.ts +88 -0
- package/lib/shell-env.js +78 -74
- package/lib/shell.d.ts +10 -0
- package/lib/shell.js +5 -0
- package/lib/subprocess.d.ts +313 -0
- package/lib/subprocess.js +267 -262
- package/lib/terminal-activity.d.ts +98 -0
- package/lib/terminal-activity.js +29 -39
- package/lib/terminal-route.d.ts +27 -0
- package/lib/terminal-route.js +16 -8
- package/lib/watcher.d.ts +77 -0
- package/lib/watcher.js +120 -126
- package/lib/workspace-files-route.d.ts +132 -0
- package/lib/workspace-files-route.js +73 -81
- package/lib/workspace-files-wsl.d.ts +257 -0
- package/lib/workspace-files-wsl.js +311 -251
- package/lib/wsl.d.ts +266 -0
- package/lib/wsl.js +150 -155
- package/locale/preflight/en.json +6 -0
- package/locale/preflight/zh.json +6 -0
- package/package.json +78 -22
- package/scripts/diagnose.sh +92 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,11 +7,340 @@ All notable changes to this project are documented here. The format follows
|
|
|
7
7
|
The reasoning and the measurements behind each entry are in the archived
|
|
8
8
|
engineering record,
|
|
9
9
|
[docs/archive/engineering-record.zh.md](docs/archive/engineering-record.zh.md)
|
|
10
|
-
(Chinese, repository only — it is history, never a second README).
|
|
11
|
-
reference below points at that record's numbering
|
|
10
|
+
(Chinese, repository only — it is history, never a second README). A `§`
|
|
11
|
+
reference below points at that record's numbering unless it names another
|
|
12
|
+
document: the 0.1.0 entry's `design-history §` references are to
|
|
13
|
+
[docs/archive/design-history.zh.md](docs/archive/design-history.zh.md), which
|
|
14
|
+
keeps the superseded designs under the section numbers they had while they
|
|
15
|
+
were part of the record.
|
|
12
16
|
|
|
13
17
|
## [Unreleased]
|
|
14
18
|
|
|
19
|
+
## [0.9.0] - 2026-10-06
|
|
20
|
+
|
|
21
|
+
A usability round over the sandbox failure path: the failure stops being a
|
|
22
|
+
wall the first command walks into, and becomes a message that arrives early
|
|
23
|
+
and says how to fix it.
|
|
24
|
+
|
|
25
|
+
The bwrap refusal now classifies its cause — missing versus
|
|
26
|
+
present-but-failing — and prints the direct install command in the distro's
|
|
27
|
+
own package family (apt/dnf/pacman/zypper) instead of a hardcoded `apt-get`
|
|
28
|
+
line; every consumer composes it from one place. A new `wsl-preflight`
|
|
29
|
+
service runs the same shared probe when a distro session opens and surfaces
|
|
30
|
+
an unusable bwrap as a warning with the full remedy, moving the discovery
|
|
31
|
+
moment ahead of the first failed command — advisory only, never installing.
|
|
32
|
+
`pnpm run diagnose` collects a read-only, paste-ready diagnostic report for
|
|
33
|
+
issues, and the three bare wsl-probe failures (no distro, no `$HOME`, no
|
|
34
|
+
shell) now carry their next steps. The agent probe's parity legs classify
|
|
35
|
+
the nested-interop service timeout (`Wsl/Service/WSAETIMEDOUT`, observed on
|
|
36
|
+
WSL 3.0.1.0) as SKIP with the evidence attached, so an environment failure
|
|
37
|
+
that prevents the comparison reads as what it is instead of a parity
|
|
38
|
+
violation.
|
|
39
|
+
|
|
40
|
+
## [0.8.0] - 2026-10-06
|
|
41
|
+
|
|
42
|
+
The toolchain's TypeScript story completes (pnpm, a checkJs gate, and 36 of 36
|
|
43
|
+
modules with their declarations shipped), and with it three behaviour fixes
|
|
44
|
+
land: the byte-window cap is enforced, the agent path's EXEC capture budget is
|
|
45
|
+
honoured, and the filesystem's host-path mapping speaks its synchronous
|
|
46
|
+
contract.
|
|
47
|
+
|
|
48
|
+
One theme: the toolchain moves from npm to pnpm. `pnpm-lock.yaml` replaces
|
|
49
|
+
`package-lock.json`, CI installs through corepack with
|
|
50
|
+
`pnpm install --frozen-lockfile` (the `packageManager` field pins pnpm 11.7.0,
|
|
51
|
+
matching the harness repository), and the three dependencies with install
|
|
52
|
+
scripts (`@deepseek-ai/dsh-subprocess-local`, `koffi`, `node-pty`) are
|
|
53
|
+
allow-listed in `pnpm-workspace.yaml` — pnpm 11 blocks dependency build
|
|
54
|
+
scripts by default. With it: `engines` and the CI matrix align with the harness
|
|
55
|
+
host's own floor (`^22.19.0 || >=24.0.0`), so the Node 20 legs are gone, and
|
|
56
|
+
the per-target lock test drops its unused `withResolvers` gate, a Node 22+ API
|
|
57
|
+
that hung those legs on every push.
|
|
58
|
+
|
|
59
|
+
The unit suite also takes on the integration layer. `test/provider.test.mjs`
|
|
60
|
+
boots the REAL `WslShellExecutor` and `WslFileSystem` with substitutes only at
|
|
61
|
+
the seams that would reach `wsl.exe` — the agent, the substrate, the
|
|
62
|
+
confinement — so the guard chain, the mutation routing, the agent execution
|
|
63
|
+
path with its result decoration, the one-shot fallback and the runner-failure
|
|
64
|
+
remap are measured: `lib/index.js` goes from 60% lines / 9% functions covered
|
|
65
|
+
to 97%/90% when it joins, and measures 97.49% lines / 95.16% functions in the
|
|
66
|
+
released tree. The coverage gate's branch threshold moves with it, 85 to 84 —
|
|
67
|
+
the newly measured layer's uncovered tail is the distro-resolution branches
|
|
68
|
+
(`defaultDistro`'s no-distro throw, `linuxHomePath`'s refusals, the watcher's
|
|
69
|
+
real spawn internals) that need a live `wsl.exe`, and RELEASING.md records
|
|
70
|
+
the bar for raising it again: cover that tail on the Windows CI legs, or move
|
|
71
|
+
the coverage job to `windows-latest`. And the probes join CI: a
|
|
72
|
+
`workflow_dispatch` job — named for the self-hosted Windows runner, though it
|
|
73
|
+
carries the hosted `windows-latest` label — runs five of them: `sandbox`
|
|
74
|
+
unconditionally, since it needs only bubblewrap in the default distro, then
|
|
75
|
+
`mode`, `terminal`, `picker` and `missing-wsl` where the harness app is
|
|
76
|
+
present. The `sandbox` leg fails, not skips, where bubblewrap is absent, so a
|
|
77
|
+
dispatch to a hosted runner is no green no-op. Separately,
|
|
78
|
+
`test/probe/run-all-when-closed.sh`'s suite gains the four probes it was
|
|
79
|
+
missing — `agent`, `watch`, `substrate`, `exec`.
|
|
80
|
+
|
|
81
|
+
One more theme: the whole repository comes under a TypeScript check gate.
|
|
82
|
+
`tsc --noEmit` under `strict`/`checkJs` now runs as part of `pnpm test` over
|
|
83
|
+
`lib/**`, `test/**` and the probe scripts — a scope that narrows to what is
|
|
84
|
+
NOT generated once the migration completes, `lib/**` leaving the gate for the
|
|
85
|
+
build program below — with the types taken from the peer packages' own
|
|
86
|
+
declarations and the service augmentations loaded through
|
|
87
|
+
`types/dsh-services.d.ts`. The gate's first pass surfaced the seam work this
|
|
88
|
+
package already carries: the private `spawnSpec` the WSL spawn directory needs
|
|
89
|
+
(`docs/UPSTREAM-SPAWN-SEAM.md` bridges it) and a synchronous-contract violation
|
|
90
|
+
in `processPathFromHostPath`, pending a design decision.
|
|
91
|
+
|
|
92
|
+
Extending the gate to the tests found real defects the untyped corners had
|
|
93
|
+
been hiding: `distroReadBytes` accepted the byte-window cap (both call sites
|
|
94
|
+
pass it) but neither documented nor enforced it, so a ranged `readBytes`
|
|
95
|
+
asking past the page cap was served instead of refused — upstream refuses a
|
|
96
|
+
window the same way it refuses a page. Fixed against the upstream wording and
|
|
97
|
+
arithmetic (`lib/workspace-files-wsl.js`), with an absent length now
|
|
98
|
+
defaulting to the window cap rather than the whole-file cap, as upstream's
|
|
99
|
+
`resolveWindow` defaults it; the refusal is pinned in
|
|
100
|
+
`test/workspace-files-wsl.test.mjs`. Two hand-written JSDoc contracts wider
|
|
101
|
+
than their code (`gitSpawnRewrite`'s `argv`/`cwd`, `wslErrorCode`'s
|
|
102
|
+
`stdout`/`stderr` — both tolerate absence at runtime) and one narrower than
|
|
103
|
+
its caller (`uncToPosix`'s path) were corrected to what the functions actually
|
|
104
|
+
take. Test doubles are typed as the slice of the seam they script, reaching
|
|
105
|
+
the seam's declared type through one documented cast at the injection point —
|
|
106
|
+
no `any` and no new `@ts-expect-error` anywhere in the suite.
|
|
107
|
+
|
|
108
|
+
And the migration's third step opens: `src/agent-protocol.ts` is the first
|
|
109
|
+
module whose source is TypeScript. `pnpm run build` (`tsconfig.build.json`)
|
|
110
|
+
emits `lib/agent-protocol.js` plus `lib/agent-protocol.d.ts` under the same
|
|
111
|
+
export paths, and the artifacts stay committed so a bare checkout remains
|
|
112
|
+
loadable and the tarball needs no build step; the new `lint:build` gate
|
|
113
|
+
(`test/build-freshness.mjs`) makes `pnpm test` fail the moment a committed
|
|
114
|
+
artifact drifts from its source. Generated files are excluded from the
|
|
115
|
+
`checkJs` gate — their TypeScript sources are type-checked with
|
|
116
|
+
`noEmitOnError` instead, which is strictly stronger. The protocol message
|
|
117
|
+
union now has one home: `lib/agent.js` and the script-driven tests import
|
|
118
|
+
`AgentMessage` and friends from the protocol module's declarations instead of
|
|
119
|
+
restating them.
|
|
120
|
+
|
|
121
|
+
And the declarations land for every module. A second, declaration-only pass
|
|
122
|
+
(`tsconfig.dts.json`, driven by `scripts/build.mjs`) emits `.d.ts` for the
|
|
123
|
+
hand-written, JSDoc-typed JavaScript, and every export subpath now carries its
|
|
124
|
+
`types` condition — downstream finally sees this plugin's types, verified end
|
|
125
|
+
to end (a consumer's wrong call is rejected with the precise signature). The
|
|
126
|
+
declaration pass must run against a clean tree: a stale `.d.ts` is resolved as
|
|
127
|
+
an input exactly where `./x.js` would be, and re-emitting through it silently
|
|
128
|
+
degrades the result — a precise type in `index.d.ts` collapsed to `any` that
|
|
129
|
+
way during the migration — so the build deletes the declarations its first
|
|
130
|
+
pass does not own before re-emitting, and `lint:build` snapshots the
|
|
131
|
+
artifacts, runs the real build, byte-compares and restores the tree.
|
|
132
|
+
`lint:style` gained the invariant that keeps the surface from rotting: a
|
|
133
|
+
JavaScript export without its `types` sibling fails the gate.
|
|
134
|
+
|
|
135
|
+
`lib/paths.js` follows as the second migrated module — the path algebra every
|
|
136
|
+
other module imports, plus `DistroPath`/`WorldPathOptions`, which consumers
|
|
137
|
+
reference through `import("./paths.js").DistroPath`; the TypeScript source
|
|
138
|
+
keeps those names, so nothing downstream changes except that they now come
|
|
139
|
+
from a checked source. CONTRIBUTING records the per-module checklist this
|
|
140
|
+
settled into: write `src/<name>.ts`, add the generated JavaScript to the two
|
|
141
|
+
`exclude` lists, build, and let the suite verify the artifact is
|
|
142
|
+
behaviourally identical — the `exclude` step lasts only while the tree is
|
|
143
|
+
mixed; the finished checklist ends at write, build and test, with no list to
|
|
144
|
+
maintain.
|
|
145
|
+
|
|
146
|
+
Three leaf modules then follow in one pass — `agent-errors` (the two error
|
|
147
|
+
classes the executor switches on), `probe-cache` (the verdict policy that
|
|
148
|
+
remembers successes and re-probes failures) and `listing` (the picker's pure
|
|
149
|
+
helpers, `boundedInsert`'s generic included). Each was verified export-for-
|
|
150
|
+
export against its predecessor, and the whitespace-normalized code diff is
|
|
151
|
+
tsc's statement reflow and nothing else; every source keeps its module doc
|
|
152
|
+
plus a note naming the generated artifact.
|
|
153
|
+
|
|
154
|
+
The next four carry the decision layer: `fsio-text` (the byte-for-byte
|
|
155
|
+
replication of the peer's text mechanics — `FsCodedError` gained a declared
|
|
156
|
+
`code` field, and the stream decoder is typed through `node:util`, since
|
|
157
|
+
Node's global `TextDecoder` is a value, not a type), `fs-decisions` (the
|
|
158
|
+
refusal descriptors, with `Refusal` as an exported interface and `isCoded` as
|
|
159
|
+
a real type predicate), and `git-route`/`search-route` (the two spawn
|
|
160
|
+
rewrites; their generated artifacts are byte-identical modulo whitespace).
|
|
161
|
+
Nine of the thirty-six modules now have TypeScript sources.
|
|
162
|
+
|
|
163
|
+
Six more follow — `terminal-route`, `preset-choice`, `ports`, `bwrap`,
|
|
164
|
+
`agent-confined` and `agent-shared` — and they cross a structural line: a
|
|
165
|
+
source may now import a module that is not migrated yet. `rootDirs` merges
|
|
166
|
+
`src/` and `lib/` for resolution, so `./agent.js` resolves through the
|
|
167
|
+
generated `lib/agent.d.ts` while the emitted specifier stays `./agent.js`;
|
|
168
|
+
because that merge also pulls declarations in as program inputs, pass 1 now
|
|
169
|
+
emits into a scratch directory the build script copies from, keeping inputs
|
|
170
|
+
and outputs disjoint (TS5055 otherwise). `agent-shared`'s generated artifact
|
|
171
|
+
is byte-identical even after whitespace normalization; the rest differ only
|
|
172
|
+
by tsc's statement reflow. Fifteen of the thirty-six modules are TypeScript.
|
|
173
|
+
|
|
174
|
+
The mid-size tier follows: `wsl` (the `wsl.exe` interop primitives — its four
|
|
175
|
+
option shapes are exported interfaces now), `agent-exec` (the agent-backed
|
|
176
|
+
execution handle, whose request/result/runner/handle typedefs the tests and
|
|
177
|
+
`search-exec` already imported by name) and `shell-env` (the `DSH_*` fact
|
|
178
|
+
contributor, typing the harness registry it contributes through structurally,
|
|
179
|
+
as its JSDoc always did). `agent-exec` surfaced one Node typing fact worth
|
|
180
|
+
knowing: `Buffer.alloc(0)` infers `Buffer<ArrayBuffer>` while an incoming
|
|
181
|
+
`Buffer` is `Buffer<ArrayBufferLike>`, so the accumulators are annotated
|
|
182
|
+
`Buffer`. Eighteen of the thirty-six modules are TypeScript now.
|
|
183
|
+
|
|
184
|
+
Seven small modules follow — `watcher` (the in-distro mtime watch loop and its
|
|
185
|
+
protocol, `ChildProcess` and options typed), `sandbox-core`/`sandbox` (the
|
|
186
|
+
bwrap probe-and-confine pair; `WslConfined`/`WslSandboxCoreInstance` are
|
|
187
|
+
exported interfaces and the two class fields are `declare` so the emitted
|
|
188
|
+
JavaScript stays byte-identical), `terminal-activity`, `search-exec`, and the
|
|
189
|
+
two entry re-exports `shell`/`fs` (whose artifacts are byte-identical). At
|
|
190
|
+
twenty-five of thirty-six, the remaining modules are the large ones: `agent`,
|
|
191
|
+
`fs-substrate`, `fsio-agent`, `picker`, `subprocess`, `auto-preset`,
|
|
192
|
+
`workspace-files-*`, `file-reference-wsl`, `fs-routing`, and finally `index`.
|
|
193
|
+
|
|
194
|
+
The route layer follows — `workspace-files-route` (the pure build/parse pairs
|
|
195
|
+
for the distro-routed file service), `file-reference-wsl` (the `@`-completion
|
|
196
|
+
traversal strategy, with `TraversalDirent`/`FileReferenceTraversal` as
|
|
197
|
+
exported interfaces) and `fs-routing` (the root-plane coordinate router).
|
|
198
|
+
`fs-routing` is where the compiler re-met the documented upstream seam:
|
|
199
|
+
`WslFileSystem.processPathFromHostPath` is async against the `FileSystem`
|
|
200
|
+
interface's synchronous contract, so the router's lazy backend is typed as the
|
|
201
|
+
concrete class rather than casting the mismatch away — the seam keeps its one
|
|
202
|
+
visible `@ts-expect-error` in `index.js`. The port also dropped two dead
|
|
203
|
+
imports `fs-routing` had carried since a refactor (`windowsToLinuxMount`,
|
|
204
|
+
`linuxJoin`), which the emitted artifact no longer contains. The orphaned
|
|
205
|
+
`linuxJoin` doc block above the class — a leftover of that same refactor — is
|
|
206
|
+
gone too. Twenty-eight of the thirty-six modules are TypeScript.
|
|
207
|
+
|
|
208
|
+
`fs-substrate` and `auto-preset` follow — the agent-backed filesystem face
|
|
209
|
+
(`ResolvedTarget` exported as an interface, its six instance fields declared
|
|
210
|
+
with `declare` so the emitted JavaScript stays byte-identical) and the
|
|
211
|
+
preset-adoption plugin (whose harness service slices stay spelled
|
|
212
|
+
structurally, and whose `ensureSession` patch carries the `this: unknown`
|
|
213
|
+
parameter the JSDoc already documented). Thirty of the thirty-six modules
|
|
214
|
+
are TypeScript; the remaining six are `agent`, `fsio-agent`, `picker`,
|
|
215
|
+
`subprocess`, `workspace-files-wsl` and `index`.
|
|
216
|
+
|
|
217
|
+
`picker` follows — the biggest single module migrated so far after the
|
|
218
|
+
protocol file itself (494 lines). Its config, the cached distro listing and
|
|
219
|
+
the per-distro home map are `declare`d so the emitted JavaScript stays
|
|
220
|
+
byte-identical, and the browse capability object stays an inline class field,
|
|
221
|
+
which is how the original script wrote it. Thirty-one of the thirty-six
|
|
222
|
+
modules are TypeScript.
|
|
223
|
+
|
|
224
|
+
`subprocess` follows — the composition-level provider behind the GUI's
|
|
225
|
+
terminal window, and the last module that overrides a shipped peer class for
|
|
226
|
+
the terminal/search routing. Its `spawnTerminal`/`spawn` overrides are checked
|
|
227
|
+
against the peer's declared signatures (they pass without a new assertion),
|
|
228
|
+
and the two JSDoc casts the script carried (`env`, the stdout collect budget)
|
|
229
|
+
are absorbed into the types. Thirty-two of the thirty-six modules are
|
|
230
|
+
TypeScript; the last four are `agent`, `fsio-agent`, `workspace-files-wsl`
|
|
231
|
+
and `index`.
|
|
232
|
+
|
|
233
|
+
`agent` follows — the resident in-distro agent's whole lifecycle (756 lines).
|
|
234
|
+
Its seven internal methods stay `private`, which surfaced the migration's one
|
|
235
|
+
structural seam: a class with private members is nominal, so the declaration
|
|
236
|
+
generated for the still-un-migrated `fsio-agent` and the one this source emits
|
|
237
|
+
are not interchangeable even though the runtime object is the same class. The
|
|
238
|
+
one boundary (`fs-substrate` handing agents to `DistroFs`) crosses it through a
|
|
239
|
+
single documented assertion naming the lib-side type; it disappears when
|
|
240
|
+
`fsio-agent` migrates. Thirty-three of the thirty-six modules are TypeScript.
|
|
241
|
+
|
|
242
|
+
`fsio-agent` follows, and with it that seam closes: the lib-side declaration
|
|
243
|
+
it used to drag in is gone, so the boundary assertion in `fs-substrate` is
|
|
244
|
+
deleted in the same commit — the class is declared once now, and the private
|
|
245
|
+
members it keeps are nominal against nothing else. Thirty-four of the
|
|
246
|
+
thirty-six modules are TypeScript; `workspace-files-wsl` and `index` remain.
|
|
247
|
+
|
|
248
|
+
`workspace-files-wsl` follows — the distro-routed GUI file service, with
|
|
249
|
+
`WorkspaceFilesWslConfig`/`DistroListing` exported, the row-config read kept
|
|
250
|
+
as its one documented double cast (the base class keeps `config` private), and
|
|
251
|
+
the `readByteRange` expect-error left exactly where it was: that one is an
|
|
252
|
+
open design decision, not a migration artifact. Thirty-five of the thirty-six
|
|
253
|
+
modules are TypeScript; `index` is the last one.
|
|
254
|
+
|
|
255
|
+
`index` closes the migration — the integration layer's two providers, 1400
|
|
256
|
+
lines, with both documented upstream seams intact: the private `spawnSpec` a
|
|
257
|
+
`wsl.exe` spawn needs, and the `processPathFromHostPath` contract violation,
|
|
258
|
+
keep their `@ts-expect-error` carrying the reason. The generated artifact is
|
|
259
|
+
proven structurally identical to the hand-written module: an AST comparison
|
|
260
|
+
that treats the erased type wrappers (`as`, `@type` casts, parentheses) as
|
|
261
|
+
transparent reports only the imports the source no longer needs — a never-used
|
|
262
|
+
`fileURLToPath`, the dead `isUnderDistro`, and the type-only `WslAgent` (which
|
|
263
|
+
tsc elides; the module still loads through its other edges) — plus tsc's
|
|
264
|
+
reflow and one internal rename in `decorateResult`, whose result row now
|
|
265
|
+
derives from the handle type instead of a second type parameter. `resolve()`
|
|
266
|
+
returns the precise `WslExecSpec` where the JSDoc declared the wider
|
|
267
|
+
`ShellExecSpec`. Thirty-six of thirty-six modules are TypeScript.
|
|
268
|
+
|
|
269
|
+
The transitional scaffolding then retires, nothing left for it to do:
|
|
270
|
+
`rootDirs` and the scratch declaration emission existed for a mixed tree
|
|
271
|
+
(`src/` sources importing un-migrated `lib/*.js` neighbours), and the
|
|
272
|
+
declaration-only second pass (`tsconfig.dts.json`) existed to give the
|
|
273
|
+
hand-written JavaScript its `.d.ts`. `pnpm run build` is one `tsc` pass
|
|
274
|
+
emitting JavaScript and declarations straight into `lib/`, pruning
|
|
275
|
+
declarations no source owns; the `checkJs` gate drops its 35-entry exclude
|
|
276
|
+
list and states what is NOT generated — `test/**` and the ambient service
|
|
277
|
+
types, with `src/` checked by the build program (`noEmitOnError`); and
|
|
278
|
+
`lint:build` enforces the closed corpus (every `lib/*.js` has its
|
|
279
|
+
`src/<name>.ts`, every source has both artifacts), so "`lib/` is entirely
|
|
280
|
+
generated" is a checked property rather than a convention.
|
|
281
|
+
|
|
282
|
+
The real-machine probes then re-ran green on the migrated tree — 12 of 12, the
|
|
283
|
+
one verification face CI cannot cover (its self-hosted leg is skipped):
|
|
284
|
+
filesystem mutation through the throwaway wslfs profile, terminal, mode,
|
|
285
|
+
missing-wsl, bwrap, the shell confinement wiring, sandbox-off, picker, agent
|
|
286
|
+
protocol, watch, substrate and exec. The run surfaced two defects in the probe
|
|
287
|
+
harness itself. `ELECTRON_RUN_AS_NODE` — the flag that boots the harness CLI in
|
|
288
|
+
node mode — never crossed the WSL interop boundary: interop hands a Windows
|
|
289
|
+
process only the variables `WSLENV` lists, so the inline assignment was dropped
|
|
290
|
+
and the app booted as its GUI self, leaving the probe waiting on a process that
|
|
291
|
+
would never run; `test/probe/env.sh` lists the flag now, composed with any
|
|
292
|
+
`WSLENV` the caller had. And the kill-cleanup check counted every `sleep` in
|
|
293
|
+
the distro, which the resident agent's lease watchdog — introduced after the
|
|
294
|
+
probes last ran — makes non-zero by construction, alongside in-flight timeout
|
|
295
|
+
watchers; the check counts its own command line now, so a kill that really
|
|
296
|
+
leaked still fails it. And the suite's live log sits inside the checkout,
|
|
297
|
+
where the mirror sync's `tar` read it while it grew — `file changed as we read
|
|
298
|
+
it`, exit 1, `set -e` failing the probe before it ran; the sync excludes
|
|
299
|
+
`test/probe/.scratch` now, which is run scratch nothing at runtime reads.
|
|
300
|
+
|
|
301
|
+
One real defect fell out of the type gate's migration notes and closes here:
|
|
302
|
+
the agent execution path handed the EXEC frame the volatile wrapper object
|
|
303
|
+
where a byte budget belongs. `encodeExecFrame`'s `> 0` test was false on an
|
|
304
|
+
object, the frame carried 0, and 0 is the agent's "uncapped" — so the cut at
|
|
305
|
+
the caller's per-stream budget that `agent-exec` documents never ran, and a
|
|
306
|
+
chatty command cost unbounded distro memory. `src/index.ts` now reads
|
|
307
|
+
`config.maxOutputBytes.get()` like every other volatile field, and
|
|
308
|
+
`test/provider.test.mjs` pins the resolved number in the frame (the check
|
|
309
|
+
fails against the previous artifact). The one-shot path was always correct —
|
|
310
|
+
it reads the same field through the upstream executor's own `.get()`.
|
|
311
|
+
|
|
312
|
+
The second pending seam closes the same way — with an implementation instead
|
|
313
|
+
of a note. `WslFileSystem.processPathFromHostPath` was `async` against the
|
|
314
|
+
peer interface's synchronous contract, so the consumers that read it without
|
|
315
|
+
awaiting (spill-policy's attachment mapping, the session controller's and the
|
|
316
|
+
UI's path verification) received a Promise — always truthy, never the
|
|
317
|
+
`undefined` they test for — and mapped nothing. It is synchronous now, built
|
|
318
|
+
from what is already known: the distro once `distro()` has resolved it (the
|
|
319
|
+
pinned config, or the default `wsl.exe` answered by an earlier operation) and
|
|
320
|
+
the configured `cwd`, or the resolved home for a relative path. A call that
|
|
321
|
+
would have to ask `wsl.exe` — a cold default distro, a relative path before
|
|
322
|
+
the home is known — answers `undefined`, the same "no mapping" the ssh
|
|
323
|
+
provider gives, so the consumers take their documented refusal path instead of
|
|
324
|
+
receiving a bogus value. The value keeps the world spelling the backend keys
|
|
325
|
+
on, so their map → resolve → processPath round trip closes exactly as it does
|
|
326
|
+
for the host backend. `test/provider.test.mjs` pins the sync value, the round
|
|
327
|
+
trip, and both `undefined` cases (the checks fail against the previous
|
|
328
|
+
artifact). The `@ts-expect-error` count drops to three: the two remaining
|
|
329
|
+
design decisions and the upstream spawn seam.
|
|
330
|
+
|
|
331
|
+
The last in-code seam note closes by deletion rather than repair. The GUI file
|
|
332
|
+
service's `readByteRange` — a method older than the migration, which the type
|
|
333
|
+
gate flagged with an expect-error because its host-workspace branch called a
|
|
334
|
+
base method that does not exist — turned out to be unreachable: the remote
|
|
335
|
+
layer registers exactly the methods a decorated class declares (typert writes
|
|
336
|
+
its markers per instance, from the class that carries the decorators), the
|
|
337
|
+
base service has no such method, and nothing in the plugin or in the harness
|
|
338
|
+
calls it. Ranged reads already go through the wire op they always did —
|
|
339
|
+
`readBytes` with `options.range`, which the distro branch serves and the host
|
|
340
|
+
branch delegates. The method and its one test line are gone (the range case
|
|
341
|
+
stays covered through `readBytes`), and one more expect-error goes with it:
|
|
342
|
+
two remain, the exit-4 kind and the upstream spawn seam.
|
|
343
|
+
|
|
15
344
|
## [0.7.5] - 2026-10-05
|
|
16
345
|
|
|
17
346
|
One theme: a failed environment probe retries instead of being trusted
|
|
@@ -717,6 +1046,17 @@ overwrite guard that stopped at the host.
|
|
|
717
1046
|
app's own runtime, both entries import; `test/syntax.mjs` now checks every
|
|
718
1047
|
`z.<member>` in `lib/` against the pinned peer's surface, which fails on
|
|
719
1048
|
`z.enum` and passes on `z.union`.
|
|
1049
|
+
|
|
1050
|
+
## [0.2.0] - 2026-10-03
|
|
1051
|
+
|
|
1052
|
+
One theme: the Remote-WSL parity plan (`docs/PARITY.md`) lands, Phases 0–7 —
|
|
1053
|
+
a resident in-distro agent plus the shell-execution, watch, publication,
|
|
1054
|
+
ports, terminal-routing and bootstrap work that migrates the seams onto it.
|
|
1055
|
+
The release closes with the two agent-path breaks that took down every GUI
|
|
1056
|
+
shell call, both surfacing only through the GUI's wire protocol.
|
|
1057
|
+
|
|
1058
|
+
### Fixed
|
|
1059
|
+
|
|
720
1060
|
- **`truncated` missing from the agent path's output streams** — the bash tool's
|
|
721
1061
|
canonical result copies the field unconditionally (`canonicalBashResult`), so an
|
|
722
1062
|
`undefined` failed the wire's lossless-JSON snapshot and EVERY shell tool call
|
|
@@ -799,9 +1139,6 @@ overwrite guard that stopped at the host.
|
|
|
799
1139
|
Probed end-to-end against a real distro: `test/probe/agent.sh` (8 checks, including
|
|
800
1140
|
binary-safe payloads, an in-distro timeout kill, and a 2 MB single-line response).
|
|
801
1141
|
Unit tests cover the codecs and the lifecycle state machine with a fake transport.
|
|
802
|
-
|
|
803
|
-
### Added
|
|
804
|
-
|
|
805
1142
|
- `docs/PARITY.md`: the plan to reach VS Code Remote-WSL-grade experience — a resident
|
|
806
1143
|
in-distro agent as the core, with the `fs` and `shell` seams migrated onto it and the
|
|
807
1144
|
current 9p/one-shot paths kept as the documented fallback — plus the Phase-0 contract
|
|
@@ -1343,9 +1680,9 @@ freshly created files.
|
|
|
1343
1680
|
- Three peer declarations this plugin neither imports nor injects:
|
|
1344
1681
|
`@deepseek-ai/dsh-sandbox`, `@deepseek-ai/dsh-shell` and
|
|
1345
1682
|
`@deepseek-ai/dsh-tools`. They were required by the abandoned tool-renaming
|
|
1346
|
-
designs (
|
|
1347
|
-
(
|
|
1348
|
-
`grep -rho 'from "@deepseek-ai/[^"]*"' lib/ | sort -u` — plus
|
|
1683
|
+
designs (design-history §15/§18), which could only stub the sandbox symbols
|
|
1684
|
+
locally (design-history §15.5). The remaining set is checkable in one
|
|
1685
|
+
command — `grep -rho 'from "@deepseek-ai/[^"]*"' lib/ | sort -u` — plus
|
|
1349
1686
|
`@deepseek-ai/dsh-subprocess` (the service `static inject` requires) and
|
|
1350
1687
|
`@deepseek-ai/cordis`, which every DSH plugin declares.
|
|
1351
1688
|
(`@deepseek-ai/dsh-sandbox` came back in this same release: the distro-side
|