dsh-gitbash-shell 0.29.1 → 0.30.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/CHANGELOG.md +80 -1
- package/README.md +5 -1
- package/README_EN.md +20 -0
- package/dsh.plugin.json +1 -1
- package/package.json +1 -1
- package/src/client.js +499 -0
- package/src/index.js +88 -0
- package/src/tool-runner.js +337 -0
- package/src/toolchain.js +418 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,84 @@
|
|
|
3
3
|
> 倒序排列,新版本条目在最上面。条目格式:`## vX.Y.Z — YYYY-MM-DD` + 类型(feat / fix / docs / chore)+ 要点 + 相关链接。
|
|
4
4
|
> 纪律见 AGENTS.md「变更记录纪律」:发版前先更新本文件并随版本提交;事故复盘、复现与真机验证记录也记在这里。
|
|
5
5
|
|
|
6
|
+
## v0.30.0 — 2026-09-26
|
|
7
|
+
|
|
8
|
+
**类型**:feat(新能力 —— 设置卡里一键安装/升级一份**固定的终端工具清单**,全部经 winget 官方源)
|
|
9
|
+
|
|
10
|
+
> 用户需求原话:**"所有缺的工具,能不能在插件的设置里增加一个按钮,可以选择自己一次性安装升级到最新,用winget,或者可以自定义选择一部分安装升级"**
|
|
11
|
+
> 追加的硬要求:**"绝对要保证是下载的正确的源,你这些工具id都要查清楚"**
|
|
12
|
+
> 以及**"只要人家已经有了已经安装过了就不需要安装"** / **"有的人的电脑可能安装过llvm 之类的…这种情况下我们不需要帮忙winget安装,要跳过,也不帮忙升级"**。
|
|
13
|
+
|
|
14
|
+
### 清单(`src/toolchain.js`,22 项,闭合集合)
|
|
15
|
+
|
|
16
|
+
- **基础补全(4)**:`make`(ezwinports.make)、`wget`(JernejSimoncic.Wget)、`yq`(MikeFarah.yq)、`xtree`(Excelano.xtree,现代 tree 替代)。
|
|
17
|
+
- **现代 CLI(13)**:bat、fzf、delta、zoxide、dust、procs、xh、just、shellcheck、hexyl、tldr、jj、gdu。
|
|
18
|
+
- **纳入版本管理(3)**:jq、ripgrep、fd(本机已有,交给插件统一升级)。
|
|
19
|
+
- **需要管理员(2)**:7-Zip、经典 tree —— manifest 写 `Scope: machine`,winget 必须提权,会弹 UAC。
|
|
20
|
+
- 每项自带 `publisher` + 安装器域名(`source`),**卡片上渲染出来**,让来源可核对而不是口头保证。
|
|
21
|
+
|
|
22
|
+
### 源核实(逐包查证,三重证据)
|
|
23
|
+
|
|
24
|
+
- **源**:全部来自 `winget` 官方源(`cdn.winget.microsoft.com/cache`),本机未添加任何第三方源;`--source winget` 写死在 argv 里,msstore 与第三方源永不参与。
|
|
25
|
+
- **定义**:22 个包的 manifest 全部在 **microsoft/winget-pkgs** 官方仓库,逐个读取核对(发布者字段与真实项目作者一致:sharkdp→David Peter、BurntSushi、Casey Rodarmor、Vidar Holen…)。
|
|
26
|
+
- **完整性**:22/22 均有 `InstallerSha256`,winget 安装时强制校验;18 个安装器指向 `github.com/<官方项目>/releases`,其余指向官方站
|
|
27
|
+
(ezwinports→sourceforge、7-Zip→www.7-zip.org、wget→eternallybored.org —— 后者是 GNU wget 官方认可的 Windows 构建站)。
|
|
28
|
+
|
|
29
|
+
### 实测发现(全部真机复现,并已固化为冒烟断言)
|
|
30
|
+
|
|
31
|
+
1. **同一个工具存在多个 winget 包 ID**:本机装的 ripgrep 是 **`BurntSushi.ripgrep.GNU`**,而 MSVC 构建是**另一个包**。只认一个 ID 会导致"再装一份"。
|
|
32
|
+
⇒ 清单支持 `ids[]` 变体:**识别**用任一变体,**升级**用 `winget export` 报出的**实际那个**,只有全新安装才用首选。
|
|
33
|
+
2. **已装 ≠ 命令在 PATH**:本机 7-Zip 由 winget 装好,但 MSI 没有把目录加进 PATH,`7z` 命令根本不存在。按"命令是否存在"判断会把它当缺失并重复安装。
|
|
34
|
+
⇒ 判定**以 winget 自己的库存为准**(`winget export` 的 JSON),命令存在性只用来识别"外部提供"。
|
|
35
|
+
3. **两个"无事可做"的退出码都是非零,其中一个曾被误判**:实测 `winget upgrade` 对已最新的包返回 `0x8A15002B`("找不到可用的升级"),对未安装的包返回 `0x8A150014`。
|
|
36
|
+
Node 收到的是**完整 HRESULT**(Git Bash 里只显示低位 20)。初版把 `0x8A15002B` 错归为"需要管理员",会让**每台健康的机器在升级轮里误报失败** ——
|
|
37
|
+
现按**码结构化判定**(辅以 21 语言文案兜底),并把两条断言锁进冒烟。`0x8A150014`(低位 0x14)与 `0x8A15002B`(低位 0x2B)不会互相误伤。
|
|
38
|
+
4. **"外部提供"必须只读**:本机 `fd` 来自 kimi-code(`~/.kimi-code/bin`)、`tree` 来自 Windows 自带的 `C:\WINDOWS\system32\tree.com` ——
|
|
39
|
+
两者都判为 `external`:**不安装、不升级、复选框不可勾**,只显示来源。LLVM/WinLibs 提供的工具链同理,永远不会被本插件动到。
|
|
40
|
+
5. **只读探测也能拿到权威清单**:`winget export -o <file> --include-versions` 输出 **JSON**(`list` 的表格是本地化的、宽 ID 会被截断),
|
|
41
|
+
是本插件唯一采信的库存来源;传给它的必须是 **Windows 路径**(原生程序不认 MSYS 的 `/tmp/...`)。
|
|
42
|
+
|
|
43
|
+
### 安全边界
|
|
44
|
+
|
|
45
|
+
- **路由有副作用 ⇒ 有围栏**:`/dsh-gitbash-shell/api/tools` 只接受 **loopback** 调用,且**改动类请求必须带同源 `Origin`/`Referer`**;
|
|
46
|
+
用户只是访问过的网页因此无法让他的机器装软件(跨站请求在 origin 检查处被拒)。
|
|
47
|
+
- **请求只能命名清单内的条目**:请求体里的 id 先映射到 `src/toolchain.js` 的闭合集合,未知 id 直接丢弃;`install`/`upgrade` 的 argv 一律带
|
|
48
|
+
**`--exact` + `--source winget`**,并且只由服务端拼装(`execFile` + argv 数组,永不拼 shell 字符串)。
|
|
49
|
+
- **无自由文本包 ID 输入框**(用户明确选择"固定清单就好"),所以不存在"用户填错 ID 装错包"的路径。
|
|
50
|
+
- 一次只跑一个 job(并发安装正是"半个清单已应用"的来源);进度经 `?job=1` 轻量轮询,不重复跑三个 winget 命令。
|
|
51
|
+
|
|
52
|
+
### 验证
|
|
53
|
+
|
|
54
|
+
- `npm test`:**102 → 112 全绿**。新增 10 个用例覆盖:清单结构与来源字段齐备、argv 三重锁定、变体 ID 的安装/升级取向、PATH 扫描(首个命中优先/坏目录不致命)、
|
|
55
|
+
四态状态机(`missing`/`external`/`managed`/`current`,含"winget 有而命令不在 PATH"、"外部提供即使有命令也不可动")、export JSON 只认 winget 源、
|
|
56
|
+
两个实测退出码的分类、CSRF 围栏五态、请求 ID 闭合性、`auto` 模式的装/升分流、路由接线守卫。
|
|
57
|
+
- **真机读数**(本机):22 项判定为 `missing 16 / current 4 / external 2`,其中 `rg` 正确识别为 `BurntSushi.ripgrep.GNU 15.2.0`、`7z` 识别为 `7zip.7zip 26.03`(命令不在 PATH 也判对)、
|
|
58
|
+
`fd`/`tree` 如实标为外部提供。
|
|
59
|
+
- ⚠️ **尚未做**:设置卡 UI 的浏览器端真机点击验证(需重启 DSH 或起隔离实例);本次未替用户重启其运行中的实例。
|
|
60
|
+
- 版本号 `0.29.2` → **`0.30.0`**(`package.json` 与 `dsh.plugin.json` 一致)。
|
|
61
|
+
- 顺带修复:本仓库此前**从未跑过 `npm install`**(无 `node_modules`),导致 peer 依赖 `@deepseek-ai/schemastery` 不可解析、`Config` 导出缺失而有一条测试恒失败;
|
|
62
|
+
已补装 devDependencies 并生成 `package-lock.json`。
|
|
63
|
+
|
|
64
|
+
## v0.29.2 — 2026-09-26
|
|
65
|
+
|
|
66
|
+
**类型**:docs(纯文档 patch —— 更正复验判据:原先写成 `uname -r`,实为 `uname -s`;无任何代码/行为变更)
|
|
67
|
+
|
|
68
|
+
> 用户在 Windows 上按 README 的"三步复验清单"跑 `uname -r`,得到 `3.6.9-b4195d69.x86_64` —— 按我们文档里写的判据
|
|
69
|
+
> ("应出现 `MINGW64_NT-…`")会被**误判为失败**,实际它就是 Git Bash。事实:`MINGW64_NT-10.0-<build>` 是 **`uname -s`**
|
|
70
|
+
> (system name)的输出;**`uname -r`**(release)在 Git Bash / MSYS2 下是 **MSYS 运行时版本**(形如 `3.6.9-<hash>.x86_64`),
|
|
71
|
+
> 而 **WSL 的 `uname -r`** 才是 `6.x.y.z-microsoft-standard-WSL2`。两个都不能单独用来判定。
|
|
72
|
+
|
|
73
|
+
- **README.md 三步复验第 ② 条**:判据改为 **`uname -s` ⇒ `MINGW64_NT-10.0-<build>`**(最硬)或 **`echo $MSYSTEM` ⇒ `MINGW64`**(最简),
|
|
74
|
+
并补一句"⚠️ 不要用 `uname -r` 判定"(附上两种 `uname -r` 的真实形态)。
|
|
75
|
+
- **README_EN.md**:原文没有侧栏终端一节(英文 README 尚未跟进 v0.29.x),本次补上该节并把**同样更正过的**三步复验清单写进去,
|
|
76
|
+
使中英两处判据一致。
|
|
77
|
+
- **AGENTS.md 验证清单第 10 条**:同一处错判据更正为 `uname -s`/`$MSYSTEM`,并写明为什么 `uname -r` 不能单独用;
|
|
78
|
+
同时明确**代码里的"一票否决"用的是 `bash -c "uname -s"`(`MINGW(32|64)_NT-*`),那一直是对的,未改动**。
|
|
79
|
+
- **历史条目加指路**:v0.29.0 条目里留下的 `uname -r` 判据加"(判据有误,见 v0.29.2 更正)",不改写历史叙事。
|
|
80
|
+
- **grep 复核**:全仓 `uname -r` 仅出现在 CHANGELOG 的历史条目(已加指路);`src/` 里只有 `uname -s`(`src/bash-path.js`
|
|
81
|
+
的一票否决与 `src/terminal-shell.js` 的注释),设置卡 21 语言文案与启动日志均未使用该判据。
|
|
82
|
+
- 版本号 `0.29.1` → **`0.29.2`**(`package.json` 与 `dsh.plugin.json` 一致);`npm test` 101→102 全绿不受影响(纯文档)。
|
|
83
|
+
|
|
6
84
|
## v0.29.1 — 2026-09-26
|
|
7
85
|
|
|
8
86
|
**类型**:fix(用户实测:官方「新建终端」下拉里出现**两条 `bash`** —— 一条是 v0.29.0 写入的 Git Bash,另一条是官方 `shellCandidates` 解析到的 WSL,用户分不清)
|
|
@@ -64,6 +142,7 @@
|
|
|
64
142
|
- 新开关 `autoTerminalShell`(volatile,**默认开**;旧宿主 settings 命名空间同名字段,缺键 = 开)+ 21 语言卡片文案
|
|
65
143
|
(`term.label`/`term.hint`);保留原 `dsh-better-sidebar` 通道(两条通道各自独立探测);不碰官方包、不手写用户 patch 文件。
|
|
66
144
|
- README 新增该节 + **用户三步复验清单**(开关与日志 → 终端里 `uname -r` 判 `MINGW64_NT-*` → 回退办法)。
|
|
145
|
+
**(判据有误,见 v0.29.2 更正:Git Bash 的 `uname -r` 是 MSYS 运行时版本,应看 `uname -s` / `$MSYSTEM`。)**
|
|
67
146
|
**回退语义写明**:关掉开关**只阻止以后的自动写入**,**不会**删除已经写进配置的 `shell` 字段;要彻底恢复原样需删掉
|
|
68
147
|
profile patch 里 `terminal-controller` 行的 `shell` 字段并重启(21 语言卡片 hint 同步写上这一句)。
|
|
69
148
|
**菜单如实说明**:未改 `shellCandidates` ⇒ 选择菜单里**仍可能列出**解析到 WSL 的候选 `bash`,被改的是**默认项/首项**。
|
|
@@ -78,7 +157,7 @@
|
|
|
78
157
|
- 用户显式指向 `C:/Windows/System32/bash.exe` ⇒ `NOT adopted … an explicit choice is never overwritten`,patch **未变**;
|
|
79
158
|
- `autoTerminalShell: false` ⇒ `adoption is off …`,patch **未变**;
|
|
80
159
|
- 无头浏览器零 pageerror。
|
|
81
|
-
- **未在 Windows 验证**:真实 PATH/注册表命中、菜单里 shell 项、新终端里 `uname -r` 是否 `MINGW64_NT
|
|
160
|
+
- **未在 Windows 验证**:真实 PATH/注册表命中、菜单里 shell 项、新终端里 `uname -r` 是否 `MINGW64_NT-*`(判据有误,见 v0.29.2);
|
|
82
161
|
设置卡新增开关行的截图级渲染(该行复用既有开关写法,21 语言键由冒烟 parity 覆盖)。需用户按 README 三步复验。
|
|
83
162
|
- 相关:issue #11 后续(同一用户的 Windows 实测反馈)
|
|
84
163
|
|
package/README.md
CHANGED
|
@@ -169,7 +169,11 @@ DSH 自己的「新建终端」**不经过**本插件的执行器:它由官方
|
|
|
169
169
|
**三步复验(Windows)**:
|
|
170
170
|
1. 装好 Git for Windows,重启 DSH,打开本插件设置卡:开关「自动接管侧栏终端」为开;宿主日志出现
|
|
171
171
|
`official sidebar terminal switched to Git Bash: …`。
|
|
172
|
-
2.
|
|
172
|
+
2. 新建终端,在终端里确认**它确实是 Git Bash**(两条判据任选,**`uname -s` 最硬**):
|
|
173
|
+
- `uname -s` ⇒ `MINGW64_NT-10.0-<build>`(Git Bash 的 system name;WSL 这里是 `Linux`);
|
|
174
|
+
- `echo $MSYSTEM` ⇒ `MINGW64`(最简)。
|
|
175
|
+
⚠️ **不要用 `uname -r` 判定**:Git Bash / MSYS2 下它是 **MSYS 运行时版本**(形如 `3.6.9-b4195d69.x86_64`,
|
|
176
|
+
真实用户实测就是这个值),而 **WSL 的 `uname -r`** 才是 `6.x.y.z-microsoft-standard-WSL2` —— 两者都不能单独用来判定。
|
|
173
177
|
3. **回退**:⚠️ 关掉设置卡里的开关**只阻止以后的自动写入,不会删除已经写进配置的字段**。要彻底恢复原样,
|
|
174
178
|
请把 profile 的 patch 里 `terminal-controller` 行的 `shell` 字段**删掉**,再重启 DSH(终端随即回到原来的 shell);
|
|
175
179
|
只想让它别再自动改、但不介意保留现状的话,关开关即可。
|
package/README_EN.md
CHANGED
|
@@ -185,6 +185,26 @@ assembly, so zero prompt noise), path arguments and result metadata are no longe
|
|
|
185
185
|
the file tools receive Windows paths. **Bash stays Git Bash either way** — the switch only
|
|
186
186
|
governs the cross-tool path dialect.
|
|
187
187
|
|
|
188
|
+
## Sidebar terminal (v0.29.0+): the official "new terminal" runs Git Bash
|
|
189
|
+
|
|
190
|
+
dsh's own terminal is resolved by the official `terminal-controller` row, not by this plugin's executor. On a machine
|
|
191
|
+
whose PATH `bash` is the WSL launcher, that terminal used to start Ubuntu. This plugin now writes the verified Git Bash
|
|
192
|
+
into that row (only when the row has no shell of its own — an explicit choice is never overwritten; the display name is
|
|
193
|
+
`Git Bash` so it cannot be confused with the WSL candidate, which is left in the menu). `shellCandidates` is untouched.
|
|
194
|
+
|
|
195
|
+
**Three-step check (Windows)**
|
|
196
|
+
|
|
197
|
+
1. Install Git for Windows, restart dsh, open this plugin's settings card: the "adopt the sidebar terminal" switch is on
|
|
198
|
+
and the host log shows `official sidebar terminal switched to Git Bash: …`.
|
|
199
|
+
2. Open a new terminal and confirm it really is Git Bash (either check works; **`uname -s` is the hardest**):
|
|
200
|
+
- `uname -s` ⇒ `MINGW64_NT-10.0-<build>` (Git Bash's system name; WSL prints `Linux`);
|
|
201
|
+
- `echo $MSYSTEM` ⇒ `MINGW64` (simplest).
|
|
202
|
+
⚠️ **Do not judge by `uname -r`**: under Git Bash / MSYS2 it is the **MSYS runtime version** (e.g.
|
|
203
|
+
`3.6.9-b4195d69.x86_64`), whereas WSL prints `6.x.y.z-microsoft-standard-WSL2` — neither can decide this alone.
|
|
204
|
+
3. **Revert**: turning the switch off only stops FUTURE writes; it does not remove the `shell` field already written to
|
|
205
|
+
the profile config. To restore the original exactly, delete that field from the `terminal-controller` row in the
|
|
206
|
+
profile patch and restart dsh.
|
|
207
|
+
|
|
188
208
|
## Cooperation with dsh-better-sidebar
|
|
189
209
|
|
|
190
210
|
When [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) (v0.15.2+) is installed, on Windows this plugin adopts its official runtime settings seam (`terminalShell` — by the sidebar's own contract, "settings-page overrides win for terminals opened afterwards"), so both the sidebar's UI terminal tabs and the model-facing `terminal_*` tools open Git Bash — no upstream change, new terminals pick it up immediately. In addition, this bundle's patch also sets `config.shell` on the sidebar's row (boot-time resolution, so the **tab label reads `bash` too**; the row edit is harmless-skipped when the sidebar is not installed). Rules:
|
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-external/dsh-gitbash-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"description": "Windows 全模式 Git Bash:用 Git for Windows bash 替换 PowerShell 执行器,并物化 standard/minimal/code/cordis 的 Git Bash 变体 preset。双 era 适配 dsh <= 0.1.1(内置 id 'code')与 >= 0.1.2(改名 'ptc'),启动探测自动选择,preset id 永不变。联动:dsh-ptc-cordis-preset(两者同装时 PTC 创造模式自动物化为 Git Bash 版)+ dsh-better-sidebar(终端 UI 标签与模型 terminal_* 工具自动切到 Git Bash)。",
|
|
6
6
|
"engines": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-gitbash-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "Windows 上让 agent 的每条 shell 命令改经 Git for Windows bash 执行;物化四个内置预设的 Git Bash 变体,统一 MSYS 盘根路径方言,侧栏终端接管可开关。· Run every agent shell command through Git for Windows bash on Windows; materialize Git Bash variants of the built-in presets, unify the MSYS drive-root path dialect, and adopt the sidebar terminal behind a switch.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|