dsh-win-multi-bash 0.1.1 → 0.1.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/README.i18n.yaml CHANGED
@@ -4,5 +4,5 @@
4
4
  # along and re-record with the harness docs tooling (not shipped with this
5
5
  # package):
6
6
  # node scripts/verify-docs.mjs --write <dir> # run from the deepseek-harness checkout
7
- README.md: ec808f83664fbe3c6096c9268cf027809ee69f52
8
- README.zh.md: 83e60cea590d3763f89c80bb3d955895513e9d0d
7
+ README.md: 498a99ec73bd8a0015e2737d54696eb04d0989d6
8
+ README.zh.md: 7fcc09ebfab371d4236645737710808cbf22c7c9
package/README.md CHANGED
@@ -62,6 +62,16 @@ wsl.exe -d Ubuntu-24.04 -e bash -c "command -v bwrap && bwrap --version" # ver
62
62
  - Other distro families: Fedora `dnf install bubblewrap`, Alpine `apk add bubblewrap`.
63
63
  - After installing you **must restart `dsh web`** (or touch the shell settings section to rebuild backends) — the probe verdict is cached for the host process lifetime, and `wsl_bash` stays unconfined until then.
64
64
 
65
+ ## Tool prompts (model-facing descriptions)
66
+
67
+ The `git_bash` / `wsl_bash` tool descriptions are deliberately concise and mirror the official `tool-pwsh` skeleton: a fresh shell per call, the dialect's paths/env form, `[exit code: N]` markers, `$DSH_*` environment facts, sandbox behavior, output truncation, background jobs, and the escalation contract. The longer dialect notes (MSYS path rewriting, WSL base64 payloads) live in this README rather than in the model-facing text.
68
+
69
+ `git_bash`'s description additionally carries a path-format hint:
70
+
71
+ > MSYS paths work inside Git Bash only — dsh's file tools (`read`, `write`, `edit`) on Windows take native `C:\...` paths.
72
+
73
+ So when a command prints an MSYS path (e.g. `/d/WorkSpace/foo`), convert it to its Windows form (`D:\WorkSpace\foo`) before handing it to dsh's file tools; inside the bash command itself, MSYS paths are what the shell expects.
74
+
65
75
  ## Path conversion (MSYS auto-rewriting)
66
76
 
67
77
  Git Bash rewrites leading-slash POSIX paths into Windows paths (e.g. `<Git root>\root`) whenever a native Windows program is called — standard MSYS behavior, not a plugin defect. Calling `wsl.exe` (or any native exe) with POSIX paths from inside `git_bash` therefore fails:
package/README.zh.md CHANGED
@@ -62,6 +62,16 @@ wsl.exe -d Ubuntu-24.04 -e bash -c "command -v bwrap && bwrap --version" # 验
62
62
  - 其它发行版系:Fedora `dnf install bubblewrap`,Alpine `apk add bubblewrap`。
63
63
  - 装完后**必须重启 `dsh web`**(或改动 shell 设置节触发后端重建)——探针结果在宿主进程生命周期内缓存,重启前 `wsl_bash` 仍按无沙箱运行。
64
64
 
65
+ ## 工具提示词(面向模型的描述)
66
+
67
+ `git_bash` / `wsl_bash` 的工具描述刻意保持精简,与官方 `tool-pwsh` 同构:每次调用全新 shell、方言的路径/环境变量写法、`[exit code: N]` 标记、`$DSH_*` 环境事实、沙箱行为、输出截断、后台任务与升级契约。更长的方言说明(MSYS 路径改写、WSL base64 载荷)放在本文档而不是模型可见的描述里。
68
+
69
+ `git_bash` 的描述还带一条路径格式提示:
70
+
71
+ > MSYS paths work inside Git Bash only — dsh's file tools (`read`, `write`, `edit`) on Windows take native `C:\...` paths.
72
+
73
+ 即命令输出里的 MSYS 路径(如 `/d/WorkSpace/foo`)在交给 dsh 文件工具前要转成 Windows 形式(`D:\WorkSpace\foo`);而在 bash 命令内部,MSYS 路径才是 shell 期望的写法。
74
+
65
75
  ## 路径转换(MSYS 自动改写)
66
76
 
67
77
  Git Bash 在调用原生 Windows 程序时会把形如 `/root` 的 POSIX 路径自动改写成 Windows 路径(如 `<Git 根目录>\root`),这是 MSYS 的标准行为,不是本插件的缺陷。在 `git_bash` 里直接调用 `wsl.exe`(或其他原生 exe)并传 POSIX 路径时会被改写而失败:
package/cordis.patch.yml CHANGED
@@ -20,8 +20,13 @@
20
20
  # win-mb-tool-git — registers the model-facing `git_bash` tool
21
21
  # (request.shell 'git-bash', MSYS dialect) into the
22
22
  # host tools registry: every session sees it regardless
23
- # of its agent preset.
24
- # win-mb-tool-wsl — the `wsl_bash` tool (request.shell 'wsl-bash').
23
+ # of its agent preset. Its model-facing description
24
+ # mirrors the official tool-pwsh skeleton (concise)
25
+ # and reminds the model that MSYS paths are valid only
26
+ # inside Git Bash — dsh's file tools on Windows take
27
+ # native C:\... paths.
28
+ # win-mb-tool-wsl — the `wsl_bash` tool (request.shell 'wsl-bash');
29
+ # its description mirrors tool-pwsh's concise skeleton.
25
30
  #
26
31
  # Both tool rows and the selector are win32-only; POSIX keeps the direct
27
32
  # bash-sandbox seat untouched.
@@ -118,18 +118,15 @@ const DIALECT_FACTS = {
118
118
  msys: {
119
119
  shell: "Git Bash (MSYS2)",
120
120
  invoke: "bash -c",
121
- paths: "MSYS paths such as /d/WorkSpace or native C:\\...",
121
+ paths: "MSYS form (`/d/WorkSpace` or `C:\\...`)",
122
122
  env: "$VAR",
123
- toolchain: "the Git for Windows toolchain (git, Windows .exe tools, POSIX utilities)",
124
- conversion: "MSYS auto-converts leading-slash arguments to Windows paths whenever a native Windows executable is called, so POSIX paths get mangled (e.g. `wsl.exe -e ls /root` fails on `D:/Program Files/Git/root`); prefix such calls with `MSYS_NO_PATHCONV=1` to pass arguments verbatim"
123
+ note: "MSYS paths work inside Git Bash only — dsh's file tools (`read`, `write`, `edit`) on Windows take native `C:\\...` paths"
125
124
  },
126
125
  wsl: {
127
126
  shell: "WSL Linux",
128
127
  invoke: "bash -c",
129
- paths: "Linux paths such as /mnt/c/... (Windows paths auto-converted by wsl.exe)",
130
- env: "$VAR",
131
- toolchain: "the Linux userland (apt, gcc, python, ...)",
132
- conversion: "the command rides as a base64 payload, so quoting and Linux paths reach the distro verbatim (no MSYS-style mangling)"
128
+ paths: "Linux paths (`/mnt/c/...`)",
129
+ env: "$VAR"
133
130
  }
134
131
  };
135
132
  /** Runtime configuration schema for a shell tool instance. */
@@ -137,7 +134,10 @@ const Config$1 = z.object({ enableRunInBackground: z.boolean().default(true) });
137
134
  /**
138
135
  * The model-facing description of one shell tool instance. The POSIX variant
139
136
  * keeps the legacy wording byte-for-byte (the ACP/headless tool-schema
140
- * fixtures pin it); msys/wsl instances describe their dialect facts.
137
+ * fixtures pin it); msys/wsl instances mirror the official tool-pwsh
138
+ * skeleton (fresh shell, paths/env, exit codes, sandbox, truncation,
139
+ * background, escalation) with only their dialect's shell/paths/env facts
140
+ * plus at most one short dialect note.
141
141
  * @param dialect - the shell dialect the instance runs.
142
142
  * @param backgroundEnabled - whether `run_in_background` is advertised.
143
143
  * @param escalationModes - the escalation targets this composition advertises;
@@ -148,7 +148,8 @@ function shellDescription(dialect, backgroundEnabled, escalationModes) {
148
148
  const background = backgroundEnabled ? "Set `run_in_background: true` for long-running commands: the call returns a job id immediately; read its output with `job_output` and stop it with `job_kill`." : "Background execution is not available; long-running commands must finish within the timeout.";
149
149
  if (dialect === "posix") return `Execute a bash command (\`bash -c\`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass \`workdir\` instead of using \`cd\`. Non-zero exits are reported as \`[exit code: N]\`. Current harness environment facts are exposed through managed \`\$${DSH_ENV_PREFIX}*\` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as \`[sandbox: file access denied under <mode> mode]\` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. ` + background + escalationTail(escalationModes);
150
150
  const facts = DIALECT_FACTS[dialect];
151
- return `Execute a ${facts.shell} command (${facts.invoke}) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass \`workdir\` instead of using \`cd\`. Paths use ${facts.paths}; read environment variables with ${facts.env}; ${facts.toolchain} is available. Note: ${facts.conversion}. Non-zero exits are reported as \`[exit code: N]\`. Current harness environment facts are exposed through managed \`\$${DSH_ENV_PREFIX}*\` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as \`[sandbox: file access denied under <mode> mode]\` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. ` + background + escalationTail(escalationModes);
151
+ const note = facts.note === void 0 ? "" : ` Note: ${facts.note}.`;
152
+ return `Execute a ${facts.shell} command (${facts.invoke}) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass \`workdir\` instead of using \`cd\`. Paths use ${facts.paths}; read environment variables with ${facts.env}.` + note + ` Non-zero exits are reported as \`[exit code: N]\`. Current harness environment facts are exposed through managed \`\$${DSH_ENV_PREFIX}*\` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as \`[sandbox: file access denied under <mode> mode]\` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. ` + background + escalationTail(escalationModes);
152
153
  }
153
154
  /**
154
155
  * The same-turn escalation guidance appended after a denial marker. Kept in
@@ -17,8 +17,19 @@ import { processOutcome } from "./background.js";
17
17
  import { parseExitStatus, renderProcessRead, renderResult } from "./render.js";
18
18
  const DIALECT_FACTS = {
19
19
  posix: { shell: 'bash', invoke: 'bash -c', paths: 'POSIX paths', env: '$VAR', toolchain: 'the full Unix toolchain' },
20
- msys: { shell: 'Git Bash (MSYS2)', invoke: 'bash -c', paths: 'MSYS paths such as /d/WorkSpace or native C:\\...', env: '$VAR', toolchain: 'the Git for Windows toolchain (git, Windows .exe tools, POSIX utilities)', conversion: 'MSYS auto-converts leading-slash arguments to Windows paths whenever a native Windows executable is called, so POSIX paths get mangled (e.g. `wsl.exe -e ls /root` fails on `D:/Program Files/Git/root`); prefix such calls with `MSYS_NO_PATHCONV=1` to pass arguments verbatim' },
21
- wsl: { shell: 'WSL Linux', invoke: 'bash -c', paths: 'Linux paths such as /mnt/c/... (Windows paths auto-converted by wsl.exe)', env: '$VAR', toolchain: 'the Linux userland (apt, gcc, python, ...)', conversion: 'the command rides as a base64 payload, so quoting and Linux paths reach the distro verbatim (no MSYS-style mangling)' },
20
+ msys: {
21
+ shell: 'Git Bash (MSYS2)',
22
+ invoke: 'bash -c',
23
+ paths: 'MSYS form (`/d/WorkSpace` or `C:\\...`)',
24
+ env: '$VAR',
25
+ note: 'MSYS paths work inside Git Bash only — dsh\'s file tools (`read`, `write`, `edit`) on Windows take native `C:\\...` paths',
26
+ },
27
+ wsl: {
28
+ shell: 'WSL Linux',
29
+ invoke: 'bash -c',
30
+ paths: 'Linux paths (`/mnt/c/...`)',
31
+ env: '$VAR',
32
+ },
22
33
  };
23
34
  /** Runtime configuration schema for a shell tool instance. */
24
35
  export const Config = z.object({
@@ -27,7 +38,10 @@ export const Config = z.object({
27
38
  /**
28
39
  * The model-facing description of one shell tool instance. The POSIX variant
29
40
  * keeps the legacy wording byte-for-byte (the ACP/headless tool-schema
30
- * fixtures pin it); msys/wsl instances describe their dialect facts.
41
+ * fixtures pin it); msys/wsl instances mirror the official tool-pwsh
42
+ * skeleton (fresh shell, paths/env, exit codes, sandbox, truncation,
43
+ * background, escalation) with only their dialect's shell/paths/env facts
44
+ * plus at most one short dialect note.
31
45
  * @param dialect - the shell dialect the instance runs.
32
46
  * @param backgroundEnabled - whether `run_in_background` is advertised.
33
47
  * @param escalationModes - the escalation targets this composition advertises;
@@ -49,11 +63,12 @@ export function shellDescription(dialect, backgroundEnabled, escalationModes) {
49
63
  return base + escalationTail(escalationModes);
50
64
  }
51
65
  const facts = DIALECT_FACTS[dialect];
66
+ const note = facts.note === undefined ? '' : ` Note: ${facts.note}.`;
52
67
  const base = `Execute a ${facts.shell} command (${facts.invoke}) and return its stdout/stderr. `
53
68
  + 'Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — '
54
69
  + 'pass `workdir` instead of using `cd`. '
55
- + `Paths use ${facts.paths}; read environment variables with ${facts.env}; ${facts.toolchain} is available. `
56
- + `Note: ${facts.conversion}. `
70
+ + `Paths use ${facts.paths}; read environment variables with ${facts.env}.`
71
+ + note + ' '
57
72
  + 'Non-zero exits are reported as `[exit code: N]`. '
58
73
  + `Current harness environment facts are exposed through managed \`\$${DSH_ENV_PREFIX}*\` variables; inspect them when needed. `
59
74
  + 'Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under <mode> mode]` — a policy denial, not a bug in the command; do not retry another way. '
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-win-multi-bash",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "author": "Dinosaur_MC",
5
5
  "repository": {
6
6
  "type": "git",