dsh-bash-terminal-ts 0.4.0 → 0.6.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.en.md CHANGED
@@ -1,197 +1,88 @@
1
- # dsh-bash-terminal-ts
1
+ # dsh-bash-terminal
2
2
 
3
- [![test](https://github.com/drscrewdriver/dsh-bash-terminal-ts/actions/workflows/test.yml/badge.svg)](https://github.com/drscrewdriver/dsh-bash-terminal-ts/actions/workflows/test.yml)
3
+ > Community: [LINUX DO](https://linux.do) · [GitHub](https://github.com/drscrewdriver/dsh-bash-terminal-ts)
4
4
 
5
- **English** | [日本語](README.ja.md) | [한국어](README.ko.md) | [中文](README.md)
5
+ A DeepSeek Harness (DSH) plugin: one `shell` tool that runs commands through **PowerShell / Git Bash / MSYS2 / WSL** on Windows, plus an **interactive terminal** tool — all following the terminal **you** choose in the Web UI settings.
6
6
 
7
- A DSH (DeepSeek Harness) plugin: a single `shell` tool that runs **PowerShell / Git Bash / MSYS2 / WSL** commands through one unified entry point on Windows.
7
+ ![test](https://github.com/drscrewdriver/dsh-bash-terminal-ts/actions/workflows/test.yml/badge.svg)
8
8
 
9
- The terminal is **selected by you in the Web UI** — the model cannot change it. Pick one once, and every command from then on runs through it.
9
+ > **TypeScript rewrite of `MAXeaglet/dsh-bash-terminal`**, with working MSYS2/MINGW64 support. Two compatibility lines:
10
+ >
11
+ > | Branch | DSH segment | Package name | Status |
12
+ > |--------|-------------|--------------|--------|
13
+ > | `ts/0.1.5` | 0.1.5-alpha.1 – 0.1.5-rc.x | `dsh-bash-terminal` | this branch; `build` / `unit` / `apply` / `client` / `terminal` green locally |
14
+ > | `main` | 0.1.2-alpha.1 – 0.1.2-rc.x | `dsh-bash-terminal-ts` | the TypeScript rewrite's mainline |
15
+ >
16
+ > The two lines **deliberately use different package names**, so they install side by side without overwriting each other. Pick the branch that covers your DSH build.
10
17
 
11
- ## Why use it
18
+ ## Features
12
19
 
13
- | Selling point | In one line |
14
- |------|--------|
15
- | **MSYS2 genuinely works** | This isn't "a new dropdown option" — it gets three things right at once: `bash.exe` resolution, the login shell, and the `MSYSTEM` environment. Pick MSYS2 and `gcc` / `make` just work (see "MSYS2 support" below) |
16
- | **TypeScript source** | `strict` + `noUncheckedIndexedAccess`; pure functions build argv/env and are unit-testable |
17
- | **Targets DSH 0.1.2 as the primary version** | `engines.dsh: >=0.1.2-rc.1 <0.2.0-0`, built against the 0.1.2 `ctx.subprocess` / `ctx.sandbox` / PTY seams |
18
- | **Four terminals, one tool** | A single `shell` tool covers PowerShell / Git Bash / MSYS2 / WSL, so the model never has to learn four parameter sets |
19
- | **Sandbox aligned with the official mechanism** | Uses the official `ctx.sandboxPolicy` + `ctx.sandbox`, fail-closed, and surfaces the same-turn escalation hint when a call is denied |
20
- | **Interactive terminal** | A separate real-PTY session tool: `open / send / read / signal / close`, with Ctrl+C support and state that survives across turns |
21
-
22
- ## Supported backends
23
-
24
- | Backend | What actually runs | Syntax / paths | Environment variables |
25
- |------|----------|-------------|----------|
26
- | `powershell` (default) | `pwsh -NoLogo -NoProfile -NonInteractive -Command <cmd>` | PowerShell; `C:\...` | `$env:NAME` |
27
- | `gitbash` | Git for Windows `bash -lc <cmd>` | POSIX; `/d/WorkSpace`; PATH includes `/usr/bin`, `/mingw64/bin` | `$NAME` |
28
- | `msys2` | `C:\msys64\usr\bin\bash.exe -lc <cmd>` (login shell; `MSYSTEM=MINGW64`) | POSIX; ships a full GCC / mingw64 toolchain | `$NAME` |
20
+ | Backend | Runs | Syntax / paths | Env vars |
21
+ |---------|------|----------------|----------|
22
+ | `powershell` (default) | `pwsh -NoLogo -NoProfile -NonInteractive -Command <cmd>` | PowerShell; `C:\\...` | `$env:NAME` |
23
+ | `gitbash` | Git for Windows `bash -lc <cmd>` | POSIX; `/d/workspace`; PATH includes `/usr/bin` and `/mingw64/bin` | `$NAME` |
24
+ | `msys2` | MSYS2 `bash -lc <cmd>` (`C:\msys64\usr\bin\bash.exe`) | POSIX; `/c/...`; PATH includes `/usr/bin` and `/mingw64/bin` (gcc / make) | `$NAME` (MSYSTEM=MINGW64 injected) |
29
25
  | `wsl` | `wsl [-d <distro>] -e bash -lc <cmd>` | Linux; `/mnt/d/...` | `$NAME` (via WSLENV) |
30
26
 
31
- Every call spins up a fresh shell: **no state is preserved** (cwd / variables / aliases) — pass `workdir` instead of using `cd`. Use the interactive terminal tool when you need state to persist across turns.
32
-
33
- ## MSYS2 support
34
-
35
- MSYS2 looks like "just one more backend", but it actually hides three traps, and the plugin handles each one:
36
-
37
- **1. You cannot launch `msys2.exe`.**
38
- `C:\msys64\msys2.exe` is a Cygwin launcher that allocates a console window. This plugin spawns processes with piped stdio (the standard DSH approach), and under those conditions it **exits 0 while returning zero bytes of output** — the command fails silently, appearing to "succeed" while doing nothing at all. So the candidate order is `usr\bin\bash.exe` → `bin\bash.exe` → `msys2.exe` as a fallback, and **a usable `bash.exe` always wins**.
39
-
40
- **2. `-lc` is not optional.**
41
- Only a login shell reads `/etc/profile`, and only `/etc/profile` adds `/usr/bin` and `/mingw64/bin` to PATH. With a bare `-c`, `tr`, `sed`, and `gcc` all come back as `command not found`.
42
-
43
- **3. `MSYSTEM=MINGW64` has to be injected.**
44
- Otherwise `/etc/profile` initializes with the default MSYS environment and the gcc and make in `/mingw64/bin` are unavailable. The plugin injects it through `buildEnv` (**values you set explicitly take precedence**), and the `shell` tool and the interactive terminal share that same `buildEnv` — so you never hit a "works in the tool but not in the terminal" discrepancy.
45
-
46
- Verified in practice (real PTY): the prompt changes from `MSYS` to `MINGW64`, and `command -v gcc` → `/mingw64/bin/gcc`.
47
-
48
- All three are guarded by regression tests: `test/unit.ts` asserts that `bash.exe` is ordered before `msys2.exe`; `test/apply.ts` asserts that the PTY environment contains `MSYSTEM=MINGW64` and that it does not leak into gitbash.
27
+ - **User decides, the AI cannot override**: pick the default terminal in Settings -> General -> Default terminal (PowerShell / Git Bash / MSYS2 / WSL). The setting persists through the DSH settings system; the `shell` tool always obeys it.
28
+ - **Official sandbox seam**: the `shell` tool resolves the DSH sandbox policy per call and confines PowerShell argv through `ctx.sandbox` — same fail-closed `SandboxUnavailableError` semantics as the shipped executors. Git Bash, MSYS2 and WSL run unconfined: WSL is its own Linux VM, while Git Bash and MSYS2 cannot run under the DSH Windows ACL restricted-token runner (Cygwin/MSYS2 aborts with `CreateFileMapping` Win32 error 5). Official `sandbox_permissions` / `justification` escalation and denial markers included.
29
+ - **Interactive terminal**: the `terminal` tool opens persistent real-PTY sessions over node-pty — on non-Windows via the official `ctx.subprocess.spawnTerminal` seam, on Windows directly through node-pty because the upstream seam's process inspector is POSIX-only. Actions `open` / `send` / `read` / `signal` / `close`; shell state persists across calls; sessions are managed as background jobs and auto-close when idle.
30
+ - **Background execution** via the generic jobs registry (`run_in_background` / `job_output` / `job_kill`).
49
31
 
50
- ## Design notes
32
+ ## Screenshots
51
33
 
52
- - **The terminal is the user's decision, and the AI cannot change it**: the Web UI settings page (Settings → General) shows a "Default terminal" dropdown (PowerShell / Git Bash / MSYS2 / WSL); the `shell` tool always uses that setting and never exposes a terminal parameter to the model. The setting persists through the DSH settings system (settings.yaml).
53
- - **It does not take over the `ctx.shell` capability seam**: DSH's built-in sandboxed `pwsh` tool stays available as-is; this plugin's `shell` tool is an **additional** multi-terminal entry point.
54
- - Processes are spawned through the shared `ctx.subprocess` seam: process-tree termination (Windows `taskkill /T`), SIGTERM → grace → SIGKILL, and output spill files, matching the behavior of the official `dsh-tool-bash` / `dsh-tool-pwsh`.
55
- - Background tasks register with the generic `jobs` registry and support `run_in_background` / `job_output` / `job_kill`.
56
- - The tool's `shell` parameter is an enum (the UI renders it as a dropdown), and the model chooses a terminal on each call.
57
- - The `<option>` entries for the four backends in the frontend dropdown, along with the `shell.<id>` strings in both locale bundles, are covered by drift-guard tests — add a backend and forget the copy, and the tests fail immediately.
34
+ The **Default terminal** row in Settings -> General: the user picks PowerShell / Git Bash / MSYS2 / WSL, and the `shell` tool obeys that choice — the model cannot override it.
58
35
 
59
- ## Installation
36
+ ![Default terminal setting row](assets/shells.png)
60
37
 
61
- ### Standard install (npm)
38
+ ## Install
62
39
 
63
- ```powershell
64
- # 1. Install the plugin package
65
- npm install -g dsh-bash-terminal-ts
66
- dsh plugin --profile web add dsh-bash-terminal-ts
67
-
68
- # 2. Patch the DSH settings allowlist (a DSH limitation, see the note below; install.ps1 can run this step on its own)
69
- powershell -ExecutionPolicy Bypass -File install.ps1 install
70
-
71
- # 3. Restart dsh web
72
- ```
73
-
74
- ### Local development install (junction-linked, source edits take effect immediately)
40
+ The package ships the official `dsh.bundle` manifest (its own `cordis.patch.yml`): listing `dsh-bash-terminal` in a profile's `dsh.profile.bundles` auto-applies the mount — no manual profile edits.
75
41
 
76
42
  ```powershell
77
- # 1. Link the plugin package into the profile's node_modules (junction, so source edits take effect immediately)
78
- $profile = "$env:USERPROFILE\.dsh\profiles\web"
79
- New-Item -ItemType Junction -Path "$profile\node_modules\dsh-bash-terminal-ts" -Target "D:\WorkSpace\projects\dsh-bash-terminal-ts" | Out-Null
80
-
81
- # 2. Let the plugin resolve its @deepseek-ai/* dependencies (junction into the profile's dependency tree)
82
- New-Item -ItemType Junction -Path "D:\WorkSpace\projects\dsh-bash-terminal-ts\node_modules\@deepseek-ai" -Target "$profile\..\node_modules\@deepseek-ai" | Out-Null
83
-
84
- # 3. Append the mount line to cordis.patch.yml (see the patch snippet below)
85
- # 4. (Only after changing frontend source) rebuild the client bundle:
86
- # cd D:\WorkSpace\projects\dsh-bash-terminal-ts && node scripts/build-client.mjs
87
- # 5. Let the settings UI accept this plugin's settings writes (a DSH limitation, see the note below)
88
- # 6. Restart dsh web
89
- ```
90
-
91
- > **DSH settings UI allowlist limitation**: DSH's api-gateway (dsh-host-apiproxy) enforces a
92
- > **hardcoded allowlist** of the settings namespaces exposed to the Web settings client
93
- > (third-party plugin settings are rejected with `settings-not-exposed` by default, so
94
- > changes made in the UI silently do nothing).
95
- > install.ps1 patches that allowlist automatically (adding `bash-terminal`, after backing up
96
- > the original file). **You must re-run install.ps1 after upgrading DSH** to restore the
97
- > patch. On uninstall, install.ps1 reverts it.
98
-
99
- Add to `cordis.patch.yml`:
100
-
101
- ```yaml
102
- - insert:
103
- - id: tool-bash-terminal
104
- name: 'dsh-bash-terminal-ts'
43
+ npm install -g dsh-bash-terminal
44
+ dsh plugin --profile web add dsh-bash-terminal # adds to profile bundles + applies the patch
45
+ powershell -ExecutionPolicy Bypass -File install.ps1 install # patches the DSH settings-UI allowlist (see below)
46
+ # restart dsh web
105
47
  ```
106
48
 
107
- Verify the composition tree (no restart required):
49
+ > **DSH limitation**: the Web settings client only exposes a hard-coded allowlist of settings namespaces (`dsh-host-apiproxy`); third-party settings writes are refused with `settings-not-exposed` otherwise. `install.ps1` patches the allowlist (with a backup) — re-run it after upgrading DSH; `install` / `uninstall` restores it.
108
50
 
109
- ```powershell
110
- node "$env:APPDATA\nvm\v24.16.0\node_modules\@deepseek-ai\dsh\lib\bin.js" --profile web --dump-config | Select-String dsh-bash-terminal-ts
111
- ```
51
+ For local development (junction install, source changes apply instantly) see the Chinese README's development section.
112
52
 
113
- ## Usage
53
+ ## Sandbox
114
54
 
115
- **The user sets the default terminal in the Web UI**: open Settings (gear icon) → General → the "Default terminal" dropdown, and choose one of PowerShell / Git Bash / MSYS2 / WSL. The change takes effect immediately and is persisted.
55
+ - `danger-full-access` sessions run directly (no wrapping).
56
+ - Confined sessions wrap PowerShell argv through `ctx.sandbox.confine`; fail-closed when no backend is available.
57
+ - Git Bash is never wrapped: the Windows ACL restricted-token runner cannot host Cygwin/MSYS2 (`CreateFileMapping` Win32 error 5); results report `enforcement: gitbash-unconfined`.
58
+ - MSYS2 is never wrapped either (same Cygwin/MSYS2 runtime incompatibility); results report `enforcement: msys2-unconfined`.
59
+ - WSL is never wrapped (its VM isolation is the sandbox; results report `enforcement: wsl-isolation`).
60
+ - Denied calls render the official `[sandbox: file access denied under <mode> mode]` marker plus a same-turn escalation hint; the model may retry once with `sandbox_permissions` + `justification` (user-approved via `ctx.approval`).
61
+ - Note: when DSH's Windows ACL runner is available, it confines PowerShell; Git Bash and MSYS2 remain unconfined due to the Cygwin/MSYS2 incompatibility.
116
62
 
117
- Once the model sees the `shell` tool, it automatically runs commands through the terminal you selected (the tool exposes no terminal parameter, so the model cannot override your choice):
63
+ ## Interactive terminal
118
64
 
119
- - Default terminal = Git Bash: `shell(command: "git status")` runs through Git Bash
120
- - Default terminal = MSYS2: `shell(command: "gcc --version")` runs through MSYS2 (login shell, PATH includes `/usr/bin` and `/mingw64/bin`, with a full GCC / mingw64 toolchain)
121
- - Default terminal = WSL: `shell(command: "ls -la /mnt/d/WorkSpace")` runs through WSL; pass `distro: "Ubuntu"` to target a specific distribution
122
- - Default terminal = PowerShell: `shell(command: "Get-Process node")` runs through PowerShell
65
+ `terminal` actions: `open` (start a session on the configured default terminal), `send` (write input + read new output), `read`, `signal` (SIGINT = Ctrl+C etc.), `close`, `list` (enumerate live sessions). Reads wait for output to settle (quiet 300ms, cap 5s) so `send` returns the complete reply; buffer overflow reports a `truncated` notice. State (cwd / variables / aliases) persists across calls; end input with `\\n`. Sessions are background jobs (`job_kill` works) and auto-close after 10 idle minutes (`idleMs` overrides on open).
123
66
 
124
- ## Configuration
67
+ ## Interactive terminal known limits (ConPTY)
125
68
 
126
- **Web UI settings** (recommended): Settings → General → "Default terminal".
69
+ - **Windows PowerShell 5.1 cannot start in a ConPTY** (0x8009001d) — install [PowerShell 7](https://github.com/PowerShell/PowerShell/releases) for interactive PowerShell (one-shot commands are unaffected).
70
+ - **wsl.exe interactive mode may hit a WSL service RPC error under ConPTY** (0x8007072c, intermittent) — one-shot `wsl -e bash -lc ...` works; for interactive WSL prefer a real terminal (Windows Terminal / WSL app) or retry.
71
+ - **node-pty accepts no named signals on Windows**: `signal` maps `SIGINT` to Ctrl+C (`\x03`); other signals (`SIGTERM` / `SIGKILL` / `SIGTSTP` / `SIGHUP`) degrade to terminating the session.
72
+ - Git Bash interactive sessions work fully.
127
73
 
128
- The plugin row's `config` (overrides the defaults and forms the composition baseline for the setting):
74
+ ## Config
129
75
 
130
- | Key | Default | Description |
131
- |----|------|------|
132
- | `defaultShell` | `powershell` | The backend used when the setting does not override it |
133
- | `timeoutMs` | 120000 | Default timeout |
134
- | `maxTimeoutMs` | 600000 | Upper bound for a caller-supplied timeoutMs |
135
- | `pwshPath` | auto-detected | Pin the pwsh.exe path |
136
- | `gitBashPath` | auto-detected | Pin the git bash.exe path |
137
- | `msys2Path` | auto-detected | Pin the MSYS2 entry path (must point at `bash.exe`, not `msys2.exe`; see "MSYS2 support") |
138
- | `wslPath` | auto-detected | Pin the wsl.exe path |
76
+ Web UI: Settings -> General -> Default terminal. Plugin row `config` overrides: `defaultShell`, `timeoutMs`, `maxTimeoutMs`, `pwshPath`, `gitBashPath`, `msys2Path`, `wslPath`.
139
77
 
140
78
  ## Uninstall
141
79
 
142
80
  ```powershell
143
- Remove-Item "$env:USERPROFILE\.dsh\profiles\web\node_modules\dsh-bash-terminal-ts" -Force
144
- # Then delete the insert block from cordis.patch.yml and restart dsh web
81
+ powershell -ExecutionPolicy Bypass -File install.ps1 uninstall
145
82
  ```
146
83
 
147
- ## Sandbox (official mechanism integration)
148
-
149
- The `shell` tool goes through DSH's official sandbox seams (`ctx.sandboxPolicy` + `ctx.sandbox`):
150
-
151
- - Every call resolves the current sandbox policy; `danger-full-access` sessions execute directly (unwrapped).
152
- - The PowerShell / Git Bash / MSYS2 backends wrap argv through `ctx.sandbox.confine` — with the same **fail-closed** semantics as the official executor: requesting a confined mode with no backend available throws `SandboxUnavailableError` rather than falling back to an unconfined run.
153
- - The WSL backend is not wrapped: a WSL instance is its own isolated Linux VM (results report `enforcement: wsl-isolation`).
154
- - When a confined mode denies the call, the result carries the official marker `[sandbox: file access denied under <mode> mode]` along with the same-turn escalation hint; the model can request a single escalation using `sandbox_permissions` + `justification` (approved by the user through `ctx.approval`), exactly as with the official bash/pwsh tools.
155
- - Note: DSH's Windows ACL sandbox launcher (`node-addon-landlock-run-win32-x64`) is not published to npm yet, so the native sandbox backend is currently unavailable; the architecture is ready and activates automatically once DSH ships it.
156
-
157
- ## ⚠️ Security notes
158
-
159
- Commands run by the `shell` tool **outside the DSH sandbox**, with the same privileges as the dsh process
160
- (equivalent to full-access command execution), and they do not benefit from the `pwsh` tool's
161
- ConstrainedLanguage restrictions. DSH's file operation tools (read/write/edit) remain bound by the file sandbox.
162
- Use this only in sessions you trust; when you need sandbox-protected PowerShell, keep using the official `pwsh` tool.
163
-
164
- ## Known limitations
165
-
166
- - The plugin only registers its tool on the `win32` platform.
167
- - A WSL background process may briefly linger inside the distribution after a timeout or interruption (the WSL instance shuts down automatically once its last process exits).
168
- - Git Bash and MSYS2 are both msys2 environments, so their behavior differs from WSL's Linux behavior (path mapping, package availability).
169
- - If `C:\msys64` is installed in a non-default location and is not on PATH, `msys2Path` must be configured explicitly.
170
-
171
- ## Testing
84
+ ## Tests
172
85
 
173
86
  ```powershell
174
- git clone https://github.com/drscrewdriver/dsh-bash-terminal-ts.git
175
- cd dsh-bash-terminal-ts
176
- npm install # install dependencies (including typescript)
177
- npm run build # tsc compiles src/*.ts → lib/*.js; client.tsx → dist/client.js; test/*.ts → test-dist/
178
- npm test # node test-dist/unit.js → apply.js → client.js
87
+ node test/unit.mjs && node test/apply.mjs && node test/client.mjs && node test/terminal.mjs
179
88
  ```
180
-
181
- CI runs the same suite on `windows-latest` (`.github/workflows/test.yml`).
182
-
183
- ## Technical implementation
184
-
185
- Requirements: **Node.js 22+ (24 recommended)**, DSH 0.1.2+.
186
-
187
- The source is TypeScript (`strict` + `noUncheckedIndexedAccess`), and the compiled artifacts `lib/` and `dist/` are committed alongside the repository, so DSH loads `lib/index.js` directly and the plugin **works without a build step**.
188
-
189
- All require-side dependencies (13 packages, `@deepseek-ai/*` and friends) are declared as `peerDependencies` + `peerDependenciesMeta.optional`, avoiding a duplicate install alongside the host's own copies.
190
-
191
- ## Credits
192
-
193
- This project evolves from [MAXeaglet/dsh-bash-terminal](https://github.com/MAXeaglet/dsh-bash-terminal) — the original `shell` tool, the three-backend PowerShell / Git Bash / WSL architecture, and the sandbox seam integration all come from the original author, MAXeaglet. This version builds on that work by adding the MSYS2 backend, a TypeScript rewrite, and DSH 0.1.2 support.
194
-
195
- ## License
196
-
197
- MIT
package/README.md CHANGED
@@ -1,51 +1,34 @@
1
- # dsh-bash-terminal-ts
1
+ # dsh-bash-terminal
2
2
 
3
- [![test](https://github.com/drscrewdriver/dsh-bash-terminal-ts/actions/workflows/test.yml/badge.svg)](https://github.com/drscrewdriver/dsh-bash-terminal-ts/actions/workflows/test.yml)
3
+ > 🌐 [English](README.en.md) · 社区交流:[LINUX DO](https://linux.do) · [GitHub](https://github.com/drscrewdriver/dsh-bash-terminal-ts)
4
4
 
5
- [English](README.en.md) | [日本語](README.ja.md) | [한국어](README.ko.md) | **中文**
5
+ ![test](https://github.com/drscrewdriver/dsh-bash-terminal-ts/actions/workflows/test.yml/badge.svg)
6
6
 
7
7
  DSH(DeepSeek Harness)插件:一个 `shell` 工具,在 Windows 上统一执行 **PowerShell / Git Bash / MSYS2 / WSL** 四种终端命令。
8
8
 
9
- 终端由**你在 Web UI 里选**,模型不能改。选一次,之后所有命令都按你选的终端跑。
10
-
11
- ## 为什么用它
12
-
13
- | 卖点 | 一句话 |
14
- |------|--------|
15
- | **MSYS2 真的能用** | 不是"加了个下拉选项",而是把 `bash.exe` 解析、登录 shell、`MSYSTEM` 环境三件事都做对了 —— 选 MSYS2 就能直接 `gcc`、`make`(见下方「MSYS2 支持」) |
16
- | **TypeScript 源码** | `strict` + `noUncheckedIndexedAccess`;纯函数负责 argv/env 构造,可单测 |
17
- | **以 DSH 0.1.2 为主版** | `engines.dsh: >=0.1.2-rc.1 <0.2.0-0`,随 0.1.2 的 `ctx.subprocess` / `ctx.sandbox` / PTY 接缝构建 |
18
- | **四种终端一个工具** | 同一套 `shell` 工具覆盖 PowerShell / Git Bash / MSYS2 / WSL,模型不用学四套参数 |
19
- | **沙箱对齐官方** | 走官方 `ctx.sandboxPolicy` + `ctx.sandbox`,fail-closed,拒绝时给出同轮升级提示 |
20
- | **交互式终端** | 另有真 PTY 会话工具:`open / send / read / signal / close`,可 Ctrl+C,跨轮保持状态 |
21
-
22
- ## 支持的后端
9
+ > **本仓库是 `MAXeaglet/dsh-bash-terminal` 的 TypeScript 重写**,带可用的 MSYS2/MINGW64 支持。两条兼容线:
10
+ >
11
+ > | 分支 | DSH 段 | 包名 | 状态 |
12
+ > |------|--------|------|------|
13
+ > | `ts/0.1.5` | 0.1.5-alpha.1 – 0.1.5-rc.x | `dsh-bash-terminal` | 本分支;`build` / `unit` / `apply` / `client` / `terminal` 本机全绿 |
14
+ > | `main` | 0.1.2-alpha.1 – 0.1.2-rc.x | `dsh-bash-terminal-ts` | TypeScript 重写主线 |
15
+ >
16
+ > **两条线刻意使用不同包名**,因此可以并存安装、互不覆盖。请按你的 DSH 版本选分支。
23
17
 
24
18
  | 后端 | 实际执行 | 语法 / 路径 | 环境变量 |
25
19
  |------|----------|-------------|----------|
26
20
  | `powershell`(默认) | `pwsh -NoLogo -NoProfile -NonInteractive -Command <cmd>` | PowerShell;`C:\...` | `$env:NAME` |
27
- | `gitbash` | Git for Windows `bash -lc <cmd>` | POSIX;`/d/WorkSpace`;PATH 含 `/usr/bin`、`/mingw64/bin` | `$NAME` |
28
- | `msys2` | `C:\msys64\usr\bin\bash.exe -lc <cmd>`(登录 shell;`MSYSTEM=MINGW64`) | POSIX;自带完整 GCC / mingw64 工具链 | `$NAME` |
21
+ | `gitbash` | Git for Windows `bash -lc <cmd>` | POSIX;`/d/workspace`;PATH 含 `/usr/bin`、`/mingw64/bin` | `$NAME` |
22
+ | `msys2` | MSYS2 `bash -lc <cmd>`(`C:\msys64\usr\bin\bash.exe`) | POSIX;`/c/...`;PATH 含 `/usr/bin`、`/mingw64/bin`(gcc / make) | `$NAME`(自动注入 `MSYSTEM=MINGW64`) |
29
23
  | `wsl` | `wsl [-d <distro>] -e bash -lc <cmd>` | Linux;`/mnt/d/...` | `$NAME`(经 WSLENV) |
30
24
 
31
- 每次调用都启动全新 shell:**不保留状态**(cwd / 变量 / 别名)—— 请传 `workdir` 而不是用 `cd`。需要跨轮保持状态时用交互式终端工具。
32
-
33
- ## MSYS2 支持
34
-
35
- MSYS2 看着只是"再加一个后端",实际有三个坑,插件逐个处理了:
25
+ 每次调用都启动全新 shell:**不保留状态**(cwd / 变量 / 别名)——请传 `workdir` 而不是用 `cd`。
36
26
 
37
- **1. 不能启动 `msys2.exe`。**
38
- `C:\msys64\msys2.exe` 是分配控制台窗口的 Cygwin 启动器。本插件用管道 stdio spawn(这是 DSH 的标准方式),此时它会 **exit 0 返回零字节输出** —— 命令静默失败,看起来"成功"了但什么都没做。所以候选顺序是:`usr\bin\bash.exe` → `bin\bash.exe` → `msys2.exe` 兜底,**可用的 `bash.exe` 永远优先**。
27
+ ## 界面预览
39
28
 
40
- **2. `-lc` 不能省。**
41
- 只有登录 shell 会读 `/etc/profile`,而只有 `/etc/profile` 会把 `/usr/bin` 与 `/mingw64/bin` 加进 PATH。用裸 `-c` 的话 `tr`、`sed`、`gcc` 全是 `command not found`。
29
+ 设置 → 通用 里的「默认终端」行:用户在 PowerShell / Git Bash / MSYS2 / WSL 之间选择,`shell` 工具只按这个设置执行,模型无法覆盖:
42
30
 
43
- **3. 要注入 `MSYSTEM=MINGW64`。**
44
- 否则 `/etc/profile` 按默认 MSYS 环境初始化,`/mingw64/bin` 里的 gcc、make 不可用。插件经 `buildEnv` 注入(**你显式设置的值优先**),并且 `shell` 工具与交互式终端走的是同一个 `buildEnv` —— 不会出现"工具能跑、终端不能跑"的偏差。
45
-
46
- 实测(真 PTY):prompt 从 `MSYS` 变成 `MINGW64`,`command -v gcc` → `/mingw64/bin/gcc`。
47
-
48
- 这三条都有回归测试守着:`test/unit.ts` 断言 `bash.exe` 排在 `msys2.exe` 之前;`test/apply.ts` 断言 PTY 环境含 `MSYSTEM=MINGW64`,且不会泄漏到 gitbash。
31
+ ![默认终端设置行](assets/shells.png)
49
32
 
50
33
  ## 设计要点
51
34
 
@@ -53,59 +36,60 @@ MSYS2 看着只是"再加一个后端",实际有三个坑,插件逐个处理
53
36
  - **不占用 `ctx.shell` 能力接缝**:DSH 自带的沙箱化 `pwsh` 工具保持原样可用;本插件的 `shell` 工具是**额外的**多终端入口。
54
37
  - 通过共享的 `ctx.subprocess` seam 派生进程:进程树终止(Windows `taskkill /T`)、SIGTERM→grace→SIGKILL、输出 spill 文件,与官方 `dsh-tool-bash` / `dsh-tool-pwsh` 行为一致。
55
38
  - 后台任务注册进通用 `jobs` registry,支持 `run_in_background` / `job_output` / `job_kill`。
56
- - 工具参数 `shell` 是枚举(UI 自动渲染为下拉),模型每次调用自行选择终端。
57
- - 四种后端在前端下拉里的 `<option>`、以及两种语言包里的 `shell.<id>` 文案,都有 drift 守卫测试 —— 加后端忘了改文案会直接测试失败。
39
+ - 前端设置页的「默认终端」是枚举(UI 自动渲染为下拉),模型每次调用都只按该设置执行,无法自行切换终端。
58
40
 
59
- ## 安装
41
+ ## 安装(web profile)
60
42
 
61
- ### 标准安装(npm)
43
+ ### 标准安装(npm 发布后,官方 bundle 机制)
44
+
45
+ 插件带官方 `dsh.bundle` manifest(包内 `cordis.patch.yml`),profile 列出本包时 DSH **自动应用挂载**,无需手改 profile 配置:
62
46
 
63
47
  ```powershell
64
48
  # 1. 安装插件包
65
- npm install -g dsh-bash-terminal-ts
66
- dsh plugin --profile web add dsh-bash-terminal-ts
49
+ npm install -g dsh-bash-terminal
50
+ dsh plugin --profile web add dsh-bash-terminal # 自动加进 profile 的 bundles 并应用 patch
67
51
 
68
- # 2. patch DSH 设置白名单(DSH 限制,见下方说明;install.ps1 可单独执行此步)
52
+ # 2. patch DSH 设置白名单(DSH 限制,见下方说明)
69
53
  powershell -ExecutionPolicy Bypass -File install.ps1 install
70
54
 
71
55
  # 3. 重启 dsh web
72
56
  ```
73
57
 
58
+ > 已用临时 profile 实测:`bundles: [dsh-bash-terminal]` → dump-config 自动出现 `tool-bash-terminal` entry。
59
+
74
60
  ### 本地开发安装(junction 直连,改源码即时生效)
75
61
 
76
62
  ```powershell
77
63
  # 1. 链接插件包到 profile 的 node_modules(junction,改源码即时生效)
78
64
  $profile = "$env:USERPROFILE\.dsh\profiles\web"
79
- New-Item -ItemType Junction -Path "$profile\node_modules\dsh-bash-terminal-ts" -Target "D:\WorkSpace\projects\dsh-bash-terminal-ts" | Out-Null
65
+ New-Item -ItemType Junction -Path "$profile\node_modules\dsh-bash-terminal" -Target "D:\workspace\projects\dsh-bash-terminal" | Out-Null
80
66
 
81
- # 2. 让插件能解析 @deepseek-ai/* 依赖(junction 到 profile 的依赖树)
82
- New-Item -ItemType Junction -Path "D:\WorkSpace\projects\dsh-bash-terminal-ts\node_modules\@deepseek-ai" -Target "$profile\..\node_modules\@deepseek-ai" | Out-Null
67
+ # 2. 让插件能解析 @deepseek-ai/* 依赖(junction 到 profile 的依赖树,插件与宿主共用同一份模块实例)
68
+ New-Item -ItemType Junction -Path "D:\workspace\projects\dsh-bash-terminal\node_modules\@deepseek-ai" -Target "$profile\..\node_modules\@deepseek-ai" | Out-Null
83
69
 
84
- # 3. 在 cordis.patch.yml 追加挂载行(见下方 patch 片段)
70
+ # 3. 让 profile 通过官方 bundle 挂载插件(install.ps1 install 会自动做;等价于在 dsh.profile.bundles 加 "dsh-bash-terminal")
85
71
  # 4. (仅修改前端源码后)重新打包 client bundle:
86
- # cd D:\WorkSpace\projects\dsh-bash-terminal-ts && node scripts/build-client.mjs
87
- # 5. 让设置 UI 接受本插件的设置写入(DSH 限制,见下方说明)
88
- # 6. 重启 dsh web
72
+ # cd D:\workspace\projects\dsh-bash-terminal && node scripts/build-client.mjs
73
+ # 5. 重启 dsh web
89
74
  ```
90
75
 
91
- > **DSH 设置 UI 白名单限制**:DSH 的 api-gateway(dsh-host-apiproxy)对
92
- > Web 设置客户端暴露的 settings namespace 有**硬编码白名单**(第三方插件
93
- > 的设置默认会被 `settings-not-exposed` 拒绝,UI 里改了不生效)。
94
- > install.ps1 会自动 patch 该白名单(加入 `bash-terminal`,先备份原文件)。
95
- > **升级 DSH 后需重新运行 install.ps1** 恢复 patch。卸载时 install.ps1 会还原。
76
+ > ⚠️ **不要在本项目里跑 `npm install`**:它会删掉上面第 2 步的 junction,转而给插件装一份**独立的**
77
+ > `@deepseek-ai/*` 副本 —— 插件和宿主就不再共用模块实例,宿主升级后插件会停在旧 API 上
78
+ > (本项目曾因此停在 0.1.0-rc.6)。只刷新 lock 时用 `npm install --package-lock-only`。
96
79
 
97
- `cordis.patch.yml` 追加:
80
+ > **兼容性**:要求 DSH ≥ **0.1.5-rc.1**。0.1.5 把浏览器模块表里的 `@deepseek-ai/dsh-client-runtime`
81
+ > 改名为 `@deepseek-ai/dsh-client-store` 且只按精确裸名命中;旧 bundle 在新宿主上会报
82
+ > `Failed to load plugins` / `require(...) missed the module table`。
83
+ >
84
+ > 另:0.1.5 的 Web 设置面改为 `settings.describe()` 动态枚举,**不再有 namespace 白名单**
85
+ > (`settings-not-exposed` 已不存在),`install.ps1` 里的白名单 patch 只是历史遗留、可忽略。
98
86
 
99
- ```yaml
100
- - insert:
101
- - id: tool-bash-terminal
102
- name: 'dsh-bash-terminal-ts'
103
- ```
87
+ > 当前已不再需要手动改 profile 的 `cordis.patch.yml`:插件包内自带 `dsh.bundle.patch`(包内 `cordis.patch.yml`),只要 profile 的 `dsh.profile.bundles` 里有 `dsh-bash-terminal`,DSH 就会自动挂载。
104
88
 
105
89
  验证组合树(无需重启):
106
90
 
107
91
  ```powershell
108
- node "$env:APPDATA\nvm\v24.16.0\node_modules\@deepseek-ai\dsh\lib\bin.js" --profile web --dump-config | Select-String dsh-bash-terminal-ts
92
+ node "$env:APPDATA\nvm\<node-version>\node_modules\@deepseek-ai\dsh\lib\bin.js" --profile web --dump-config | Select-String dsh-bash-terminal
109
93
  ```
110
94
 
111
95
  ## 使用
@@ -115,10 +99,18 @@ node "$env:APPDATA\nvm\v24.16.0\node_modules\@deepseek-ai\dsh\lib\bin.js" --prof
115
99
  模型看到 `shell` 工具后,执行命令时自动使用你选择的终端(工具不暴露终端参数,模型无法更改你的选择):
116
100
 
117
101
  - 默认终端 = Git Bash 时:`shell(command: "git status")` 走 Git Bash
118
- - 默认终端 = MSYS2 时:`shell(command: "gcc --version")` 走 MSYS2(登录 shell,PATH 含 `/usr/bin` 与 `/mingw64/bin`,自带完整 GCC / mingw64 工具链)
119
- - 默认终端 = WSL 时:`shell(command: "ls -la /mnt/d/WorkSpace")` 走 WSL;传 `distro: "Ubuntu"` 可指定发行版
102
+ - 默认终端 = MSYS2 时:`shell(command: "gcc --version")` 走 MSYS2(MINGW64 环境,`/mingw64/bin` 的 gcc、make 可用)
103
+ - 默认终端 = WSL 时:`shell(command: "ls -la /mnt/d/workspace")` 走 WSL;传 `distro: "Ubuntu"` 可指定发行版
120
104
  - 默认终端 = PowerShell 时:`shell(command: "Get-Process node")` 走 PowerShell
121
105
 
106
+ ## 模型使用示例
107
+
108
+ - 一次性命令(默认终端):`shell(command: "git status", description: "查看 git 状态")`
109
+ - 跨轮保持状态(交互式):`terminal(action: "open")` → 记下 `sessionId` → `terminal(action: "send", sessionId, input: "cd /d/project\n")` → `terminal(action: "send", sessionId, input: "npm run dev\n")` → `terminal(action: "close", sessionId)`
110
+ - 中断正在运行的程序:`terminal(action: "signal", sessionId, signal: "SIGINT")`
111
+ - 查看活动会话:`terminal(action: "list")`
112
+ - 沙箱拒绝后升级:`shell(command: ..., sandbox_permissions: "workspace-write", justification: "...")`
113
+
122
114
  ## 配置
123
115
 
124
116
  **Web UI 设置**(推荐):设置 → 通用 →「默认终端」。
@@ -132,63 +124,80 @@ node "$env:APPDATA\nvm\v24.16.0\node_modules\@deepseek-ai\dsh\lib\bin.js" --prof
132
124
  | `maxTimeoutMs` | 600000 | 调用方 timeoutMs 上限 |
133
125
  | `pwshPath` | 自动探测 | 固定 pwsh.exe 路径 |
134
126
  | `gitBashPath` | 自动探测 | 固定 git bash.exe 路径 |
135
- | `msys2Path` | 自动探测 | 固定 MSYS2 入口路径(需指向 `bash.exe`,不要指向 `msys2.exe`;见「MSYS2 支持」) |
127
+ | `msys2Path` | 自动探测(`C:\msys64\usr\bin\bash.exe` 优先,`msys2.exe` 兜底) | 固定 MSYS2 bash.exe 路径 |
136
128
  | `wslPath` | 自动探测 | 固定 wsl.exe 路径 |
137
129
 
130
+ ## 发布(npm)
131
+
132
+ npm 账号已启用 2FA 发布验证,需一次性验证码:
133
+
134
+ ```powershell
135
+ cd D:\workspace\projects\dsh-bash-terminal
136
+ npm publish --otp <验证码> # 验证码来自你的认证器
137
+ ```
138
+
139
+ 发布前先 `npm pack --dry-run` 检查内容、跑 `npm run build` 重建(tsc 服务端编译 + client bundle + 测试编译)。
140
+
138
141
  ## 卸载
139
142
 
143
+ 推荐直接运行:
144
+
140
145
  ```powershell
141
- Remove-Item "$env:USERPROFILE\.dsh\profiles\web\node_modules\dsh-bash-terminal-ts" -Force
142
- # 并从 cordis.patch.yml 删掉 insert 块,重启 dsh web
146
+ powershell -ExecutionPolicy Bypass -File install.ps1 uninstall
143
147
  ```
144
148
 
149
+ 它会删除 junction、恢复设置白名单、清理旧版遗留的 `cordis.patch.yml` 挂载块,并从 `dsh.profile.bundles` 移除 `dsh-bash-terminal`。之后重启 dsh web 即可。
150
+
151
+ 手动卸载时,除了删除 `node_modules\dsh-bash-terminal`,还要记得从 profile `package.json` 的 `dsh.profile.bundles` 中移除 `dsh-bash-terminal`。
152
+
153
+ ## 交互式终端(terminal 工具)
154
+
155
+ `terminal` 工具在 PTY 接缝(node-pty;Windows 上因上游 `spawnTerminal` 的 process inspector 仅支持 POSIX,由 `lib/terminal.js` 直连 node-pty,非 Windows 仍走官方 `ctx.subprocess.spawnTerminal`)上提供**持久交互会话**:
156
+
157
+ - `action: open` 启动一个真实终端会话(按你设置的默认终端;wsl 可传 `distro`),返回 `sessionId`
158
+ - `action: send` 写入输入并读新输出;`action: read` 只读不写;`action: signal` 向前台进程组发信号(SIGINT = Ctrl+C)
159
+ - `action: close` 终止会话
160
+ - **会话状态跨调用保持**(cwd / 变量 / 别名),适合 REPL、ssh、交互式 CLI
161
+ - `send` 会等待输出稳定(300ms 静默,上限 5s)返回**完整回复**;输出超 1MB 时报 `truncated` 提示
162
+ - 输入用 `\\n`(或 \\r)结尾表示回车
163
+
145
164
  ## 沙箱(官方机制对接)
146
165
 
147
166
  `shell` 工具走 DSH 官方沙箱接缝(`ctx.sandboxPolicy` + `ctx.sandbox`):
148
167
 
149
168
  - 每次调用解析当前沙箱策略;`danger-full-access` 会话直接执行(不包装)。
150
- - PowerShell / Git Bash / MSYS2 后端经 `ctx.sandbox.confine` 包装 argv —— 与官方 executor 相同的 **fail-closed** 语义:请求受限模式但无可用后端时抛 `SandboxUnavailableError`,拒绝裸跑。
169
+ - PowerShell 后端经 `ctx.sandbox.confine` 包装 argv —— 与官方 executor 相同的 **fail-closed** 语义:请求受限模式但无可用后端时抛 `SandboxUnavailableError`,拒绝裸跑。
170
+ - Git Bash 后端不包装:DSH 的 Windows ACL 受限令牌 runner 与 Cygwin/MSYS2 不兼容(bash 启动即因 `CreateFileMapping` Win32 error 5 终止),因此 Git Bash 在受限模式下也不经沙箱包装;结果报告 `enforcement: gitbash-unconfined`。
171
+ - MSYS2 后端同样不包装(同一 Cygwin/MSYS2 运行时不兼容);结果报告 `enforcement: msys2-unconfined`。
151
172
  - WSL 后端不包装:WSL 独立 Linux 虚拟机本身就是隔离(结果报告 `enforcement: wsl-isolation`)。
152
173
  - 受限模式下被沙箱拒绝时,结果携带官方标记 `[sandbox: file access denied under <mode> mode]` 与同轮升级提示;模型可凭 `sandbox_permissions` + `justification` 发起一次升级(经 `ctx.approval` 用户审批),与官方 bash/pwsh 工具完全一致。
153
- - 注意:DSH 的 Windows ACL 沙箱 launcher(`node-addon-landlock-run-win32-x64`)当前尚未在 npm 发布,本机沙箱后端暂不可用;架构已就绪,DSH 发布后自动生效。
174
+ - 注意:DSH 的 Windows ACL runner 可用时,PowerShell 的受限模式会经它包装;Git Bash 与 MSYS2 因 Cygwin/MSYS2 不兼容而保持不包装。
154
175
 
155
176
  ## ⚠️ 安全说明
156
177
 
157
- `shell` 工具的命令**在 DSH 沙箱之外**运行,与 dsh 进程同权限(等同完整访问的命令执行),
158
- 不享受 `pwsh` 工具的 ConstrainedLanguage 限制。DSH 的文件操作工具(read/write/edit)仍受文件沙箱约束。
159
- 仅在你信任的会话中使用;需要受沙箱保护的 PowerShell 时请继续使用官方 `pwsh` 工具。
178
+ `shell` 工具在受限模式下:PowerShell 会经 `ctx.sandbox.confine` 包装(fail-closed);Git Bash 与 MSYS2 因 Cygwin/MSYS2 与 Windows ACL 受限令牌不兼容而**不包装**(与 dsh 进程同权限);WSL 因独立 Linux VM 不包装。它是**额外的多终端入口**,不享受官方 `pwsh` 工具的 ConstrainedLanguage 限制。DSH 的文件操作工具(read/write/edit)仍受文件沙箱约束。仅在你信任的会话中使用;需要受沙箱保护的 PowerShell 时请继续使用官方 `pwsh` 工具。
179
+
180
+ ## 交互终端已知限制(ConPTY)
181
+
182
+ - **PowerShell 5.1 无法在 ConPTY 启动**(0x8009001d)—— 交互式 PowerShell 需要安装 [PowerShell 7](https://github.com/PowerShell/PowerShell/releases)(一次性命令不受影响)。
183
+ - **wsl.exe 交互模式在 ConPTY 下可能触发 WSL 服务 RPC 错误**(0x8007072c,偶发)—— 一次性 `wsl -e bash -lc ...` 命令正常;交互会话建议直接用 Windows Terminal / WSL 终端,或重试。
184
+ - **Windows 上 node-pty 不接受命名信号**:`signal` 的 `SIGINT` 映射为 Ctrl+C(`\x03`),其他信号(`SIGTERM` / `SIGKILL` / `SIGTSTP` / `SIGHUP`)退化为终止会话。
185
+ - Git Bash 交互会话完全正常。
160
186
 
161
187
  ## 已知限制
162
188
 
163
- - 本插件仅在 `win32` 平台注册工具。
164
189
  - WSL 后台进程在超时/中断后可能在发行版内短暂残留(WSL 实例在最后一个进程退出后自动关闭)。
165
- - Git Bash 与 MSYS2 都是 msys2 环境,与 WSL 的 Linux 行为存在差异(路径映射、包可用性)。
166
- - 若 `C:\msys64` 装在非默认位置且不在 PATH 上,需显式配置 `msys2Path`。
190
+ - Git Bash 是 msys2 环境,与 WSL 的 Linux 行为存在差异(路径映射、包可用性)。
191
+ - MSYS2 后端需要本机安装 MSYS2(默认 `C:\msys64`);未安装时 `shell` 报 `backend unavailable`,可用 `msys2Path` 指定自定义位置。候选顺序永远是 `bash.exe` 优先、`msys2.exe` 兜底——`msys2.exe` 在管道 stdio 下会静默返回零字节,仅作最后手段。
192
+ - 本插件仅在 `win32` 平台注册工具。
167
193
 
168
194
  ## 测试
169
195
 
170
196
  ```powershell
171
- git clone https://github.com/drscrewdriver/dsh-bash-terminal-ts.git
172
- cd dsh-bash-terminal-ts
197
+ cd D:\workspace\projects\dsh-bash-terminal
173
198
  npm install # 安装依赖(含 typescript)
174
- npm run build # tsc 编译 src/*.ts → lib/*.js;client.tsx → dist/client.js;test/*.ts → test-dist/
175
- npm test # node test-dist/unit.js → apply.js → client.js
199
+ npm run build # tsc 编译 src/*.ts → lib/*.js;client.tsx → lib/client.js + dist/client.js;test/*.ts → test-dist/
200
+ npm test # node test-dist/unit.js → apply.js → client.js → terminal.js
176
201
  ```
177
202
 
178
- CI 在 `windows-latest` 上跑同一套(`.github/workflows/test.yml`)。
179
-
180
- ## 技术实现
181
-
182
- 运行要求:**Node.js 22+(推荐 24)**,DSH 0.1.2+。
183
-
184
- 源码为 TypeScript(`strict` + `noUncheckedIndexedAccess`),编译产物 `lib/`、`dist/` 随仓库提交,DSH 直接按 `lib/index.js` 加载,**无需安装即可使用**。
185
-
186
- require 侧依赖(`@deepseek-ai/*` 等 13 个包)全部声明为 `peerDependencies` + `peerDependenciesMeta.optional`,避免与宿主自带的副本重复安装。
187
-
188
- ## 致谢
189
-
190
- 本项目基于 [MAXeaglet/dsh-bash-terminal](https://github.com/MAXeaglet/dsh-bash-terminal) 演进 —— 原始的 `shell` 工具、PowerShell / Git Bash / WSL 三后端架构与沙箱接缝对接均来自原作者。本版在此基础上加入 MSYS2 后端、TypeScript 重写与 DSH 0.1.2 适配。
191
-
192
- ## License
193
-
194
- MIT
203
+ 源码为 TypeScript(`strict` + `noUncheckedIndexedAccess`),编译产物 `lib/`、`dist/` 随仓库提交,DSH 直接按 `lib/index.js` 加载,无需安装即可使用。
package/cordis.patch.yml CHANGED
@@ -1,5 +1,5 @@
1
- # dsh-bash-terminal-ts bundle layer — applied automatically when a profile lists
1
+ # dsh-bash-terminal bundle layer — applied automatically when a profile lists
2
2
  # this package in dsh.profile.bundles (dsh.bundle.patch declaration).
3
3
  - insert:
4
4
  - id: tool-bash-terminal
5
- name: 'dsh-bash-terminal-ts'
5
+ name: 'dsh-bash-terminal'