dsh-plugin-wsl-env 0.13.0 → 0.13.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/CHANGELOG.md +41 -0
- package/docs/ROADMAP-1.0.md +3 -3
- package/docs/UPSTREAM-FSIO-EXPORT.md +3 -2
- package/lib/agent-exec.d.ts +9 -2
- package/lib/agent-exec.js +2 -2
- package/lib/index.js +8 -0
- package/lib/preflight.js +7 -1
- package/lib/shell-env.js +8 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,47 @@ were part of the record.
|
|
|
16
16
|
|
|
17
17
|
## [Unreleased]
|
|
18
18
|
|
|
19
|
+
## [0.13.1] - 2026-10-19
|
|
20
|
+
|
|
21
|
+
A patch release restoring `wsl-shell-env`: the component mounts again, and the
|
|
22
|
+
managed `DSH_*` facts it contributes now reach commands on the default
|
|
23
|
+
resident-agent path.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **Upstream proposals filed.** The session-notice seam
|
|
28
|
+
([#10263](https://github.com/deepseek-ai/deepseek-harness/discussions/10263)),
|
|
29
|
+
the `spawnSpec` seam (#10261), the fsio export (#10262), the UNC-workspace bug
|
|
30
|
+
(#10260) and the WSL-workspaces RFC (#10264) now point at their discussions;
|
|
31
|
+
the local drafts carry the links.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- **`wsl-shell-env` no longer fails to activate.** The row sweeps the
|
|
36
|
+
live-agent list at mount to warm facts for sessions that opened before it,
|
|
37
|
+
but declared only `shellEnv` in `inject` and read `ctx.agents` as a property.
|
|
38
|
+
Cordis 4 refuses that read — `cannot get property "agents" without inject` —
|
|
39
|
+
so `apply()` rejected and the plugin manager listed the component as 异常
|
|
40
|
+
(`包含的组件 → 异常`), with the whole contribution missing from shell calls.
|
|
41
|
+
The sweep now reads the service through `ctx.get("agents")`, the sanctioned
|
|
42
|
+
access for a service this row does not inject: activation no longer depends
|
|
43
|
+
on an agent loop, and the sweep still runs when one is composed.
|
|
44
|
+
`wsl-preflight` carried the same property read inside a `try`/`catch`, where
|
|
45
|
+
the throw silently disabled its mount sweep; it gets the same fix.
|
|
46
|
+
`test/shell-env.test.mjs` and the real-cordis check in
|
|
47
|
+
`test/preflight.test.mjs` mount both rows against the guard.
|
|
48
|
+
|
|
49
|
+
- **The managed `DSH_*` namespace now reaches commands on the default
|
|
50
|
+
resident-agent path.** `ShellExecSpec.dshEnv` was forwarded only by the
|
|
51
|
+
one-shot `wsl.exe` fallback; `executeViaAgent` dropped it before
|
|
52
|
+
`agent.exec` — after the mount fix above, the row registered its facts but
|
|
53
|
+
no model shell call could see `DSH_HOME`, `DSH_SESSION_ID` or any
|
|
54
|
+
`DSH_WSL_*` value (`env | grep '^DSH_'` was empty). The handle now carries
|
|
55
|
+
the merged map (`env` first, `dshEnv` last — the same order the one-shot
|
|
56
|
+
path uses) into the agent's `SETENV` frames. `test/agent-exec.test.mjs` and
|
|
57
|
+
`test/provider.test.mjs` pin the frame, and both checks fail against the
|
|
58
|
+
previous build.
|
|
59
|
+
|
|
19
60
|
## [0.13.0] - 2026-10-19
|
|
20
61
|
|
|
21
62
|
This release ships the P0/P1 hardening batch: session-scoped `auto`
|
package/docs/ROADMAP-1.0.md
CHANGED
|
@@ -339,9 +339,9 @@ command.
|
|
|
339
339
|
- [x] The preflight checks bwrap, systemd PID 1, `systemd-run` and Linger.
|
|
340
340
|
- [x] The warning is visibly attached to the session through the
|
|
341
341
|
runtime-context entry (not only logs).
|
|
342
|
-
- [ ] A GUI notice/banner renders it: upstream
|
|
343
|
-
|
|
344
|
-
|
|
342
|
+
- [ ] A GUI notice/banner renders it: filed upstream as
|
|
343
|
+
[#10263](https://github.com/deepseek-ai/deepseek-harness/discussions/10263);
|
|
344
|
+
until a seam lands, the advisory stays in the log and runtime context.
|
|
345
345
|
- [x] The warning never installs anything and never changes fail-closed
|
|
346
346
|
behavior.
|
|
347
347
|
- [x] A session with a usable environment produces no warning.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Upstream proposal: export the fsio text helpers from `dsh-fs-local`
|
|
2
2
|
|
|
3
|
-
Status:
|
|
4
|
-
|
|
3
|
+
Status: filed upstream as
|
|
4
|
+
[deepseek-ai/deepseek-harness#10262](https://github.com/deepseek-ai/deepseek-harness/discussions/10262)
|
|
5
|
+
(Ideas); the filing convention is [UPSTREAM-TERMINAL-TITLE.md](UPSTREAM-TERMINAL-TITLE.md).
|
|
5
6
|
Targeting `deepseek-harness` @ `packages/fs/fs-local`, the `0.2.1-rc.x` line
|
|
6
7
|
this plugin pins exactly (`@deepseek-ai/dsh-fs-local@0.2.1-rc.2`, in both the
|
|
7
8
|
dev and peer dependency blocks of `package.json`). This is the Shape-A
|
package/lib/agent-exec.d.ts
CHANGED
|
@@ -129,10 +129,10 @@ export interface AgentExecutionHandle {
|
|
|
129
129
|
* @returns the execution handle (`status`, `exitCode`, `signal`, `observed`,
|
|
130
130
|
* `done`, `readOutput`, `kill`, `result`).
|
|
131
131
|
*/
|
|
132
|
-
export declare function agentExecutionHandle({ agent, cwd, argv, timeoutMs, maxOutputBytes, signal, onStarted }: {
|
|
132
|
+
export declare function agentExecutionHandle({ agent, cwd, argv, timeoutMs, maxOutputBytes, env, signal, onStarted }: {
|
|
133
133
|
/**
|
|
134
134
|
* The {@link WslAgent}-like runner: `exec` accepting
|
|
135
|
-
* `{cwd, argv, timeoutMs, signal}` and resolving `{exitCode, stdout, stderr}`;
|
|
135
|
+
* `{cwd, argv, timeoutMs, env, signal}` and resolving `{exitCode, stdout, stderr}`;
|
|
136
136
|
* throws `AgentUnavailableError` when out.
|
|
137
137
|
*/
|
|
138
138
|
agent: AgentExecRunner;
|
|
@@ -150,6 +150,13 @@ export declare function agentExecutionHandle({ agent, cwd, argv, timeoutMs, maxO
|
|
|
150
150
|
* stream as `truncated: true`.
|
|
151
151
|
*/
|
|
152
152
|
maxOutputBytes?: number;
|
|
153
|
+
/**
|
|
154
|
+
* Environment for this command: the caller's entries with the managed
|
|
155
|
+
* `DSH_*` snapshot merged last. The agent applies it as `SETENV` frames
|
|
156
|
+
* immediately before the command's `EXEC` (see `WslAgent.exec`); dropping it
|
|
157
|
+
* here is what kept every managed fact out of the resident-agent path.
|
|
158
|
+
*/
|
|
159
|
+
env?: Record<string, string>;
|
|
153
160
|
/** The caller's cancellation. */
|
|
154
161
|
signal?: AbortSignal;
|
|
155
162
|
/**
|
package/lib/agent-exec.js
CHANGED
|
@@ -54,7 +54,7 @@ function memoryReader(buffer) {
|
|
|
54
54
|
* @returns the execution handle (`status`, `exitCode`, `signal`, `observed`,
|
|
55
55
|
* `done`, `readOutput`, `kill`, `result`).
|
|
56
56
|
*/
|
|
57
|
-
export function agentExecutionHandle({ agent, cwd, argv, timeoutMs = 0, maxOutputBytes = 0, signal, onStarted }) {
|
|
57
|
+
export function agentExecutionHandle({ agent, cwd, argv, timeoutMs = 0, maxOutputBytes = 0, env, signal, onStarted }) {
|
|
58
58
|
// Our own controller is the kill channel; the caller's signal races it.
|
|
59
59
|
const controller = new AbortController();
|
|
60
60
|
let timedOut = false;
|
|
@@ -72,7 +72,7 @@ export function agentExecutionHandle({ agent, cwd, argv, timeoutMs = 0, maxOutpu
|
|
|
72
72
|
controller.abort(new Error(BASH_TIMEOUT_REASON));
|
|
73
73
|
}, timeoutMs).unref?.();
|
|
74
74
|
}
|
|
75
|
-
const settle = agent.exec({ cwd, argv, timeoutMs, maxOutputBytes, signal: controller.signal }).then((result) => ({ ok: true, result }), (error) => {
|
|
75
|
+
const settle = agent.exec({ cwd, argv, timeoutMs, maxOutputBytes, env, signal: controller.signal }).then((result) => ({ ok: true, result }), (error) => {
|
|
76
76
|
// A workdir the distro cannot enter is the command's own failure, not
|
|
77
77
|
// the agent's: synthesize the relay-shaped stderr the one-shot path
|
|
78
78
|
// produces, so the executor's `workdirFailure` check reports it the
|
package/lib/index.js
CHANGED
|
@@ -831,6 +831,13 @@ export class WslShellExecutor extends LocalBashExecutor {
|
|
|
831
831
|
const argv = runtime !== undefined
|
|
832
832
|
? this.distroArgv(resolved, shell)
|
|
833
833
|
: confined !== undefined ? confined.argv : this.distroArgv(resolved, shell);
|
|
834
|
+
// The managed `DSH_*` snapshot merges last, exactly as the one-shot path's
|
|
835
|
+
// spawn env does (`ShellExecSpec`: `dshEnv` wins over `env`). The agent
|
|
836
|
+
// applies these as SETENV frames immediately before the command's EXEC, so
|
|
837
|
+
// the resident path now carries `DSH_HOME`, `DSH_SESSION_ID` and the
|
|
838
|
+
// `DSH_WSL_*` facts too — without this the whole registry was invisible on
|
|
839
|
+
// the default path while the one-shot fallback forwarded it.
|
|
840
|
+
const env = { ...resolved.env, ...resolved.dshEnv };
|
|
834
841
|
const execution = agentExecutionHandle({
|
|
835
842
|
agent,
|
|
836
843
|
// The one-shot path converts the spec's workdir into the distro's
|
|
@@ -839,6 +846,7 @@ export class WslShellExecutor extends LocalBashExecutor {
|
|
|
839
846
|
// reach `chdir` (that is the bug this line fixes).
|
|
840
847
|
cwd: toLinuxPath(resolved.workdir, { distro }),
|
|
841
848
|
argv,
|
|
849
|
+
env: Object.keys(env).length > 0 ? env : undefined,
|
|
842
850
|
timeoutMs: resolved.timeoutMs,
|
|
843
851
|
// The agent enforces the collect budget distro-side (the EXEC frame
|
|
844
852
|
// carries it); `maxSpillBytes` stays one-shot-only — the agent path has
|
package/lib/preflight.js
CHANGED
|
@@ -176,8 +176,14 @@ export async function apply(ctx, config = {}) {
|
|
|
176
176
|
// Mount order is not a guarantee: a session created during startup can finish
|
|
177
177
|
// before this service mounts and miss the event entirely (dsh-headless does
|
|
178
178
|
// exactly that, and auto-preset sweeps for the same reason).
|
|
179
|
+
//
|
|
180
|
+
// `agents` is optional (this row injects nothing), so read it with `ctx.get`:
|
|
181
|
+
// a property read of an undeclared service throws in cordis 4, and the catch
|
|
182
|
+
// below would turn that into a silent no-op — exactly the sweep this block
|
|
183
|
+
// exists to perform.
|
|
179
184
|
try {
|
|
180
|
-
|
|
185
|
+
const agents = ctx.get("agents");
|
|
186
|
+
for (const agent of agents?.list() ?? [])
|
|
181
187
|
void check(agent);
|
|
182
188
|
}
|
|
183
189
|
catch (error) {
|
package/lib/shell-env.js
CHANGED
|
@@ -157,7 +157,14 @@ export async function apply(ctx, config = {}) {
|
|
|
157
157
|
ensurePorts(parsed.distro);
|
|
158
158
|
};
|
|
159
159
|
const off = lifecycle.on?.("agent/created", (payload) => consider(payload?.agent));
|
|
160
|
-
|
|
160
|
+
// The live-agent sweep is a convenience, not a dependency: `inject` names
|
|
161
|
+
// only `shellEnv`, so reading `ctx.agents` as a property makes cordis 4
|
|
162
|
+
// throw "cannot get property \"agents\" without inject" and marks the whole
|
|
163
|
+
// component failed. `ctx.get` is the sanctioned read for a service this
|
|
164
|
+
// plugin did not inject, and it answers undefined when no agent loop is
|
|
165
|
+
// composed — the row still activates and resolves facts per shell call.
|
|
166
|
+
const live = ctx.get("agents");
|
|
167
|
+
for (const agent of live?.list?.() ?? [])
|
|
161
168
|
consider(agent);
|
|
162
169
|
const dispose = ctx.shellEnv.register({
|
|
163
170
|
name: "dsh-plugin-wsl-env",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-wsl-env",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "\u8ba9 DeepSeek Harness \u4ee5 WSL \u5b50\u7cfb\u7edf\u4f5c\u4e3a\u4f1a\u8bdd\u7684\u6267\u884c\u73af\u5883\uff1ashell\u3001\u6587\u4ef6\u8bfb\u5199\u4e0e\u547d\u4ee4\u6267\u884c\u5747\u5728\u5b50\u7cfb\u7edf\u5185\u5b8c\u6210\uff0c\u76ee\u5f55\u9009\u62e9\u5668\u4e0e GUI \u7ec8\u7aef\u540c\u6837\u5b9a\u4f4d\u5230\u5b50\u7cfb\u7edf\u8def\u5f84\uff0c\u5e76\u901a\u8fc7\u5b50\u7cfb\u7edf\u5185\u7684 bubblewrap \u5bf9\u547d\u4ee4\u8fdb\u884c\u6c99\u7bb1\u9694\u79bb",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
@@ -125,9 +125,9 @@
|
|
|
125
125
|
"lint:types": "tsc --noEmit",
|
|
126
126
|
"build": "node scripts/build.mjs",
|
|
127
127
|
"lint:build": "node test/build-freshness.mjs",
|
|
128
|
-
"test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=85 --test-coverage-branches=84 --test-coverage-functions=70 --test-coverage-exclude='scripts/**' test/agent-exec.test.mjs test/agent-fs-script.test.mjs test/agent-protocol.test.mjs test/agent.test.mjs test/fs-substrate.test.mjs test/fs.boot.test.mjs test/composition.test.mjs test/provider.test.mjs test/file-reference-wsl.test.mjs test/fsio-agent.test.mjs test/fsio-text.test.mjs test/git-route.test.mjs test/listing.test.mjs test/paths.test.mjs test/ports.test.mjs test/preset-choice.test.mjs test/probe-cache.test.mjs test/preflight.test.mjs test/sandbox.test.mjs test/search-exec.test.mjs test/search-route.test.mjs test/shell.test.mjs test/terminal-activity.test.mjs test/terminal.test.mjs test/watcher.test.mjs test/wsl.test.mjs test/fs-decisions.test.mjs test/session-scope.test.mjs test/session-runtime.test.mjs test/native-agent.test.mjs test/peers.test.mjs test/agent-shared.test.mjs test/distro-route.test.mjs test/fs-routing.test.mjs test/doctor.test.mjs test/profile-preset.test.mjs test/packaging.test.mjs test/peer-canary.test.mjs",
|
|
128
|
+
"test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=85 --test-coverage-branches=84 --test-coverage-functions=70 --test-coverage-exclude='scripts/**' test/agent-exec.test.mjs test/agent-fs-script.test.mjs test/agent-protocol.test.mjs test/agent.test.mjs test/fs-substrate.test.mjs test/fs.boot.test.mjs test/composition.test.mjs test/provider.test.mjs test/file-reference-wsl.test.mjs test/fsio-agent.test.mjs test/fsio-text.test.mjs test/git-route.test.mjs test/listing.test.mjs test/paths.test.mjs test/ports.test.mjs test/preset-choice.test.mjs test/probe-cache.test.mjs test/preflight.test.mjs test/sandbox.test.mjs test/search-exec.test.mjs test/search-route.test.mjs test/shell.test.mjs test/shell-env.test.mjs test/terminal-activity.test.mjs test/terminal.test.mjs test/watcher.test.mjs test/wsl.test.mjs test/fs-decisions.test.mjs test/session-scope.test.mjs test/session-runtime.test.mjs test/native-agent.test.mjs test/peers.test.mjs test/agent-shared.test.mjs test/distro-route.test.mjs test/fs-routing.test.mjs test/doctor.test.mjs test/profile-preset.test.mjs test/packaging.test.mjs test/peer-canary.test.mjs",
|
|
129
129
|
"test:syntax": "node test/syntax.mjs",
|
|
130
|
-
"test:unit": "node --test test/fs.boot.test.mjs test/fsio-text.test.mjs test/composition.test.mjs test/provider.test.mjs test/file-reference-wsl.test.mjs test/paths.test.mjs test/listing.test.mjs test/shell.test.mjs test/terminal.test.mjs test/probe-cache.test.mjs test/preflight.test.mjs test/preset-choice.test.mjs test/sandbox.test.mjs test/agent-protocol.test.mjs test/agent.test.mjs test/agent-fs-script.test.mjs test/fsio-agent.test.mjs test/fs-substrate.test.mjs test/agent-exec.test.mjs test/ports.test.mjs test/watcher.test.mjs test/wsl.test.mjs test/fs-decisions.test.mjs test/git-route.test.mjs test/search-route.test.mjs test/search-exec.test.mjs test/terminal-activity.test.mjs test/session-scope.test.mjs test/session-runtime.test.mjs test/native-agent.test.mjs test/peers.test.mjs test/agent-shared.test.mjs test/distro-route.test.mjs test/fs-routing.test.mjs test/doctor.test.mjs test/profile-preset.test.mjs test/packaging.test.mjs test/peer-canary.test.mjs",
|
|
130
|
+
"test:unit": "node --test test/fs.boot.test.mjs test/fsio-text.test.mjs test/composition.test.mjs test/provider.test.mjs test/file-reference-wsl.test.mjs test/paths.test.mjs test/listing.test.mjs test/shell.test.mjs test/shell-env.test.mjs test/terminal.test.mjs test/probe-cache.test.mjs test/preflight.test.mjs test/preset-choice.test.mjs test/sandbox.test.mjs test/agent-protocol.test.mjs test/agent.test.mjs test/agent-fs-script.test.mjs test/fsio-agent.test.mjs test/fs-substrate.test.mjs test/agent-exec.test.mjs test/ports.test.mjs test/watcher.test.mjs test/wsl.test.mjs test/fs-decisions.test.mjs test/git-route.test.mjs test/search-route.test.mjs test/search-exec.test.mjs test/terminal-activity.test.mjs test/session-scope.test.mjs test/session-runtime.test.mjs test/native-agent.test.mjs test/peers.test.mjs test/agent-shared.test.mjs test/distro-route.test.mjs test/fs-routing.test.mjs test/doctor.test.mjs test/profile-preset.test.mjs test/packaging.test.mjs test/peer-canary.test.mjs",
|
|
131
131
|
"lint:style": "node test/style.mjs",
|
|
132
132
|
"lint:links": "node scripts/check-links.mjs",
|
|
133
133
|
"prepublishOnly": "pnpm test",
|