mcp-terminal-runner 0.2.2 → 0.4.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.md +5 -4
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -184
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +24 -3
- package/dist/index.test.js.map +1 -1
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +15 -0
- package/dist/server.js.map +1 -0
- package/dist/services/SessionManager.d.ts +26 -0
- package/dist/services/SessionManager.d.ts.map +1 -0
- package/dist/services/SessionManager.js +97 -0
- package/dist/services/SessionManager.js.map +1 -0
- package/dist/services/session-manager.d.ts +26 -0
- package/dist/services/session-manager.d.ts.map +1 -0
- package/dist/services/session-manager.js +105 -0
- package/dist/services/session-manager.js.map +1 -0
- package/dist/tools/execute.d.ts +3 -0
- package/dist/tools/execute.d.ts.map +1 -0
- package/dist/tools/execute.js +53 -0
- package/dist/tools/execute.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +9 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/session.d.ts +3 -0
- package/dist/tools/session.d.ts.map +1 -0
- package/dist/tools/session.js +150 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/command.d.ts +7 -0
- package/dist/utils/command.d.ts.map +1 -0
- package/dist/utils/command.js +60 -0
- package/dist/utils/command.js.map +1 -0
- package/dist/utils/env.d.ts +2 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +14 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/paths.d.ts +4 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +87 -0
- package/dist/utils/paths.js.map +1 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ For security reasons, this server requires an explicit list of allowed commands.
|
|
|
24
24
|
|
|
25
25
|
### Security (Optional): Allowed Working Directory Roots
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
You can optionally restrict which working directories are allowed via `ALLOWED_CWD_ROOTS`.
|
|
28
28
|
|
|
29
29
|
- **Format**: Comma-separated list of allowed root paths.
|
|
30
30
|
- **Behavior**:
|
|
@@ -74,11 +74,12 @@ Add the following to your MCP client configuration (e.g., VS Code `settings.json
|
|
|
74
74
|
### Available Tools
|
|
75
75
|
|
|
76
76
|
#### `execute_command`
|
|
77
|
-
|
|
77
|
+
Execute a shell command. Note: This tool is for non-interactive, short-lived commands only. Interactive commands are not supported.
|
|
78
78
|
|
|
79
79
|
- **Input**:
|
|
80
|
-
- `command` (string): The
|
|
81
|
-
- `cwd` (string
|
|
80
|
+
- `command` (string): The shell command to execute.
|
|
81
|
+
- `cwd` (string): The working directory to execute the command within.
|
|
82
|
+
- `input` (string, optional): Optional input to write to stdin. Useful for commands that require user interaction.
|
|
82
83
|
- **Output**:
|
|
83
84
|
- Returns a YAML-formatted string containing:
|
|
84
85
|
- `exit_code`: The command's exit code.
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,194 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
-
};
|
|
6
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
4
|
exports.server = void 0;
|
|
8
|
-
const node_child_process_1 = require("node:child_process");
|
|
9
|
-
const promises_1 = require("node:fs/promises");
|
|
10
|
-
const node_path_1 = require("node:path");
|
|
11
|
-
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
12
5
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const version = '0.1.0';
|
|
19
|
-
const server = new mcp_js_1.McpServer({
|
|
20
|
-
name: 'mcp-terminal-runner',
|
|
21
|
-
version,
|
|
22
|
-
}, {
|
|
23
|
-
capabilities: {
|
|
24
|
-
tools: {},
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
exports.server = server;
|
|
28
|
-
const parseCommaSeparatedEnv = (value) => {
|
|
29
|
-
if (!value) {
|
|
30
|
-
return [];
|
|
31
|
-
}
|
|
32
|
-
return value
|
|
33
|
-
.split(',')
|
|
34
|
-
.map((item) => item.trim())
|
|
35
|
-
.filter((item) => item.length > 0);
|
|
36
|
-
};
|
|
37
|
-
const isWithinRoot = (root, target) => {
|
|
38
|
-
const rel = (0, node_path_1.relative)(root, target);
|
|
39
|
-
if (rel === '') {
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
const isOutsideRoot = rel.startsWith('..') || (0, node_path_1.isAbsolute)(rel);
|
|
43
|
-
return !isOutsideRoot;
|
|
44
|
-
};
|
|
45
|
-
const resolveAndValidateCwd = async (cwdInput) => {
|
|
46
|
-
if (process.platform === 'win32' && cwdInput.startsWith('/')) {
|
|
47
|
-
const allowedRoots = parseCommaSeparatedEnv(process.env.ALLOWED_CWD_ROOTS);
|
|
48
|
-
if (allowedRoots.length === 0) {
|
|
49
|
-
return cwdInput;
|
|
50
|
-
}
|
|
51
|
-
const cwdNormalized = node_path_1.posix.normalize(cwdInput);
|
|
52
|
-
const allowed = allowedRoots.some((root) => {
|
|
53
|
-
const rel = node_path_1.posix.relative(root, cwdNormalized);
|
|
54
|
-
return rel === '' || !(rel.startsWith('..') || node_path_1.posix.isAbsolute(rel));
|
|
55
|
-
});
|
|
56
|
-
if (!allowed) {
|
|
57
|
-
throw new Error('cwd is not allowed by ALLOWED_CWD_ROOTS');
|
|
58
|
-
}
|
|
59
|
-
return cwdInput;
|
|
60
|
-
}
|
|
61
|
-
const cwdResolved = (0, node_path_1.resolve)(process.cwd(), cwdInput);
|
|
62
|
-
try {
|
|
63
|
-
const cwdStat = await (0, promises_1.stat)(cwdResolved);
|
|
64
|
-
if (!cwdStat.isDirectory()) {
|
|
65
|
-
throw new Error(`cwd is not a directory: ${cwdInput}`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
if (error instanceof Error &&
|
|
70
|
-
error.message.includes('cwd is not a directory')) {
|
|
71
|
-
throw error;
|
|
72
|
-
}
|
|
73
|
-
throw new Error(`cwd does not exist: ${cwdInput}`);
|
|
74
|
-
}
|
|
75
|
-
const cwdCanonical = await (0, promises_1.realpath)(cwdResolved);
|
|
76
|
-
const allowedRoots = parseCommaSeparatedEnv(process.env.ALLOWED_CWD_ROOTS);
|
|
77
|
-
if (allowedRoots.length === 0) {
|
|
78
|
-
return cwdResolved;
|
|
79
|
-
}
|
|
80
|
-
const canonicalRoots = await Promise.all(allowedRoots.map(async (root) => {
|
|
81
|
-
const rootResolved = (0, node_path_1.resolve)(process.cwd(), root);
|
|
82
|
-
try {
|
|
83
|
-
return await (0, promises_1.realpath)(rootResolved);
|
|
84
|
-
}
|
|
85
|
-
catch {
|
|
86
|
-
throw new Error(`Invalid configuration: ALLOWED_CWD_ROOTS contains an invalid root: ${root}`);
|
|
87
|
-
}
|
|
88
|
-
}));
|
|
89
|
-
const allowed = canonicalRoots.some((root) => isWithinRoot(root, cwdCanonical));
|
|
90
|
-
if (!allowed) {
|
|
91
|
-
throw new Error('cwd is not allowed by ALLOWED_CWD_ROOTS');
|
|
92
|
-
}
|
|
93
|
-
return cwdResolved;
|
|
94
|
-
};
|
|
95
|
-
const runCommand = async (command, cwd) => new Promise((resolvePromise, rejectPromise) => {
|
|
96
|
-
const child = (0, cross_spawn_1.default)(command, {
|
|
97
|
-
cwd,
|
|
98
|
-
shell: true,
|
|
99
|
-
windowsHide: true,
|
|
100
|
-
});
|
|
101
|
-
let stdout = '';
|
|
102
|
-
let stderr = '';
|
|
103
|
-
child.stdout?.setEncoding('utf8');
|
|
104
|
-
child.stderr?.setEncoding('utf8');
|
|
105
|
-
child.stdout?.on('data', (chunk) => {
|
|
106
|
-
stdout += chunk;
|
|
107
|
-
});
|
|
108
|
-
child.stderr?.on('data', (chunk) => {
|
|
109
|
-
stderr += chunk;
|
|
110
|
-
});
|
|
111
|
-
child.on('error', (error) => {
|
|
112
|
-
rejectPromise(error);
|
|
113
|
-
});
|
|
114
|
-
child.on('close', (code) => {
|
|
115
|
-
resolvePromise({
|
|
116
|
-
exitCode: typeof code === 'number' ? code : 1,
|
|
117
|
-
stdout,
|
|
118
|
-
stderr,
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
const getWslCwd = () => {
|
|
123
|
-
if (process.platform !== 'win32') {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
try {
|
|
127
|
-
// Try to convert current working directory to WSL path
|
|
128
|
-
const wslPath = (0, node_child_process_1.execSync)(`wsl wslpath -u "${process.cwd()}"`)
|
|
129
|
-
.toString()
|
|
130
|
-
.trim();
|
|
131
|
-
if (wslPath.startsWith('/')) {
|
|
132
|
-
return wslPath;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
catch {
|
|
136
|
-
// Ignore errors if wsl/wslpath is not available or fails
|
|
137
|
-
}
|
|
138
|
-
return;
|
|
139
|
-
};
|
|
140
|
-
server.tool('execute_command', 'Execute a shell command', {
|
|
141
|
-
command: zod_1.z.string().describe('The shell command to execute'),
|
|
142
|
-
cwd: zod_1.z
|
|
143
|
-
.string()
|
|
144
|
-
.optional()
|
|
145
|
-
.describe('Optional working directory to execute the command within'),
|
|
146
|
-
}, async (args) => {
|
|
147
|
-
const [bin] = (0, args_tokenizer_1.tokenizeArgs)(args.command);
|
|
148
|
-
const allowedCommands = parseCommaSeparatedEnv(process.env.ALLOWED_COMMANDS);
|
|
149
|
-
try {
|
|
150
|
-
if (!(allowedCommands.includes('*') || allowedCommands.includes(bin))) {
|
|
151
|
-
throw new Error(`Command "${bin}" is not allowed, allowed commands: ${allowedCommands.length > 0 ? allowedCommands.join(', ') : '(none)'}`);
|
|
152
|
-
}
|
|
153
|
-
const cwdToUse = args.cwd ?? getWslCwd();
|
|
154
|
-
const cwdResolved = cwdToUse
|
|
155
|
-
? await resolveAndValidateCwd(cwdToUse)
|
|
156
|
-
: undefined;
|
|
157
|
-
let finalCommand = args.command;
|
|
158
|
-
let finalCwd = cwdResolved;
|
|
159
|
-
if (process.platform === 'win32' && cwdResolved?.startsWith('/')) {
|
|
160
|
-
finalCommand = `wsl --cd "${cwdResolved}" -- bash -c "${args.command.replace(/"/g, '\\"')}"`;
|
|
161
|
-
finalCwd = undefined;
|
|
162
|
-
}
|
|
163
|
-
const result = await runCommand(finalCommand, finalCwd);
|
|
164
|
-
return {
|
|
165
|
-
content: [
|
|
166
|
-
{
|
|
167
|
-
type: 'text',
|
|
168
|
-
text: (0, js_yaml_1.dump)({
|
|
169
|
-
exit_code: result.exitCode,
|
|
170
|
-
stdout: result.stdout,
|
|
171
|
-
stderr: result.stderr,
|
|
172
|
-
}),
|
|
173
|
-
},
|
|
174
|
-
],
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
catch (error) {
|
|
178
|
-
return {
|
|
179
|
-
content: [
|
|
180
|
-
{
|
|
181
|
-
type: 'text',
|
|
182
|
-
text: `Error executing command: ${error instanceof Error ? error.message : String(error)}`,
|
|
183
|
-
},
|
|
184
|
-
],
|
|
185
|
-
isError: true,
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
});
|
|
6
|
+
const server_js_1 = require("./server.js");
|
|
7
|
+
const index_js_1 = require("./tools/index.js");
|
|
8
|
+
// biome-ignore lint/performance/noBarrelFile: entry point
|
|
9
|
+
var server_js_2 = require("./server.js");
|
|
10
|
+
Object.defineProperty(exports, "server", { enumerable: true, get: function () { return server_js_2.server; } });
|
|
189
11
|
async function main() {
|
|
12
|
+
(0, index_js_1.registerTools)(server_js_1.server);
|
|
190
13
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
191
|
-
await server.connect(transport);
|
|
14
|
+
await server_js_1.server.connect(transport);
|
|
192
15
|
}
|
|
193
16
|
if (require.main === module) {
|
|
194
17
|
main().catch((error) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAEA,wEAAiF;AACjF,2CAAqC;AACrC,+CAAiD;AAEjD,0DAA0D;AAC1D,yCAAqC;AAA5B,mGAAA,MAAM,OAAA;AAEf,KAAK,UAAU,IAAI;IACjB,IAAA,wBAAa,EAAC,kBAAM,CAAC,CAAC;IACtB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,kBAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACrB,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.test.js
CHANGED
|
@@ -7,8 +7,12 @@ const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
|
|
|
7
7
|
const inMemory_js_1 = require("@modelcontextprotocol/sdk/inMemory.js");
|
|
8
8
|
const js_yaml_1 = require("js-yaml");
|
|
9
9
|
const index_js_2 = require("./index.js");
|
|
10
|
+
const index_js_3 = require("./tools/index.js");
|
|
10
11
|
describe('MCP Server', () => {
|
|
11
12
|
let client;
|
|
13
|
+
beforeAll(() => {
|
|
14
|
+
(0, index_js_3.registerTools)(index_js_2.server);
|
|
15
|
+
});
|
|
12
16
|
beforeEach(async () => {
|
|
13
17
|
const [clientTransport, serverTransport] = inMemory_js_1.InMemoryTransport.createLinkedPair();
|
|
14
18
|
// Connect server
|
|
@@ -32,7 +36,7 @@ describe('MCP Server', () => {
|
|
|
32
36
|
process.env.ALLOWED_COMMANDS = 'echo';
|
|
33
37
|
const result = await client.callTool({
|
|
34
38
|
name: 'execute_command',
|
|
35
|
-
arguments: { command: 'echo hello' },
|
|
39
|
+
arguments: { command: 'echo hello', cwd: process.cwd() },
|
|
36
40
|
});
|
|
37
41
|
expect(result.content).toBeDefined();
|
|
38
42
|
expect(result.content[0].type).toBe('text');
|
|
@@ -45,7 +49,7 @@ describe('MCP Server', () => {
|
|
|
45
49
|
process.env.ALLOWED_COMMANDS = 'ls';
|
|
46
50
|
const result = await client.callTool({
|
|
47
51
|
name: 'execute_command',
|
|
48
|
-
arguments: { command: 'echo hello' },
|
|
52
|
+
arguments: { command: 'echo hello', cwd: process.cwd() },
|
|
49
53
|
});
|
|
50
54
|
expect(result.isError).toBe(true);
|
|
51
55
|
expect(result.content[0].text).toContain('not allowed');
|
|
@@ -54,12 +58,28 @@ describe('MCP Server', () => {
|
|
|
54
58
|
process.env.ALLOWED_COMMANDS = '*';
|
|
55
59
|
const result = await client.callTool({
|
|
56
60
|
name: 'execute_command',
|
|
57
|
-
arguments: { command: 'echo hello' },
|
|
61
|
+
arguments: { command: 'echo hello', cwd: process.cwd() },
|
|
62
|
+
});
|
|
63
|
+
expect(result.content).toBeDefined();
|
|
64
|
+
const text = result.content[0].text;
|
|
65
|
+
const output = (0, js_yaml_1.load)(text);
|
|
66
|
+
expect(output.exit_code).toBe(0);
|
|
67
|
+
});
|
|
68
|
+
it('should execute command with input', async () => {
|
|
69
|
+
process.env.ALLOWED_COMMANDS = 'cat';
|
|
70
|
+
const result = await client.callTool({
|
|
71
|
+
name: 'execute_command',
|
|
72
|
+
arguments: {
|
|
73
|
+
command: 'cat',
|
|
74
|
+
cwd: process.cwd(),
|
|
75
|
+
input: 'hello world',
|
|
76
|
+
},
|
|
58
77
|
});
|
|
59
78
|
expect(result.content).toBeDefined();
|
|
60
79
|
const text = result.content[0].text;
|
|
61
80
|
const output = (0, js_yaml_1.load)(text);
|
|
62
81
|
expect(output.exit_code).toBe(0);
|
|
82
|
+
expect(output.stdout).toContain('hello world');
|
|
63
83
|
});
|
|
64
84
|
it('should execute command within absolute cwd', async () => {
|
|
65
85
|
process.env.ALLOWED_COMMANDS = 'node';
|
|
@@ -167,6 +187,7 @@ describe('MCP Server', () => {
|
|
|
167
187
|
name: 'execute_command',
|
|
168
188
|
arguments: {
|
|
169
189
|
command: 'echo hello && echo world',
|
|
190
|
+
cwd: process.cwd(),
|
|
170
191
|
},
|
|
171
192
|
});
|
|
172
193
|
expect(result.isError).not.toBe(true);
|
package/dist/index.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":";;AAAA,+CAAkD;AAClD,qCAAiC;AACjC,yCAA2C;AAC3C,wEAAmE;AACnE,uEAA0E;AAC1E,qCAA+B;AAC/B,yCAAoC;
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,eAAO,MAAM,MAAM,WAUlB,CAAC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.server = void 0;
|
|
4
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
5
|
+
// Hardcoded version to avoid import issues with outside rootDir
|
|
6
|
+
const version = '0.1.0';
|
|
7
|
+
exports.server = new mcp_js_1.McpServer({
|
|
8
|
+
name: 'mcp-terminal-runner',
|
|
9
|
+
version,
|
|
10
|
+
}, {
|
|
11
|
+
capabilities: {
|
|
12
|
+
tools: {},
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;AAAA,oEAAoE;AAEpE,gEAAgE;AAChE,MAAM,OAAO,GAAG,OAAO,CAAC;AAEX,QAAA,MAAM,GAAG,IAAI,kBAAS,CACjC;IACE,IAAI,EAAE,qBAAqB;IAC3B,OAAO;CACR,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;KACV;CACF,CACF,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ChildProcess } from 'node:child_process';
|
|
2
|
+
export interface Session {
|
|
3
|
+
id: string;
|
|
4
|
+
process: ChildProcess;
|
|
5
|
+
stdoutBuffer: string[];
|
|
6
|
+
stderrBuffer: string[];
|
|
7
|
+
createdAt: number;
|
|
8
|
+
outputListeners: (() => void)[];
|
|
9
|
+
}
|
|
10
|
+
export declare class SessionManager {
|
|
11
|
+
private readonly sessions;
|
|
12
|
+
createSession(process: ChildProcess): {
|
|
13
|
+
sessionId: string;
|
|
14
|
+
pid: number;
|
|
15
|
+
};
|
|
16
|
+
getSession(id: string): Session | undefined;
|
|
17
|
+
readOutput(id: string, timeout?: number): Promise<{
|
|
18
|
+
stdout: string;
|
|
19
|
+
stderr: string;
|
|
20
|
+
isActive: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
writeInput(id: string, input: string): void;
|
|
23
|
+
stopSession(id: string, signal?: NodeJS.Signals): void;
|
|
24
|
+
}
|
|
25
|
+
export declare const sessionManager: SessionManager;
|
|
26
|
+
//# sourceMappingURL=SessionManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../src/services/SessionManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;CACjC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;IAEvD,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IAmCxE,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI3C,UAAU,CACR,EAAE,EAAE,MAAM,EACV,OAAO,SAAI,GACV,OAAO,CAAC;QACT,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;IAkDF,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAa3C,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,OAAmB,GAAG,IAAI;CAQlE;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sessionManager = exports.SessionManager = void 0;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
class SessionManager {
|
|
6
|
+
sessions = new Map();
|
|
7
|
+
createSession(process) {
|
|
8
|
+
const id = (0, node_crypto_1.randomUUID)();
|
|
9
|
+
const session = {
|
|
10
|
+
id,
|
|
11
|
+
process,
|
|
12
|
+
stdoutBuffer: [],
|
|
13
|
+
stderrBuffer: [],
|
|
14
|
+
createdAt: Date.now(),
|
|
15
|
+
outputListeners: [],
|
|
16
|
+
};
|
|
17
|
+
process.stdout?.setEncoding('utf8');
|
|
18
|
+
process.stderr?.setEncoding('utf8');
|
|
19
|
+
const notifyListeners = () => {
|
|
20
|
+
const listeners = session.outputListeners;
|
|
21
|
+
session.outputListeners = [];
|
|
22
|
+
for (const listener of listeners) {
|
|
23
|
+
listener();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
process.stdout?.on('data', (chunk) => {
|
|
27
|
+
session.stdoutBuffer.push(chunk);
|
|
28
|
+
notifyListeners();
|
|
29
|
+
});
|
|
30
|
+
process.stderr?.on('data', (chunk) => {
|
|
31
|
+
session.stderrBuffer.push(chunk);
|
|
32
|
+
notifyListeners();
|
|
33
|
+
});
|
|
34
|
+
this.sessions.set(id, session);
|
|
35
|
+
return { sessionId: id, pid: process.pid ?? -1 };
|
|
36
|
+
}
|
|
37
|
+
getSession(id) {
|
|
38
|
+
return this.sessions.get(id);
|
|
39
|
+
}
|
|
40
|
+
readOutput(id, timeout = 0) {
|
|
41
|
+
const session = this.sessions.get(id);
|
|
42
|
+
if (!session) {
|
|
43
|
+
throw new Error(`Session not found: ${id}`);
|
|
44
|
+
}
|
|
45
|
+
const flush = () => {
|
|
46
|
+
const stdout = session.stdoutBuffer.join('');
|
|
47
|
+
const stderr = session.stderrBuffer.join('');
|
|
48
|
+
session.stdoutBuffer = [];
|
|
49
|
+
session.stderrBuffer = [];
|
|
50
|
+
const isActive = session.process.exitCode === null &&
|
|
51
|
+
session.process.signalCode === null;
|
|
52
|
+
return { stdout, stderr, isActive };
|
|
53
|
+
};
|
|
54
|
+
// If there is data or no timeout, return immediately
|
|
55
|
+
if (session.stdoutBuffer.length > 0 ||
|
|
56
|
+
session.stderrBuffer.length > 0 ||
|
|
57
|
+
timeout <= 0) {
|
|
58
|
+
return Promise.resolve(flush());
|
|
59
|
+
}
|
|
60
|
+
// Wait for data or timeout
|
|
61
|
+
return new Promise((resolvePromise) => {
|
|
62
|
+
let timer;
|
|
63
|
+
const onData = () => {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
resolvePromise(flush());
|
|
66
|
+
};
|
|
67
|
+
timer = setTimeout(() => {
|
|
68
|
+
// Remove listener if timed out
|
|
69
|
+
session.outputListeners = session.outputListeners.filter((l) => l !== onData);
|
|
70
|
+
resolvePromise(flush());
|
|
71
|
+
}, timeout);
|
|
72
|
+
session.outputListeners.push(onData);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
writeInput(id, input) {
|
|
76
|
+
const session = this.sessions.get(id);
|
|
77
|
+
if (!session) {
|
|
78
|
+
throw new Error(`Session not found: ${id}`);
|
|
79
|
+
}
|
|
80
|
+
if (session.process.stdin) {
|
|
81
|
+
session.process.stdin.write(input);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
throw new Error('Process stdin is not available');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
stopSession(id, signal = 'SIGTERM') {
|
|
88
|
+
const session = this.sessions.get(id);
|
|
89
|
+
if (!session) {
|
|
90
|
+
throw new Error(`Session not found: ${id}`);
|
|
91
|
+
}
|
|
92
|
+
session.process.kill(signal);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.SessionManager = SessionManager;
|
|
96
|
+
exports.sessionManager = new SessionManager();
|
|
97
|
+
//# sourceMappingURL=SessionManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionManager.js","sourceRoot":"","sources":["../../src/services/SessionManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ChildProcess } from 'node:child_process';
|
|
2
|
+
export interface Session {
|
|
3
|
+
id: string;
|
|
4
|
+
process: ChildProcess;
|
|
5
|
+
stdoutBuffer: string[];
|
|
6
|
+
stderrBuffer: string[];
|
|
7
|
+
createdAt: number;
|
|
8
|
+
outputListeners: (() => void)[];
|
|
9
|
+
}
|
|
10
|
+
export declare class SessionManager {
|
|
11
|
+
private readonly sessions;
|
|
12
|
+
createSession(process: ChildProcess): {
|
|
13
|
+
sessionId: string;
|
|
14
|
+
pid: number;
|
|
15
|
+
};
|
|
16
|
+
getSession(id: string): Session | undefined;
|
|
17
|
+
readOutput(id: string, timeout?: number): Promise<{
|
|
18
|
+
stdout: string;
|
|
19
|
+
stderr: string;
|
|
20
|
+
isActive: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
writeInput(id: string, input: string): void;
|
|
23
|
+
stopSession(id: string, signal?: NodeJS.Signals): void;
|
|
24
|
+
}
|
|
25
|
+
export declare const sessionManager: SessionManager;
|
|
26
|
+
//# sourceMappingURL=session-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/services/session-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;CACjC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;IAEvD,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IAmCxE,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI3C,UAAU,CACR,EAAE,EAAE,MAAM,EACV,OAAO,SAAI,GACV,OAAO,CAAC;QACT,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;IA2DF,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAa3C,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,OAAmB,GAAG,IAAI;CAQlE;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sessionManager = exports.SessionManager = void 0;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
class SessionManager {
|
|
6
|
+
sessions = new Map();
|
|
7
|
+
createSession(process) {
|
|
8
|
+
const id = (0, node_crypto_1.randomUUID)();
|
|
9
|
+
const session = {
|
|
10
|
+
id,
|
|
11
|
+
process,
|
|
12
|
+
stdoutBuffer: [],
|
|
13
|
+
stderrBuffer: [],
|
|
14
|
+
createdAt: Date.now(),
|
|
15
|
+
outputListeners: [],
|
|
16
|
+
};
|
|
17
|
+
process.stdout?.setEncoding('utf8');
|
|
18
|
+
process.stderr?.setEncoding('utf8');
|
|
19
|
+
const notifyListeners = () => {
|
|
20
|
+
const listeners = session.outputListeners;
|
|
21
|
+
session.outputListeners = [];
|
|
22
|
+
for (const listener of listeners) {
|
|
23
|
+
listener();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
process.stdout?.on('data', (chunk) => {
|
|
27
|
+
session.stdoutBuffer.push(chunk);
|
|
28
|
+
notifyListeners();
|
|
29
|
+
});
|
|
30
|
+
process.stderr?.on('data', (chunk) => {
|
|
31
|
+
session.stderrBuffer.push(chunk);
|
|
32
|
+
notifyListeners();
|
|
33
|
+
});
|
|
34
|
+
this.sessions.set(id, session);
|
|
35
|
+
return { sessionId: id, pid: process.pid ?? -1 };
|
|
36
|
+
}
|
|
37
|
+
getSession(id) {
|
|
38
|
+
return this.sessions.get(id);
|
|
39
|
+
}
|
|
40
|
+
readOutput(id, timeout = 0) {
|
|
41
|
+
const session = this.sessions.get(id);
|
|
42
|
+
if (!session) {
|
|
43
|
+
throw new Error(`Session not found: ${id}`);
|
|
44
|
+
}
|
|
45
|
+
const flush = () => {
|
|
46
|
+
const stdout = session.stdoutBuffer.join('');
|
|
47
|
+
const stderr = session.stderrBuffer.join('');
|
|
48
|
+
session.stdoutBuffer = [];
|
|
49
|
+
session.stderrBuffer = [];
|
|
50
|
+
const isActive = session.process.exitCode === null &&
|
|
51
|
+
session.process.signalCode === null;
|
|
52
|
+
return { stdout, stderr, isActive };
|
|
53
|
+
};
|
|
54
|
+
// If there is data or no timeout, return immediately
|
|
55
|
+
if (session.stdoutBuffer.length > 0 ||
|
|
56
|
+
session.stderrBuffer.length > 0 ||
|
|
57
|
+
timeout <= 0) {
|
|
58
|
+
return Promise.resolve(flush());
|
|
59
|
+
}
|
|
60
|
+
// Wait for data or timeout
|
|
61
|
+
return new Promise((resolvePromise) => {
|
|
62
|
+
let timeoutTimer;
|
|
63
|
+
let debounceTimer;
|
|
64
|
+
const finish = () => {
|
|
65
|
+
clearTimeout(timeoutTimer);
|
|
66
|
+
clearTimeout(debounceTimer);
|
|
67
|
+
// Remove listener
|
|
68
|
+
session.outputListeners = session.outputListeners.filter((l) => l !== onData);
|
|
69
|
+
resolvePromise(flush());
|
|
70
|
+
};
|
|
71
|
+
const onData = () => {
|
|
72
|
+
// When data arrives, wait a bit (debounce) to collect subsequent chunks
|
|
73
|
+
if (debounceTimer) {
|
|
74
|
+
clearTimeout(debounceTimer);
|
|
75
|
+
}
|
|
76
|
+
debounceTimer = setTimeout(finish, 50); // 50ms debounce
|
|
77
|
+
};
|
|
78
|
+
// Global timeout
|
|
79
|
+
timeoutTimer = setTimeout(finish, timeout);
|
|
80
|
+
session.outputListeners.push(onData);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
writeInput(id, input) {
|
|
84
|
+
const session = this.sessions.get(id);
|
|
85
|
+
if (!session) {
|
|
86
|
+
throw new Error(`Session not found: ${id}`);
|
|
87
|
+
}
|
|
88
|
+
if (session.process.stdin) {
|
|
89
|
+
session.process.stdin.write(input);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
throw new Error('Process stdin is not available');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
stopSession(id, signal = 'SIGTERM') {
|
|
96
|
+
const session = this.sessions.get(id);
|
|
97
|
+
if (!session) {
|
|
98
|
+
throw new Error(`Session not found: ${id}`);
|
|
99
|
+
}
|
|
100
|
+
session.process.kill(signal);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
exports.SessionManager = SessionManager;
|
|
104
|
+
exports.sessionManager = new SessionManager();
|
|
105
|
+
//# sourceMappingURL=session-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/services/session-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,eAAO,MAAM,mBAAmB,GAAI,QAAQ,SAAS,SA0DpD,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerExecuteTool = void 0;
|
|
4
|
+
const js_yaml_1 = require("js-yaml");
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const command_js_1 = require("../utils/command.js");
|
|
7
|
+
const registerExecuteTool = (server) => {
|
|
8
|
+
server.tool('execute_command', 'Execute a shell command. Note: This tool is for non-interactive, short-lived commands only. Interactive commands are not supported.', {
|
|
9
|
+
command: zod_1.z.string().describe('The shell command to execute'),
|
|
10
|
+
cwd: zod_1.z
|
|
11
|
+
.string()
|
|
12
|
+
.describe('The working directory to execute the command within'),
|
|
13
|
+
input: zod_1.z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe('Optional input to write to stdin. Useful for commands that require user interaction.'),
|
|
17
|
+
}, async (args) => {
|
|
18
|
+
try {
|
|
19
|
+
const { command: finalCommand, cwd: finalCwd } = await (0, command_js_1.prepareCommand)(args.command, args.cwd);
|
|
20
|
+
const result = await (0, command_js_1.runCommand)(finalCommand, finalCwd, args.input);
|
|
21
|
+
return {
|
|
22
|
+
content: [
|
|
23
|
+
{
|
|
24
|
+
type: 'text',
|
|
25
|
+
text: (0, js_yaml_1.dump)({
|
|
26
|
+
exit_code: result.exitCode,
|
|
27
|
+
stdout: result.stdout,
|
|
28
|
+
stderr: result.stderr,
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
let errorMessage = error instanceof Error ? error.message : String(error);
|
|
36
|
+
if (errorMessage.includes('ENOENT')) {
|
|
37
|
+
errorMessage +=
|
|
38
|
+
'\nNote: This tool does not support interactive commands. Ensure the command is non-interactive and the executable exists.';
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
content: [
|
|
42
|
+
{
|
|
43
|
+
type: 'text',
|
|
44
|
+
text: `Error executing command: ${errorMessage}`,
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
isError: true,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
exports.registerExecuteTool = registerExecuteTool;
|
|
53
|
+
//# sourceMappingURL=execute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":";;;AACA,qCAA+B;AAC/B,6BAAwB;AACxB,oDAAiE;AAE1D,MAAM,mBAAmB,GAAG,CAAC,MAAiB,EAAE,EAAE;IACvD,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,qIAAqI,EACrI;QACE,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAC5D,GAAG,EAAE,OAAC;aACH,MAAM,EAAE;aACR,QAAQ,CAAC,qDAAqD,CAAC;QAClE,KAAK,EAAE,OAAC;aACL,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,sFAAsF,CACvF;KACJ,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAA,2BAAc,EACnE,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,GAAG,CACT,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAU,EAAC,YAAY,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAEpE,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAA,cAAI,EAAC;4BACT,SAAS,EAAE,MAAM,CAAC,QAAQ;4BAC1B,MAAM,EAAE,MAAM,CAAC,MAAM;4BACrB,MAAM,EAAE,MAAM,CAAC,MAAM;yBACtB,CAAC;qBACH;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,YAAY,GACd,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAEzD,IAAI,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpC,YAAY;oBACV,2HAA2H,CAAC;YAChI,CAAC;YAED,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,4BAA4B,YAAY,EAAE;qBACjD;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AA1DW,QAAA,mBAAmB,uBA0D9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,eAAO,MAAM,aAAa,GAAI,QAAQ,SAAS,SAE9C,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerTools = void 0;
|
|
4
|
+
const execute_js_1 = require("./execute.js");
|
|
5
|
+
const registerTools = (server) => {
|
|
6
|
+
(0, execute_js_1.registerExecuteTool)(server);
|
|
7
|
+
};
|
|
8
|
+
exports.registerTools = registerTools;
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":";;;AACA,6CAAmD;AAE5C,MAAM,aAAa,GAAG,CAAC,MAAiB,EAAE,EAAE;IACjD,IAAA,gCAAmB,EAAC,MAAM,CAAC,CAAC;AAC9B,CAAC,CAAC;AAFW,QAAA,aAAa,iBAExB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/tools/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,eAAO,MAAM,oBAAoB,GAAI,QAAQ,SAAS,SA6LrD,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.registerSessionTools = void 0;
|
|
7
|
+
const cross_spawn_1 = __importDefault(require("cross-spawn"));
|
|
8
|
+
const js_yaml_1 = require("js-yaml");
|
|
9
|
+
const zod_1 = require("zod");
|
|
10
|
+
const session_manager_js_1 = require("../services/session-manager.js");
|
|
11
|
+
const command_js_1 = require("../utils/command.js");
|
|
12
|
+
const registerSessionTools = (server) => {
|
|
13
|
+
server.tool('start_command', 'Start a background command session. Use this for interactive commands or long-running processes.', {
|
|
14
|
+
command: zod_1.z.string().describe('The shell command to execute'),
|
|
15
|
+
cwd: zod_1.z
|
|
16
|
+
.string()
|
|
17
|
+
.describe('The working directory to execute the command within'),
|
|
18
|
+
timeout: zod_1.z
|
|
19
|
+
.number()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe('Maximum time (in milliseconds) to wait for initial output. Default is 0 (no wait).'),
|
|
22
|
+
}, async (args) => {
|
|
23
|
+
try {
|
|
24
|
+
const { command: finalCommand, cwd: finalCwd } = await (0, command_js_1.prepareCommand)(args.command, args.cwd);
|
|
25
|
+
const child = (0, cross_spawn_1.default)(finalCommand, {
|
|
26
|
+
cwd: finalCwd,
|
|
27
|
+
shell: true,
|
|
28
|
+
windowsHide: true,
|
|
29
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
30
|
+
});
|
|
31
|
+
const { sessionId, pid } = session_manager_js_1.sessionManager.createSession(child);
|
|
32
|
+
const result = { sessionId, pid };
|
|
33
|
+
if (args.timeout && args.timeout > 0) {
|
|
34
|
+
const output = await session_manager_js_1.sessionManager.readOutput(sessionId, args.timeout);
|
|
35
|
+
result.stdout = output.stdout;
|
|
36
|
+
result.stderr = output.stderr;
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: 'text',
|
|
42
|
+
text: (0, js_yaml_1.dump)(result),
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{
|
|
51
|
+
type: 'text',
|
|
52
|
+
text: `Error starting command: ${error instanceof Error ? error.message : String(error)}`,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
isError: true,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
server.tool('read_output', 'Read buffered output from a command session', {
|
|
60
|
+
sessionId: zod_1.z.string().describe('The ID of the session'),
|
|
61
|
+
timeout: zod_1.z
|
|
62
|
+
.number()
|
|
63
|
+
.optional()
|
|
64
|
+
.describe('Maximum time (in milliseconds) to wait for new output if the buffer is empty. Default is 0 (no wait).'),
|
|
65
|
+
}, async (args) => {
|
|
66
|
+
try {
|
|
67
|
+
const result = await session_manager_js_1.sessionManager.readOutput(args.sessionId, args.timeout);
|
|
68
|
+
return {
|
|
69
|
+
content: [
|
|
70
|
+
{
|
|
71
|
+
type: 'text',
|
|
72
|
+
text: (0, js_yaml_1.dump)(result),
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
return {
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: 'text',
|
|
82
|
+
text: `Error reading output: ${error instanceof Error ? error.message : String(error)}`,
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
isError: true,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
server.tool('write_input', 'Write input to a command session', {
|
|
90
|
+
sessionId: zod_1.z.string().describe('The ID of the session'),
|
|
91
|
+
input: zod_1.z.string().describe('The input to write'),
|
|
92
|
+
}, async (args) => {
|
|
93
|
+
try {
|
|
94
|
+
await Promise.resolve();
|
|
95
|
+
session_manager_js_1.sessionManager.writeInput(args.sessionId, args.input);
|
|
96
|
+
return {
|
|
97
|
+
content: [
|
|
98
|
+
{
|
|
99
|
+
type: 'text',
|
|
100
|
+
text: (0, js_yaml_1.dump)({ success: true }),
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
return {
|
|
107
|
+
content: [
|
|
108
|
+
{
|
|
109
|
+
type: 'text',
|
|
110
|
+
text: `Error writing input: ${error instanceof Error ? error.message : String(error)}`,
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
isError: true,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
server.tool('stop_command', 'Stop a command session', {
|
|
118
|
+
sessionId: zod_1.z.string().describe('The ID of the session'),
|
|
119
|
+
signal: zod_1.z
|
|
120
|
+
.string()
|
|
121
|
+
.optional()
|
|
122
|
+
.describe('The signal to send (default: SIGTERM)'),
|
|
123
|
+
}, async (args) => {
|
|
124
|
+
try {
|
|
125
|
+
await Promise.resolve();
|
|
126
|
+
session_manager_js_1.sessionManager.stopSession(args.sessionId, args.signal ?? 'SIGTERM');
|
|
127
|
+
return {
|
|
128
|
+
content: [
|
|
129
|
+
{
|
|
130
|
+
type: 'text',
|
|
131
|
+
text: (0, js_yaml_1.dump)({ success: true }),
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
return {
|
|
138
|
+
content: [
|
|
139
|
+
{
|
|
140
|
+
type: 'text',
|
|
141
|
+
text: `Error stopping session: ${error instanceof Error ? error.message : String(error)}`,
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
isError: true,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
exports.registerSessionTools = registerSessionTools;
|
|
150
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/tools/session.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CommandResult } from '../types.js';
|
|
2
|
+
export declare const runCommand: (command: string, cwd?: string, input?: string) => Promise<CommandResult>;
|
|
3
|
+
export declare const prepareCommand: (command: string, cwd: string) => Promise<{
|
|
4
|
+
command: string;
|
|
5
|
+
cwd?: string;
|
|
6
|
+
}>;
|
|
7
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/utils/command.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,eAAO,MAAM,UAAU,GACrB,SAAS,MAAM,EACf,MAAM,MAAM,EACZ,QAAQ,MAAM,KACb,OAAO,CAAC,aAAa,CAsCpB,CAAC;AAEL,eAAO,MAAM,cAAc,GACzB,SAAS,MAAM,EACf,KAAK,MAAM,KACV,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CA0B3C,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.prepareCommand = exports.runCommand = void 0;
|
|
7
|
+
const args_tokenizer_1 = require("args-tokenizer");
|
|
8
|
+
const cross_spawn_1 = __importDefault(require("cross-spawn"));
|
|
9
|
+
const env_js_1 = require("./env.js");
|
|
10
|
+
const paths_js_1 = require("./paths.js");
|
|
11
|
+
const runCommand = async (command, cwd, input) => new Promise((resolvePromise, rejectPromise) => {
|
|
12
|
+
const child = (0, cross_spawn_1.default)(command, {
|
|
13
|
+
cwd,
|
|
14
|
+
shell: true,
|
|
15
|
+
windowsHide: true,
|
|
16
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
17
|
+
});
|
|
18
|
+
if (input) {
|
|
19
|
+
child.stdin?.write(input);
|
|
20
|
+
child.stdin?.end();
|
|
21
|
+
}
|
|
22
|
+
let stdout = '';
|
|
23
|
+
let stderr = '';
|
|
24
|
+
child.stdout?.setEncoding('utf8');
|
|
25
|
+
child.stderr?.setEncoding('utf8');
|
|
26
|
+
child.stdout?.on('data', (chunk) => {
|
|
27
|
+
stdout += chunk;
|
|
28
|
+
});
|
|
29
|
+
child.stderr?.on('data', (chunk) => {
|
|
30
|
+
stderr += chunk;
|
|
31
|
+
});
|
|
32
|
+
child.on('error', (error) => {
|
|
33
|
+
rejectPromise(error);
|
|
34
|
+
});
|
|
35
|
+
child.on('close', (code) => {
|
|
36
|
+
resolvePromise({
|
|
37
|
+
exitCode: typeof code === 'number' ? code : 1,
|
|
38
|
+
stdout,
|
|
39
|
+
stderr,
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
exports.runCommand = runCommand;
|
|
44
|
+
const prepareCommand = async (command, cwd) => {
|
|
45
|
+
const [bin] = (0, args_tokenizer_1.tokenizeArgs)(command);
|
|
46
|
+
const allowedCommands = (0, env_js_1.parseCommaSeparatedEnv)(process.env.ALLOWED_COMMANDS);
|
|
47
|
+
if (!(allowedCommands.includes('*') || allowedCommands.includes(bin))) {
|
|
48
|
+
throw new Error(`Command "${bin}" is not allowed, allowed commands: ${allowedCommands.length > 0 ? allowedCommands.join(', ') : '(none)'}`);
|
|
49
|
+
}
|
|
50
|
+
const cwdResolved = await (0, paths_js_1.resolveAndValidateCwd)(cwd);
|
|
51
|
+
let finalCommand = command;
|
|
52
|
+
let finalCwd = cwdResolved;
|
|
53
|
+
if (process.platform === 'win32' && cwdResolved.startsWith('/')) {
|
|
54
|
+
finalCommand = `wsl --cd "${cwdResolved}" -- bash -c "${command.replace(/"/g, '\\"')}"`;
|
|
55
|
+
finalCwd = undefined;
|
|
56
|
+
}
|
|
57
|
+
return { command: finalCommand, cwd: finalCwd };
|
|
58
|
+
};
|
|
59
|
+
exports.prepareCommand = prepareCommand;
|
|
60
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/utils/command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,MAAM,EAQxE,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseCommaSeparatedEnv = void 0;
|
|
4
|
+
const parseCommaSeparatedEnv = (value) => {
|
|
5
|
+
if (!value) {
|
|
6
|
+
return [];
|
|
7
|
+
}
|
|
8
|
+
return value
|
|
9
|
+
.split(',')
|
|
10
|
+
.map((item) => item.trim())
|
|
11
|
+
.filter((item) => item.length > 0);
|
|
12
|
+
};
|
|
13
|
+
exports.parseCommaSeparatedEnv = parseCommaSeparatedEnv;
|
|
14
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":";;;AAAO,MAAM,sBAAsB,GAAG,CAAC,KAAyB,EAAY,EAAE;IAC5E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACvC,CAAC,CAAC;AARW,QAAA,sBAAsB,0BAQjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,KAAG,OAQ3D,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,UAAU,MAAM,KACf,OAAO,CAAC,MAAM,CAiEhB,CAAC;AAEF,eAAO,MAAM,SAAS,QAAO,MAAM,GAAG,SAgBrC,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getWslCwd = exports.resolveAndValidateCwd = exports.isWithinRoot = void 0;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const promises_1 = require("node:fs/promises");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const env_js_1 = require("./env.js");
|
|
8
|
+
const isWithinRoot = (root, target) => {
|
|
9
|
+
const rel = (0, node_path_1.relative)(root, target);
|
|
10
|
+
if (rel === '') {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
const isOutsideRoot = rel.startsWith('..') || (0, node_path_1.isAbsolute)(rel);
|
|
14
|
+
return !isOutsideRoot;
|
|
15
|
+
};
|
|
16
|
+
exports.isWithinRoot = isWithinRoot;
|
|
17
|
+
const resolveAndValidateCwd = async (cwdInput) => {
|
|
18
|
+
if (process.platform === 'win32' && cwdInput.startsWith('/')) {
|
|
19
|
+
const allowedRoots = (0, env_js_1.parseCommaSeparatedEnv)(process.env.ALLOWED_CWD_ROOTS);
|
|
20
|
+
if (allowedRoots.length === 0) {
|
|
21
|
+
return cwdInput;
|
|
22
|
+
}
|
|
23
|
+
const cwdNormalized = node_path_1.posix.normalize(cwdInput);
|
|
24
|
+
const allowed = allowedRoots.some((root) => {
|
|
25
|
+
const rel = node_path_1.posix.relative(root, cwdNormalized);
|
|
26
|
+
return rel === '' || !(rel.startsWith('..') || node_path_1.posix.isAbsolute(rel));
|
|
27
|
+
});
|
|
28
|
+
if (!allowed) {
|
|
29
|
+
throw new Error('cwd is not allowed by ALLOWED_CWD_ROOTS');
|
|
30
|
+
}
|
|
31
|
+
return cwdInput;
|
|
32
|
+
}
|
|
33
|
+
const cwdResolved = (0, node_path_1.resolve)(process.cwd(), cwdInput);
|
|
34
|
+
try {
|
|
35
|
+
const cwdStat = await (0, promises_1.stat)(cwdResolved);
|
|
36
|
+
if (!cwdStat.isDirectory()) {
|
|
37
|
+
throw new Error(`cwd is not a directory: ${cwdInput}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (error instanceof Error &&
|
|
42
|
+
error.message.includes('cwd is not a directory')) {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
throw new Error(`cwd does not exist: ${cwdInput}`);
|
|
46
|
+
}
|
|
47
|
+
const cwdCanonical = await (0, promises_1.realpath)(cwdResolved);
|
|
48
|
+
const allowedRoots = (0, env_js_1.parseCommaSeparatedEnv)(process.env.ALLOWED_CWD_ROOTS);
|
|
49
|
+
if (allowedRoots.length === 0) {
|
|
50
|
+
return cwdResolved;
|
|
51
|
+
}
|
|
52
|
+
const canonicalRoots = await Promise.all(allowedRoots.map(async (root) => {
|
|
53
|
+
const rootResolved = (0, node_path_1.resolve)(process.cwd(), root);
|
|
54
|
+
try {
|
|
55
|
+
return await (0, promises_1.realpath)(rootResolved);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
throw new Error(`Invalid configuration: ALLOWED_CWD_ROOTS contains an invalid root: ${root}`);
|
|
59
|
+
}
|
|
60
|
+
}));
|
|
61
|
+
const allowed = canonicalRoots.some((root) => (0, exports.isWithinRoot)(root, cwdCanonical));
|
|
62
|
+
if (!allowed) {
|
|
63
|
+
throw new Error('cwd is not allowed by ALLOWED_CWD_ROOTS');
|
|
64
|
+
}
|
|
65
|
+
return cwdResolved;
|
|
66
|
+
};
|
|
67
|
+
exports.resolveAndValidateCwd = resolveAndValidateCwd;
|
|
68
|
+
const getWslCwd = () => {
|
|
69
|
+
if (process.platform !== 'win32') {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
// Try to convert current working directory to WSL path
|
|
74
|
+
const wslPath = (0, node_child_process_1.execSync)(`wsl wslpath -u "${process.cwd()}"`)
|
|
75
|
+
.toString()
|
|
76
|
+
.trim();
|
|
77
|
+
if (wslPath.startsWith('/')) {
|
|
78
|
+
return wslPath;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Ignore errors if wsl/wslpath is not available or fails
|
|
83
|
+
}
|
|
84
|
+
return;
|
|
85
|
+
};
|
|
86
|
+
exports.getWslCwd = getWslCwd;
|
|
87
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":";;;AAAA,2DAA8C;AAC9C,+CAAkD;AAClD,yCAAiE;AACjE,qCAAkD;AAE3C,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,MAAc,EAAW,EAAE;IACpE,MAAM,GAAG,GAAG,IAAA,oBAAQ,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnC,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,aAAa,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAA,sBAAU,EAAC,GAAG,CAAC,CAAC;IAC9D,OAAO,CAAC,aAAa,CAAC;AACxB,CAAC,CAAC;AARW,QAAA,YAAY,gBAQvB;AAEK,MAAM,qBAAqB,GAAG,KAAK,EACxC,QAAgB,EACC,EAAE;IACnB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7D,MAAM,YAAY,GAAG,IAAA,+BAAsB,EAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC3E,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,aAAa,GAAG,iBAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACzC,MAAM,GAAG,GAAG,iBAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;YAChD,OAAO,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,IAAA,mBAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,IAAA,eAAI,EAAC,WAAW,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IACE,KAAK,YAAY,KAAK;YACtB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EAChD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,IAAA,mBAAQ,EAAC,WAAW,CAAC,CAAC;IAEjD,MAAM,YAAY,GAAG,IAAA,+BAAsB,EAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC3E,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,GAAG,CACtC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC9B,MAAM,YAAY,GAAG,IAAA,mBAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,OAAO,MAAM,IAAA,mBAAQ,EAAC,YAAY,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,sEAAsE,IAAI,EAAE,CAC7E,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAC3C,IAAA,oBAAY,EAAC,IAAI,EAAE,YAAY,CAAC,CACjC,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAnEW,QAAA,qBAAqB,yBAmEhC;AAEK,MAAM,SAAS,GAAG,GAAuB,EAAE;IAChD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,uDAAuD;QACvD,MAAM,OAAO,GAAG,IAAA,6BAAQ,EAAC,mBAAmB,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC;aAC1D,QAAQ,EAAE;aACV,IAAI,EAAE,CAAC;QACV,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;IACD,OAAO;AACT,CAAC,CAAC;AAhBW,QAAA,SAAS,aAgBpB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-terminal-runner",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mcp-terminal-runner": "dist/index.js"
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"build": "tsc",
|
|
10
10
|
"dev": "ts-node src/index.ts",
|
|
11
11
|
"start": "node dist/index.js",
|
|
12
|
+
"inspector": "npm run build && npx @modelcontextprotocol/inspector node dist/index.js",
|
|
12
13
|
"check": "ultracite check",
|
|
13
14
|
"fix": "ultracite fix",
|
|
14
15
|
"typecheck": "tsc --noEmit",
|