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.ja.md
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
# dsh-bash-terminal-ts
|
|
2
|
-
|
|
3
|
-
[](https://github.com/drscrewdriver/dsh-bash-terminal-ts/actions/workflows/test.yml)
|
|
4
|
-
|
|
5
|
-
[English](README.en.md) | **日本語** | [한국어](README.ko.md) | [中文](README.md)
|
|
6
|
-
|
|
7
|
-
DSH(DeepSeek Harness)プラグイン:Windows 上で **PowerShell / Git Bash / MSYS2 / WSL** の 4 種類のターミナルコマンドを 1 つの `shell` ツールに統合して実行します。
|
|
8
|
-
|
|
9
|
-
ターミナルは**あなたが Web UI で選びます**。モデルは変更できません。一度選べば、以降のすべてのコマンドはそのターミナルで実行されます。
|
|
10
|
-
|
|
11
|
-
## なぜ使うのか
|
|
12
|
-
|
|
13
|
-
| 売り | ひとことで |
|
|
14
|
-
|------|--------|
|
|
15
|
-
| **MSYS2 が本当に動く** | 「ドロップダウンの選択肢を 1 つ足した」だけではありません。`bash.exe` の解決、ログインシェル、`MSYSTEM` 環境という 3 点をすべて正しく処理しています —— 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
|
-
| **4 種類のターミナルを 1 つのツールで** | 同じ `shell` ツールが PowerShell / Git Bash / MSYS2 / WSL をカバーするので、モデルは 4 通りもの引数を覚える必要がありません |
|
|
19
|
-
| **サンドボックスは公式準拠** | 公式の `ctx.sandboxPolicy` + `ctx.sandbox` を使用し、fail-closed。拒否時には同一ターン内での昇格案内を返します |
|
|
20
|
-
| **対話型ターミナル** | 本物の PTY セッションツールも用意しています:`open / send / read / signal / close`。Ctrl+C が使え、ターンをまたいで状態を保持します |
|
|
21
|
-
|
|
22
|
-
## 対応バックエンド
|
|
23
|
-
|
|
24
|
-
| バックエンド | 実際の実行 | 構文 / パス | 環境変数 |
|
|
25
|
-
|------|----------|-------------|----------|
|
|
26
|
-
| `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>`(ログインシェル;`MSYSTEM=MINGW64`) | POSIX;完全な GCC / mingw64 ツールチェーンを同梱 | `$NAME` |
|
|
29
|
-
| `wsl` | `wsl [-d <distro>] -e bash -lc <cmd>` | Linux;`/mnt/d/...` | `$NAME`(WSLENV 経由) |
|
|
30
|
-
|
|
31
|
-
呼び出しごとにまったく新しいシェルが起動します:**状態は保持されません**(cwd / 変数 / エイリアス)。`cd` ではなく `workdir` を渡してください。ターンをまたいで状態を保持したい場合は対話型ターミナルツールを使ってください。
|
|
32
|
-
|
|
33
|
-
## MSYS2 サポート
|
|
34
|
-
|
|
35
|
-
MSYS2 は「バックエンドをもう 1 つ足すだけ」に見えますが、実際には 3 つの落とし穴があり、本プラグインはそれを 1 つずつ処理しています。
|
|
36
|
-
|
|
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` が常に優先されます**。
|
|
39
|
-
|
|
40
|
-
**2. `-lc` は省略できません。**
|
|
41
|
-
`/etc/profile` を読むのはログインシェルだけで、`/usr/bin` と `/mingw64/bin` を PATH に追加するのも `/etc/profile` だけです。裸の `-c` を使うと `tr`、`sed`、`gcc` がすべて `command not found` になります。
|
|
42
|
-
|
|
43
|
-
**3. `MSYSTEM=MINGW64` を注入する必要があります。**
|
|
44
|
-
そうしないと `/etc/profile` がデフォルトの MSYS 環境として初期化され、`/mingw64/bin` にある gcc や make が使えません。本プラグインは `buildEnv` 経由で注入します(**あなたが明示的に設定した値が優先されます**)。また `shell` ツールと対話型ターミナルは同じ `buildEnv` を通るため、「ツールでは動くのにターミナルでは動かない」といったずれは発生しません。
|
|
45
|
-
|
|
46
|
-
実測(本物の PTY):プロンプトが `MSYS` から `MINGW64` に変わり、`command -v gcc` → `/mingw64/bin/gcc` となります。
|
|
47
|
-
|
|
48
|
-
これら 3 点はすべて回帰テストで守られています。`test/unit.ts` は `bash.exe` が `msys2.exe` より前に並ぶことを断言し、`test/apply.ts` は PTY 環境に `MSYSTEM=MINGW64` が含まれ、かつ gitbash に漏れないことを断言します。
|
|
49
|
-
|
|
50
|
-
## 設計上の要点
|
|
51
|
-
|
|
52
|
-
- **ターミナルはユーザーが決め、AI は変更できない**:Web UI の設定画面(設定 → 一般)に「デフォルトターミナル」ドロップダウン(PowerShell / Git Bash / MSYS2 / WSL)が表示されます。`shell` ツールは常にこの設定のみを使用し、モデルにターミナル引数を公開しません。設定は DSH settings システム(settings.yaml)で永続化されます。
|
|
53
|
-
- **`ctx.shell` 能力の接合部を占有しない**:DSH 標準のサンドボックス化された `pwsh` ツールはそのまま利用可能です。本プラグインの `shell` ツールは**追加の**マルチターミナル入口です。
|
|
54
|
-
- 共有された `ctx.subprocess` seam を通じてプロセスを派生させます:プロセスツリーの終了(Windows `taskkill /T`)、SIGTERM→grace→SIGKILL、出力の spill ファイル。公式の `dsh-tool-bash` / `dsh-tool-pwsh` と同じ挙動です。
|
|
55
|
-
- バックグラウンドタスクは共通の `jobs` registry に登録され、`run_in_background` / `job_output` / `job_kill` をサポートします。
|
|
56
|
-
- ツール引数 `shell` は列挙型です(UI ではドロップダウンとして自動レンダリングされます)。モデルは呼び出しごとにターミナルを自身で選択します。
|
|
57
|
-
- 4 つのバックエンドについて、フロントエンドのドロップダウン内の `<option>` と 2 つの言語パックの `shell.<id>` 文言には drift ガードテストがあります —— バックエンドを追加して文言の更新を忘れると、テストがそのまま失敗します。
|
|
58
|
-
|
|
59
|
-
## インストール
|
|
60
|
-
|
|
61
|
-
### 標準インストール(npm)
|
|
62
|
-
|
|
63
|
-
```powershell
|
|
64
|
-
# 1. プラグインパッケージをインストール
|
|
65
|
-
npm install -g dsh-bash-terminal-ts
|
|
66
|
-
dsh plugin --profile web add dsh-bash-terminal-ts
|
|
67
|
-
|
|
68
|
-
# 2. DSH 設定のホワイトリストを patch(DSH 側の制限。下記の説明を参照。install.ps1 でこの手順だけを単独実行することもできます)
|
|
69
|
-
powershell -ExecutionPolicy Bypass -File install.ps1 install
|
|
70
|
-
|
|
71
|
-
# 3. dsh web を再起動
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### ローカル開発インストール(junction 直結、ソース変更が即時反映)
|
|
75
|
-
|
|
76
|
-
```powershell
|
|
77
|
-
# 1. プラグインパッケージを profile の node_modules にリンク(junction なのでソース変更が即時反映されます)
|
|
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. プラグインが @deepseek-ai/* 依存を解決できるようにする(profile の依存ツリーへ junction)
|
|
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. cordis.patch.yml にマウント行を追記(下記の patch 断片を参照)
|
|
85
|
-
# 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 を再起動
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
> **DSH 設定 UI のホワイトリスト制限**:DSH の api-gateway(dsh-host-apiproxy)は、
|
|
92
|
-
> Web 設定クライアントに公開する settings namespace について**ハードコードされた
|
|
93
|
-
> ホワイトリスト**を持っています(サードパーティ製プラグインの設定はデフォルトで
|
|
94
|
-
> `settings-not-exposed` として拒否され、UI で変更しても反映されません)。
|
|
95
|
-
> install.ps1 はこのホワイトリストを自動で patch します(`bash-terminal` を追加し、
|
|
96
|
-
> 元のファイルは先にバックアップされます)。
|
|
97
|
-
> **DSH をアップグレードした後は install.ps1 を再実行して** patch を復元してください。アンインストール時には install.ps1 が元に戻します。
|
|
98
|
-
|
|
99
|
-
`cordis.patch.yml` への追記:
|
|
100
|
-
|
|
101
|
-
```yaml
|
|
102
|
-
- insert:
|
|
103
|
-
- id: tool-bash-terminal
|
|
104
|
-
name: 'dsh-bash-terminal-ts'
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
組み立てツリーの検証(再起動不要):
|
|
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
|
-
## 使い方
|
|
114
|
-
|
|
115
|
-
**ユーザーは Web UI でデフォルトターミナルを設定します**:設定(歯車)→ 一般 →「デフォルトターミナル」ドロップダウンから、PowerShell / Git Bash / MSYS2 / WSL のいずれかを選びます。変更は即時反映され、永続化されます。
|
|
116
|
-
|
|
117
|
-
モデルは `shell` ツールを認識すると、コマンド実行時にあなたが選んだターミナルを自動的に使用します(ツールはターミナル引数を公開しないため、モデルはあなたの選択を変更できません)。
|
|
118
|
-
|
|
119
|
-
- デフォルトターミナル = Git Bash の場合:`shell(command: "git status")` は Git Bash を通ります
|
|
120
|
-
- デフォルトターミナル = MSYS2 の場合:`shell(command: "gcc --version")` は MSYS2 を通ります(ログインシェルで、PATH に `/usr/bin` と `/mingw64/bin` を含み、完全な GCC / mingw64 ツールチェーンを同梱)
|
|
121
|
-
- デフォルトターミナル = WSL の場合:`shell(command: "ls -la /mnt/d/WorkSpace")` は WSL を通ります。`distro: "Ubuntu"` を渡すとディストリビューションを指定できます
|
|
122
|
-
- デフォルトターミナル = PowerShell の場合:`shell(command: "Get-Process node")` は PowerShell を通ります
|
|
123
|
-
|
|
124
|
-
## 設定
|
|
125
|
-
|
|
126
|
-
**Web UI 設定**(推奨):設定 → 一般 →「デフォルトターミナル」。
|
|
127
|
-
|
|
128
|
-
プラグイン row の `config`(デフォルトを上書きし、設定の composition の基準となります):
|
|
129
|
-
|
|
130
|
-
| キー | デフォルト | 説明 |
|
|
131
|
-
|----|------|------|
|
|
132
|
-
| `defaultShell` | `powershell` | 設定で上書きされていない場合のバックエンド |
|
|
133
|
-
| `timeoutMs` | 120000 | デフォルトのタイムアウト |
|
|
134
|
-
| `maxTimeoutMs` | 600000 | 呼び出し側 timeoutMs の上限 |
|
|
135
|
-
| `pwshPath` | 自動検出 | pwsh.exe のパスを固定 |
|
|
136
|
-
| `gitBashPath` | 自動検出 | git bash.exe のパスを固定 |
|
|
137
|
-
| `msys2Path` | 自動検出 | MSYS2 入口パスを固定(`bash.exe` を指す必要があり、`msys2.exe` を指してはいけません。「MSYS2 サポート」参照) |
|
|
138
|
-
| `wslPath` | 自動検出 | wsl.exe のパスを固定 |
|
|
139
|
-
|
|
140
|
-
## アンインストール
|
|
141
|
-
|
|
142
|
-
```powershell
|
|
143
|
-
Remove-Item "$env:USERPROFILE\.dsh\profiles\web\node_modules\dsh-bash-terminal-ts" -Force
|
|
144
|
-
# あわせて cordis.patch.yml から insert ブロックを削除し、dsh web を再起動します
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## サンドボックス(公式機構との接続)
|
|
148
|
-
|
|
149
|
-
`shell` ツールは DSH 公式のサンドボックス接合部(`ctx.sandboxPolicy` + `ctx.sandbox`)を通ります:
|
|
150
|
-
|
|
151
|
-
- 呼び出しごとに現在のサンドボックス方針を解決します。`danger-full-access` のセッションではそのまま実行されます(ラップしません)。
|
|
152
|
-
- PowerShell / Git Bash / MSYS2 の各バックエンドは `ctx.sandbox.confine` を通じて argv をラップします —— 公式 executor と同じ **fail-closed** の意味論です:制限モードを要求したのに利用可能なバックエンドがない場合は `SandboxUnavailableError` を投げ、ラップなしの実行を拒否します。
|
|
153
|
-
- WSL バックエンドはラップしません:WSL の独立した Linux 仮想マシン自体が隔離であるためです(結果は `enforcement: wsl-isolation` を報告します)。
|
|
154
|
-
- 制限モードでサンドボックスに拒否された場合、結果には公式のマーカー `[sandbox: file access denied under <mode> mode]` と同一ターン内での昇格案内が付与されます。モデルは `sandbox_permissions` + `justification` によって 1 回の昇格を申請できます(`ctx.approval` を通じたユーザー承認を経由)。公式の bash/pwsh ツールと完全に同じです。
|
|
155
|
-
- 注意:DSH の Windows ACL サンドボックス launcher(`node-addon-landlock-run-win32-x64`)は現在まだ npm で公開されていないため、本機のサンドボックスバックエンドは当面利用できません。アーキテクチャはすでに整っており、DSH の公開後には自動的に有効になります。
|
|
156
|
-
|
|
157
|
-
## ⚠️ セキュリティに関する注意
|
|
158
|
-
|
|
159
|
-
`shell` ツールのコマンドは**DSH サンドボックスの外側**で実行され、dsh プロセスと同じ権限を持ちます(完全アクセスのコマンド実行に相当します)。
|
|
160
|
-
`pwsh` ツールの ConstrainedLanguage 制限は適用されません。DSH のファイル操作ツール(read/write/edit)は引き続きファイルサンドボックスの制約を受けます。
|
|
161
|
-
信頼できるセッションでのみ使用してください。サンドボックスで保護された PowerShell が必要な場合は、引き続き公式の `pwsh` ツールを使用してください。
|
|
162
|
-
|
|
163
|
-
## 既知の制限
|
|
164
|
-
|
|
165
|
-
- 本プラグインは `win32` プラットフォームでのみツールを登録します。
|
|
166
|
-
- WSL のバックグラウンドプロセスは、タイムアウトや中断の後、ディストリビューション内に一時的に残ることがあります(WSL インスタンスは最後のプロセスが終了した時点で自動的に終了します)。
|
|
167
|
-
- Git Bash と MSYS2 はどちらも msys2 環境であり、WSL の Linux とは挙動に差があります(パスマッピング、パッケージの可用性)。
|
|
168
|
-
- `C:\msys64` がデフォルト以外の場所にインストールされていて PATH 上にない場合は、`msys2Path` を明示的に設定する必要があります。
|
|
169
|
-
|
|
170
|
-
## テスト
|
|
171
|
-
|
|
172
|
-
```powershell
|
|
173
|
-
git clone https://github.com/drscrewdriver/dsh-bash-terminal-ts.git
|
|
174
|
-
cd dsh-bash-terminal-ts
|
|
175
|
-
npm install # 依存をインストール(typescript を含む)
|
|
176
|
-
npm run build # tsc でコンパイル src/*.ts → lib/*.js;client.tsx → dist/client.js;test/*.ts → test-dist/
|
|
177
|
-
npm test # node test-dist/unit.js → apply.js → client.js
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
CI は `windows-latest` 上で同じ一式を実行します(`.github/workflows/test.yml`)。
|
|
181
|
-
|
|
182
|
-
## 技術実装
|
|
183
|
-
|
|
184
|
-
動作要件:**Node.js 22+(24 を推奨)**、DSH 0.1.2+。
|
|
185
|
-
|
|
186
|
-
ソースは TypeScript(`strict` + `noUncheckedIndexedAccess`)で、コンパイル成果物 `lib/`、`dist/` はリポジトリにコミットされています。DSH は `lib/index.js` をそのまま読み込むため、**インストール不要で使用できます**。
|
|
187
|
-
|
|
188
|
-
require 側の依存(`@deepseek-ai/*` など 13 パッケージ)はすべて `peerDependencies` + `peerDependenciesMeta.optional` として宣言し、ホストが同梱するコピーとの重複インストールを避けています。
|
|
189
|
-
|
|
190
|
-
## 謝辞
|
|
191
|
-
|
|
192
|
-
本プロジェクトは [MAXeaglet/dsh-bash-terminal](https://github.com/MAXeaglet/dsh-bash-terminal) を基に発展させたものです —— オリジナルの `shell` ツール、PowerShell / Git Bash / WSL の 3 バックエンド構成、およびサンドボックス接合部との接続はいずれも原作者によるものです。本バージョンではこれに MSYS2 バックエンド、TypeScript への書き直し、DSH 0.1.2 への適合を加えています。
|
|
193
|
-
|
|
194
|
-
## ライセンス
|
|
195
|
-
|
|
196
|
-
MIT
|
package/README.ko.md
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
# dsh-bash-terminal-ts
|
|
2
|
-
|
|
3
|
-
[](https://github.com/drscrewdriver/dsh-bash-terminal-ts/actions/workflows/test.yml)
|
|
4
|
-
|
|
5
|
-
[English](README.en.md) | [日本語](README.ja.md) | **한국어** | [中文](README.md)
|
|
6
|
-
|
|
7
|
-
DSH(DeepSeek Harness) 플러그인: Windows에서 **PowerShell / Git Bash / MSYS2 / WSL** 네 가지 터미널 명령을 하나의 `shell` 도구로 통합 실행합니다.
|
|
8
|
-
|
|
9
|
-
터미널은 **Web UI에서 직접 선택**하며, 모델은 바꿀 수 없습니다. 한 번 선택하면 이후 모든 명령이 선택한 터미널로 실행됩니다.
|
|
10
|
-
|
|
11
|
-
## 왜 사용해야 할까요
|
|
12
|
-
|
|
13
|
-
| 장점 | 한 줄 요약 |
|
|
14
|
-
|------|--------|
|
|
15
|
-
| **MSYS2가 실제로 동작합니다** | 단순히 "드롭다운 항목을 하나 추가한" 것이 아니라 `bash.exe` 해석, 로그인 셸, `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
|
-
## 지원하는 백엔드
|
|
23
|
-
|
|
24
|
-
| 백엔드 | 실제 실행 | 문법 / 경로 | 환경 변수 |
|
|
25
|
-
|------|----------|-------------|----------|
|
|
26
|
-
| `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>`(로그인 셸; `MSYSTEM=MINGW64`) | POSIX; 완전한 GCC / mingw64 툴체인 내장 | `$NAME` |
|
|
29
|
-
| `wsl` | `wsl [-d <distro>] -e bash -lc <cmd>` | Linux; `/mnt/d/...` | `$NAME`(WSLENV 경유) |
|
|
30
|
-
|
|
31
|
-
호출할 때마다 완전히 새로운 셸을 시작하며 **상태를 유지하지 않습니다**(cwd / 변수 / 별칭) —— `cd` 대신 `workdir`를 전달하세요. 턴 간에 상태를 유지해야 한다면 대화형 터미널 도구를 사용하세요.
|
|
32
|
-
|
|
33
|
-
## MSYS2 지원
|
|
34
|
-
|
|
35
|
-
MSYS2는 얼핏 "백엔드를 하나 더 추가하는 것"처럼 보이지만 실제로는 세 가지 함정이 있고, 플러그인이 이를 하나씩 처리했습니다.
|
|
36
|
-
|
|
37
|
-
**1. `msys2.exe`는 실행할 수 없습니다.**
|
|
38
|
-
`C:\msys64\msys2.exe`는 콘솔 창을 할당하는 Cygwin 런처입니다. 이 플러그인은 파이프 stdio로 spawn하는데(DSH의 표준 방식), 이때 이 런처는 **exit 0을 반환하면서 출력은 0바이트**입니다 —— 명령이 조용히 실패하므로 "성공"한 것처럼 보이지만 아무 일도 하지 않습니다. 그래서 후보 순서는 `usr\bin\bash.exe` → `bin\bash.exe` → `msys2.exe` 폴백이며, **사용 가능한 `bash.exe`가 항상 우선**입니다.
|
|
39
|
-
|
|
40
|
-
**2. `-lc`는 생략할 수 없습니다.**
|
|
41
|
-
로그인 셸만 `/etc/profile`을 읽고, `/etc/profile`만 `/usr/bin`과 `/mingw64/bin`을 PATH에 추가합니다. 순수 `-c`를 쓰면 `tr`, `sed`, `gcc`가 전부 `command not found`가 됩니다.
|
|
42
|
-
|
|
43
|
-
**3. `MSYSTEM=MINGW64`를 주입해야 합니다.**
|
|
44
|
-
그렇지 않으면 `/etc/profile`이 기본 MSYS 환경으로 초기화되어 `/mingw64/bin`의 gcc, make를 사용할 수 없습니다. 플러그인은 `buildEnv`를 통해 주입하며(**명시적으로 설정한 값이 우선**), `shell` 도구와 대화형 터미널이 동일한 `buildEnv`를 사용하므로 "도구는 되는데 터미널은 안 되는" 편차가 생기지 않습니다.
|
|
45
|
-
|
|
46
|
-
실측(실제 PTY): 프롬프트가 `MSYS`에서 `MINGW64`로 바뀌고, `command -v gcc` → `/mingw64/bin/gcc`.
|
|
47
|
-
|
|
48
|
-
이 세 가지는 모두 회귀 테스트가 지키고 있습니다: `test/unit.ts`는 `bash.exe`가 `msys2.exe`보다 앞에 오는지 검증하고, `test/apply.ts`는 PTY 환경에 `MSYSTEM=MINGW64`가 포함되고 이것이 gitbash로 누출되지 않는지 검증합니다.
|
|
49
|
-
|
|
50
|
-
## 설계 포인트
|
|
51
|
-
|
|
52
|
-
- **터미널은 사용자가 정하고 AI는 바꿀 수 없습니다**: Web UI 설정 페이지(설정 → 일반)에 "기본 터미널" 드롭다운(PowerShell / Git Bash / MSYS2 / WSL)이 나타나며, `shell` 도구는 항상 이 설정만 사용하고 터미널 파라미터를 모델에 노출하지 않습니다. 설정은 DSH settings 시스템을 통해 영구 저장됩니다(settings.yaml).
|
|
53
|
-
- **`ctx.shell` 능력 접점을 점유하지 않습니다**: DSH에 내장된 샌드박스 `pwsh` 도구는 그대로 사용할 수 있으며, 이 플러그인의 `shell` 도구는 **추가적인** 멀티 터미널 진입점입니다.
|
|
54
|
-
- 공유 `ctx.subprocess` seam을 통해 프로세스를 생성합니다: 프로세스 트리 종료(Windows `taskkill /T`), SIGTERM→grace→SIGKILL, 출력 spill 파일 등이 공식 `dsh-tool-bash` / `dsh-tool-pwsh`와 동일하게 동작합니다.
|
|
55
|
-
- 백그라운드 작업은 공용 `jobs` registry에 등록되며 `run_in_background` / `job_output` / `job_kill`을 지원합니다.
|
|
56
|
-
- 도구 파라미터 `shell`은 열거형이고(UI가 자동으로 드롭다운으로 렌더링), 모델이 호출할 때마다 터미널을 직접 선택합니다.
|
|
57
|
-
- 네 가지 백엔드의 프런트엔드 드롭다운 `<option>`과 두 언어 팩의 `shell.<id>` 문구에는 drift 가드 테스트가 있어, 백엔드를 추가하고 문구를 고치지 않으면 테스트가 바로 실패합니다.
|
|
58
|
-
|
|
59
|
-
## 설치
|
|
60
|
-
|
|
61
|
-
### 표준 설치(npm)
|
|
62
|
-
|
|
63
|
-
```powershell
|
|
64
|
-
# 1. 플러그인 패키지 설치
|
|
65
|
-
npm install -g dsh-bash-terminal-ts
|
|
66
|
-
dsh plugin --profile web add dsh-bash-terminal-ts
|
|
67
|
-
|
|
68
|
-
# 2. DSH 설정 화이트리스트 패치 (DSH 제약, 아래 설명 참조; install.ps1로 이 단계만 따로 실행 가능)
|
|
69
|
-
powershell -ExecutionPolicy Bypass -File install.ps1 install
|
|
70
|
-
|
|
71
|
-
# 3. dsh web 재시작
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### 로컬 개발 설치(junction 직접 연결, 소스 수정 즉시 반영)
|
|
75
|
-
|
|
76
|
-
```powershell
|
|
77
|
-
# 1. 플러그인 패키지를 profile의 node_modules에 연결 (junction, 소스 수정 즉시 반영)
|
|
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. 플러그인이 @deepseek-ai/* 의존성을 해석하도록 연결 (profile 의존성 트리로 junction)
|
|
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. cordis.patch.yml에 마운트 행 추가 (아래 patch 조각 참조)
|
|
85
|
-
# 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 재시작
|
|
89
|
-
```
|
|
90
|
-
|
|
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이 원래대로 되돌립니다.
|
|
96
|
-
|
|
97
|
-
`cordis.patch.yml` 추가:
|
|
98
|
-
|
|
99
|
-
```yaml
|
|
100
|
-
- insert:
|
|
101
|
-
- id: tool-bash-terminal
|
|
102
|
-
name: 'dsh-bash-terminal-ts'
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
조합 트리 검증(재시작 불필요):
|
|
106
|
-
|
|
107
|
-
```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
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## 사용
|
|
112
|
-
|
|
113
|
-
**사용자가 Web UI에서 기본 터미널을 설정합니다**: 설정(톱니바퀴) → 일반 → "기본 터미널" 드롭다운에서 PowerShell / Git Bash / MSYS2 / WSL 중 하나를 선택합니다. 변경 사항은 즉시 반영되고 영구 저장됩니다.
|
|
114
|
-
|
|
115
|
-
모델은 `shell` 도구를 인식하면 명령을 실행할 때 자동으로 선택한 터미널을 사용합니다(도구가 터미널 파라미터를 노출하지 않으므로 모델이 선택을 바꿀 수 없습니다):
|
|
116
|
-
|
|
117
|
-
- 기본 터미널 = Git Bash일 때: `shell(command: "git status")`는 Git Bash로 실행
|
|
118
|
-
- 기본 터미널 = MSYS2일 때: `shell(command: "gcc --version")`은 MSYS2로 실행(로그인 셸, PATH에 `/usr/bin`과 `/mingw64/bin` 포함, 완전한 GCC / mingw64 툴체인 내장)
|
|
119
|
-
- 기본 터미널 = WSL일 때: `shell(command: "ls -la /mnt/d/WorkSpace")`는 WSL로 실행되며, `distro: "Ubuntu"`를 전달해 배포판을 지정할 수 있습니다
|
|
120
|
-
- 기본 터미널 = PowerShell일 때: `shell(command: "Get-Process node")`는 PowerShell로 실행
|
|
121
|
-
|
|
122
|
-
## 설정
|
|
123
|
-
|
|
124
|
-
**Web UI 설정**(권장): 설정 → 일반 → "기본 터미널".
|
|
125
|
-
|
|
126
|
-
플러그인 row의 `config`(기본값을 덮어쓰며, 설정의 composition 기준이 됩니다):
|
|
127
|
-
|
|
128
|
-
| 키 | 기본값 | 설명 |
|
|
129
|
-
|----|------|------|
|
|
130
|
-
| `defaultShell` | `powershell` | 설정이 덮어쓰지 않았을 때의 백엔드 |
|
|
131
|
-
| `timeoutMs` | 120000 | 기본 타임아웃 |
|
|
132
|
-
| `maxTimeoutMs` | 600000 | 호출자 timeoutMs 상한 |
|
|
133
|
-
| `pwshPath` | 자동 감지 | pwsh.exe 경로 고정 |
|
|
134
|
-
| `gitBashPath` | 자동 감지 | git bash.exe 경로 고정 |
|
|
135
|
-
| `msys2Path` | 자동 감지 | MSYS2 진입 경로 고정(`bash.exe`를 가리켜야 하며 `msys2.exe`를 가리키면 안 됩니다. "MSYS2 지원" 참고) |
|
|
136
|
-
| `wslPath` | 자동 감지 | wsl.exe 경로 고정 |
|
|
137
|
-
|
|
138
|
-
## 제거
|
|
139
|
-
|
|
140
|
-
```powershell
|
|
141
|
-
Remove-Item "$env:USERPROFILE\.dsh\profiles\web\node_modules\dsh-bash-terminal-ts" -Force
|
|
142
|
-
# 그리고 cordis.patch.yml에서 insert 블록을 삭제하고 dsh web 재시작
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## 샌드박스(공식 메커니즘 연동)
|
|
146
|
-
|
|
147
|
-
`shell` 도구는 DSH 공식 샌드박스 접점(`ctx.sandboxPolicy` + `ctx.sandbox`)을 사용합니다:
|
|
148
|
-
|
|
149
|
-
- 호출할 때마다 현재 샌드박스 정책을 해석하며, `danger-full-access` 세션은 래핑 없이 직접 실행합니다.
|
|
150
|
-
- PowerShell / Git Bash / MSYS2 백엔드는 `ctx.sandbox.confine`으로 argv를 래핑합니다 —— 공식 executor와 동일한 **fail-closed** 의미론으로, 제한 모드를 요청했지만 사용할 수 있는 백엔드가 없으면 `SandboxUnavailableError`를 던지고 그대로 실행하는 것을 거부합니다.
|
|
151
|
-
- WSL 백엔드는 래핑하지 않습니다: WSL은 그 자체가 독립적인 Linux 가상 머신이므로 격리로 간주합니다(결과에 `enforcement: wsl-isolation`으로 보고).
|
|
152
|
-
- 제한 모드에서 샌드박스가 거부하면 결과에 공식 마커 `[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가 게시되면 자동으로 적용됩니다.
|
|
154
|
-
|
|
155
|
-
## ⚠️ 보안 안내
|
|
156
|
-
|
|
157
|
-
`shell` 도구의 명령은 **DSH 샌드박스 밖에서** 실행되며 dsh 프로세스와 동일한 권한을 가집니다(완전 접근 명령 실행과 동일).
|
|
158
|
-
`pwsh` 도구의 ConstrainedLanguage 제한을 받지 않습니다. DSH의 파일 작업 도구(read/write/edit)는 여전히 파일 샌드박스의 제약을 받습니다.
|
|
159
|
-
신뢰할 수 있는 세션에서만 사용하세요. 샌드박스 보호가 필요한 PowerShell이 필요하다면 공식 `pwsh` 도구를 계속 사용하세요.
|
|
160
|
-
|
|
161
|
-
## 알려진 제한 사항
|
|
162
|
-
|
|
163
|
-
- 이 플러그인은 `win32` 플랫폼에서만 도구를 등록합니다.
|
|
164
|
-
- WSL 백그라운드 프로세스는 타임아웃/중단 후 배포판 안에 잠시 남아 있을 수 있습니다(WSL 인스턴스는 마지막 프로세스가 종료되면 자동으로 닫힙니다).
|
|
165
|
-
- Git Bash와 MSYS2는 모두 msys2 환경이므로 WSL의 Linux 동작과 차이가 있습니다(경로 매핑, 패키지 가용성).
|
|
166
|
-
- `C:\msys64`가 기본 위치가 아닌 곳에 설치되어 있고 PATH에 없다면 `msys2Path`를 명시적으로 설정해야 합니다.
|
|
167
|
-
|
|
168
|
-
## 테스트
|
|
169
|
-
|
|
170
|
-
```powershell
|
|
171
|
-
git clone https://github.com/drscrewdriver/dsh-bash-terminal-ts.git
|
|
172
|
-
cd dsh-bash-terminal-ts
|
|
173
|
-
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
|
|
176
|
-
```
|
|
177
|
-
|
|
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 3백엔드 아키텍처, 샌드박스 접점 연동은 모두 원작자 MAXeaglet의 것입니다. 이 버전은 그 위에 MSYS2 백엔드, TypeScript 재작성, DSH 0.1.2 대응을 추가했습니다.
|
|
191
|
-
|
|
192
|
-
## 라이선스
|
|
193
|
-
|
|
194
|
-
MIT
|