smart-terminal-mcp 1.2.8 → 1.2.9
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.md +7 -1
- package/package.json +1 -1
- package/src/tools.js +3 -3
- package/test/command-runner.test.js +28 -1
package/README.md
CHANGED
|
@@ -161,7 +161,7 @@ Execute a command with deterministic completion detection. Large outputs are tru
|
|
|
161
161
|
|
|
162
162
|
### `terminal_run`
|
|
163
163
|
|
|
164
|
-
Run a one-shot non-interactive command using `cmd + args` with `shell=false`. Safer than `terminal_exec` for predictable automation. Output is capped by `maxOutputBytes` rather than head + tail truncation. Shell built-ins such as `dir` or `cd` are not supported. On Windows, `terminal_run` resolves `PATH`/`PATHEXT` and launches `.cmd` / `.bat` wrappers via `cmd.exe` when needed.
|
|
164
|
+
Run a one-shot non-interactive command using `cmd + args` with `shell=false`. Safer than `terminal_exec` for predictable automation. Output is capped by `maxOutputBytes` rather than head + tail truncation. Shell built-ins such as `dir` or `cd` are not supported. On Windows, `terminal_run` resolves `PATH`/`PATHEXT` and launches `.cmd` / `.bat` wrappers via `cmd.exe` when needed. Prefer passing the target executable directly as `cmd` instead of wrapping it in `powershell -Command` or `cmd /c`, especially when Windows paths contain spaces.
|
|
165
165
|
|
|
166
166
|
| Param | Type | Default | Description |
|
|
167
167
|
|-------|------|---------|-------------|
|
|
@@ -346,6 +346,12 @@ terminal_run({ cmd: "git", args: ["status", "--porcelain=v1", "--branch"] })
|
|
|
346
346
|
-> { ok: true, stdout: { raw: "...", parsed: { branch: {...}, staged: [], modified: [], untracked: [] } } }
|
|
347
347
|
```
|
|
348
348
|
|
|
349
|
+
For Windows tools installed under `Program Files`, prefer this shape over `powershell -Command`:
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
terminal_run({ cmd: "C:\\Program Files\\Vendor\\Tool.exe", args: ["/flag:value", "/other"] })
|
|
353
|
+
```
|
|
354
|
+
|
|
349
355
|
### Page through large read-only output
|
|
350
356
|
|
|
351
357
|
```
|
package/package.json
CHANGED
package/src/tools.js
CHANGED
|
@@ -107,10 +107,10 @@ export function registerTools(server, manager) {
|
|
|
107
107
|
// --- terminal_run ---
|
|
108
108
|
server.tool(
|
|
109
109
|
'terminal_run',
|
|
110
|
-
'Run a
|
|
110
|
+
'Run a binary directly; avoid shell quoting.',
|
|
111
111
|
{
|
|
112
|
-
cmd: z.string().describe('Executable'),
|
|
113
|
-
args: z.array(z.string()).default([]).describe('
|
|
112
|
+
cmd: z.string().describe('Executable path or name'),
|
|
113
|
+
args: z.array(z.string()).default([]).describe('Args passed verbatim'),
|
|
114
114
|
cwd: z.string().optional().describe('Working directory'),
|
|
115
115
|
timeout: z.number().int().min(1000).max(600000).default(DEFAULT_TIMEOUT_MS).describe('Timeout in ms'),
|
|
116
116
|
maxOutputBytes: z.number().int().min(1024).max(1048576).default(DEFAULT_MAX_OUTPUT_BYTES).describe('Max output bytes'),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import test from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
|
-
import { mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { chmod, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { getStructuredParserHint, runCommand } from '../src/command-runner.js';
|
|
@@ -168,6 +168,33 @@ test('runCommand executes explicit .cmd files on Windows', async (t) => {
|
|
|
168
168
|
}
|
|
169
169
|
});
|
|
170
170
|
|
|
171
|
+
test('runCommand handles explicit command paths with spaces', async () => {
|
|
172
|
+
const tempDir = await mkdtemp(join(tmpdir(), 'smart terminal mcp-'));
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
const isWindows = process.platform === 'win32';
|
|
176
|
+
const scriptPath = join(tempDir, isWindows ? 'space wrapper.cmd' : 'space-wrapper.sh');
|
|
177
|
+
const scriptBody = isWindows
|
|
178
|
+
? '@echo off\r\necho [%~1]\r\n'
|
|
179
|
+
: '#!/bin/sh\necho "[$1]"\n';
|
|
180
|
+
|
|
181
|
+
await writeFile(scriptPath, scriptBody);
|
|
182
|
+
if (!isWindows) await chmod(scriptPath, 0o755);
|
|
183
|
+
|
|
184
|
+
const result = await runCommand({
|
|
185
|
+
cmd: scriptPath,
|
|
186
|
+
args: ['hello world'],
|
|
187
|
+
parse: false,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
assert.equal(result.ok, true);
|
|
191
|
+
assert.equal(result.exitCode, 0);
|
|
192
|
+
assert.match(result.stdout.raw, /\[hello world\]/);
|
|
193
|
+
} finally {
|
|
194
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
171
198
|
test('runCommand adds a helpful ENOENT hint on Windows for PATH commands', async (t) => {
|
|
172
199
|
if (process.platform !== 'win32') {
|
|
173
200
|
t.skip('Windows-only behavior');
|