@vinhnt-sdk/tools 1.0.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/LICENSE +21 -0
- package/dist/arity.d.ts +22 -0
- package/dist/arity.d.ts.map +1 -0
- package/dist/arity.js +96 -0
- package/dist/arity.js.map +1 -0
- package/dist/context.d.ts +43 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +2 -0
- package/dist/context.js.map +1 -0
- package/dist/define-tool.d.ts +45 -0
- package/dist/define-tool.d.ts.map +1 -0
- package/dist/define-tool.js +120 -0
- package/dist/define-tool.js.map +1 -0
- package/dist/definitions.d.ts +24 -0
- package/dist/definitions.d.ts.map +1 -0
- package/dist/definitions.js +2 -0
- package/dist/definitions.js.map +1 -0
- package/dist/description-lint.d.ts +25 -0
- package/dist/description-lint.d.ts.map +1 -0
- package/dist/description-lint.js +90 -0
- package/dist/description-lint.js.map +1 -0
- package/dist/diff.d.ts +7 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +26 -0
- package/dist/diff.js.map +1 -0
- package/dist/domain.d.ts +39 -0
- package/dist/domain.d.ts.map +1 -0
- package/dist/domain.js +20 -0
- package/dist/domain.js.map +1 -0
- package/dist/file-history.d.ts +43 -0
- package/dist/file-history.d.ts.map +1 -0
- package/dist/file-history.js +55 -0
- package/dist/file-history.js.map +1 -0
- package/dist/file-tools.d.ts +56 -0
- package/dist/file-tools.d.ts.map +1 -0
- package/dist/file-tools.js +542 -0
- package/dist/file-tools.js.map +1 -0
- package/dist/git-tools.d.ts +8 -0
- package/dist/git-tools.d.ts.map +1 -0
- package/dist/git-tools.js +114 -0
- package/dist/git-tools.js.map +1 -0
- package/dist/history-hook.d.ts +4 -0
- package/dist/history-hook.d.ts.map +1 -0
- package/dist/history-hook.js +62 -0
- package/dist/history-hook.js.map +1 -0
- package/dist/image-tools.d.ts +11 -0
- package/dist/image-tools.d.ts.map +1 -0
- package/dist/image-tools.js +55 -0
- package/dist/image-tools.js.map +1 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/json-schema.d.ts +22 -0
- package/dist/json-schema.d.ts.map +1 -0
- package/dist/json-schema.js +2 -0
- package/dist/json-schema.js.map +1 -0
- package/dist/lazy-registry.d.ts +23 -0
- package/dist/lazy-registry.d.ts.map +1 -0
- package/dist/lazy-registry.js +64 -0
- package/dist/lazy-registry.js.map +1 -0
- package/dist/policy.d.ts +5 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +2 -0
- package/dist/policy.js.map +1 -0
- package/dist/provider-helpers.d.ts +26 -0
- package/dist/provider-helpers.d.ts.map +1 -0
- package/dist/provider-helpers.js +46 -0
- package/dist/provider-helpers.js.map +1 -0
- package/dist/provider.d.ts +80 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +96 -0
- package/dist/provider.js.map +1 -0
- package/dist/providers/agent-provider.d.ts +32 -0
- package/dist/providers/agent-provider.d.ts.map +1 -0
- package/dist/providers/agent-provider.js +35 -0
- package/dist/providers/agent-provider.js.map +1 -0
- package/dist/providers/builtin-provider.d.ts +36 -0
- package/dist/providers/builtin-provider.d.ts.map +1 -0
- package/dist/providers/builtin-provider.js +86 -0
- package/dist/providers/builtin-provider.js.map +1 -0
- package/dist/providers/file-loader.d.ts +47 -0
- package/dist/providers/file-loader.d.ts.map +1 -0
- package/dist/providers/file-loader.js +120 -0
- package/dist/providers/file-loader.js.map +1 -0
- package/dist/providers/index.d.ts +6 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +5 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/skill-provider.d.ts +23 -0
- package/dist/providers/skill-provider.d.ts.map +1 -0
- package/dist/providers/skill-provider.js +28 -0
- package/dist/providers/skill-provider.js.map +1 -0
- package/dist/question-tool.d.ts +15 -0
- package/dist/question-tool.d.ts.map +1 -0
- package/dist/question-tool.js +51 -0
- package/dist/question-tool.js.map +1 -0
- package/dist/read-tracker.d.ts +8 -0
- package/dist/read-tracker.d.ts.map +1 -0
- package/dist/read-tracker.js +33 -0
- package/dist/read-tracker.js.map +1 -0
- package/dist/registry.d.ts +58 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +128 -0
- package/dist/registry.js.map +1 -0
- package/dist/sandbox.d.ts +85 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +409 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/search-tools.d.ts +11 -0
- package/dist/search-tools.d.ts.map +1 -0
- package/dist/search-tools.js +124 -0
- package/dist/search-tools.js.map +1 -0
- package/dist/shell-parser.d.ts +9 -0
- package/dist/shell-parser.d.ts.map +1 -0
- package/dist/shell-parser.js +68 -0
- package/dist/shell-parser.js.map +1 -0
- package/dist/shell-tool.d.ts +22 -0
- package/dist/shell-tool.d.ts.map +1 -0
- package/dist/shell-tool.js +100 -0
- package/dist/shell-tool.js.map +1 -0
- package/dist/todo-tool.d.ts +2 -0
- package/dist/todo-tool.d.ts.map +1 -0
- package/dist/todo-tool.js +121 -0
- package/dist/todo-tool.js.map +1 -0
- package/dist/tool-search.d.ts +14 -0
- package/dist/tool-search.d.ts.map +1 -0
- package/dist/tool-search.js +46 -0
- package/dist/tool-search.js.map +1 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +9 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +26 -0
- package/dist/validate.js.map +1 -0
- package/dist/web-search-tool.d.ts +84 -0
- package/dist/web-search-tool.d.ts.map +1 -0
- package/dist/web-search-tool.js +134 -0
- package/dist/web-search-tool.js.map +1 -0
- package/dist/web-tools.d.ts +10 -0
- package/dist/web-tools.d.ts.map +1 -0
- package/dist/web-tools.js +62 -0
- package/dist/web-tools.js.map +1 -0
- package/package.json +58 -0
package/dist/sandbox.js
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool sandboxing for isolated execution.
|
|
3
|
+
*
|
|
4
|
+
* @module tool/sandbox
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
import { parseCommand } from "./shell-parser.js";
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Environment sanitization
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
const SENSITIVE_ENV_PREFIXES = [
|
|
12
|
+
"AWS_",
|
|
13
|
+
"GOOGLE_",
|
|
14
|
+
"AZURE_",
|
|
15
|
+
"GITHUB_",
|
|
16
|
+
"GITLAB_",
|
|
17
|
+
"npm_",
|
|
18
|
+
"NODE_",
|
|
19
|
+
];
|
|
20
|
+
const SENSITIVE_ENV_KEYS = new Set([
|
|
21
|
+
"HOME",
|
|
22
|
+
"USER",
|
|
23
|
+
"USERNAME",
|
|
24
|
+
"PASSWORD",
|
|
25
|
+
"SECRET",
|
|
26
|
+
"TOKEN",
|
|
27
|
+
"API_KEY",
|
|
28
|
+
"APIKEY",
|
|
29
|
+
"PRIVATE_KEY",
|
|
30
|
+
"DATABASE_URL",
|
|
31
|
+
"DB_URL",
|
|
32
|
+
"REDIS_URL",
|
|
33
|
+
]);
|
|
34
|
+
function sanitizeEnv() {
|
|
35
|
+
const safe = {};
|
|
36
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
37
|
+
const upperKey = key.toUpperCase();
|
|
38
|
+
const isSensitive = SENSITIVE_ENV_PREFIXES.some((p) => upperKey.startsWith(p)) ||
|
|
39
|
+
SENSITIVE_ENV_KEYS.has(upperKey);
|
|
40
|
+
if (!isSensitive) {
|
|
41
|
+
safe[key] = value;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return safe;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Create an empty environment with only explicitly allowed variables.
|
|
48
|
+
* This is the secure default for process isolation.
|
|
49
|
+
*/
|
|
50
|
+
function createEmptyEnv(allowedVars) {
|
|
51
|
+
const env = {};
|
|
52
|
+
if (allowedVars) {
|
|
53
|
+
for (const key of allowedVars) {
|
|
54
|
+
const value = process.env[key];
|
|
55
|
+
if (value !== undefined) {
|
|
56
|
+
env[key] = value;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return env;
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Command allowlisting
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
/** Default allowed commands for process isolation */
|
|
66
|
+
const DEFAULT_ALLOWED_COMMANDS = new Set([
|
|
67
|
+
"node",
|
|
68
|
+
"npm",
|
|
69
|
+
"npx",
|
|
70
|
+
"pnpm",
|
|
71
|
+
"git",
|
|
72
|
+
"ls",
|
|
73
|
+
"cat",
|
|
74
|
+
"grep",
|
|
75
|
+
"find",
|
|
76
|
+
"head",
|
|
77
|
+
"tail",
|
|
78
|
+
"wc",
|
|
79
|
+
"sort",
|
|
80
|
+
"uniq",
|
|
81
|
+
"diff",
|
|
82
|
+
"echo",
|
|
83
|
+
"pwd",
|
|
84
|
+
"whoami",
|
|
85
|
+
"date",
|
|
86
|
+
]);
|
|
87
|
+
/** Blocked command patterns (security) */
|
|
88
|
+
const BLOCKED_COMMAND_PATTERNS = [
|
|
89
|
+
/\brm\s+-rf\s+\/[^a-z]/i, // rm -rf / (not /something)
|
|
90
|
+
/\bmkfs\b/i,
|
|
91
|
+
/\bdd\b.*of=\/dev/i,
|
|
92
|
+
/\bformat\b/i,
|
|
93
|
+
/\bshutdown\b/i,
|
|
94
|
+
/\breboot\b/i,
|
|
95
|
+
/\bkill\s+-9\s+1\b/i, // kill PID 1
|
|
96
|
+
/\bcurl\b.*\|\s*sh/i, // curl | sh
|
|
97
|
+
/\bwget\b.*\|\s*sh/i, // wget | sh
|
|
98
|
+
];
|
|
99
|
+
/**
|
|
100
|
+
* Check if a command is allowed in the sandbox.
|
|
101
|
+
*/
|
|
102
|
+
function isCommandAllowed(command, allowedCommands) {
|
|
103
|
+
const parsed = parseCommand(command);
|
|
104
|
+
const baseCommand = parsed.file.split("/").pop()?.split("\\").pop() ?? parsed.file;
|
|
105
|
+
// Check blocked patterns first
|
|
106
|
+
for (const pattern of BLOCKED_COMMAND_PATTERNS) {
|
|
107
|
+
if (pattern.test(command)) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Check allowlist
|
|
112
|
+
const allowlist = allowedCommands ?? DEFAULT_ALLOWED_COMMANDS;
|
|
113
|
+
return allowlist.has(baseCommand);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Default sandbox scopes — exported for convenience.
|
|
117
|
+
* User có thể register custom scope qua ProcessSandbox adapter.
|
|
118
|
+
*/
|
|
119
|
+
export const KNOWN_SANDBOX_SCOPES = ["host", "process", "container"];
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// Host sandbox (no isolation — current behavior)
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
import { execFile } from "node:child_process";
|
|
124
|
+
class HostSandbox {
|
|
125
|
+
scope = "host";
|
|
126
|
+
async execute(options) {
|
|
127
|
+
const start = Date.now();
|
|
128
|
+
return new Promise((resolve) => {
|
|
129
|
+
const parsed = parseCommand(options.command);
|
|
130
|
+
const child = execFile(parsed.file, parsed.args, {
|
|
131
|
+
cwd: options.cwd,
|
|
132
|
+
timeout: options.timeoutMs,
|
|
133
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
134
|
+
encoding: "utf-8",
|
|
135
|
+
windowsHide: true,
|
|
136
|
+
env: options.env && Object.keys(options.env).length > 0
|
|
137
|
+
? { ...sanitizeEnv(), ...options.env }
|
|
138
|
+
: undefined,
|
|
139
|
+
}, (err, stdout, stderr) => {
|
|
140
|
+
const durationMs = Date.now() - start;
|
|
141
|
+
if (err) {
|
|
142
|
+
const exitCode = typeof err.code === "number" ? err.code : 1;
|
|
143
|
+
const timedOut = err.killed === true;
|
|
144
|
+
resolve({
|
|
145
|
+
result: { stdout: stdout ?? "", stderr: stderr ?? "", exitCode },
|
|
146
|
+
exitCode,
|
|
147
|
+
durationMs,
|
|
148
|
+
timedOut,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
resolve({
|
|
153
|
+
result: { stdout: stdout ?? "", stderr: stderr ?? "", exitCode: 0 },
|
|
154
|
+
exitCode: 0,
|
|
155
|
+
durationMs,
|
|
156
|
+
timedOut: false,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
if (options.signal) {
|
|
161
|
+
if (options.signal.aborted) {
|
|
162
|
+
child.kill();
|
|
163
|
+
resolve({
|
|
164
|
+
result: { stdout: "", stderr: "Aborted", exitCode: 1 },
|
|
165
|
+
exitCode: 1,
|
|
166
|
+
durationMs: Date.now() - start,
|
|
167
|
+
timedOut: false,
|
|
168
|
+
});
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
options.signal.addEventListener("abort", () => {
|
|
172
|
+
child.kill();
|
|
173
|
+
resolve({
|
|
174
|
+
result: { stdout: "", stderr: options.signal?.reason ?? "Aborted", exitCode: 1 },
|
|
175
|
+
exitCode: 1,
|
|
176
|
+
durationMs: Date.now() - start,
|
|
177
|
+
timedOut: false,
|
|
178
|
+
});
|
|
179
|
+
}, { once: true });
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
async destroy() {
|
|
184
|
+
// No resources to clean up
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
// Process sandbox (Node.js Permission Model + command allowlist)
|
|
189
|
+
// ---------------------------------------------------------------------------
|
|
190
|
+
class ProcessSandboxImpl {
|
|
191
|
+
scope = "process";
|
|
192
|
+
config;
|
|
193
|
+
constructor(config) {
|
|
194
|
+
this.config = config;
|
|
195
|
+
}
|
|
196
|
+
async execute(options) {
|
|
197
|
+
const start = Date.now();
|
|
198
|
+
// Validate command against allowlist
|
|
199
|
+
if (!isCommandAllowed(options.command, this.config.allowedCommands)) {
|
|
200
|
+
return {
|
|
201
|
+
result: {
|
|
202
|
+
stdout: "",
|
|
203
|
+
stderr: `Command not allowed: ${options.command.split(" ")[0]}`,
|
|
204
|
+
exitCode: 126,
|
|
205
|
+
},
|
|
206
|
+
exitCode: 126,
|
|
207
|
+
durationMs: Date.now() - start,
|
|
208
|
+
timedOut: false,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
// Create secure environment (empty by default, only explicitly allowed vars)
|
|
212
|
+
const secureEnv = this.config.allowedEnvVars
|
|
213
|
+
? createEmptyEnv(this.config.allowedEnvVars)
|
|
214
|
+
: createEmptyEnv();
|
|
215
|
+
// Parse the command
|
|
216
|
+
const parsed = parseCommand(options.command);
|
|
217
|
+
// Build exec args with security options
|
|
218
|
+
const execArgs = [];
|
|
219
|
+
// Add Node.js Permission Model flags if enabled (Node 22+)
|
|
220
|
+
if (this.config.enablePermissionModel && parsed.file === "node") {
|
|
221
|
+
execArgs.push("--permission");
|
|
222
|
+
// Allow read-only access to current directory
|
|
223
|
+
execArgs.push(`--allow-fs-read=${options.cwd}`);
|
|
224
|
+
// Allow read-write to temp directory
|
|
225
|
+
execArgs.push("--allow-fs-read=/tmp");
|
|
226
|
+
execArgs.push("--allow-fs-write=/tmp");
|
|
227
|
+
// Block all other access by default
|
|
228
|
+
}
|
|
229
|
+
// Add resource limits
|
|
230
|
+
const maxBuffer = 10 * 1024 * 1024; // 10MB
|
|
231
|
+
return new Promise((resolve) => {
|
|
232
|
+
const child = execFile(parsed.file, [...execArgs, ...parsed.args], {
|
|
233
|
+
cwd: options.cwd,
|
|
234
|
+
timeout: options.timeoutMs,
|
|
235
|
+
maxBuffer,
|
|
236
|
+
encoding: "utf-8",
|
|
237
|
+
windowsHide: true,
|
|
238
|
+
env: secureEnv,
|
|
239
|
+
// Security options
|
|
240
|
+
...(process.platform !== "win32" ? {
|
|
241
|
+
// On Linux/macOS, use additional security
|
|
242
|
+
uid: process.getuid?.(),
|
|
243
|
+
gid: process.getgid?.(),
|
|
244
|
+
} : {}),
|
|
245
|
+
}, (err, stdout, stderr) => {
|
|
246
|
+
const durationMs = Date.now() - start;
|
|
247
|
+
if (err) {
|
|
248
|
+
const exitCode = typeof err.code === "number" ? err.code : 1;
|
|
249
|
+
const timedOut = err.killed === true;
|
|
250
|
+
resolve({
|
|
251
|
+
result: { stdout: stdout ?? "", stderr: stderr ?? "", exitCode },
|
|
252
|
+
exitCode,
|
|
253
|
+
durationMs,
|
|
254
|
+
timedOut,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
resolve({
|
|
259
|
+
result: { stdout: stdout ?? "", stderr: stderr ?? "", exitCode: 0 },
|
|
260
|
+
exitCode: 0,
|
|
261
|
+
durationMs,
|
|
262
|
+
timedOut: false,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
if (options.signal) {
|
|
267
|
+
if (options.signal.aborted) {
|
|
268
|
+
child.kill();
|
|
269
|
+
resolve({
|
|
270
|
+
result: { stdout: "", stderr: "Aborted", exitCode: 1 },
|
|
271
|
+
exitCode: 1,
|
|
272
|
+
durationMs: Date.now() - start,
|
|
273
|
+
timedOut: false,
|
|
274
|
+
});
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
options.signal.addEventListener("abort", () => {
|
|
278
|
+
child.kill();
|
|
279
|
+
resolve({
|
|
280
|
+
result: { stdout: "", stderr: options.signal?.reason ?? "Aborted", exitCode: 1 },
|
|
281
|
+
exitCode: 1,
|
|
282
|
+
durationMs: Date.now() - start,
|
|
283
|
+
timedOut: false,
|
|
284
|
+
});
|
|
285
|
+
}, { once: true });
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
async destroy() {
|
|
290
|
+
// Clean up resources if any
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// ---------------------------------------------------------------------------
|
|
294
|
+
// Container sandbox (placeholder for future implementation)
|
|
295
|
+
// ---------------------------------------------------------------------------
|
|
296
|
+
class ContainerSandboxImpl {
|
|
297
|
+
scope = "container";
|
|
298
|
+
async execute(options) {
|
|
299
|
+
// Container sandbox would use Docker, bubblewrap, or similar
|
|
300
|
+
// For now, fall back to process sandbox with a warning
|
|
301
|
+
console.warn("[sandbox] Container sandbox not yet implemented, using process sandbox");
|
|
302
|
+
const processSandbox = new ProcessSandboxImpl({
|
|
303
|
+
defaultTimeoutMs: options.timeoutMs,
|
|
304
|
+
scope: "process",
|
|
305
|
+
});
|
|
306
|
+
return processSandbox.execute(options);
|
|
307
|
+
}
|
|
308
|
+
async destroy() {
|
|
309
|
+
// Clean up container resources if any
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// ---------------------------------------------------------------------------
|
|
313
|
+
// Factory
|
|
314
|
+
// ---------------------------------------------------------------------------
|
|
315
|
+
/**
|
|
316
|
+
* Create a process sandbox based on the configured scope.
|
|
317
|
+
*
|
|
318
|
+
* @param config - Sandbox configuration
|
|
319
|
+
* @returns ProcessSandbox instance
|
|
320
|
+
*/
|
|
321
|
+
export function createSandbox(config) {
|
|
322
|
+
switch (config.scope) {
|
|
323
|
+
case "process":
|
|
324
|
+
return new ProcessSandboxImpl(config);
|
|
325
|
+
case "container":
|
|
326
|
+
return new ContainerSandboxImpl();
|
|
327
|
+
case "host":
|
|
328
|
+
default:
|
|
329
|
+
return new HostSandbox();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// ---------------------------------------------------------------------------
|
|
333
|
+
// Legacy API (backward compatible)
|
|
334
|
+
// ---------------------------------------------------------------------------
|
|
335
|
+
/** Create a minimal ToolContext from an AbortSignal (for backward compat) */
|
|
336
|
+
export function signalToToolContext(signal) {
|
|
337
|
+
const ctrl = signal ? new AbortController() : new AbortController();
|
|
338
|
+
if (signal) {
|
|
339
|
+
signal.addEventListener("abort", () => ctrl.abort(signal.reason), { once: true });
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
sessionId: "",
|
|
343
|
+
runId: "",
|
|
344
|
+
agentId: "",
|
|
345
|
+
agentName: "",
|
|
346
|
+
signal: ctrl.signal,
|
|
347
|
+
env: {},
|
|
348
|
+
ask: async () => "once",
|
|
349
|
+
metadata: () => { },
|
|
350
|
+
setCompensation: () => { },
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
export class ToolSandbox {
|
|
354
|
+
config;
|
|
355
|
+
constructor(config = { defaultTimeoutMs: 30_000 }) {
|
|
356
|
+
this.config = config;
|
|
357
|
+
}
|
|
358
|
+
async execute(tool, input, ctx) {
|
|
359
|
+
const timeout = new AbortController();
|
|
360
|
+
const timer = setTimeout(() => timeout.abort(), this.config.defaultTimeoutMs);
|
|
361
|
+
const combinedSignal = combineSignals(ctx.signal, timeout.signal);
|
|
362
|
+
const augmentedCtx = { ...ctx, signal: combinedSignal };
|
|
363
|
+
try {
|
|
364
|
+
const result = await raceAbort(tool.execute(input, augmentedCtx), combinedSignal);
|
|
365
|
+
return result;
|
|
366
|
+
}
|
|
367
|
+
finally {
|
|
368
|
+
clearTimeout(timer);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
// ---------------------------------------------------------------------------
|
|
373
|
+
// Internal helpers
|
|
374
|
+
// ---------------------------------------------------------------------------
|
|
375
|
+
function raceAbort(promise, signal) {
|
|
376
|
+
if (signal.aborted) {
|
|
377
|
+
return Promise.reject(new DOMException(signal.reason ?? "Aborted", "AbortError"));
|
|
378
|
+
}
|
|
379
|
+
return new Promise((resolve, reject) => {
|
|
380
|
+
const onAbort = () => {
|
|
381
|
+
reject(new DOMException(signal.reason ?? "Timed out", "AbortError"));
|
|
382
|
+
};
|
|
383
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
384
|
+
promise.then((val) => {
|
|
385
|
+
signal.removeEventListener("abort", onAbort);
|
|
386
|
+
resolve(val);
|
|
387
|
+
}, (err) => {
|
|
388
|
+
signal.removeEventListener("abort", onAbort);
|
|
389
|
+
reject(err);
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
function combineSignals(...signals) {
|
|
394
|
+
const valid = signals.filter((s) => s !== undefined);
|
|
395
|
+
if (valid.length === 0)
|
|
396
|
+
return new AbortController().signal;
|
|
397
|
+
if (valid.length === 1)
|
|
398
|
+
return valid[0];
|
|
399
|
+
const controller = new AbortController();
|
|
400
|
+
for (const s of valid) {
|
|
401
|
+
if (s.aborted) {
|
|
402
|
+
controller.abort(s.reason);
|
|
403
|
+
return controller.signal;
|
|
404
|
+
}
|
|
405
|
+
s.addEventListener("abort", () => controller.abort(s.reason), { once: true });
|
|
406
|
+
}
|
|
407
|
+
return controller.signal;
|
|
408
|
+
}
|
|
409
|
+
//# sourceMappingURL=sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ToolDefinition } from "./definitions.js";
|
|
2
|
+
type RootGetter = string | (() => string);
|
|
3
|
+
/**
|
|
4
|
+
* Default ignored directories for search — convenience only.
|
|
5
|
+
* User tự extend: `config.ignoredDirs = [...DEFAULT_IGNORED_DIRS, "my-dir"]`
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_IGNORED_DIRS: string[];
|
|
8
|
+
export declare function createGlobFilesTool(workspaceRoot: RootGetter, ignoredDirs?: string[]): ToolDefinition;
|
|
9
|
+
export declare function createGrepFilesTool(workspaceRoot: RootGetter, ignoredDirs?: string[]): ToolDefinition;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=search-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-tools.d.ts","sourceRoot":"","sources":["../src/search-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAcvD,KAAK,UAAU,GAAG,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;AAM1C;;;GAGG;AACH,eAAO,MAAM,oBAAoB,UAA6E,CAAC;AAiB/G,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,CAuBrG;AAED,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,CA6DrG"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { defineTool } from "./define-tool.js";
|
|
5
|
+
const GlobFilesSchema = z.object({
|
|
6
|
+
pattern: z.string().min(1),
|
|
7
|
+
maxResults: z.number().positive().optional(),
|
|
8
|
+
});
|
|
9
|
+
const GrepFilesSchema = z.object({
|
|
10
|
+
pattern: z.string().min(1),
|
|
11
|
+
include: z.string().optional(),
|
|
12
|
+
maxResults: z.number().positive().optional(),
|
|
13
|
+
});
|
|
14
|
+
function resolveRoot(r) {
|
|
15
|
+
return typeof r === "function" ? r() : r;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Default ignored directories for search — convenience only.
|
|
19
|
+
* User tự extend: `config.ignoredDirs = [...DEFAULT_IGNORED_DIRS, "my-dir"]`
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_IGNORED_DIRS = ["node_modules", ".git", ".next", "dist", ".turbo", "coverage", ".vscode"];
|
|
22
|
+
async function globRecursive(dir, pattern, base, results, ignoreDirs) {
|
|
23
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
24
|
+
for (const entry of entries) {
|
|
25
|
+
if (ignoreDirs.has(entry.name))
|
|
26
|
+
continue;
|
|
27
|
+
const fullPath = join(dir, entry.name);
|
|
28
|
+
const relPath = relative(base, fullPath);
|
|
29
|
+
if (entry.name.includes(pattern) || relPath.includes(pattern)) {
|
|
30
|
+
results.push(relPath);
|
|
31
|
+
}
|
|
32
|
+
if (entry.isDirectory()) {
|
|
33
|
+
await globRecursive(fullPath, pattern, base, results, ignoreDirs);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function createGlobFilesTool(workspaceRoot, ignoredDirs) {
|
|
38
|
+
const ignoreSet = new Set(ignoredDirs ?? DEFAULT_IGNORED_DIRS);
|
|
39
|
+
return defineTool({
|
|
40
|
+
name: "glob_files",
|
|
41
|
+
description: "Recursively find files matching a pattern in the workspace.",
|
|
42
|
+
risk: "read",
|
|
43
|
+
input: GlobFilesSchema,
|
|
44
|
+
jsonSchema: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
pattern: { type: "string", description: "File name or path fragment to match" },
|
|
48
|
+
maxResults: { type: "number", description: "Maximum results (default 50)", default: 50 },
|
|
49
|
+
},
|
|
50
|
+
required: ["pattern"],
|
|
51
|
+
},
|
|
52
|
+
async execute(v, _ctx) {
|
|
53
|
+
const root = resolveRoot(workspaceRoot);
|
|
54
|
+
const results = [];
|
|
55
|
+
await globRecursive(root, v.pattern, root, results, ignoreSet);
|
|
56
|
+
return results.slice(0, v.maxResults ?? 50);
|
|
57
|
+
},
|
|
58
|
+
}).toDefinition();
|
|
59
|
+
}
|
|
60
|
+
export function createGrepFilesTool(workspaceRoot, ignoredDirs) {
|
|
61
|
+
const ignoreSet = new Set(ignoredDirs ?? DEFAULT_IGNORED_DIRS);
|
|
62
|
+
return defineTool({
|
|
63
|
+
name: "grep_files",
|
|
64
|
+
description: "Search file contents for a regex pattern. Returns matches with line numbers.",
|
|
65
|
+
risk: "read",
|
|
66
|
+
input: GrepFilesSchema,
|
|
67
|
+
jsonSchema: {
|
|
68
|
+
type: "object",
|
|
69
|
+
properties: {
|
|
70
|
+
pattern: { type: "string", description: "Regex pattern to search" },
|
|
71
|
+
include: { type: "string", description: "File pattern filter (e.g. *.ts, *.md)" },
|
|
72
|
+
maxResults: { type: "number", description: "Maximum match lines (default 30)", default: 30 },
|
|
73
|
+
},
|
|
74
|
+
required: ["pattern"],
|
|
75
|
+
},
|
|
76
|
+
async execute(v, _ctx) {
|
|
77
|
+
const root = resolveRoot(workspaceRoot);
|
|
78
|
+
const maxResults = v.maxResults ?? 30;
|
|
79
|
+
const regex = new RegExp(v.pattern);
|
|
80
|
+
const matches = [];
|
|
81
|
+
async function searchDir(dir) {
|
|
82
|
+
if (matches.length >= maxResults)
|
|
83
|
+
return;
|
|
84
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
85
|
+
for (const entry of entries) {
|
|
86
|
+
if (matches.length >= maxResults)
|
|
87
|
+
return;
|
|
88
|
+
if (ignoreSet.has(entry.name))
|
|
89
|
+
continue;
|
|
90
|
+
const fullPath = join(dir, entry.name);
|
|
91
|
+
if (entry.isDirectory()) {
|
|
92
|
+
await searchDir(fullPath);
|
|
93
|
+
}
|
|
94
|
+
else if (!v.include || entry.name.endsWith(v.include.replace("*", ""))) {
|
|
95
|
+
try {
|
|
96
|
+
const st = await stat(fullPath);
|
|
97
|
+
if (st.size > 100_000)
|
|
98
|
+
continue;
|
|
99
|
+
const content = await readFile(fullPath, "utf-8");
|
|
100
|
+
const lines = content.split("\n");
|
|
101
|
+
for (let i = 0; i < lines.length; i++) {
|
|
102
|
+
if (regex.test(lines[i])) {
|
|
103
|
+
matches.push({
|
|
104
|
+
file: relative(root, fullPath),
|
|
105
|
+
line: i + 1,
|
|
106
|
+
content: lines[i].trim().slice(0, 200),
|
|
107
|
+
});
|
|
108
|
+
if (matches.length >= maxResults)
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
await searchDir(root);
|
|
120
|
+
return matches;
|
|
121
|
+
},
|
|
122
|
+
}).toDefinition();
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=search-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-tools.js","sourceRoot":"","sources":["../src/search-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AACH,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAIH,SAAS,WAAW,CAAC,CAAa;IAChC,OAAO,OAAO,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AAE/G,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,OAAe,EAAE,IAAY,EAAE,OAAiB,EAAE,UAAuB;IACjH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9D,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,aAAyB,EAAE,WAAsB;IACnF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,WAAW,IAAI,oBAAoB,CAAC,CAAC;IAE/D,OAAO,UAAU,CAAqD;QACpE,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,6DAA6D;QAC1E,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,eAAe;QACtB,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBAC/E,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE,OAAO,EAAE,EAAE,EAAE;aACzF;YACD,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;QACD,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI;YACnB,MAAM,IAAI,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;YACxC,MAAM,OAAO,GAAa,EAAE,CAAC;YAC7B,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;YAC/D,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;KACF,CAAC,CAAC,YAAY,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,aAAyB,EAAE,WAAsB;IACnF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,WAAW,IAAI,oBAAoB,CAAC,CAAC;IAE/D,OAAO,UAAU,CAAgH;QAC/H,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,8EAA8E;QAC3F,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,eAAe;QACtB,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yBAAyB,EAAE;gBACnE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uCAAuC,EAAE;gBACjF,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE,OAAO,EAAE,EAAE,EAAE;aAC7F;YACD,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;QACD,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI;YACnB,MAAM,IAAI,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;YACxC,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YACpC,MAAM,OAAO,GAAsD,EAAE,CAAC;YAEtE,KAAK,UAAU,SAAS,CAAC,GAAW;gBAClC,IAAI,OAAO,CAAC,MAAM,IAAI,UAAU;oBAAE,OAAO;gBACzC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC5D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC5B,IAAI,OAAO,CAAC,MAAM,IAAI,UAAU;wBAAE,OAAO;oBACzC,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;wBAAE,SAAS;oBACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;oBACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;wBACxB,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;oBAC5B,CAAC;yBAAM,IACL,CAAC,CAAC,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAC7D,CAAC;wBACD,IAAI,CAAC;4BACH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;4BAChC,IAAI,EAAE,CAAC,IAAI,GAAG,OAAO;gCAAE,SAAS;4BAChC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;4BAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gCACtC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;oCAC1B,OAAO,CAAC,IAAI,CAAC;wCACX,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;wCAC9B,IAAI,EAAE,CAAC,GAAG,CAAC;wCACX,OAAO,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;qCACxC,CAAC,CAAC;oCACH,IAAI,OAAO,CAAC,MAAM,IAAI,UAAU;wCAAE,OAAO;gCAC3C,CAAC;4BACH,CAAC;wBACH,CAAC;wBAAC,MAAM,CAAC;4BACP,SAAS;wBACX,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;YACtB,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC,CAAC,YAAY,EAAE,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-parser.d.ts","sourceRoot":"","sources":["../src/shell-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAiC1E"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell command parsing utility.
|
|
3
|
+
* Extracts file and args from a command string, handling quotes and escapes.
|
|
4
|
+
*/
|
|
5
|
+
export function parseCommand(cmd) {
|
|
6
|
+
const trimmed = cmd.trim();
|
|
7
|
+
if (!trimmed)
|
|
8
|
+
return { file: "", args: [] };
|
|
9
|
+
const tokens = [];
|
|
10
|
+
let i = 0;
|
|
11
|
+
let current = "";
|
|
12
|
+
let inSingle = false;
|
|
13
|
+
let inDouble = false;
|
|
14
|
+
while (i < trimmed.length) {
|
|
15
|
+
const ch = trimmed[i] ?? "";
|
|
16
|
+
if (inSingle) {
|
|
17
|
+
if (ch === "'") {
|
|
18
|
+
inSingle = false;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
current += ch;
|
|
22
|
+
}
|
|
23
|
+
i++;
|
|
24
|
+
}
|
|
25
|
+
else if (inDouble) {
|
|
26
|
+
if (ch === '"') {
|
|
27
|
+
inDouble = false;
|
|
28
|
+
}
|
|
29
|
+
else if (ch === "\\" && i + 1 < trimmed.length) {
|
|
30
|
+
current += trimmed[i + 1];
|
|
31
|
+
i += 2;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
current += ch;
|
|
35
|
+
i++;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else if (ch === "'") {
|
|
39
|
+
inSingle = true;
|
|
40
|
+
i++;
|
|
41
|
+
}
|
|
42
|
+
else if (ch === '"') {
|
|
43
|
+
inDouble = true;
|
|
44
|
+
i++;
|
|
45
|
+
}
|
|
46
|
+
else if (ch === "\\" && i + 1 < trimmed.length) {
|
|
47
|
+
current += trimmed[i + 1];
|
|
48
|
+
i += 2;
|
|
49
|
+
}
|
|
50
|
+
else if (/\s/.test(ch)) {
|
|
51
|
+
if (current) {
|
|
52
|
+
tokens.push(current);
|
|
53
|
+
current = "";
|
|
54
|
+
}
|
|
55
|
+
i++;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
current += ch;
|
|
59
|
+
i++;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (current)
|
|
63
|
+
tokens.push(current);
|
|
64
|
+
if (tokens.length === 0)
|
|
65
|
+
return { file: "", args: [] };
|
|
66
|
+
return { file: tokens[0], args: tokens.slice(1) };
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=shell-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-parser.js","sourceRoot":"","sources":["../src/shell-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IAE5C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBAAC,QAAQ,GAAG,KAAK,CAAC;YAAC,CAAC;iBAChC,CAAC;gBAAC,OAAO,IAAI,EAAE,CAAC;YAAC,CAAC;YACvB,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACpB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBAAC,QAAQ,GAAG,KAAK,CAAC;YAAC,CAAC;iBAChC,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;gBAAC,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAC,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;iBACjF,CAAC;gBAAC,OAAO,IAAI,EAAE,CAAC;gBAAC,CAAC,EAAE,CAAC;YAAC,CAAC;QAC9B,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAAC,QAAQ,GAAG,IAAI,CAAC;YAAC,CAAC,EAAE,CAAC;QAAC,CAAC;aAC3C,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAAC,QAAQ,GAAG,IAAI,CAAC;YAAC,CAAC,EAAE,CAAC;QAAC,CAAC;aACzC,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAAC,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAAC,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;aACjF,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACvB,IAAI,OAAO,EAAE,CAAC;gBAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;YAAC,CAAC;YACpD,CAAC,EAAE,CAAC;QACN,CAAC;aACI,CAAC;YAAC,OAAO,IAAI,EAAE,CAAC;YAAC,CAAC,EAAE,CAAC;QAAC,CAAC;IAC9B,CAAC;IACD,IAAI,OAAO;QAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAElC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACvD,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACrD,CAAC"}
|