dsh-wsl-workspace 0.3.1 → 0.4.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/README.de.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # dsh-wsl-workspace
2
2
 
3
+ [![dsh.so security](https://www.dsh.so/badge/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
4
+ [![dsh.so install](https://www.dsh.so/badge/install/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
5
+
3
6
  [English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [Español](README.es.md) · [Português](README.pt.md) · [Русский](README.ru.md)
4
7
 
5
8
  ![alt text](image-3.png)
package/README.es.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # dsh-wsl-workspace
2
2
 
3
+ [![dsh.so security](https://www.dsh.so/badge/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
4
+ [![dsh.so install](https://www.dsh.so/badge/install/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
5
+
3
6
  [English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [Español](README.es.md) · [Português](README.pt.md) · [Русский](README.ru.md)
4
7
 
5
8
  ![alt text](image-3.png)
package/README.fr.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # dsh-wsl-workspace
2
2
 
3
+ [![dsh.so security](https://www.dsh.so/badge/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
4
+ [![dsh.so install](https://www.dsh.so/badge/install/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
5
+
3
6
  [English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [Español](README.es.md) · [Português](README.pt.md) · [Русский](README.ru.md)
4
7
 
5
8
  ![alt text](image-3.png)
package/README.ja.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # dsh-wsl-workspace
2
2
 
3
+ [![dsh.so security](https://www.dsh.so/badge/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
4
+ [![dsh.so install](https://www.dsh.so/badge/install/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
5
+
3
6
  [English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [Español](README.es.md) · [Português](README.pt.md) · [Русский](README.ru.md)
4
7
 
5
8
  ![alt text](image-3.png)
package/README.ko.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # dsh-wsl-workspace
2
2
 
3
+ [![dsh.so security](https://www.dsh.so/badge/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
4
+ [![dsh.so install](https://www.dsh.so/badge/install/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
5
+
3
6
  [English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [Español](README.es.md) · [Português](README.pt.md) · [Русский](README.ru.md)
4
7
 
5
8
  ![alt text](image-3.png)
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # dsh-wsl-workspace
2
2
 
3
+ [![dsh.so security](https://www.dsh.so/badge/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
4
+ [![dsh.so install](https://www.dsh.so/badge/install/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
5
+
3
6
  [English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [Español](README.es.md) · [Português](README.pt.md) · [Русский](README.ru.md)
4
7
  ![alt text](image-3.png)
5
8
  Add a WSL workspace from the DeepSeek Harness web GUI and run the whole agent session — bash commands and file reads/writes — inside a local WSL distribution with Linux paths. Nothing needs to be installed inside WSL. The session can reach both WSL and Windows at the same time: bash commands run inside the WSL distribution, while Windows files stay accessible via `/mnt/<drive>` (for example `/mnt/c/Users/...`).
@@ -31,8 +34,29 @@ Click "Create & open" to start a new session in the workspace. In the new sessio
31
34
 
32
35
  - **bash tool**: runs inside the WSL distribution as the configured username (empty = the distro default user, often `root`), so it can read and write anywhere in the distro. The Windows ACL sandbox cannot wrap `wsl.exe` — its children run on the Linux kernel side — so WSL itself is the isolation boundary and the DSH file policy does not apply to bash.
33
36
  - **File tools (`read`/`write`/`edit`)**: go through the Windows-side WSL 9P share and run under the DSH file policy. Under `workspace-write`, reads work anywhere but writes are restricted to the session workspace; switch the file policy to `danger-full-access` to also allow writes outside it. The username field does not affect the file tools.
37
+ - **Skill catalog**: the session's skill catalog is discovered starting at the session cwd's nearest `.git` ancestor (falling back to the cwd itself), then scanning downward for `.dsh/skills` / `.agents/skills` — including nested projects — bounded to 4 directory levels, 64 skill directories and 4096 visited directories. Register the workspace at the project root you work in; if the registered workspace itself sits inside a larger git repository, the scan starts at that repository's root (matching the host's own rule) and sibling projects may surface. Results are cached per scan root and served stale-while-revalidate: a fresh scan (the first lookup, and a background refresh every 10 seconds) may take a moment on very large trees — a workspace registered at the distro root `/` scans the whole filesystem — but repeated lookups always answer instantly and never block on a refresh. Skill bodies always load live. One substrate limit to know: the Windows-side `\\wsl.localhost` share cannot resolve Linux symlinks (they read back as unresolvable entries), so a project linked into the workspace via `ln -s` is not discoverable — the scan walks past it without failing; register the workspace at a level that contains the real project directories instead.
34
38
  - The garbled `localhost` port-forwarding banner `wsl.exe` prints to stderr when the distro was not running yet is harmless.
35
39
 
40
+ ## Changelog
41
+
42
+ ### 0.4.0 — 2026-08-29
43
+
44
+ Follow-ups from the [#12](https://github.com/6Mikao9/dsh-wsl-workspace/issues/12) limitation list and the [#13](https://github.com/6Mikao9/dsh-wsl-workspace/issues/13) compatibility work:
45
+
46
+ - **Lookup cache**: completed skill-catalog lookups are cached per scan root and served **stale-while-revalidate** — the first scan of a workspace is real (seconds on large trees), every later lookup answers instantly, an expired entry never blocks (it is served immediately while a background refresh runs, so even a workspace registered at the distro root stays responsive), and `get()` keeps reading skill bodies live.
47
+ - **Boundary hardening**: UNC spellings with double separators, trailing slashes, uppercase hosts, the legacy `\\wsl$` form and distro-root cwds all parse and scan correctly; skill files saved as UTF-8 with a BOM or with CRLF line endings (including CRLF block scalars) now parse; unreadable directories prune without failing the scan; a name+description+body fingerprint guarantees aliased skill files never publish twice.
48
+ - **Symlinked projects — investigated, substrate-limited**: the discovery walk now recognizes directory symlinks explicitly and prunes them safely (no crashes, no loops). Following them is not possible over the `\\wsl.localhost` 9P share — the Windows side cannot resolve Linux symlink targets (probed: `readlink` → `EISDIR`, `stat`/`readdir` → `ENOENT`) — so a project linked into the workspace via `ln -s` stays undiscoverable; a name+body fingerprint dedupe also guarantees aliased skill files can never publish twice on substrates that do resolve links.
49
+ - **Block-scalar frontmatter**: `description:` / `whenToUse:` written as YAML block scalars (`|` literal, `>` folded) now parse — such skills were silently dropped before.
50
+ - **Compatibility manifest**: `dsh.compatibility.dshReleases` declares per-release compatibility with the official DSH versions, backed by reproducible disposable-Profile install/start/uninstall evidence (`scripts/verify-dsh-compat.sh`), and `engines` declares the Node.js floor.
51
+ - **Guard scripts**: `scripts/check-rank-parity.mjs` fails the release when the copied project-rank constants drift from the host's `dsh-skill-filesystem`.
52
+
53
+ ### 0.3.2 — 2026-08-29
54
+
55
+ - **WSL workspace sessions now inject nested-project skill catalogs** ([#10](https://github.com/6Mikao9/dsh-wsl-workspace/issues/10)): `.dsh/skills` and `.agents/skills` directories of projects nested below the registered workspace root are discovered and published with the host's project ranks and sources, so the model sees the same skill catalog it would see when the session cwd is the project folder itself. Discovery is depth- and budget-bounded, prunes `node_modules`/dot-directories, and leaves non-WSL sessions untouched.
56
+ - **Host-parity scan root**: lookups from inside a project subtree resolve the nearest `.git` ancestor first, so the enclosing project's skills stay visible from deeper cwds; skills above that ancestor do not leak.
57
+ - **Hardening**: the skill-root budget is enforced per push, and the `skills.registerProvider` call is guarded so a host whose `skills` service has a different shape can no longer break plugin load.
58
+ - **Housekeeping**: removed stale prebuilt `lib/` chunks that shipped dead vendor code (including an inlined schemastery copy that triggered dsh.so's `new Function` static rule); added `scripts/repro-setup.sh` plus a nested skill-catalog regression suite, and a matching TESTING.md section.
59
+
36
60
  ## License & attribution
37
61
 
38
62
  MIT — see [LICENSE](LICENSE) and [NOTICE](NOTICE). The NOTICE precisely lists:
package/README.pt.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # dsh-wsl-workspace
2
2
 
3
+ [![dsh.so security](https://www.dsh.so/badge/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
4
+ [![dsh.so install](https://www.dsh.so/badge/install/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
5
+
3
6
  [English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [Español](README.es.md) · [Português](README.pt.md) · [Русский](README.ru.md)
4
7
 
5
8
  ![alt text](image-3.png)
package/README.ru.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # dsh-wsl-workspace
2
2
 
3
+ [![dsh.so security](https://www.dsh.so/badge/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
4
+ [![dsh.so install](https://www.dsh.so/badge/install/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
5
+
3
6
  [English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [Español](README.es.md) · [Português](README.pt.md) · [Русский](README.ru.md)
4
7
 
5
8
  ![alt text](image-3.png)
package/README.zh.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # dsh-wsl-workspace
2
2
 
3
+ [![dsh.so security](https://www.dsh.so/badge/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
4
+ [![dsh.so install](https://www.dsh.so/badge/install/dsh-wsl-workspace.svg)](https://www.dsh.so/artifact/dsh-wsl-workspace)
5
+
3
6
  [English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [Español](README.es.md) · [Português](README.pt.md) · [Русский](README.ru.md)
4
7
  ![alt text](image-3.png)
5
8
  在 DeepSeek Harness Web GUI 中「添加 WSL 工作区」:让 agent 会话的 bash 命令与文件读写都运行在本机 WSL 发行版里,路径均为 Linux 形式,WSL 内无需安装任何工具链。会话可同时访问 WSL 与 Windows 两个系统——bash 命令在 WSL 发行版内执行,Windows 文件随时可通过 `/mnt/<drive>`(如 `/mnt/c/Users/...`)访问。
package/TESTING.md CHANGED
@@ -13,7 +13,7 @@ This document describes how to verify `dsh-wsl-workspace` after a change or befo
13
13
  Run the unit tests from the plugin directory:
14
14
 
15
15
  ```powershell
16
- node --experimental-strip-types --test tests/variants.test.ts tests/fs-execution-context.test.ts tests/shell.test.ts tests/paths.test.ts
16
+ node --experimental-strip-types --test tests/variants.test.ts tests/fs-execution-context.test.ts tests/shell.test.ts tests/paths.test.ts tests/wsl-skills.test.ts
17
17
  ```
18
18
 
19
19
  Coverage:
@@ -24,6 +24,12 @@ Coverage:
24
24
  | `tests/fs-execution-context.test.ts` | `WslFileSystem` inherits the calling session's cwd through `AsyncLocalStorage` on `tools/execute`; agentless calls fall back to the configured distro. |
25
25
  | `tests/shell.test.ts` | The login-shell `cd` prefix preserves the resolved workdir (including single-quote escaping); non-login shells leave the command unchanged. |
26
26
  | `tests/paths.test.ts` | UNC ↔ Linux path translation, `/mnt/<drive>` mapping, canonical Windows path keys, WSL username validation. |
27
+ | `tests/wsl-skills.test.ts` | The WSL skill provider (issue #10): non-WSL lookups return nothing, nested `.dsh/skills` / `.agents/skills` discovery with host ranks/sources, `get()` body loading, pruning of `node_modules` / dot-directories and unreadable directories, frontmatter validation **including block scalars, CRLF files and UTF-8 BOMs**, depth and skill-root budgets, the nearest-`.git`-ancestor rule (a cwd deeper than the project root still sees the project's skills, and skills above that ancestor do not leak), the skill-root cap, the **per-scan-root lookup cache with stale-while-revalidate** (copy semantics, TTL expiry serving stale + background refresh, overlapping lookups sharing one refresh, `get()` staying live), **UNC spelling forms** (legacy `\\wsl$`, uppercase hosts, trailing slashes, distro-root cwds) and **directory-symlink handling** (unresolvable links pruned per the 9P substrate, aliasing deduplicated, hops bounded by depth). |
28
+
29
+ ## Provider parity and compatibility checks
30
+
31
+ - `node scripts/check-rank-parity.mjs` — the provider's project ranks are copied from `@deepseek-ai/dsh-skill-filesystem` (the host does not export them). This script parses the host's built lib when the package is resolvable on this machine and fails on drift. Run it before every release on a machine with the harness installed.
32
+ - `scripts/verify-dsh-compat.sh <version>...` — disposable-Profile install/start/uninstall evidence against specific `@deepseek-ai/dsh` releases: fully isolated (`DSH_HOME` redirected to a temp tree, own port), boots the published harness version with the plugin added by name, probes `POST /wsl-workspace/api`, then removes the plugin and verifies the route disappears. Emits per-version verdict lines used for the `dsh.compatibility.dshReleases` manifest records.
27
33
 
28
34
  ## Preset materialization integration test
29
35
 
@@ -59,6 +65,27 @@ The `build` script chains it after `tsdown`:
59
65
  pnpm build # tsdown && node scripts/verify-lib.mjs
60
66
  ```
61
67
 
68
+ ## Nested skill-catalog regression (issue #10)
69
+
70
+ The WSL skill provider publishes `.dsh/skills` / `.agents/skills` from nested projects below a WSL workspace (and from the cwd's nearest `.git` ancestor). Regression-test it on the real 9P share:
71
+
72
+ 1. Rebuild the repro tree inside the distribution (`scripts/repro-setup.sh` creates `~/repro-ws-root` with nested projects, pruned traps, and an over-budget deep skill):
73
+
74
+ ```powershell
75
+ cp scripts/repro-setup.sh //wsl.localhost/<distro>/tmp/
76
+ wsl -d <distro> -- bash -c "bash /tmp/repro-setup.sh"
77
+ ```
78
+
79
+ 2. Drive the provider against the real `\\wsl.localhost` share — four assertions print (workspace-root cwd finds root + nested skills; nested-project cwd finds only that project; `get()` loads a body; non-WSL cwd returns nothing). Override the target with `WSL_COMPAT_DISTRO` / `WSL_COMPAT_USER` / `WSL_COMPAT_ROOT`:
80
+
81
+ ```powershell
82
+ node scripts/repro-e2e.mjs
83
+ ```
84
+
85
+ The script hardcodes `\\wsl.localhost\Ubuntu\home\mille\repro-ws-root`; adjust the two paths at the top when running as another user or distro.
86
+ 3. In the running harness, open a session on the repro workspace and ask the agent to load the nested skills (`brainstorming`, `systematic-debugging`, `writing-plans`) through its skill tool — each must load with the `wsl-workspace` provider attribution, and no duplicate entries may appear. In a non-WSL workspace session the same skills must be "unknown".
87
+ 4. Clean-install check (simulates another user): `npm pack`, `npm install <tarball>` in an empty temp project (peers must resolve), then `dsh plugin --profile web add <extracted tarball dir>`, restart `dsh web`, and repeat the end-to-end checks below plus the nested-skill probe above.
88
+
62
89
  ## End-to-end verification in the running harness
63
90
 
64
91
  After installing the plugin into a profile and restarting `dsh web`:
@@ -73,8 +100,10 @@ After installing the plugin into a profile and restarting `dsh web`:
73
100
  ## Release checklist
74
101
 
75
102
  1. `pnpm build` — rebuilds `lib/` and runs the verification gate.
76
- 2. `node --experimental-strip-types --test tests/variants.test.ts tests/fs-execution-context.test.ts tests/shell.test.ts tests/paths.test.ts` — all green.
103
+ 2. `node --experimental-strip-types --test tests/variants.test.ts tests/fs-execution-context.test.ts tests/shell.test.ts tests/paths.test.ts tests/wsl-skills.test.ts` — all green.
77
104
  3. `node tests/host-materialize.mjs` — all assertions pass.
78
105
  4. `node --experimental-strip-types tests/smoke.ts` — real-WSL round-trip passes.
79
- 5. `npm pack --dry-run` — confirm the tarball carries only live `lib/` chunks, `src/`, `cordis.patch.yml`, READMEs, `LICENSE`, and `NOTICE`.
80
- 6. Install the tarball into a clean profile (`dsh plugin --profile web add <tarball>`), restart `dsh web`, and run the end-to-end checks above.
106
+ 5. `node scripts/check-rank-parity.mjs` — host rank constants still match our copies.
107
+ 6. `node scripts/repro-e2e.mjs` (after `scripts/repro-setup.sh`) — nested skill-catalog assertions pass.
108
+ 7. `npm pack --dry-run` — confirm the tarball carries only live `lib/` chunks, `src/`, `cordis.patch.yml`, READMEs, `LICENSE`, and `NOTICE` (`pnpm build` prunes unreferenced chunks automatically via `scripts/prune-lib.mjs`).
109
+ 8. Install the tarball into a clean profile (`dsh plugin --profile web add <tarball>`), restart `dsh web`, and run the end-to-end checks above plus the nested-skill probe. When the compatibility manifest changes, also run `scripts/verify-dsh-compat.sh` for every declared release.