dsh-plugin-wsl-env 0.13.1 → 0.13.2
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 +67 -0
- package/CONTRIBUTING.md +18 -7
- package/SUPPORT.md +1 -1
- package/cordis.patch.yml +2 -1
- package/docs/PEER-PARITY.md +24 -19
- package/package.json +22 -22
- package/scripts/doctor.mjs +39 -6
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,73 @@ were part of the record.
|
|
|
16
16
|
|
|
17
17
|
## [Unreleased]
|
|
18
18
|
|
|
19
|
+
## [0.13.2] - 2026-10-26
|
|
20
|
+
|
|
21
|
+
This release tracks DeepSeek Harness `0.2.1-rc.3`: the peer declarations become
|
|
22
|
+
floor ranges so a newer harness installs the plugin unchanged, and the
|
|
23
|
+
lockfile's transitive `undici` moves past a security advisory that Dependabot
|
|
24
|
+
could not clear on its own.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **`undici` in the lockfile moves to the security-fixed `8.12.3` via a pnpm
|
|
29
|
+
override.** `undici` rides in only as an exact transitive pin of
|
|
30
|
+
`@deepseek-ai/dsh-http-proxy` — a package upstream controls — so Dependabot's
|
|
31
|
+
security job could resolve no patched version (it reports "the latest
|
|
32
|
+
possible version … is 8.11.2" and fails). `pnpm-workspace.yaml` now carries
|
|
33
|
+
`overrides: { undici: '>=8.12.3' }` (the pnpm 11 settings home; the
|
|
34
|
+
`package.json` `pnpm` field is no longer read), the lockfile swaps the one
|
|
35
|
+
package, and the override comment records that it is retired when upstream
|
|
36
|
+
moves the pin. Nothing under `src/` reads `undici`; the check chain is
|
|
37
|
+
unaffected.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- **The peer declarations become floor ranges, so a newer harness installs
|
|
42
|
+
the plugin unchanged.** The `@deepseek-ai/dsh-*` entries in
|
|
43
|
+
`peerDependencies` move from the exact pin to `>=0.2.1-rc.3`, and
|
|
44
|
+
`@deepseek-ai/cordis` / `@deepseek-ai/schemastery` widen from `~` to `^`
|
|
45
|
+
(`^4.0.5`, `^3.18.5`). An app that ships a newer harness release now
|
|
46
|
+
satisfies the peers without waiting for a plugin release — same-line rc
|
|
47
|
+
bumps and every stable release install cleanly; only a brand-new
|
|
48
|
+
prerelease line (`0.2.2-rc.1` against `>=0.2.1-rc.3`) still warns, because
|
|
49
|
+
semver admits a prerelease only against a comparator on its own tuple and
|
|
50
|
+
no range can promise an unpublished line. That residue is what the weekly
|
|
51
|
+
peer-canary is for: it still resolves the `next` dist-tag into a scratch
|
|
52
|
+
tree and flags when the line moves past a floor — the signal to re-run the
|
|
53
|
+
`docs/PEER-PARITY.md` comparison and raise the floor in the commit that
|
|
54
|
+
matches the harness release. The devDependencies keep their exact pins, so
|
|
55
|
+
the gates stay reproducible and the parity audit keeps naming one line.
|
|
56
|
+
`scripts/doctor.mjs` learned the new shapes (`peerSatisfied` now reads `>=`
|
|
57
|
+
and `^`, and its `compareVersions` orders prerelease identifiers by semver
|
|
58
|
+
§11 — `rc.10` above `rc.9`), `scripts/peer-canary.mjs` parses and preserves
|
|
59
|
+
the shapes, and `AGENTS.md`, `CONTRIBUTING.md`, `SUPPORT.md` and
|
|
60
|
+
`docs/PEER-PARITY.md` state the new policy.
|
|
61
|
+
|
|
62
|
+
- **The dev pin line moves to DeepSeek Harness `0.2.1-rc.3`.** Every
|
|
63
|
+
`@deepseek-ai/dsh-*` pin in `devDependencies` goes from `0.2.1-rc.2` to
|
|
64
|
+
`0.2.1-rc.3` — the release the `next` dist-tag resolves to — and
|
|
65
|
+
`pnpm-lock.yaml` refreshes with it. `@deepseek-ai/cordis` and
|
|
66
|
+
`@deepseek-ai/schemastery` stay at `4.0.5` / `3.18.5`: upstream's `vendor/`
|
|
67
|
+
did not change on this line.
|
|
68
|
+
|
|
69
|
+
No module under `src/` changed, and that is the finding. The three peers
|
|
70
|
+
this plugin subclasses or replicates ship byte-identical `lib/index.js`
|
|
71
|
+
files on rc.3 — `dsh-fs-local` (the fsio dialect, still 909 lines), `dsh-fs`
|
|
72
|
+
(the `FsVersion` brand) and `dsh-bash-local` (the spill machinery) — so
|
|
73
|
+
every line reference in `docs/PEER-PARITY.md` still names the same code;
|
|
74
|
+
only the tarballs' digests changed, and the parity doc now carries the
|
|
75
|
+
`0.2.1-rc.3` ones with the re-check dated 2026-10-26. That byte-identity is
|
|
76
|
+
also the evidence behind the new peer floor: the same code answers above
|
|
77
|
+
rc.3. Upstream's release notes for the line are UI- and LLM-side
|
|
78
|
+
(navigation entry customization, analytics, the official `/models`
|
|
79
|
+
listing): the one composition-visible change is a new `entry-customization`
|
|
80
|
+
UI row in the app's own `cordis.patch.yml`, which rides with the app's
|
|
81
|
+
bundle rather than this plugin's layer. `preset-wsl` needed no
|
|
82
|
+
regeneration — `packages/bundle/web-app/presets/standard.patch.yml` is
|
|
83
|
+
byte-identical on rc.3 — and the provenance comment in `cordis.patch.yml`
|
|
84
|
+
now names the rc.3 tree.
|
|
85
|
+
|
|
19
86
|
## [0.13.1] - 2026-10-19
|
|
20
87
|
|
|
21
88
|
A patch release restoring `wsl-shell-env`: the component mounts again, and the
|
package/CONTRIBUTING.md
CHANGED
|
@@ -23,13 +23,24 @@ Developing and running the gates do have dependencies. The tests import pinned
|
|
|
23
23
|
algorithm, and the boot test starts a row through the real Loader — so a fresh
|
|
24
24
|
checkout needs one `pnpm install` before the gates pass.
|
|
25
25
|
|
|
26
|
-
Those pins are deliberate, and they
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
Those pins are deliberate, and they split by role. The `devDependencies` stay
|
|
27
|
+
exact so the gates and the `docs/PEER-PARITY.md` audit name one reproducible
|
|
28
|
+
line. The `peerDependencies` are floors — `>=` for the `@deepseek-ai/dsh-*`
|
|
29
|
+
packages, caret for `@deepseek-ai/cordis` and `@deepseek-ai/schemastery` — so
|
|
30
|
+
an app that ships a newer harness keeps installing the plugin without waiting
|
|
31
|
+
for a plugin release. A floor is still raised on purpose, not by drift: it
|
|
32
|
+
moves in the commit that matches a harness release, with the parity comparison
|
|
33
|
+
and the gate chain re-run, and the weekly peer-canary
|
|
34
|
+
(`.github/workflows/peer-canary.yml`) resolves the `next` dist-tag into a
|
|
35
|
+
scratch tree and flags when the line has moved past the floor. One semver
|
|
36
|
+
limit is worth knowing: a floor range cannot name future prerelease lines —
|
|
37
|
+
`0.2.2-rc.1` does not satisfy `>=0.2.1-rc.3`, because the spec admits a
|
|
38
|
+
prerelease only against a comparator on its own `[major, minor, patch]` tuple
|
|
39
|
+
— so a brand-new rc line warns until the floor rises; same-line rcs and every
|
|
40
|
+
stable release never do.
|
|
41
|
+
|
|
42
|
+
The plugin subclasses peer classes and mirrors peer protocol, so the range
|
|
43
|
+
says nothing about the parity claims: those are re-verified per floor raise.
|
|
33
44
|
|
|
34
45
|
pnpm runs the scripts in this repository, pinned through the `packageManager`
|
|
35
46
|
field (corepack resolves it). Treat `pnpm run <script>` as the reference
|
package/SUPPORT.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|---|---|
|
|
7
7
|
| Operating system | Windows 10 and Windows 11 |
|
|
8
8
|
| Linux side | WSL2 with at least one distro, and systemd as PID 1 with a lingering user manager (`loginctl enable-linger`) for the shipped session runtime. Set `sessionSandbox: false` on the preset's `wsl-shell` to keep the per-command sandbox instead |
|
|
9
|
-
| DSH packages | the `0.2.1-rc.
|
|
9
|
+
| DSH packages | the `0.2.1-rc.3`-or-newer packages the `peerDependencies` floors declare; an app on a newer harness installs unchanged |
|
|
10
10
|
|
|
11
11
|
The DSH row is checked weekly: `.github/workflows/peer-canary.yml` resolves the
|
|
12
12
|
`next` dist-tag of every pinned peer, installs that line into a scratch copy and
|
package/cordis.patch.yml
CHANGED
|
@@ -185,7 +185,8 @@
|
|
|
185
185
|
# Generated from the shipped standard preset so the embedded plan-mode
|
|
186
186
|
# section and every nested group survive byte-for-byte: this copy is
|
|
187
187
|
# `packages/bundle/web-app/presets/standard.patch.yml` of the
|
|
188
|
-
# `dsh-v0.2.1-rc.
|
|
188
|
+
# `dsh-v0.2.1-rc.3` source tree (unchanged since `0.2.1-rc.2`), changed
|
|
189
|
+
# in exactly three ways —
|
|
189
190
|
# 1. every shipped row mounts inside `wsl-env`, so the preset's tools see
|
|
190
191
|
# the distro's shell and fs (the realm is declared on the group);
|
|
191
192
|
# 2. `tool-bash` is enabled and `tool-pwsh` disabled outright, where the
|
package/docs/PEER-PARITY.md
CHANGED
|
@@ -7,18 +7,20 @@ same refusal dialect on both substrates. The **read path** holds end to end;
|
|
|
7
7
|
the **edit path** carries two declared divergences, listed at the end. This
|
|
8
8
|
file records the verification against the real peers.
|
|
9
9
|
|
|
10
|
-
- Peers: `@deepseek-ai/dsh-fs-local@0.2.1-rc.
|
|
11
|
-
|
|
10
|
+
- Peers: `@deepseek-ai/dsh-fs-local@0.2.1-rc.3` (the exact version the
|
|
11
|
+
devDependencies pin, and the floor the peer range `>=0.2.1-rc.3` was
|
|
12
|
+
verified against), plus `@deepseek-ai/dsh-fs@0.2.1-rc.3` for the
|
|
12
13
|
`FsVersion` brand the local package imports. Divergence 2 is measured
|
|
13
|
-
against a third peer, `@deepseek-ai/dsh-bash-local@0.2.1-rc.
|
|
14
|
+
against a third peer, `@deepseek-ai/dsh-bash-local@0.2.1-rc.3` — the shell
|
|
14
15
|
executor carries the collect-budget/spill machinery; `spill` and
|
|
15
16
|
`maxSpillBytes` do not appear in `dsh-fs-local` at all.
|
|
16
|
-
- The `0.2.1-rc.
|
|
17
|
-
peers' shipped `lib/index.js` are **byte-identical** to the `0.2.
|
|
17
|
+
- The `0.2.1-rc.3` move leaves every line reference below intact: all three
|
|
18
|
+
peers' shipped `lib/index.js` are **byte-identical** to the `0.2.1-rc.2`
|
|
18
19
|
ones (`cmp` clean; `dsh-fs-local`'s is still 909 lines), so only the
|
|
19
|
-
tarballs' digests changed
|
|
20
|
-
|
|
21
|
-
`
|
|
20
|
+
tarballs' digests changed — upstream shipped the manifests' version fields
|
|
21
|
+
and nothing else in these packages. `dsh-fs@0.2.1-rc.3` still has no
|
|
22
|
+
`./invariant` export subpath (dropped back at `0.2.1-rc.2`); this plugin
|
|
23
|
+
imports neither it nor `dsh-invariants`.
|
|
22
24
|
- What "not imported" means: the peer's **fsio module** is not reachable from
|
|
23
25
|
the package's exports, so `lib/fsio-text.js` reimplements it and imports
|
|
24
26
|
nothing from it (the export is proposed in `docs/UPSTREAM-FSIO-EXPORT.md`).
|
|
@@ -33,24 +35,24 @@ file records the verification against the real peers.
|
|
|
33
35
|
|
|
34
36
|
```sh
|
|
35
37
|
mkdir -p /tmp/peer-audit && cd /tmp/peer-audit
|
|
36
|
-
npm pack @deepseek-ai/dsh-fs-local@0.2.1-rc.
|
|
37
|
-
openssl dgst -sha512 -binary deepseek-ai-dsh-fs-local-0.2.1-rc.
|
|
38
|
-
tar xzf deepseek-ai-dsh-fs-local-0.2.1-rc.
|
|
38
|
+
npm pack @deepseek-ai/dsh-fs-local@0.2.1-rc.3 @deepseek-ai/dsh-fs@0.2.1-rc.3 --pack-destination .
|
|
39
|
+
openssl dgst -sha512 -binary deepseek-ai-dsh-fs-local-0.2.1-rc.3.tgz | base64 -w0
|
|
40
|
+
tar xzf deepseek-ai-dsh-fs-local-0.2.1-rc.3.tgz # -> package/lib/index.js
|
|
39
41
|
wc -l package/lib/index.js # expect 909
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
The tarballs this audit compared, by content — the same values
|
|
43
|
-
`npm view <pkg>@0.2.1-rc.
|
|
45
|
+
`npm view <pkg>@0.2.1-rc.3 dist.integrity` reports:
|
|
44
46
|
|
|
45
47
|
```
|
|
46
|
-
@deepseek-ai/dsh-fs-local@0.2.1-rc.
|
|
47
|
-
@deepseek-ai/dsh-fs@0.2.1-rc.
|
|
48
|
+
@deepseek-ai/dsh-fs-local@0.2.1-rc.3 sha512-bB2CwCqvYAdAKl28+5XXMRRq1NBtRmYX3wNOpJ2JlGBm7uj2Aix9Vl9rFig4AQcXXd5Bk738b5KNsOIkbXy+XQ==
|
|
49
|
+
@deepseek-ai/dsh-fs@0.2.1-rc.3 sha512-tENLWe471WlAXMc13J4cns8xU6lFyu1smwpkSKR85vhGr6FyWZhTlpVohZYm66LbwKTmSWiDhd9Urk7VxN9B9w==
|
|
48
50
|
```
|
|
49
51
|
|
|
50
52
|
Each row of the table below names the peer's `lib/index.js` line and the
|
|
51
53
|
literal both sides must produce. Verified 2026-10-03; the read/edit split
|
|
52
54
|
re-verified 2026-10-06; the whole table re-checked against `0.2.1-rc.2`,
|
|
53
|
-
2026-10-17.
|
|
55
|
+
2026-10-17 and against `0.2.1-rc.3`, 2026-10-26.
|
|
54
56
|
|
|
55
57
|
## Verdict
|
|
56
58
|
|
|
@@ -93,7 +95,7 @@ declared extensions, listed at the end.
|
|
|
93
95
|
2. **Per-stream truncation flags.** The EXEC frame carries an output budget;
|
|
94
96
|
the RES line reports which streams the agent cut, surfaced as honest
|
|
95
97
|
`truncated` flags. The collect-budget/spill machinery of the shell peer,
|
|
96
|
-
`@deepseek-ai/dsh-bash-local@0.2.1-rc.
|
|
98
|
+
`@deepseek-ai/dsh-bash-local@0.2.1-rc.3` (`lib/index.js:30`, `:110`), is the
|
|
97
99
|
spill-file path we deliberately do not run.
|
|
98
100
|
3. **The transport around the ops** (ACK, KILL, the confined resident) is
|
|
99
101
|
protocol this package owns; the peer has no agent.
|
|
@@ -120,9 +122,12 @@ declared extensions, listed at the end.
|
|
|
120
122
|
|
|
121
123
|
## Maintenance
|
|
122
124
|
|
|
123
|
-
When `package.json
|
|
124
|
-
new tarballs, check the sha512, and walk the table's peer line
|
|
125
|
-
against the replicas. The
|
|
125
|
+
When a peer floor or dev pin moves in `package.json`, re-run the comparison
|
|
126
|
+
above — pack the new tarballs, check the sha512, and walk the table's peer line
|
|
127
|
+
references against the replicas. The weekly peer-canary resolves the `next`
|
|
128
|
+
dist-tag into a scratch tree and runs the gate chain against it, so the signal
|
|
129
|
+
to raise the floor arrives before a user reports a drift. The fastest canary:
|
|
130
|
+
stat a file, list its directory, and
|
|
126
131
|
compare the versions (`test/fsio-agent.test.mjs` asserts the intra-distro half
|
|
127
132
|
of this); the strings above are the other half. The split dialect has its own
|
|
128
133
|
regression: `test/fs-substrate.test.mjs` asserts the missing-file refusal, and
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-wsl-env",
|
|
3
|
-
"version": "0.13.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.13.2",
|
|
4
|
+
"description": "让 DeepSeek Harness 以 WSL 子系统作为会话的执行环境:shell、文件读写与命令执行均在子系统内完成,目录选择器与 GUI 终端同样定位到子系统路径,并通过子系统内的 bubblewrap 对命令进行沙箱隔离",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
7
7
|
"dsh",
|
|
@@ -179,32 +179,32 @@
|
|
|
179
179
|
"@deepseek-ai/cordis": "4.0.5",
|
|
180
180
|
"@deepseek-ai/cordis-plugin-include": "*",
|
|
181
181
|
"@deepseek-ai/cordis-plugin-loader": "*",
|
|
182
|
-
"@deepseek-ai/dsh-bash-local": "0.2.1-rc.
|
|
183
|
-
"@deepseek-ai/dsh-fs": "0.2.1-rc.
|
|
184
|
-
"@deepseek-ai/dsh-fs-local": "0.2.1-rc.
|
|
185
|
-
"@deepseek-ai/dsh-fs-sandbox": "0.2.1-rc.
|
|
186
|
-
"@deepseek-ai/dsh-host-directory-picker": "0.2.1-rc.
|
|
187
|
-
"@deepseek-ai/dsh-sandbox": "0.2.1-rc.
|
|
188
|
-
"@deepseek-ai/dsh-sandbox-policy": "0.2.1-rc.
|
|
189
|
-
"@deepseek-ai/dsh-subprocess": "0.2.1-rc.
|
|
190
|
-
"@deepseek-ai/dsh-subprocess-local": "0.2.1-rc.
|
|
191
|
-
"@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.
|
|
182
|
+
"@deepseek-ai/dsh-bash-local": "0.2.1-rc.3",
|
|
183
|
+
"@deepseek-ai/dsh-fs": "0.2.1-rc.3",
|
|
184
|
+
"@deepseek-ai/dsh-fs-local": "0.2.1-rc.3",
|
|
185
|
+
"@deepseek-ai/dsh-fs-sandbox": "0.2.1-rc.3",
|
|
186
|
+
"@deepseek-ai/dsh-host-directory-picker": "0.2.1-rc.3",
|
|
187
|
+
"@deepseek-ai/dsh-sandbox": "0.2.1-rc.3",
|
|
188
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.2.1-rc.3",
|
|
189
|
+
"@deepseek-ai/dsh-subprocess": "0.2.1-rc.3",
|
|
190
|
+
"@deepseek-ai/dsh-subprocess-local": "0.2.1-rc.3",
|
|
191
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.3",
|
|
192
192
|
"@types/js-yaml": "^4.0.9",
|
|
193
193
|
"@types/node": "~22.20.5",
|
|
194
194
|
"js-yaml": "4.3.2",
|
|
195
195
|
"typescript": "~6.0.3"
|
|
196
196
|
},
|
|
197
197
|
"peerDependencies": {
|
|
198
|
-
"@deepseek-ai/cordis": "
|
|
199
|
-
"@deepseek-ai/dsh-bash-local": "0.2.1-rc.
|
|
200
|
-
"@deepseek-ai/dsh-fs": "0.2.1-rc.
|
|
201
|
-
"@deepseek-ai/dsh-fs-local": "0.2.1-rc.
|
|
202
|
-
"@deepseek-ai/dsh-host-directory-picker": "0.2.1-rc.
|
|
203
|
-
"@deepseek-ai/dsh-sandbox": "0.2.1-rc.
|
|
204
|
-
"@deepseek-ai/dsh-subprocess": "0.2.1-rc.
|
|
205
|
-
"@deepseek-ai/dsh-subprocess-local": "0.2.1-rc.
|
|
206
|
-
"@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.
|
|
207
|
-
"@deepseek-ai/schemastery": "
|
|
198
|
+
"@deepseek-ai/cordis": "^4.0.5",
|
|
199
|
+
"@deepseek-ai/dsh-bash-local": ">=0.2.1-rc.3",
|
|
200
|
+
"@deepseek-ai/dsh-fs": ">=0.2.1-rc.3",
|
|
201
|
+
"@deepseek-ai/dsh-fs-local": ">=0.2.1-rc.3",
|
|
202
|
+
"@deepseek-ai/dsh-host-directory-picker": ">=0.2.1-rc.3",
|
|
203
|
+
"@deepseek-ai/dsh-sandbox": ">=0.2.1-rc.3",
|
|
204
|
+
"@deepseek-ai/dsh-subprocess": ">=0.2.1-rc.3",
|
|
205
|
+
"@deepseek-ai/dsh-subprocess-local": ">=0.2.1-rc.3",
|
|
206
|
+
"@deepseek-ai/dsh-typert-protocol": ">=0.2.1-rc.3",
|
|
207
|
+
"@deepseek-ai/schemastery": "^3.18.5"
|
|
208
208
|
},
|
|
209
209
|
"peerDependenciesMeta": {
|
|
210
210
|
"@deepseek-ai/cordis": {
|
package/scripts/doctor.mjs
CHANGED
|
@@ -145,19 +145,24 @@ function parseArgs(argv) {
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
/**
|
|
148
|
-
* Whether an installed version satisfies one peer range. The
|
|
149
|
-
*
|
|
150
|
-
*
|
|
148
|
+
* Whether an installed version satisfies one peer range. The manifest's peer
|
|
149
|
+
* ranges are floor ranges (`>=`) and caret ranges (`^`), and the
|
|
150
|
+
* devDependencies carry exact pins — those three shapes are all this
|
|
151
|
+
* understands; anything else is reported as unchecked rather than guessed at.
|
|
152
|
+
* The floor is the plugin's own compatibility claim, so it compares plainly
|
|
153
|
+
* against the floor version; the semver gate that excludes other lines'
|
|
154
|
+
* prereleases is an installer concern, not this check's.
|
|
151
155
|
* @param {string} installed - the installed version.
|
|
152
156
|
* @param {string} range - the declared peer range.
|
|
153
157
|
* @returns {boolean | undefined} true/false, or undefined for an unsupported shape.
|
|
154
158
|
*/
|
|
155
159
|
export function peerSatisfied(installed, range) {
|
|
156
|
-
if (range.startsWith("
|
|
160
|
+
if (range.startsWith(">=")) return compareVersions(installed, range.slice(2)) >= 0;
|
|
161
|
+
if (range.startsWith("^")) {
|
|
157
162
|
const [major, minor, patch] = range.slice(1).split(".");
|
|
158
163
|
return compareVersions(installed, `${major}.${minor}.${patch ?? "0"}`) >= 0
|
|
159
164
|
&& installed.split(".")[0] === major
|
|
160
|
-
&& installed.split(".")[1] === minor;
|
|
165
|
+
&& (major !== "0" || installed.split(".")[1] === minor);
|
|
161
166
|
}
|
|
162
167
|
if (/^[0-9]/.test(range)) return installed === range;
|
|
163
168
|
return undefined;
|
|
@@ -188,7 +193,35 @@ export function compareVersions(left, right) {
|
|
|
188
193
|
if (a.pre === b.pre) return 0;
|
|
189
194
|
if (a.pre === "") return 1;
|
|
190
195
|
if (b.pre === "") return -1;
|
|
191
|
-
return a.pre
|
|
196
|
+
return comparePrerelease(a.pre, b.pre);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Compare two prerelease strings by semver §11: dot-separated identifiers,
|
|
201
|
+
* numeric ones numerically and below alphanumeric ones, the rest lexically,
|
|
202
|
+
* a longer list above its own prefix. Plain `localeCompare` would order
|
|
203
|
+
* `rc.10` below `rc.9`.
|
|
204
|
+
* @param {string} left - the first prerelease.
|
|
205
|
+
* @param {string} right - the second prerelease.
|
|
206
|
+
* @returns {number} negative, zero or positive like a comparator.
|
|
207
|
+
*/
|
|
208
|
+
function comparePrerelease(left, right) {
|
|
209
|
+
const a = left.split(".");
|
|
210
|
+
const b = right.split(".");
|
|
211
|
+
for (let i = 0; i < Math.max(a.length, b.length); i += 1) {
|
|
212
|
+
const x = a[i];
|
|
213
|
+
const y = b[i];
|
|
214
|
+
if (x === undefined) return -1;
|
|
215
|
+
if (y === undefined) return 1;
|
|
216
|
+
if (x === y) continue;
|
|
217
|
+
const numericX = /^\d+$/.test(x);
|
|
218
|
+
const numericY = /^\d+$/.test(y);
|
|
219
|
+
if (numericX && numericY) return Number(x) - Number(y);
|
|
220
|
+
if (numericX) return -1;
|
|
221
|
+
if (numericY) return 1;
|
|
222
|
+
return x < y ? -1 : 1;
|
|
223
|
+
}
|
|
224
|
+
return 0;
|
|
192
225
|
}
|
|
193
226
|
|
|
194
227
|
/**
|