dsh-bash-terminal-ts 0.2.6 → 0.5.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 +82 -197
- package/README.md +197 -194
- package/cordis.patch.yml +5 -5
- package/dist/client.core.js +46 -39
- package/dist/client.js +47 -40
- package/dsh.plugin.json +22 -22
- package/lib/client.js +148 -0
- package/lib/dsh-types.d.ts +1 -1
- package/lib/index.d.ts +17 -16
- package/lib/index.js +47 -47
- package/lib/terminal.d.ts +24 -1
- package/lib/terminal.js +214 -49
- package/package.json +38 -57
- package/screenshots.json +3 -0
- package/scripts/build-client.mjs +14 -13
- package/src/client.tsx +70 -46
- package/src/dsh-types.ts +1 -1
- package/src/index.ts +47 -47
- package/src/terminal.ts +254 -54
- package/README.ja.md +0 -196
- package/README.ko.md +0 -194
package/README.en.md
CHANGED
|
@@ -1,197 +1,82 @@
|
|
|
1
|
-
# dsh-bash-terminal
|
|
2
|
-
|
|
3
|
-
[
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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'
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Verify the composition tree (no restart required):
|
|
108
|
-
|
|
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
|
-
```
|
|
112
|
-
|
|
113
|
-
## Usage
|
|
114
|
-
|
|
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.
|
|
116
|
-
|
|
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):
|
|
118
|
-
|
|
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
|
|
123
|
-
|
|
124
|
-
## Configuration
|
|
125
|
-
|
|
126
|
-
**Web UI settings** (recommended): Settings → General → "Default terminal".
|
|
127
|
-
|
|
128
|
-
The plugin row's `config` (overrides the defaults and forms the composition baseline for the setting):
|
|
129
|
-
|
|
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 |
|
|
139
|
-
|
|
140
|
-
## Uninstall
|
|
141
|
-
|
|
142
|
-
```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
|
|
145
|
-
```
|
|
146
|
-
|
|
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
|
|
172
|
-
|
|
173
|
-
```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
|
|
179
|
-
```
|
|
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
|
|
1
|
+
# dsh-bash-terminal
|
|
2
|
+
|
|
3
|
+
> Community: [LINUX DO](https://linux.do) · [GitHub](https://github.com/drscrewdriver/dsh-bash-terminal-ts)
|
|
4
|
+
|
|
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
|
+
|
|
7
|
+

|
|
8
|
+
|
|
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.
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
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) |
|
|
25
|
+
| `wsl` | `wsl [-d <distro>] -e bash -lc <cmd>` | Linux; `/mnt/d/...` | `$NAME` (via WSLENV) |
|
|
26
|
+
|
|
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`).
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
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.
|
|
35
|
+
|
|
36
|
+
```powershell
|
|
37
|
+
npm install -g dsh-bash-terminal
|
|
38
|
+
dsh plugin --profile web add dsh-bash-terminal # adds to profile bundles + applies the patch
|
|
39
|
+
powershell -ExecutionPolicy Bypass -File install.ps1 install # patches the DSH settings-UI allowlist (see below)
|
|
40
|
+
# restart dsh web
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> **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.
|
|
44
|
+
|
|
45
|
+
For local development (junction install, source changes apply instantly) see the Chinese README's development section.
|
|
46
|
+
|
|
47
|
+
## Sandbox
|
|
48
|
+
|
|
49
|
+
- `danger-full-access` sessions run directly (no wrapping).
|
|
50
|
+
- Confined sessions wrap PowerShell argv through `ctx.sandbox.confine`; fail-closed when no backend is available.
|
|
51
|
+
- Git Bash is never wrapped: the Windows ACL restricted-token runner cannot host Cygwin/MSYS2 (`CreateFileMapping` Win32 error 5); results report `enforcement: gitbash-unconfined`.
|
|
52
|
+
- MSYS2 is never wrapped either (same Cygwin/MSYS2 runtime incompatibility); results report `enforcement: msys2-unconfined`.
|
|
53
|
+
- WSL is never wrapped (its VM isolation is the sandbox; results report `enforcement: wsl-isolation`).
|
|
54
|
+
- 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`).
|
|
55
|
+
- Note: when DSH's Windows ACL runner is available, it confines PowerShell; Git Bash and MSYS2 remain unconfined due to the Cygwin/MSYS2 incompatibility.
|
|
56
|
+
|
|
57
|
+
## Interactive terminal
|
|
58
|
+
|
|
59
|
+
`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).
|
|
60
|
+
|
|
61
|
+
## Interactive terminal known limits (ConPTY)
|
|
62
|
+
|
|
63
|
+
- **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).
|
|
64
|
+
- **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.
|
|
65
|
+
- **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.
|
|
66
|
+
- Git Bash interactive sessions work fully.
|
|
67
|
+
|
|
68
|
+
## Config
|
|
69
|
+
|
|
70
|
+
Web UI: Settings -> General -> Default terminal. Plugin row `config` overrides: `defaultShell`, `timeoutMs`, `maxTimeoutMs`, `pwshPath`, `gitBashPath`, `msys2Path`, `wslPath`.
|
|
71
|
+
|
|
72
|
+
## Uninstall
|
|
73
|
+
|
|
74
|
+
```powershell
|
|
75
|
+
powershell -ExecutionPolicy Bypass -File install.ps1 uninstall
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Tests
|
|
79
|
+
|
|
80
|
+
```powershell
|
|
81
|
+
node test/unit.mjs && node test/apply.mjs && node test/client.mjs && node test/terminal.mjs
|
|
82
|
+
```
|