dsh-wsl-tool 1.8.0 → 1.8.1
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/PUBLISHING.md +161 -0
- package/README.md +26 -8
- package/README.zh-CN.md +21 -7
- package/lib/tools/wsl.js +9 -1
- package/package.json +2 -1
package/PUBLISHING.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Publishing
|
|
2
|
+
|
|
3
|
+
Maintainer notes for releasing this plugin. Four channels carry the same commit
|
|
4
|
+
and they are not interchangeable.
|
|
5
|
+
|
|
6
|
+
| Channel | What it is | What ships it |
|
|
7
|
+
|---|---|---|
|
|
8
|
+
| GitHub Release asset | what the plugin market installs from | `.github/workflows/release.yml`, on a `v*` tag |
|
|
9
|
+
| npm | the package `dsh-wsl-tool` | the same workflow, as its last step |
|
|
10
|
+
| Catalog entry | the listing line and the install command the market shows | a PR to `awesome-dsh-plugin/awesome-dsh-plugin` |
|
|
11
|
+
| Your working profile | the copy DSH actually loads | `npm run sync`, then a DSH restart |
|
|
12
|
+
|
|
13
|
+
## The name split is deliberate
|
|
14
|
+
|
|
15
|
+
The npm package is **`dsh-wsl-tool`**, not `dsh-wsl`. The registry answers
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
403 Forbidden - PUT https://registry.npmjs.org/dsh-wsl -
|
|
19
|
+
Package name too similar to existing package is-wsl
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
for the repository name. A name policy is not a permission problem: no token, no
|
|
23
|
+
2FA bypass, and no scope changes it, and the name stays unclaimable. The
|
|
24
|
+
repository, the plugin (`tool-wsl`), and the market listing keep the `dsh-wsl`
|
|
25
|
+
name.
|
|
26
|
+
|
|
27
|
+
Nothing else depends on that name, because `cordis.patch.yml` names its entry by
|
|
28
|
+
**relative path**:
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
- insert:
|
|
32
|
+
- id: tool-wsl
|
|
33
|
+
name: './index.js'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
DSH anchors a relative `name:` beside the patch file that declared it
|
|
37
|
+
(`anchorInsertedPluginNames` in `@deepseek-ai/dsh-app-boot`), so this row loads
|
|
38
|
+
this bundle's own `index.js` whatever the install folder is called —
|
|
39
|
+
`node_modules/dsh-wsl-tool` from npm, `node_modules/dsh-wsl` in a local `file:`
|
|
40
|
+
profile. A bare package name would resolve in only one of those layouts, and
|
|
41
|
+
would silently couple this file to the registry name. `test/smoke.mjs` asserts
|
|
42
|
+
both that the entry stays relative and that it resolves.
|
|
43
|
+
|
|
44
|
+
## Release checklist
|
|
45
|
+
|
|
46
|
+
1. Green locally:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
npm test # shim backend, real WSL
|
|
50
|
+
DSH_SUBPROCESS_LOCAL=/path/to/dsh/node_modules npm run test:real
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
2. Bump, sync, commit, tag, push:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
npm version <x.y.z> --no-git-tag-version
|
|
57
|
+
npm run sync # into the profile copy DSH loads
|
|
58
|
+
git add -A && git commit -m "..."
|
|
59
|
+
git tag -a v<x.y.z> -m "..."
|
|
60
|
+
git push origin main && git push origin v<x.y.z>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`npm run sync` defaults to
|
|
64
|
+
`%USERPROFILE%/.dsh/profiles/web/node_modules/dsh-wsl` — the folder the
|
|
65
|
+
profile's dependency key created, which need not match the npm name. Pass a
|
|
66
|
+
path to target another profile. Restart DSH afterwards: the plugin is imported
|
|
67
|
+
once at load.
|
|
68
|
+
|
|
69
|
+
3. The tag runs the pipeline. The order is deliberate — the release asset goes
|
|
70
|
+
**first** because it is the market's critical path, then npm, so a failing npm
|
|
71
|
+
publish fails the run loudly without withholding the release.
|
|
72
|
+
|
|
73
|
+
The build step asks `npm pack --silent` for the tarball name (it follows
|
|
74
|
+
`package.json`, so it is `dsh-wsl-tool-<version>.tgz`) and copies it to
|
|
75
|
+
`dsh-wsl.tgz`, which is the fixed name the catalog's URL points at. Never
|
|
76
|
+
rename that copy: the market install breaks the moment the asset is not called
|
|
77
|
+
`dsh-wsl.tgz`, and `--latest` is what keeps `releases/latest` resolving to it.
|
|
78
|
+
|
|
79
|
+
4. Verify each channel.
|
|
80
|
+
|
|
81
|
+
**CI** — a check annotation is readable anonymously, unlike the job log:
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
curl -s "https://api.github.com/repos/XINY11451/dsh-wsl/actions/runs?per_page=5"
|
|
85
|
+
curl -s "https://api.github.com/repos/XINY11451/dsh-wsl/check-runs/<id>/annotations"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
A successful publish leaves `published <version> to npm`; a failure leaves
|
|
89
|
+
`npm publish failed: <the npm error lines>`, which is why the workflow turns
|
|
90
|
+
npm's stderr into `::error::` instead of only printing it.
|
|
91
|
+
|
|
92
|
+
**npm**:
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
curl -s https://registry.npmjs.org/dsh-wsl-tool # dist-tags.latest
|
|
96
|
+
npm view dsh-wsl-tool version --registry https://registry.npmjs.org
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Fetching `dist.tarball` and unpacking it is the honest check — it proves the
|
|
100
|
+
artifact, not just the metadata. Scripted requests to `npmjs.com`'s HTML hit a
|
|
101
|
+
Cloudflare challenge; the registry API is the source of truth.
|
|
102
|
+
|
|
103
|
+
**Market asset** (this is what users install, and it is independent of npm):
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
curl -sL -o /tmp/a.tgz https://github.com/XINY11451/dsh-wsl/releases/latest/download/dsh-wsl.tgz
|
|
107
|
+
tar -xzOf /tmp/a.tgz package/package.json | grep '"version"'
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Catalog**: the catalog's generated data is at
|
|
111
|
+
<https://awesome-dsh-plugin.com/plugins.json> — look up `dsh-wsl` and read
|
|
112
|
+
`npm`, `version`, `downloads`, `install`, `tarball`.
|
|
113
|
+
|
|
114
|
+
## The catalog entry
|
|
115
|
+
|
|
116
|
+
The listing lives at `data/plugins/XINY11451__dsh-wsl.yml` in
|
|
117
|
+
`awesome-dsh-plugin/awesome-dsh-plugin`, one file per plugin. Only
|
|
118
|
+
`description.en` is required; `description.zh` is optional. Edit it through a
|
|
119
|
+
one-file PR (the web UI's pencil button forks and proposes the change).
|
|
120
|
+
|
|
121
|
+
Two of its keys are hand-written and must stay:
|
|
122
|
+
|
|
123
|
+
- `tarball:` — the fixed release URL above. It is what the market's `install`
|
|
124
|
+
command points at today.
|
|
125
|
+
- `url` / `name` / `category` — `category: wsl`.
|
|
126
|
+
|
|
127
|
+
Everything else about the entry is **generated** and must never be written by
|
|
128
|
+
hand: `npm`, `version`, `downloads`, `screenshots`, and `install`. In particular
|
|
129
|
+
`scripts/probe-npm.mjs` reads `package.json`'s `name` from the repository's
|
|
130
|
+
`HEAD`, then accepts the package only when the registry document's
|
|
131
|
+
`versions[latest].repository.url` contains `<owner>/<repo>`
|
|
132
|
+
(case-insensitively — that check is what stops name squatting). So keep
|
|
133
|
+
`repository` in `package.json` accurate, or the catalog stops discovering the npm
|
|
134
|
+
package. "Not published" verdicts are re-probed daily, so a freshly published
|
|
135
|
+
version can take a day to appear; when it does, `install` switches from the
|
|
136
|
+
tarball URL to `dsh plugin --profile web add dsh-wsl-tool`.
|
|
137
|
+
|
|
138
|
+
## Things that bite
|
|
139
|
+
|
|
140
|
+
- **A tag event runs the workflow from the tag's commit.** To change the
|
|
141
|
+
pipeline you must commit *and cut a new tag*; re-running an old run reuses the
|
|
142
|
+
workflow it was created with, and moving a tag is not a fix.
|
|
143
|
+
- **Job logs need authentication; annotations do not.** There is no `gh` and no
|
|
144
|
+
`GITHUB_TOKEN` on the maintainer machine, so anything that must be diagnosable
|
|
145
|
+
without a credential belongs in an annotation.
|
|
146
|
+
- **An interactive `npm publish` asks for a one-time password** and cannot be
|
|
147
|
+
driven from an unattended run. CI authenticates with a granular token that may
|
|
148
|
+
bypass 2FA, stored as the `NPM_TOKEN` secret; with the secret absent the step
|
|
149
|
+
skips with a notice instead of failing. Now that the package exists, OIDC
|
|
150
|
+
trusted publishing is the better replacement.
|
|
151
|
+
- **`publishConfig.registry` in `package.json` wins** over a developer's
|
|
152
|
+
`~/.npmrc` mirror, so a mirror configured for reads cannot intercept a publish.
|
|
153
|
+
- **The profile's dependency key is not the package name** (`dsh-wsl` versus
|
|
154
|
+
`dsh-wsl-tool`). Do not "fix" that by hand: the profile is managed by pnpm, and
|
|
155
|
+
its `pnpm-lock.yaml`, `node_modules/.modules.yaml`, and
|
|
156
|
+
`node_modules/.package-map.json` all record the key. The relative patch entry
|
|
157
|
+
means the difference costs nothing.
|
|
158
|
+
- **Short unscoped names ending in `-wsl` are a minefield.** `dsh-wsl` collides
|
|
159
|
+
with `is-wsl`; longer suffixed names such as `dsh-wsl-workspace` are published
|
|
160
|
+
by other authors and pass. Prefer npm's suggestion (a scope) or a clearly
|
|
161
|
+
suffixed name, and check the registry before tagging.
|
package/README.md
CHANGED
|
@@ -96,18 +96,33 @@ specifier you install under.
|
|
|
96
96
|
or `dsh plugin add --profile <profile> file:<path-to-this-repo>` from a
|
|
97
97
|
checkout (which names the dependency after this package).
|
|
98
98
|
|
|
99
|
-
2.
|
|
99
|
+
2. Nothing else. The package's `cordis.patch.yml` inserts the `tool-wsl` row
|
|
100
|
+
itself when the bundle is loaded, process-wide, so the three tools are
|
|
101
|
+
available to every agent preset without further wiring.
|
|
100
102
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
`name` is the installed package name — use your own dependency key if you
|
|
107
|
-
installed under a different one.
|
|
103
|
+
Do **not** also list `tool-wsl` in a preset: DSH registers tools by name, and
|
|
104
|
+
the second registration fails with
|
|
105
|
+
`tool "wsl" is already registered in this scope`. One row, from the bundle.
|
|
108
106
|
|
|
109
107
|
3. Restart DSH.
|
|
110
108
|
|
|
109
|
+
## Compatibility
|
|
110
|
+
|
|
111
|
+
Verified against DSH **0.1.7-rc.2** (and 0.1.5-rc.2 before it): the tool schemas
|
|
112
|
+
pass DSH's own `assertSupportedJsonSchema`, the subprocess seam is exercised
|
|
113
|
+
against the real provider rather than a shim, and the background-job path is
|
|
114
|
+
checked against the real job registry, including the session-id ownership fence
|
|
115
|
+
that 0.1.7 tightened. `test/real-seam.mjs` is that check and it re-verifies a host
|
|
116
|
+
in about a minute, so point it at any DSH installation after an upgrade:
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
DSH_SUBPROCESS_LOCAL=/path/to/dsh/node_modules npm run test:real
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
A background job is owned by the calling session (`owner: exec.agent.id`), which
|
|
123
|
+
is what lets the model read it back with `job_output`/`job_kill` and what keeps
|
|
124
|
+
other sessions out; an execution with no agent starts the job unowned.
|
|
125
|
+
|
|
111
126
|
## `wsl` parameters
|
|
112
127
|
|
|
113
128
|
| Param | Required | Type | Notes |
|
|
@@ -312,6 +327,9 @@ the folder name itself never matters.
|
|
|
312
327
|
|
|
313
328
|
then restart DSH — the plugin is imported once at load.
|
|
314
329
|
|
|
330
|
+
Releasing — the tag-triggered workflow, the npm name, and the catalog entry — is
|
|
331
|
+
documented in [`PUBLISHING.md`](PUBLISHING.md).
|
|
332
|
+
|
|
315
333
|
## Listing
|
|
316
334
|
|
|
317
335
|
The repository carries the `dsh-plugin` topic and is listed under the `wsl`
|
package/README.zh-CN.md
CHANGED
|
@@ -86,17 +86,29 @@ launcher: WSL 版本: 2.6.3.0 · 内核版本: 6.6.87.2-1 · WSLg 版本: 1.0.71
|
|
|
86
86
|
`dsh plugin add --profile <profile> file:<path-to-this-repo>` 从本地检出安装
|
|
87
87
|
(依赖名会取本包自身的名字)。
|
|
88
88
|
|
|
89
|
-
2.
|
|
89
|
+
2. 不必再做别的。本包的 `cordis.patch.yml` 会在组合包加载时**自己插入** `tool-wsl` 行
|
|
90
|
+
(进程级),因此三个工具对所有 agent preset 都可用,无需额外接线。
|
|
90
91
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
name: 'dsh-wsl-tool'
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
`name` 即安装后的包名;若你用了别的依赖名,就填那个名字。
|
|
92
|
+
**不要**再在 preset 里列一遍 `tool-wsl`:DSH 按名字注册工具,第二次注册会直接失败
|
|
93
|
+
—— `tool "wsl" is already registered in this scope`。这一行只由组合包提供。
|
|
97
94
|
|
|
98
95
|
3. 重启 DSH。
|
|
99
96
|
|
|
97
|
+
## 兼容性
|
|
98
|
+
|
|
99
|
+
已在 DSH **0.1.7-rc.2** 上验证(此前为 0.1.5-rc.2):工具 schema 通过 DSH 自己的
|
|
100
|
+
`assertSupportedJsonSchema`;subprocess 接缝是跑在**真实 provider** 上而非替身;后台任务
|
|
101
|
+
路径跑在**真实 job 注册表**上,包含 0.1.7 收紧的「会话 id 属主围栏」。这套检查就是
|
|
102
|
+
`test/real-seam.mjs`,约一分钟即可重验一个新宿主——升级后把它指向新的 DSH 安装即可:
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
DSH_SUBPROCESS_LOCAL=/path/to/dsh/node_modules npm run test:real
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
后台任务由**调用方会话**持有(`owner: exec.agent.id`),这既是模型能用
|
|
109
|
+
`job_output`/`job_kill` 读回它的依据,也是其他会话读不到它的围栏;exec 里没有 agent 时
|
|
110
|
+
任务则是无主的。
|
|
111
|
+
|
|
100
112
|
## `wsl` 参数
|
|
101
113
|
|
|
102
114
|
| 参数 | 必填 | 类型 | 说明 |
|
|
@@ -299,6 +311,8 @@ npm run sync -- /path/to/profiles/<profile>/node_modules/<你的依赖名>
|
|
|
299
311
|
|
|
300
312
|
然后重启 DSH——插件在加载时只导入一次。
|
|
301
313
|
|
|
314
|
+
发版流程(tag 触发的流水线、npm 包名与目录条目)见 [`PUBLISHING.md`](PUBLISHING.md)。
|
|
315
|
+
|
|
302
316
|
## 收录
|
|
303
317
|
|
|
304
318
|
本仓库带有 `dsh-plugin` topic,并已提交至 awesome-dsh-plugin 社区列表的 `wsl` 分类。
|
package/lib/tools/wsl.js
CHANGED
|
@@ -71,7 +71,15 @@ export function createWslTool({ ctx, config, runner }) {
|
|
|
71
71
|
kind: 'wsl',
|
|
72
72
|
label: jobLabel(command),
|
|
73
73
|
outputLimitBytes: config.maxOutputBytes,
|
|
74
|
-
|
|
74
|
+
// `owner` is the owner's SESSION ID, not the Agent handle: the registry
|
|
75
|
+
// resolves it through the live-agent registry (`agents.get(sessionId)`)
|
|
76
|
+
// and fails with `session "…" has no live agent` for anything else. It
|
|
77
|
+
// is also the fence key — the model's `job_output`/`job_kill` reach this
|
|
78
|
+
// job by passing the same session id as their caller. Bound to
|
|
79
|
+
// `exec.agent.id` exactly as `dsh-tool-bash` and `dsh-tool-pwsh` do.
|
|
80
|
+
// An execution with no agent starts an unowned job, which is open to any
|
|
81
|
+
// caller but never listed for a session.
|
|
82
|
+
...(exec?.agent === undefined ? {} : { owner: exec.agent.id }),
|
|
75
83
|
// The spawn happens INSIDE run(): the contract says a throw leaves
|
|
76
84
|
// nothing registered, so spawning first and registering second could
|
|
77
85
|
// leak a process if registration failed.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-wsl-tool",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"description": "Model-facing WSL tools for DeepSeek Harness: run Linux commands from Windows with background jobs, stdin, path translation, destructive-command guard and WSL capability diagnostics.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"cordis.patch.yml",
|
|
30
30
|
"README.md",
|
|
31
31
|
"README.zh-CN.md",
|
|
32
|
+
"PUBLISHING.md",
|
|
32
33
|
"screenshots.json",
|
|
33
34
|
"assets",
|
|
34
35
|
"LICENSE"
|