bashterm-mcp-server 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.2.2] - 2026-06-04
6
+
7
+ ### Added
8
+ - 扩展激活时自动配置 Claude Code hook,禁止内置 Bash 工具,引导使用 BashTerm MCP 工具
9
+ - `restoreClaudeCodeDefaultBash` 命令,允许用户一键恢复 Claude Code 默认 Bash 工具
10
+
11
+ ### Fixed
12
+ - 修复 `shell` 参数无效导致终端使用默认 shell 而非指定 shell 的问题
13
+ - 修复 Windows 中文输出乱码问题
14
+ - 修复 Claude Code hook 自动配置 JSON 格式错误
15
+
16
+ ### Changed
17
+ - `autoConfigureClaudeCode` 改为写入用户目录 `~/.claude/settings.json` 而非项目级别配置
18
+ - README 安装指南简化为仅安装 VSCode 扩展即可,零手动配置
19
+ - README 完善 Claude Code Bash 回归与恢复说明
20
+
21
+ ## [0.2.1] - 2026-06-04
22
+
23
+ ### Changed
24
+ - 全面重命名为 BashTerm MCP:统一所有文档和代码中的项目名称引用
25
+ - 修复 v0.2.0 标签指向错误的 commit
26
+
5
27
  ## [0.2.0] - 2026-06-04
6
28
 
7
29
  ### Added
package/CLAUDE.md CHANGED
@@ -1,66 +1,100 @@
1
- # Project: bashterm-mcp
1
+ # Project: BashTerm MCP
2
2
 
3
3
  MCP server that runs commands in visible VSCode terminal tabs.
4
4
 
5
+ ---
6
+
5
7
  ## Release Process
6
8
 
7
- When publishing a new version, follow these steps in order:
9
+ 以下以发布 v0.2.1 为例,一步一步执行。
8
10
 
9
- ### 1. Update version
11
+ ### 1. 更新版本号(2 个文件,3 处)
10
12
 
11
13
  ```bash
12
- # In package.json, bump the version
13
- # e.g., "version": "0.1.6" → "version": "0.1.7"
14
+ # package.json "version": "0.2.0" → "0.2.1"
15
+ # server.json 顶层 "version": "0.2.0" → "0.2.1"
16
+ # server.json packages[0].version: "0.2.0" → "0.2.1"
14
17
  ```
15
18
 
16
- ### 2. Update CHANGELOG.md
19
+ ### 2. 更新 CHANGELOG.md
17
20
 
18
- Add a new entry at the top with the new version and date:
21
+ 在文件顶部新增条目:
19
22
 
20
23
  ```markdown
21
- ## [0.1.7] - YYYY-MM-DD
24
+ ## [0.2.1] - YYYY-MM-DD
22
25
 
23
26
  ### Added
24
- - ...
27
+ - 新功能...
25
28
 
26
29
  ### Fixed
27
- - ...
30
+ - 修复...
31
+
32
+ ### Changed
33
+ - 变更...
28
34
  ```
29
35
 
30
- ### 3. Update README.md
36
+ ### 3. 更新 README.md 和 README.zh-CN.md
37
+
38
+ 替换 **Latest Changes** 节为新版本改动,只列核心条目,完整历史指向 CHANGELOG.md。
31
39
 
32
- Replace the "Latest Changes" section with the new version's changes. Keep only the latest version in README — full history lives in CHANGELOG.md.
40
+ > ⚠️ **不要用 `replace_all` 做模糊全局替换!** `bashterm-` 会匹配并误伤 `bashterm-mcp` URL。只精确替换目标字符串。
33
41
 
34
- ### 4. Build and publish
42
+ ### 4. 构建和测试
35
43
 
36
44
  ```bash
37
- # Build
38
- npm run build
45
+ npm run build # esbuild 双产物:dist/extension.js + dist/mcp-entry.js
46
+ npm test # 45 tests must pass
47
+ ```
39
48
 
40
- # Publish to npm
41
- npm publish --access public
49
+ ### 5. 打包 VSIX
42
50
 
43
- # Package vsix
51
+ ```bash
44
52
  npx vsce package --allow-missing-repository
53
+ # 生成 bashterm-mcp-server-0.2.1.vsix
54
+ ```
55
+
56
+ ### 6. 发布 npm
57
+
58
+ ```bash
59
+ npm whoami # 确认已登录
60
+ npm publish --access public
61
+ ```
62
+
63
+ ### 7. 创建 GitHub Release
45
64
 
46
- # Install locally for testing
47
- cp dist/extension.js dist/mcp-entry.js ~/.vscode/extensions/hcdb.bashterm-<version>/dist/
65
+ ```bash
66
+ gh release create v0.2.1 \
67
+ --title "v0.2.1 — BashTerm MCP" \
68
+ --notes "从 CHANGELOG.md 复制改动内容" \
69
+ bashterm-mcp-server-0.2.1.vsix
48
70
  ```
49
71
 
50
- ### 5. Upload to VSCode Marketplace
72
+ ### 8. 上传 VSCode Marketplace
73
+
74
+ 1. 打开 https://marketplace.visualstudio.com/manage/publishers/hcdb
75
+ 2. 找到 BashTerm MCP → `...` → **Update**
76
+ 3. 上传 `.vsix`
51
77
 
52
- 1. Go to https://marketplace.visualstudio.com/manage/publishers/hcdb
53
- 2. Click "..." next to BashTerm MCP → "Update"
54
- 3. Upload the `.vsix` file
78
+ > 备选:配置 Azure DevOps PAT 后可用 `npx vsce publish` 一键发布。
55
79
 
56
- ### 6. Commit and push
80
+ ### 9. 提交和推送
57
81
 
58
82
  ```bash
59
83
  git add -A
60
- git commit -m "v0.1.7: <summary of changes>"
84
+ git commit -m "v0.2.1:<变更摘要>"
61
85
  git push
62
86
  ```
63
87
 
88
+ ### 10. 验证
89
+
90
+ - [ ] `npx bashterm-mcp-server@latest` 正常启动
91
+ - [ ] VSCode 扩展商店搜索 "BashTerm MCP" 显示新版本
92
+ - [ ] https://www.npmjs.com/package/bashterm-mcp-server 显示新版本
93
+ - [ ] GitHub Release 徽章显示新版本号
94
+ - [ ] README.md 和 README.zh-CN.md 的徽章链接全部正常
95
+
96
+ ---
97
+
64
98
  ## Extension Cache Workaround
65
99
 
66
100
  VSCode aggressively caches extensions. When developing locally:
@@ -68,17 +102,8 @@ VSCode aggressively caches extensions. When developing locally:
68
102
  ```bash
69
103
  # Quick update (after modifying source)
70
104
  npm run build
71
- cp dist/extension.js ~/.vscode/extensions/hcdb.bashterm-<version>/dist/extension.js
105
+ cp dist/extension.js ~/.vscode/extensions/hcdb.bashterm-mcp-server-<version>/dist/extension.js
72
106
  # Then "Developer: Reload Window"
73
107
 
74
108
  # If reload doesn't pick up changes, close and reopen VSCode completely
75
109
  ```
76
-
77
- ## Terminal Execution
78
-
79
- Prefer the BashTerm MCP tools (`run`, `exec`, `read`, etc.) over the built-in Bash tool for executing commands. BashTerm runs commands in visible VSCode terminal tabs where the user can see output in real time.
80
-
81
- For commands that may take longer than 30 seconds or produce large output, use pull mode:
82
- 1. Call `run` with `waitForCompletion: false`
83
- 2. Call `read` with `offset: -10` to check progress
84
- 3. Repeat until done
package/README.md CHANGED
@@ -1,312 +1,122 @@
1
- # BashTerm
2
-
3
- [![中文文档](https://img.shields.io/badge/README-中文-red)](README.zh-CN.md) [![GitHub Release](https://img.shields.io/github/v/release/1170953489/bashterm-mcp-server-mcp)](https://github.com/1170953489/bashterm-mcp-server-mcp/releases) [![npm version](https://img.shields.io/npm/v/bashterm-mcp-server-mcp)](https://www.npmjs.com/package/bashterm-mcp-server) [![VSIX](https://img.shields.io/github/v/release/1170953489/bashterm-mcp-server-mcp?label=vsix&color=blue)](https://github.com/1170953489/bashterm-mcp-server-mcp/releases)
4
-
5
- MCP server that executes commands in **visible VSCode terminal tabs** with full output capture. Unlike inline execution, every command runs in a real terminal you can see, scroll, and interact with.
6
-
7
- ## Key Features
8
-
9
- - **Visible Terminals**: Commands run in real VSCode terminal tabs, not hidden processes. You see everything in real time.
10
- - **Session Reuse**: The `run` tool automatically reuses idle sessions, creating new terminals only when needed.
11
- - **Long-Running Support**: Fire-and-forget execution with `waitForCompletion: false`, then poll output incrementally with `read`.
12
- - **Subagent Isolation**: Tag sessions with `agentId` to keep parallel agent workloads separated.
13
-
14
- > **Windows Compatible** This fork fully supports Windows, including Chinese output without garbled text.
15
-
16
- ## Requirements
17
-
18
- - VS Code 1.93+
19
- - Node.js 20+
20
-
21
- ## Getting Started
22
-
23
- ### Claude Code
24
-
25
- ```bash
26
- claude mcp add BashTerm -- npx bashterm-mcp-server-mcp-server@latest
27
- ```
28
-
29
- ### VS Code / Copilot
30
-
31
- Add to your `.vscode/mcp.json`:
32
-
33
- ```json
34
- {
35
- "servers": {
36
- "BashTerm": {
37
- "type": "stdio",
38
- "command": "npx",
39
- "args": ["bashterm-mcp-server-mcp-server@latest"]
40
- }
41
- }
42
- }
43
- ```
44
-
45
- <details>
46
- <summary>Cursor</summary>
47
-
48
- Add to your `.cursor/mcp.json`:
49
-
50
- ```json
51
- {
52
- "mcpServers": {
53
- "BashTerm": {
54
- "command": "npx",
55
- "args": ["-y", "bashterm-mcp-server-mcp-server@latest"]
56
- }
57
- }
58
- }
59
- ```
60
-
61
- </details>
62
-
63
- <details>
64
- <summary>Claude Desktop</summary>
65
-
66
- Add to your `claude_desktop_config.json`:
67
-
68
- ```json
69
- {
70
- "mcpServers": {
71
- "BashTerm": {
72
- "command": "npx",
73
- "args": ["-y", "bashterm-mcp-server-mcp-server@latest"]
74
- }
75
- }
76
- }
77
- ```
78
-
79
- </details>
80
-
81
- ### Your First Prompt
82
-
83
- After installation, try asking:
84
-
85
- > Run `ls -la` in the terminal
86
-
87
- You should see a new terminal tab open in VSCode with the command output.
88
-
89
- ## Screenshots
90
-
91
- ### Running a command with `run`
92
-
93
- ![Run command output](docs/images/run_finished.png)
94
-
95
- ### Permission dialog for `exec`
96
-
97
- ![Exec permission dialog](docs/images/ask_exec_permission.png)
98
-
99
- ### Exec result with clean output
100
-
101
- ![Exec finished](docs/images/exec_finished.png)
102
-
103
- ## Tools
104
-
105
- ### Quick Execution
106
-
107
- | Tool | Description |
108
- |------|-------------|
109
- | `run` | Create (or reuse) a terminal and execute a command in one step. Returns clean output with exit code. |
110
-
111
- ### Session Management
112
-
113
- | Tool | Description |
114
- |------|-------------|
115
- | `create` | Create a new visible terminal session. Returns a `sessionId`. |
116
- | `exec` | Execute a command in an existing session and capture output. |
117
- | `read` | Read output from a session with pagination. Supports incremental reads and tail mode (`offset: -N`). |
118
- | `input` | Send text to an interactive terminal (prompts, REPLs, confirmations). |
119
- | `list` | List active sessions. Optionally filter by `agentId`. |
120
- | `close` | Close a terminal session and its VSCode tab. |
121
-
122
- ## Usage Patterns
123
-
124
- ### Simple Command
125
-
126
- The `run` tool handles everything — creates a terminal if needed, executes, and returns clean output:
127
-
128
- ```
129
- > Run npm test
130
- ```
131
-
132
- ```
133
- $ npm test
134
- PASS src/utils.test.ts (3 tests)
135
- PASS src/index.test.ts (5 tests)
136
-
137
- [exit: 0 | 1243ms | session-abc123]
138
- ```
139
-
140
- ### Long-Running Process
141
-
142
- For builds, deployments, or any command that takes a while:
143
-
144
- ```
145
- > Start `npm run build` without waiting, then check progress
146
- ```
147
-
148
- The agent will:
149
- 1. Call `run` with `waitForCompletion: false` — returns immediately
150
- 2. Call `read` with `offset: -10` to check the last 10 lines
151
- 3. Repeat until the process completes
152
-
153
- ### Interactive Commands
154
-
155
- For commands that need user input:
156
-
157
- ```
158
- > Run npm init and answer the prompts
159
- ```
160
-
161
- The agent will:
162
- 1. Call `run` with `npm init`
163
- 2. Call `read` to see the prompt
164
- 3. Call `input` to send the answer
165
-
166
- ### Parallel Agents
167
-
168
- Subagents can work in isolated terminals using `agentId`:
169
-
170
- ```
171
- > Have one agent run tests while another runs the linter
172
- ```
173
-
174
- Each subagent gets its own terminal tagged with its `agentId`, preventing output from mixing.
175
-
176
- ## Configuration
177
-
178
- The extension reads configuration from VSCode settings under `bashterm-mcp-server-mcp-server.*`:
179
-
180
- | Setting | Type | Default | Description |
181
- |---------|------|---------|-------------|
182
- | `bashterm-mcp-server-mcp-server.maxSessions` | number | 10 | Maximum concurrent terminal sessions |
183
- | `bashterm-mcp-server-mcp-server.commandTimeout` | number | 30000 | Default command timeout in ms |
184
- | `bashterm-mcp-server-mcp-server.maxOutputLines` | number | 5000 | Max lines kept in output buffer per session |
185
- | `bashterm-mcp-server-mcp-server.idleTimeout` | number | 1800000 | Close idle sessions after this many ms (0 = disabled) |
186
- | `bashterm-mcp-server-mcp-server.blockedCommands` | string[] | `["rm -rf /"]` | Commands that will be rejected |
187
-
188
- ## Recommended: Set as Preferred Tool
189
-
190
- LLM agents like Claude Code have a built-in `Bash` tool that executes commands inline within the chat. The output is embedded in the conversation and hard to read, especially for commands with verbose output. **We recommend telling the agent to prefer this MCP over its built-in Bash tool.**
191
-
192
- Add the following to your project's `CLAUDE.md` (or equivalent instructions file):
193
-
194
- ```markdown
195
- ## Terminal Execution
196
-
197
- Prefer the BashTerm MCP tools (`run`, `exec`, `read`, etc.) over the built-in Bash tool for executing commands.
198
- BashTerm runs commands in visible VSCode terminal tabs where the user can see output in real time.
199
- Only fall back to the built-in Bash tool for simple, non-interactive operations like reading environment variables.
200
-
201
- For commands that may take longer than 30 seconds or produce large amounts of output (builds, test suites,
202
- deployments, installs), use the pull mode pattern:
203
- 1. Call `run` with `waitForCompletion: false` to launch the command without blocking.
204
- 2. Call `read` with `offset: -10` to check the last 10 lines of output.
205
- 3. Repeat step 2 until you see the command has finished (look for exit messages, prompts, or "Done").
206
- 4. Report the final result to the user.
207
-
208
- This prevents conversation timeouts and lets the user watch progress in the terminal in real time.
209
- ```
210
-
211
- **Why this matters:**
212
-
213
- | | Built-in Bash | BashTerm MCP |
214
- |---|---|---|
215
- | Output visibility | Embedded in chat, hard to scroll | Visible in VSCode terminal tab |
216
- | Real-time feedback | User sees nothing until command finishes | User watches output live |
217
- | Long-running commands | Blocks the conversation until timeout | Fire-and-forget + polling |
218
- | Session state | Each command is isolated | Persistent sessions with history |
219
- | Interactive commands | Not supported | Send input to prompts/REPLs |
220
-
221
- ## Development: Updating the Extension
222
-
223
- VSCode aggressively caches extensions in memory. When developing locally, `code --install-extension` and even "Developer: Reload Window" may **not** reload your changes. Use this workflow:
224
-
225
- ### Quick update (no restart needed)
226
-
227
- After modifying source files, build and copy directly into the installed extension directory:
228
-
229
- ```bash
230
- cd /path/to/bashterm-mcp-server-mcp
231
- npm run build
232
- cp dist/extension.js ~/.vscode/extensions/hcdb.bashterm-mcp-server-<version>/dist/extension.js
233
- ```
234
-
235
- Then run **"Developer: Reload Window"** (`Ctrl+Shift+P`).
236
-
237
- ### Full reinstall (when quick update doesn't work)
238
-
239
- If VSCode still uses old code:
240
-
241
- ```bash
242
- # 1. Uninstall and remove all copies
243
- code --uninstall-extension hcdb.bashterm
244
- rm -rf ~/.vscode/extensions/hcdb.bashterm-mcp-server-*
245
-
246
- # 2. Check for ghost entries with old publisher names
247
- # Look in ~/.vscode/extensions/extensions.json for stale entries
248
- # Remove any entries with old publisher IDs
249
-
250
- # 3. Close VSCode completely (not just reload)
251
-
252
- # 4. Rebuild and install
253
- npm run build
254
- npx vsce package --allow-missing-repository
255
- code --install-extension bashterm-mcp-server-<version>.vsix --force
256
-
257
- # 5. Open VSCode
258
- ```
259
-
260
- ### Verify the correct version is loaded
261
-
262
- ```bash
263
- # Check which extension directories exist
264
- ls ~/.vscode/extensions/ | grep terminal
265
-
266
- # Verify your changes are in the installed extension
267
- grep "YOUR_UNIQUE_STRING" ~/.vscode/extensions/hcdb.bashterm-mcp-server-*/dist/extension.js
268
-
269
- # Compare checksums
270
- md5sum dist/extension.js ~/.vscode/extensions/hcdb.bashterm-mcp-server-*/dist/extension.js
271
- ```
272
-
273
- ## Large Output Handling
274
-
275
- When `read` returns output that exceeds the MCP client's token limit, the system automatically saves the full output to a temporary JSON file and returns the file path in the error message.
276
-
277
- To extract the relevant content:
278
-
279
- ```bash
280
- # Get the last 50 lines (most relevant for status)
281
- tail -50 /path/to/saved/file.txt
282
-
283
- # Or parse the JSON to extract the text content
284
- python3 -c "import json; data=json.load(open('/path/to/file.txt')); print(data[0]['text'][-2000:])"
285
- ```
286
-
287
- The file format is JSON: `[{"type": "text", "text": "..."}]`
288
-
289
- This commonly happens with commands that produce heavy TUI output (progress bars, ANSI escape codes). Use smaller `offset` values (e.g., `offset: -20` instead of `offset: -100`) to reduce the captured output size.
290
-
291
- ## How It Works
292
-
293
- 1. The **VSCode extension** activates and starts an IPC server (Named Pipe on Windows, Unix socket on macOS/Linux)
294
- 2. The **MCP entry point** (`mcp-entry.js`) is spawned by the MCP client and bridges JSON-RPC stdio with the IPC socket
295
- 3. Commands execute via `child_process.exec()` for reliable cross-platform output capture and exit code detection
296
- 4. Output is stored in circular buffers with pagination support for efficient reading
297
-
298
- ## Latest Changes (0.2.0)
299
-
300
- - **Command allowlist**: New `allowedCommands` config to restrict which commands can run
301
- - **Session idle reaper**: Auto-close inactive terminals after 5 minutes (configurable, disable with `0`)
302
- - **Bug fixes**: Fixed duplicate output from Shell Integration + exec, negative buffer index, notification memory leak
303
- - **Performance**: Batch buffer eviction replaces per-line shift (O(n×m) → O(n+m))
304
- - **Better session reuse**: Now matches `env` and `shell` config when reusing terminals
305
- - **Shell-ready detection**: Replaces hardcoded 500ms delay with proper detection + 2s fallback
306
- - **Code cleanup**: Enabled CommandGuard, extracted shared formatting, dynamic version reading from package.json
307
-
308
- See [CHANGELOG.md](CHANGELOG.md) for full history.
309
-
310
- ## License
311
-
312
- MIT
1
+ # BashTerm MCP
2
+
3
+ [![中文文档](https://img.shields.io/badge/README-中文-red)](README.zh-CN.md) [![release](https://img.shields.io/npm/v/bashterm-mcp-server?label=release)](https://github.com/1170953489/bashterm-mcp/releases) [![npm version](https://img.shields.io/npm/v/bashterm-mcp-server)](https://www.npmjs.com/package/bashterm-mcp-server)
4
+
5
+ Run AI-generated shell commands in **real, visible VSCode terminals**.
6
+
7
+ BashTerm MCP turns Claude Code command execution into something you can see, inspect, interrupt, and continue. Instead of hidden shell calls, commands open in normal VSCode terminal tabs with live output, scrollback, interactive input, reusable sessions, and safety controls.
8
+
9
+ ## Why BashTerm MCP
10
+
11
+ - **Visible by default**: Every command runs in a real VSCode terminal tab, so you can watch builds, tests, logs, and failures as they happen.
12
+ - **Claude Code ready**: The extension registers its MCP server automatically and can guide Claude Code away from the hidden built-in `Bash` tool.
13
+ - **Long-task friendly**: Start commands without blocking the agent, then read output incrementally while the process keeps running.
14
+ - **Interactive when needed**: Answer prompts, drive REPLs, confirm commands, or send Ctrl+C-style input through the same terminal session.
15
+ - **Session reuse**: Keep context in a terminal instead of creating a fresh process for every command.
16
+ - **Parallel-agent isolation**: Use `agentId` to keep multiple AI workers in separate, readable terminals.
17
+ - **Practical guardrails**: Block dangerous command prefixes, restrict working directories, cap output buffers, and auto-close idle sessions.
18
+ - **Safe rollback**: Disable the Claude Code auto-hook or run a restore command to return to Claude Code's default Bash behavior.
19
+
20
+ ## Install
21
+
22
+ 1. Install **BashTerm MCP** from the [VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=hcdb.bashterm-mcp-server).
23
+ 2. Open VSCode.
24
+ 3. Use Claude Code normally.
25
+
26
+ The extension automatically registers the MCP server through `contributes.mcpServers`, so tools such as `run`, `exec`, `read`, and `input` are available without manual MCP JSON setup.
27
+
28
+ ## Claude Code Integration
29
+
30
+ BashTerm MCP can write a user-level PreToolUse hook to `~/.claude/settings.json`. That hook blocks Claude Code's built-in hidden `Bash` tool and tells Claude Code to use BashTerm MCP tools instead, keeping command execution visible inside VSCode.
31
+
32
+ You stay in control:
33
+
34
+ - Turn it off with `bashterm-mcp-server.autoConfigureClaudeCode`.
35
+ - Restore default Bash with `BashTerm MCP: Restore Claude Code Default Bash` from the Command Palette.
36
+ - Disable or uninstall the extension safely: it removes its own Claude Code hook during deactivation.
37
+
38
+ ## Screenshots
39
+
40
+ ![Run command output](docs/images/run_finished.png)
41
+ ![Exec permission dialog](docs/images/ask_exec_permission.png)
42
+ ![Exec finished](docs/images/exec_finished.png)
43
+
44
+ ## Common Workflows
45
+
46
+ ### Run a Command
47
+
48
+ Ask Claude Code:
49
+
50
+ ```text
51
+ Run npm test
52
+ ```
53
+
54
+ BashTerm MCP creates or reuses a visible terminal, runs the command, and returns clean output with the exit code.
55
+
56
+ ### Watch a Long Build
57
+
58
+ ```text
59
+ Start npm run build without waiting, then monitor progress
60
+ ```
61
+
62
+ The agent can launch the command with `waitForCompletion: false`, then poll output with `read` while you watch the same terminal live in VSCode.
63
+
64
+ ### Handle Interactive Prompts
65
+
66
+ ```text
67
+ Run npm init and answer the prompts
68
+ ```
69
+
70
+ The agent can start the process, read the prompt, send input, and continue step by step in the visible terminal.
71
+
72
+ ### Separate Parallel Agents
73
+
74
+ ```text
75
+ Have one agent run tests while another runs the linter
76
+ ```
77
+
78
+ Each agent can receive its own `agentId`, keeping terminal sessions and output streams separate.
79
+
80
+ ## Tools
81
+
82
+ | Tool | What it does |
83
+ |------|--------------|
84
+ | `run` | Create or reuse a terminal and run a command in one step. |
85
+ | `create` | Open a visible terminal tab and return a `sessionId`. |
86
+ | `exec` | Run a command in an existing session and capture output. |
87
+ | `read` | Read session output with offset-based pagination or tail mode. |
88
+ | `input` | Send text to an interactive process. |
89
+ | `list` | List active sessions, optionally filtered by `agentId`. |
90
+ | `close` | Close a session and its terminal tab. |
91
+
92
+ ## Configuration
93
+
94
+ Configure BashTerm MCP from VSCode settings under `bashterm-mcp-server.*`.
95
+
96
+ | Setting | Type | Default | Description |
97
+ |---------|------|---------|-------------|
98
+ | `bashterm-mcp-server.autoConfigureClaudeCode` | boolean | `true` | Automatically configure Claude Code to prefer BashTerm MCP over the built-in `Bash` tool. |
99
+ | `bashterm-mcp-server.blockedCommands` | string[] | `["rm -rf /", "mkfs", "dd if=", ":(){ :|:& };:"]` | Command prefixes that are always rejected. |
100
+ | `bashterm-mcp-server.allowedDirectories` | string[] | `[]` | Allowed working directories. Empty means unrestricted. |
101
+ | `bashterm-mcp-server.defaultTimeoutMs` | number | `30000` | Default command timeout in milliseconds. |
102
+ | `bashterm-mcp-server.maxConcurrentSessions` | number | `10` | Maximum number of concurrent terminal sessions. |
103
+ | `bashterm-mcp-server.maxOutputLines` | number | `10000` | Maximum output lines buffered per session. |
104
+ | `bashterm-mcp-server.idleTimeoutMs` | number | `300000` | Auto-close idle sessions after this many milliseconds. `0` disables it. |
105
+
106
+ ## Requirements
107
+
108
+ - VSCode 1.99+
109
+ - Node.js 20+
110
+ - Claude Code or another MCP-capable client
111
+
112
+ ## When It Helps Most
113
+
114
+ BashTerm MCP is especially useful when the agent needs to run commands you care about observing: tests, package installs, dev servers, migrations, scaffolding tools, deploy scripts, and any command that might ask for input or run longer than a few seconds.
115
+
116
+ ## Changelog
117
+
118
+ See [CHANGELOG.md](CHANGELOG.md) for release history.
119
+
120
+ ## License
121
+
122
+ MIT
package/README.zh-CN.md CHANGED
@@ -1,235 +1,121 @@
1
- # BashTerm
1
+ # BashTerm MCP
2
2
 
3
- [![English](https://img.shields.io/badge/README-English-blue)](README.md) [![GitHub Release](https://img.shields.io/github/v/release/1170953489/bashterm-mcp)](https://github.com/1170953489/bashterm-mcp/releases) [![npm version](https://img.shields.io/npm/v/bashterm-mcp)](https://www.npmjs.com/package/bashterm-mcp-server) [![VSIX](https://img.shields.io/github/v/release/1170953489/bashterm-mcp?label=vsix&color=blue)](https://github.com/1170953489/bashterm-mcp/releases)
3
+ [![English](https://img.shields.io/badge/README-English-blue)](README.md) [![release](https://img.shields.io/npm/v/bashterm-mcp-server?label=release)](https://github.com/1170953489/bashterm-mcp/releases) [![npm version](https://img.shields.io/npm/v/bashterm-mcp-server)](https://www.npmjs.com/package/bashterm-mcp-server)
4
4
 
5
- **VSCode 可见的终端标签页**中执行命令的 MCP 服务器,支持完整输出捕获。与内联执行不同,每个命令都在真正的终端中运行,你可以看到、滚动并与之交互。
5
+ AI 生成的 shell 命令在 **真实可见的 VSCode 终端**里运行。
6
6
 
7
- > **Windows 兼容版本** fork 完整支持 Windows 平台,包括中文输出不乱码。
7
+ BashTerm MCP Claude Code 的命令执行变成你能看见、能检查、能中断、能继续交互的过程。不再是隐藏的后台 Bash 调用,而是普通 VSCode 终端标签页:实时输出、历史滚动、交互输入、会话复用和安全控制都在你眼前。
8
8
 
9
- ## 核心功能
9
+ ## 为什么选择 BashTerm MCP
10
10
 
11
- - **可见终端**:命令在真实的 VSCode 终端标签页中运行,而非隐藏进程。你可以实时查看所有输出。
12
- - **会话复用**:`run` 工具会自动复用空闲会话,仅在需要时创建新终端。
13
- - **长时间运行支持**:使用 `waitForCompletion: false` 实现"发射后不管"模式,随后用 `read` 逐步获取输出。
14
- - **子代理隔离**:通过 `agentId` 标记会话,将并行代理的工作负载彼此隔离。
15
- - **跨平台**:支持 Windows、macOS、Linux。Windows 上中文输出自动解码不乱码。
11
+ - **默认可见**:每条命令都在真实 VSCode 终端标签页中运行,测试、构建、日志和报错都能实时看到。
12
+ - **开箱支持 Claude Code**:扩展会自动注册 MCP server,并可引导 Claude Code 使用 BashTerm MCP 替代隐藏的内置 `Bash`。
13
+ - **适合长任务**:命令可以非阻塞启动,进程持续运行时再增量读取输出。
14
+ - **支持交互命令**:可以回答提示、驱动 REPL、确认操作,或向同一个终端会话继续发送输入。
15
+ - **会话复用**:复用已有终端上下文,减少每条命令都新开进程带来的割裂感。
16
+ - **并行代理隔离**:通过 `agentId` 让多个 AI worker 使用不同终端,输出清晰不串台。
17
+ - **实用安全边界**:支持危险命令前缀拦截、工作目录限制、输出缓冲上限和空闲会话自动关闭。
18
+ - **可安全回退**:可关闭 Claude Code 自动 hook,或一键恢复 Claude Code 默认 Bash 行为。
16
19
 
17
- ## 环境要求
20
+ ## 安装
18
21
 
19
- - VS Code 1.93+
20
- - Node.js 20+
22
+ 1. 从 [VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=hcdb.bashterm-mcp-server) 安装 **BashTerm MCP**。
23
+ 2. 打开 VSCode。
24
+ 3. 正常使用 Claude Code。
21
25
 
22
- ## 快速开始
26
+ 扩展会通过 `contributes.mcpServers` 自动注册 MCP server,`run`、`exec`、`read`、`input` 等工具无需手写 MCP JSON 配置即可使用。
23
27
 
24
- ### Claude Code
28
+ ## Claude Code 集成
25
29
 
26
- ```bash
27
- claude mcp add BashTerm -- npx bashterm-mcp-server@latest
28
- ```
30
+ BashTerm MCP 可以向用户级 `~/.claude/settings.json` 写入 PreToolUse hook。这个 hook 会拦截 Claude Code 隐藏的内置 `Bash` 工具,并提示 Claude Code 改用 BashTerm MCP 工具,让命令执行保持在 VSCode 可见终端中。
29
31
 
30
- 或使用本 fork 的 Windows 优化版本:
32
+ 控制权始终在用户手里:
31
33
 
32
- ```bash
33
- # 下载 .vsix 安装包
34
- # Release 页面下载 bashterm-0.1.8.vsix
35
- code --install-extension bashterm-0.1.8.vsix
34
+ - 关闭 `bashterm-mcp-server.autoConfigureClaudeCode` 即可停用自动 hook。
35
+ - 在命令面板执行 `BashTerm MCP: Restore Claude Code Default Bash` 可恢复默认 Bash。
36
+ - 直接禁用或卸载扩展也安全:扩展停用时会移除自己写入的 Claude Code hook。
36
37
 
37
- # 添加 MCP 服务器(使用本地扩展内置的 mcp-entry)
38
- claude mcp add BashTerm -- node "C:\Users\<用户名>\.vscode\extensions\hcdb.bashterm-0.1.8\dist\mcp-entry.js"
39
- ```
38
+ ## 截图
40
39
 
41
- ### VS Code / Copilot
40
+ ![Run command output](docs/images/run_finished.png)
41
+ ![Exec permission dialog](docs/images/ask_exec_permission.png)
42
+ ![Exec finished](docs/images/exec_finished.png)
42
43
 
43
- `.vscode/mcp.json` 中添加:
44
+ ## 常见使用场景
44
45
 
45
- ```json
46
- {
47
- "servers": {
48
- "BashTerm": {
49
- "type": "stdio",
50
- "command": "npx",
51
- "args": ["bashterm-mcp-server@latest"]
52
- }
53
- }
54
- }
55
- ```
56
-
57
- <details>
58
- <summary>Cursor</summary>
46
+ ### 运行普通命令
59
47
 
60
- `.cursor/mcp.json` 中添加:
48
+ 告诉 Claude Code:
61
49
 
62
- ```json
63
- {
64
- "mcpServers": {
65
- "BashTerm": {
66
- "command": "npx",
67
- "args": ["-y", "bashterm-mcp-server@latest"]
68
- }
69
- }
70
- }
50
+ ```text
51
+ 运行 npm test
71
52
  ```
72
53
 
73
- </details>
74
-
75
- <details>
76
- <summary>Claude Desktop</summary>
77
-
78
- 在 `claude_desktop_config.json` 中添加:
79
-
80
- ```json
81
- {
82
- "mcpServers": {
83
- "BashTerm": {
84
- "command": "npx",
85
- "args": ["-y", "bashterm-mcp-server@latest"]
86
- }
87
- }
88
- }
89
- ```
90
-
91
- </details>
92
-
93
- ### 你的第一个提示
94
-
95
- 安装完成后,试试问:
96
-
97
- > 在终端中运行 `ls -la`
98
-
99
- 你应该能在 VSCode 中看到一个新的终端标签页打开,并显示命令输出。
100
-
101
- ## 工具
102
-
103
- ### 快速执行
104
-
105
- | 工具 | 说明 |
106
- |------|------|
107
- | `run` | 一步创建(或复用)终端并执行命令,返回清洁输出和退出码。 |
108
-
109
- ### 会话管理
110
-
111
- | 工具 | 说明 |
112
- |------|------|
113
- | `create` | 创建新的可见终端会话,返回 `sessionId`。 |
114
- | `exec` | 在已有会话中执行命令并捕获输出。 |
115
- | `read` | 分页读取会话输出,支持增量读取和 tail 模式(`offset: -N`)。 |
116
- | `input` | 向交互式终端发送文本(用于提示、REPL、确认等)。 |
117
- | `list` | 列出活动会话,可选按 `agentId` 过滤。 |
118
- | `close` | 关闭终端会话及其 VSCode 标签页。 |
119
-
120
- ## 使用模式
121
-
122
- ### 简单命令
54
+ BashTerm MCP 会创建或复用一个可见终端,执行命令,并返回清洁输出和退出码。
123
55
 
124
- `run` 工具处理一切——按需创建终端、执行命令、返回清洁输出:
56
+ ### 观察长时间构建
125
57
 
58
+ ```text
59
+ 启动 npm run build,不要等待结束,然后持续查看进度
126
60
  ```
127
- > 运行 npm test
128
- ```
129
-
130
- ```
131
- $ npm test
132
- PASS src/utils.test.ts (3 tests)
133
- PASS src/index.test.ts (5 tests)
134
61
 
135
- [exit: 0 | 1243ms | session-abc123]
136
- ```
62
+ 代理可以用 `waitForCompletion: false` 启动命令,再通过 `read` 轮询输出;同时你也能在 VSCode 终端里实时观察同一个进程。
137
63
 
138
- ### 长时间运行
64
+ ### 处理交互式提示
139
65
 
140
- 对于构建、部署或其他耗时命令:
141
-
142
- ```
143
- > 启动 npm run build 不等待,然后检查进度
66
+ ```text
67
+ 运行 npm init 并回答提示
144
68
  ```
145
69
 
146
- 代理会:
147
- 1. 调用 `run` 设置 `waitForCompletion: false` —— 立即返回
148
- 2. 调用 `read` 设置 `offset: -10` 查看最后 10 行
149
- 3. 重复直到进程完成
150
-
151
- ### 交互式命令
70
+ 代理可以启动进程、读取提示、发送输入,然后一步步驱动交互式命令。
152
71
 
153
- 对于需要用户输入的命令:
72
+ ### 隔离并行代理
154
73
 
74
+ ```text
75
+ 让一个代理跑测试,另一个代理跑 lint
155
76
  ```
156
- > 运行 npm init 并回答提示
157
- ```
158
-
159
- 代理会:
160
- 1. 调用 `run` 执行 `npm init`
161
- 2. 调用 `read` 查看提示
162
- 3. 调用 `input` 发送答案
163
-
164
- ### 并行代理
165
77
 
166
- 子代理可以使用 `agentId` 在隔离的终端中工作:
78
+ 每个代理都可以带上自己的 `agentId`,终端会话和输出流彼此分离。
167
79
 
168
- ```
169
- > 让一个代理运行测试,另一个运行代码检查
170
- ```
80
+ ## 工具列表
171
81
 
172
- 每个子代理获得自己的终端,标记其 `agentId`,防止输出混淆。
82
+ | 工具 | 功能 |
83
+ |------|------|
84
+ | `run` | 创建或复用终端,并一步执行命令。 |
85
+ | `create` | 打开可见终端标签页并返回 `sessionId`。 |
86
+ | `exec` | 在已有会话中执行命令并捕获输出。 |
87
+ | `read` | 按偏移量分页读取输出,或进入 tail 模式。 |
88
+ | `input` | 向交互式进程发送文本。 |
89
+ | `list` | 列出活动会话,可按 `agentId` 过滤。 |
90
+ | `close` | 关闭会话及其终端标签页。 |
173
91
 
174
92
  ## 配置
175
93
 
176
- 扩展从 VSCode 设置中读取 `bashterm-mcp-server.*` 配置:
94
+ 可在 VSCode 设置中配置 `bashterm-mcp-server.*`。
177
95
 
178
96
  | 设置项 | 类型 | 默认值 | 说明 |
179
97
  |--------|------|--------|------|
180
- | `bashterm-mcp-server.maxSessions` | number | 10 | 最大并发终端会话数 |
181
- | `bashterm-mcp-server.commandTimeout` | number | 30000 | 默认命令超时(毫秒) |
182
- | `bashterm-mcp-server.maxOutputLines` | number | 5000 | 每个会话最大缓冲输出行数 |
183
- | `bashterm-mcp-server.idleTimeout` | number | 1800000 | 空闲会话自动关闭时间(毫秒,0=禁用) |
184
- | `bashterm-mcp-server.blockedCommands` | string[] | `["rm -rf /"]` | 禁止执行的命令列表 |
185
-
186
- ## 推荐:设为优先工具
187
-
188
- 像 Claude Code 这样的 LLM 代理内置了 `Bash` 工具,会在聊天中内联执行命令。输出嵌入在对话中,难以阅读,尤其是输出冗长的命令。**建议告诉代理优先使用本 MCP 工具,而非内置 Bash 工具。**
189
-
190
- 将以下内容添加到项目的 `CLAUDE.md`(或等效指令文件)中:
191
-
192
- ```markdown
193
- ## 终端执行
194
-
195
- 优先使用 BashTerm MCP 工具(`run`、`exec`、`read` 等)来执行命令,而不是使用内置的 Bash 工具。
196
- BashTerm 在可见的 VSCode 终端标签页中运行命令,用户可以实时查看输出。
197
- 仅在简单、非交互式操作(如读取环境变量)时回退到内置 Bash 工具。
98
+ | `bashterm-mcp-server.autoConfigureClaudeCode` | boolean | `true` | 自动配置 Claude Code,使其优先使用 BashTerm MCP 而不是内置 `Bash`。 |
99
+ | `bashterm-mcp-server.blockedCommands` | string[] | `["rm -rf /", "mkfs", "dd if=", ":(){ :|:& };:"]` | 始终拒绝执行的命令前缀。 |
100
+ | `bashterm-mcp-server.allowedDirectories` | string[] | `[]` | 允许的工作目录。为空表示不限制。 |
101
+ | `bashterm-mcp-server.defaultTimeoutMs` | number | `30000` | 默认命令超时时间,单位毫秒。 |
102
+ | `bashterm-mcp-server.maxConcurrentSessions` | number | `10` | 最大并发终端会话数。 |
103
+ | `bashterm-mcp-server.maxOutputLines` | number | `10000` | 每个会话最多缓冲的输出行数。 |
104
+ | `bashterm-mcp-server.idleTimeoutMs` | number | `300000` | 空闲会话自动关闭时间,单位毫秒。`0` 表示禁用。 |
198
105
 
199
- 对于可能超过 30 秒或产生大量输出的命令(构建、测试套件、部署、安装),使用 pull 模式:
200
- 1. 调用 `run` 设置 `waitForCompletion: false` 启动命令但不阻塞。
201
- 2. 调用 `read` 设置 `offset: -10` 查看最后 10 行输出。
202
- 3. 重复步骤 2 直到看到命令完成(查找退出消息、提示或 "Done")。
203
- 4. 向用户报告最终结果。
204
-
205
- 这样可以防止对话超时,并让用户实时观察终端进度。
206
- ```
207
-
208
- **为什么重要:**
209
-
210
- | | 内置 Bash | BashTerm MCP |
211
- |---|---|---|
212
- | 输出可见性 | 嵌入聊天,难以滚动 | 在 VSCode 终端标签页中可见 |
213
- | 实时反馈 | 用户看不到任何输出直到命令完成 | 用户实时观看输出 |
214
- | 长时间命令 | 阻塞对话直到超时 | 发射后不管 + 轮询 |
215
- | 会话状态 | 每个命令隔离 | 持久化会话,带历史 |
216
- | 交互式命令 | 不支持 | 可向提示/REPL 发送输入 |
106
+ ## 环境要求
217
107
 
218
- ## 工作方式
108
+ - VSCode 1.99+
109
+ - Node.js 20+
110
+ - Claude Code 或其它支持 MCP 的客户端
219
111
 
220
- 1. **VSCode 扩展**激活并启动 IPC 服务器(Windows 上使用 Named Pipe,其他平台使用 Unix Socket)
221
- 2. **MCP 入口**(`mcp-entry.js`)由 MCP 客户端启动,在 JSON-RPC stdio 和 IPC socket 之间建立桥接
222
- 3. 命令通过 `child_process.exec()` 执行,输出直接捕获,不再依赖 Shell Integration API
223
- 4. 输出存储在循环缓冲区中,支持分页高效读取
112
+ ## 适合什么场景
224
113
 
225
- ## 最新更新 (0.1.8)
114
+ BashTerm MCP 特别适合那些你希望亲眼观察的命令:测试、包安装、开发服务器、数据库迁移、脚手架工具、部署脚本,以及任何可能需要输入或运行时间较长的命令。
226
115
 
227
- - **项目改名 bashterm-mcp**:全面清理旧名称 vscode-terminal-mcp 引用
228
- - **修复 bin 路径**:更正 npm 二进制入口路径
229
- - **动态版本图标**:badge 徽章现在反映实际版本号
230
- - 中文 README 补充版本徽章
116
+ ## 更新日志
231
117
 
232
- 详见 [CHANGELOG.md](CHANGELOG.md) 查看完整历史。
118
+ 完整历史见 [CHANGELOG.md](CHANGELOG.md)
233
119
 
234
120
  ## 许可证
235
121
 
package/dist/extension.js CHANGED
@@ -5389,7 +5389,7 @@ var zodToJsonSchema = (schema, options) => {
5389
5389
  };
5390
5390
 
5391
5391
  // package.json
5392
- var version = "0.2.0";
5392
+ var version = "0.2.2";
5393
5393
 
5394
5394
  // src/mcp/tools/schemas.ts
5395
5395
  var coerceBoolean = external_exports.preprocess(
@@ -5980,6 +5980,29 @@ function generateCommandId() {
5980
5980
  return `cmd-${v4_default().slice(0, 8)}`;
5981
5981
  }
5982
5982
 
5983
+ // src/utils/exec-options.ts
5984
+ function buildExecOptions(params) {
5985
+ return {
5986
+ cwd: params.cwd,
5987
+ timeout: params.timeoutMs,
5988
+ windowsHide: true,
5989
+ encoding: params.isWin ? null : "utf8",
5990
+ shell: params.shell
5991
+ };
5992
+ }
5993
+ function detectShellEncoding(isWin, shell) {
5994
+ if (!isWin) return "utf-8";
5995
+ if (!shell) return "gbk";
5996
+ const lower = shell.toLowerCase();
5997
+ if (/(^|[\/\\])(ba|z|fi|da|k)?sh(\.exe)?$/i.test(lower) || lower.includes("wsl")) {
5998
+ return "utf-8";
5999
+ }
6000
+ if (lower.includes("pwsh")) {
6001
+ return "utf-8";
6002
+ }
6003
+ return "gbk";
6004
+ }
6005
+
5983
6006
  // src/terminal/session.ts
5984
6007
  var TerminalSession = class {
5985
6008
  sessionId;
@@ -6094,12 +6117,12 @@ var TerminalSession = class {
6094
6117
  return new Promise((resolve2) => {
6095
6118
  let resolved = false;
6096
6119
  const isWin = process.platform === "win32";
6097
- const options = {
6120
+ const options = buildExecOptions({
6098
6121
  cwd: this.cwd,
6099
- timeout: timeoutMs,
6100
- windowsHide: true,
6101
- encoding: isWin ? null : "utf8"
6102
- };
6122
+ timeoutMs,
6123
+ shell: this.shell,
6124
+ isWin
6125
+ });
6103
6126
  const child = cp.exec(command, options, (error, stdout, stderr) => {
6104
6127
  if (resolved) return;
6105
6128
  resolved = true;
@@ -6107,7 +6130,8 @@ var TerminalSession = class {
6107
6130
  let outStr;
6108
6131
  let errStr;
6109
6132
  if (isWin) {
6110
- const td = new import_util4.TextDecoder("gbk");
6133
+ const textEncoding = detectShellEncoding(isWin, this.shell);
6134
+ const td = new import_util4.TextDecoder(textEncoding);
6111
6135
  outStr = stdout ? td.decode(stdout) : "";
6112
6136
  errStr = stderr ? td.decode(stderr) : "";
6113
6137
  } else {
@@ -6431,6 +6455,7 @@ var SessionManager = class {
6431
6455
  var ipcServer;
6432
6456
  var sessionManager;
6433
6457
  var statusBarItem;
6458
+ var CLAUDE_CODE_BASH_BLOCK_MESSAGE = "Please use BashTerm MCP tools (run / exec / read) instead of the built-in Bash tool. These commands execute visibly in VSCode terminal tabs.";
6434
6459
  function getSocketPath() {
6435
6460
  const tmpDir = os.tmpdir();
6436
6461
  const crypto3 = require("crypto");
@@ -6438,12 +6463,14 @@ function getSocketPath() {
6438
6463
  const hash = crypto3.createHash("md5").update(workspace4).digest("hex").slice(0, 8);
6439
6464
  const isWin = process.platform === "win32";
6440
6465
  const socketPath = isWin ? path2.join("\\\\?\\pipe", `bashterm-mcp-${hash}`) : path2.join(tmpDir, `bashterm-mcp-${hash}.sock`);
6441
- const discoveryPath = path2.join(tmpDir, "bashterm-mcp.discovery");
6466
+ return socketPath;
6467
+ }
6468
+ function publishSocketPath(socketPath) {
6469
+ const discoveryPath = path2.join(os.tmpdir(), "bashterm-mcp.discovery");
6442
6470
  try {
6443
6471
  fs.writeFileSync(discoveryPath, socketPath);
6444
6472
  } catch {
6445
6473
  }
6446
- return socketPath;
6447
6474
  }
6448
6475
  function cleanupSocket(socketPath) {
6449
6476
  if (process.platform === "win32") return;
@@ -6454,9 +6481,136 @@ function cleanupSocket(socketPath) {
6454
6481
  } catch {
6455
6482
  }
6456
6483
  }
6484
+ function getClaudeCodeSettingsPath() {
6485
+ const claudeDir = path2.join(os.homedir(), ".claude");
6486
+ return {
6487
+ claudeDir,
6488
+ settingsPath: path2.join(claudeDir, "settings.json")
6489
+ };
6490
+ }
6491
+ function isRecord(value) {
6492
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6493
+ }
6494
+ function isLegacyBashTermClaudeCodeHook(value) {
6495
+ if (!isRecord(value) || value.matcher !== "Bash") return false;
6496
+ const legacyMessage = value.message;
6497
+ return value.action === "block" && typeof legacyMessage === "string" && legacyMessage.includes("BashTerm MCP");
6498
+ }
6499
+ function isCurrentBashTermClaudeCodeHook(value) {
6500
+ if (!isRecord(value) || value.matcher !== "Bash") return false;
6501
+ if (!Array.isArray(value.hooks)) return false;
6502
+ return value.hooks.some(
6503
+ (handler) => isRecord(handler) && handler.type === "command" && typeof handler.command === "string" && handler.command.includes("BashTerm MCP")
6504
+ );
6505
+ }
6506
+ function isBashTermClaudeCodeHook(value) {
6507
+ return isLegacyBashTermClaudeCodeHook(value) || isCurrentBashTermClaudeCodeHook(value);
6508
+ }
6509
+ function readClaudeCodeSettings(settingsPath) {
6510
+ if (!fs.existsSync(settingsPath)) return {};
6511
+ try {
6512
+ const raw = fs.readFileSync(settingsPath, "utf-8");
6513
+ return JSON.parse(raw);
6514
+ } catch {
6515
+ log("Failed to parse .claude/settings.json");
6516
+ return {};
6517
+ }
6518
+ }
6519
+ function writeClaudeCodeSettings(claudeDir, settingsPath, settings) {
6520
+ if (!fs.existsSync(claudeDir)) {
6521
+ fs.mkdirSync(claudeDir, { recursive: true });
6522
+ }
6523
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
6524
+ }
6525
+ function createClaudeCodeBashBlockHook() {
6526
+ const blockCommand = process.platform === "win32" ? `powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "[Console]::Error.WriteLine('${CLAUDE_CODE_BASH_BLOCK_MESSAGE}'); exit 2"` : `sh -c 'printf "%s\\n" "${CLAUDE_CODE_BASH_BLOCK_MESSAGE}" >&2; exit 2'`;
6527
+ return {
6528
+ matcher: "Bash",
6529
+ hooks: [
6530
+ {
6531
+ type: "command",
6532
+ command: blockCommand
6533
+ }
6534
+ ]
6535
+ };
6536
+ }
6537
+ function autoConfigureClaudeCode() {
6538
+ const { claudeDir, settingsPath } = getClaudeCodeSettingsPath();
6539
+ const settings = readClaudeCodeSettings(settingsPath);
6540
+ const hooks = isRecord(settings.hooks) ? settings.hooks : {};
6541
+ const existingPreToolUse = Array.isArray(hooks.PreToolUse) ? hooks.PreToolUse : [];
6542
+ const preToolUse = existingPreToolUse.filter(
6543
+ (h) => isRecord(h) && !isLegacyBashTermClaudeCodeHook(h)
6544
+ );
6545
+ const alreadyConfigured = preToolUse.some(isCurrentBashTermClaudeCodeHook);
6546
+ const needsCleanup = preToolUse.length !== existingPreToolUse.length;
6547
+ if (alreadyConfigured && !needsCleanup) return;
6548
+ if (!alreadyConfigured) {
6549
+ preToolUse.push(createClaudeCodeBashBlockHook());
6550
+ }
6551
+ hooks.PreToolUse = preToolUse;
6552
+ settings.hooks = hooks;
6553
+ try {
6554
+ writeClaudeCodeSettings(claudeDir, settingsPath, settings);
6555
+ log("Auto-configured .claude/settings.json: Bash tool blocked, BashTerm MCP preferred");
6556
+ } catch (err) {
6557
+ logError("Failed to auto-configure .claude/settings.json", err);
6558
+ }
6559
+ }
6560
+ function restoreClaudeCodeDefaultBash() {
6561
+ const { claudeDir, settingsPath } = getClaudeCodeSettingsPath();
6562
+ if (!fs.existsSync(settingsPath)) return false;
6563
+ const settings = readClaudeCodeSettings(settingsPath);
6564
+ if (!isRecord(settings.hooks)) return false;
6565
+ const hooks = settings.hooks;
6566
+ const existingPreToolUse = Array.isArray(hooks.PreToolUse) ? hooks.PreToolUse : [];
6567
+ const preToolUse = existingPreToolUse.filter((hook) => !isBashTermClaudeCodeHook(hook));
6568
+ if (preToolUse.length === existingPreToolUse.length) return false;
6569
+ if (preToolUse.length > 0) {
6570
+ hooks.PreToolUse = preToolUse;
6571
+ } else {
6572
+ delete hooks.PreToolUse;
6573
+ }
6574
+ if (Object.keys(hooks).length > 0) {
6575
+ settings.hooks = hooks;
6576
+ } else {
6577
+ delete settings.hooks;
6578
+ }
6579
+ try {
6580
+ writeClaudeCodeSettings(claudeDir, settingsPath, settings);
6581
+ log("Restored Claude Code default Bash by removing BashTerm MCP hook");
6582
+ return true;
6583
+ } catch (err) {
6584
+ logError("Failed to restore Claude Code default Bash", err);
6585
+ return false;
6586
+ }
6587
+ }
6457
6588
  function activate(context) {
6458
6589
  const outputChannel2 = initLogger();
6459
6590
  log("BashTerm MCP extension activating...");
6591
+ const applyClaudeCodePreference = () => {
6592
+ const autoConfigureClaude = vscode4.workspace.getConfiguration("bashterm-mcp-server").get("autoConfigureClaudeCode", true);
6593
+ if (autoConfigureClaude) {
6594
+ autoConfigureClaudeCode();
6595
+ } else {
6596
+ restoreClaudeCodeDefaultBash();
6597
+ }
6598
+ };
6599
+ applyClaudeCodePreference();
6600
+ context.subscriptions.push(
6601
+ vscode4.workspace.onDidChangeConfiguration((event) => {
6602
+ if (event.affectsConfiguration("bashterm-mcp-server.autoConfigureClaudeCode")) {
6603
+ applyClaudeCodePreference();
6604
+ }
6605
+ })
6606
+ );
6607
+ context.subscriptions.push(
6608
+ vscode4.commands.registerCommand("bashterm-mcp-server.restoreClaudeCodeDefaultBash", () => {
6609
+ const restored = restoreClaudeCodeDefaultBash();
6610
+ const message = restored ? "Claude Code default Bash restored. Restart Claude Code to apply the change." : "No BashTerm MCP Claude Code hook was found.";
6611
+ void vscode4.window.showInformationMessage(message);
6612
+ })
6613
+ );
6460
6614
  sessionManager = new SessionManager();
6461
6615
  statusBarItem = vscode4.window.createStatusBarItem(
6462
6616
  vscode4.StatusBarAlignment.Left,
@@ -6474,6 +6628,7 @@ function activate(context) {
6474
6628
  });
6475
6629
  const handleMcpRequest = createMcpRequestHandler(sessionManager);
6476
6630
  const socketPath = getSocketPath();
6631
+ publishSocketPath(socketPath);
6477
6632
  cleanupSocket(socketPath);
6478
6633
  ipcServer = net.createServer((connection) => {
6479
6634
  log("IPC client connected");
@@ -6543,6 +6698,7 @@ async function handleIpcRequest(request, connection, handleMcpRequest) {
6543
6698
  }
6544
6699
  function deactivate() {
6545
6700
  log("BashTerm MCP extension deactivating...");
6701
+ restoreClaudeCodeDefaultBash();
6546
6702
  if (ipcServer) {
6547
6703
  ipcServer.close();
6548
6704
  ipcServer = void 0;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "bashterm-mcp-server",
3
3
  "displayName": "BashTerm MCP",
4
4
  "description": "MCP server that executes commands in visible VSCode terminal tabs. Supports Windows, macOS and Linux.",
5
- "version": "0.2.0",
5
+ "version": "0.2.2",
6
6
  "publisher": "hcdb",
7
7
  "license": "MIT",
8
8
  "author": "hcdb",
@@ -32,13 +32,20 @@
32
32
  "Other"
33
33
  ],
34
34
  "activationEvents": [
35
- "onStartupFinished"
35
+ "onStartupFinished",
36
+ "onCommand:bashterm-mcp-server.restoreClaudeCodeDefaultBash"
36
37
  ],
37
38
  "main": "./dist/extension.js",
38
39
  "bin": {
39
40
  "bashterm-mcp-server": "dist/mcp-entry.js"
40
41
  },
41
42
  "contributes": {
43
+ "commands": [
44
+ {
45
+ "command": "bashterm-mcp-server.restoreClaudeCodeDefaultBash",
46
+ "title": "BashTerm MCP: Restore Claude Code Default Bash"
47
+ }
48
+ ],
42
49
  "mcpServers": {
43
50
  "bashterm-mcp-server": {
44
51
  "type": "stdio",
@@ -51,6 +58,11 @@
51
58
  "configuration": {
52
59
  "title": "BashTerm MCP",
53
60
  "properties": {
61
+ "bashterm-mcp-server.autoConfigureClaudeCode": {
62
+ "type": "boolean",
63
+ "default": true,
64
+ "description": "Automatically configure Claude Code to block the built-in Bash tool and prefer BashTerm MCP tools"
65
+ },
54
66
  "bashterm-mcp-server.blockedCommands": {
55
67
  "type": "array",
56
68
  "items": {
@@ -122,6 +134,6 @@
122
134
  "eslint": "^8.57.0",
123
135
  "prettier": "^3.2.0",
124
136
  "typescript": "^5.4.0",
125
- "vitest": "^1.6.0"
137
+ "vitest": "^3.2.6"
126
138
  }
127
139
  }
package/server.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
3
  "name": "io.github.hcdb/bashterm-mcp-server",
4
- "version": "0.2.0",
4
+ "version": "0.2.2",
5
5
  "description": "BashTerm MCP — execute commands in visible VSCode terminal tabs with output capture and session reuse.",
6
6
  "author": "hcdb",
7
7
  "license": "MIT",
@@ -14,7 +14,7 @@
14
14
  {
15
15
  "registryType": "npm",
16
16
  "identifier": "bashterm-mcp-server",
17
- "version": "0.2.0",
17
+ "version": "0.2.2",
18
18
  "transport": {
19
19
  "type": "stdio"
20
20
  }