@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.
Files changed (146) hide show
  1. package/LICENSE +21 -0
  2. package/dist/arity.d.ts +22 -0
  3. package/dist/arity.d.ts.map +1 -0
  4. package/dist/arity.js +96 -0
  5. package/dist/arity.js.map +1 -0
  6. package/dist/context.d.ts +43 -0
  7. package/dist/context.d.ts.map +1 -0
  8. package/dist/context.js +2 -0
  9. package/dist/context.js.map +1 -0
  10. package/dist/define-tool.d.ts +45 -0
  11. package/dist/define-tool.d.ts.map +1 -0
  12. package/dist/define-tool.js +120 -0
  13. package/dist/define-tool.js.map +1 -0
  14. package/dist/definitions.d.ts +24 -0
  15. package/dist/definitions.d.ts.map +1 -0
  16. package/dist/definitions.js +2 -0
  17. package/dist/definitions.js.map +1 -0
  18. package/dist/description-lint.d.ts +25 -0
  19. package/dist/description-lint.d.ts.map +1 -0
  20. package/dist/description-lint.js +90 -0
  21. package/dist/description-lint.js.map +1 -0
  22. package/dist/diff.d.ts +7 -0
  23. package/dist/diff.d.ts.map +1 -0
  24. package/dist/diff.js +26 -0
  25. package/dist/diff.js.map +1 -0
  26. package/dist/domain.d.ts +39 -0
  27. package/dist/domain.d.ts.map +1 -0
  28. package/dist/domain.js +20 -0
  29. package/dist/domain.js.map +1 -0
  30. package/dist/file-history.d.ts +43 -0
  31. package/dist/file-history.d.ts.map +1 -0
  32. package/dist/file-history.js +55 -0
  33. package/dist/file-history.js.map +1 -0
  34. package/dist/file-tools.d.ts +56 -0
  35. package/dist/file-tools.d.ts.map +1 -0
  36. package/dist/file-tools.js +542 -0
  37. package/dist/file-tools.js.map +1 -0
  38. package/dist/git-tools.d.ts +8 -0
  39. package/dist/git-tools.d.ts.map +1 -0
  40. package/dist/git-tools.js +114 -0
  41. package/dist/git-tools.js.map +1 -0
  42. package/dist/history-hook.d.ts +4 -0
  43. package/dist/history-hook.d.ts.map +1 -0
  44. package/dist/history-hook.js +62 -0
  45. package/dist/history-hook.js.map +1 -0
  46. package/dist/image-tools.d.ts +11 -0
  47. package/dist/image-tools.d.ts.map +1 -0
  48. package/dist/image-tools.js +55 -0
  49. package/dist/image-tools.js.map +1 -0
  50. package/dist/index.d.ts +57 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +36 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/json-schema.d.ts +22 -0
  55. package/dist/json-schema.d.ts.map +1 -0
  56. package/dist/json-schema.js +2 -0
  57. package/dist/json-schema.js.map +1 -0
  58. package/dist/lazy-registry.d.ts +23 -0
  59. package/dist/lazy-registry.d.ts.map +1 -0
  60. package/dist/lazy-registry.js +64 -0
  61. package/dist/lazy-registry.js.map +1 -0
  62. package/dist/policy.d.ts +5 -0
  63. package/dist/policy.d.ts.map +1 -0
  64. package/dist/policy.js +2 -0
  65. package/dist/policy.js.map +1 -0
  66. package/dist/provider-helpers.d.ts +26 -0
  67. package/dist/provider-helpers.d.ts.map +1 -0
  68. package/dist/provider-helpers.js +46 -0
  69. package/dist/provider-helpers.js.map +1 -0
  70. package/dist/provider.d.ts +80 -0
  71. package/dist/provider.d.ts.map +1 -0
  72. package/dist/provider.js +96 -0
  73. package/dist/provider.js.map +1 -0
  74. package/dist/providers/agent-provider.d.ts +32 -0
  75. package/dist/providers/agent-provider.d.ts.map +1 -0
  76. package/dist/providers/agent-provider.js +35 -0
  77. package/dist/providers/agent-provider.js.map +1 -0
  78. package/dist/providers/builtin-provider.d.ts +36 -0
  79. package/dist/providers/builtin-provider.d.ts.map +1 -0
  80. package/dist/providers/builtin-provider.js +86 -0
  81. package/dist/providers/builtin-provider.js.map +1 -0
  82. package/dist/providers/file-loader.d.ts +47 -0
  83. package/dist/providers/file-loader.d.ts.map +1 -0
  84. package/dist/providers/file-loader.js +120 -0
  85. package/dist/providers/file-loader.js.map +1 -0
  86. package/dist/providers/index.d.ts +6 -0
  87. package/dist/providers/index.d.ts.map +1 -0
  88. package/dist/providers/index.js +5 -0
  89. package/dist/providers/index.js.map +1 -0
  90. package/dist/providers/skill-provider.d.ts +23 -0
  91. package/dist/providers/skill-provider.d.ts.map +1 -0
  92. package/dist/providers/skill-provider.js +28 -0
  93. package/dist/providers/skill-provider.js.map +1 -0
  94. package/dist/question-tool.d.ts +15 -0
  95. package/dist/question-tool.d.ts.map +1 -0
  96. package/dist/question-tool.js +51 -0
  97. package/dist/question-tool.js.map +1 -0
  98. package/dist/read-tracker.d.ts +8 -0
  99. package/dist/read-tracker.d.ts.map +1 -0
  100. package/dist/read-tracker.js +33 -0
  101. package/dist/read-tracker.js.map +1 -0
  102. package/dist/registry.d.ts +58 -0
  103. package/dist/registry.d.ts.map +1 -0
  104. package/dist/registry.js +128 -0
  105. package/dist/registry.js.map +1 -0
  106. package/dist/sandbox.d.ts +85 -0
  107. package/dist/sandbox.d.ts.map +1 -0
  108. package/dist/sandbox.js +409 -0
  109. package/dist/sandbox.js.map +1 -0
  110. package/dist/search-tools.d.ts +11 -0
  111. package/dist/search-tools.d.ts.map +1 -0
  112. package/dist/search-tools.js +124 -0
  113. package/dist/search-tools.js.map +1 -0
  114. package/dist/shell-parser.d.ts +9 -0
  115. package/dist/shell-parser.d.ts.map +1 -0
  116. package/dist/shell-parser.js +68 -0
  117. package/dist/shell-parser.js.map +1 -0
  118. package/dist/shell-tool.d.ts +22 -0
  119. package/dist/shell-tool.d.ts.map +1 -0
  120. package/dist/shell-tool.js +100 -0
  121. package/dist/shell-tool.js.map +1 -0
  122. package/dist/todo-tool.d.ts +2 -0
  123. package/dist/todo-tool.d.ts.map +1 -0
  124. package/dist/todo-tool.js +121 -0
  125. package/dist/todo-tool.js.map +1 -0
  126. package/dist/tool-search.d.ts +14 -0
  127. package/dist/tool-search.d.ts.map +1 -0
  128. package/dist/tool-search.js +46 -0
  129. package/dist/tool-search.js.map +1 -0
  130. package/dist/types.d.ts +30 -0
  131. package/dist/types.d.ts.map +1 -0
  132. package/dist/types.js +2 -0
  133. package/dist/types.js.map +1 -0
  134. package/dist/validate.d.ts +9 -0
  135. package/dist/validate.d.ts.map +1 -0
  136. package/dist/validate.js +26 -0
  137. package/dist/validate.js.map +1 -0
  138. package/dist/web-search-tool.d.ts +84 -0
  139. package/dist/web-search-tool.d.ts.map +1 -0
  140. package/dist/web-search-tool.js +134 -0
  141. package/dist/web-search-tool.js.map +1 -0
  142. package/dist/web-tools.d.ts +10 -0
  143. package/dist/web-tools.d.ts.map +1 -0
  144. package/dist/web-tools.js +62 -0
  145. package/dist/web-tools.js.map +1 -0
  146. package/package.json +58 -0
@@ -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":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Shell command parsing utility.
3
+ * Extracts file and args from a command string, handling quotes and escapes.
4
+ */
5
+ export declare function parseCommand(cmd: string): {
6
+ file: string;
7
+ args: string[];
8
+ };
9
+ //# sourceMappingURL=shell-parser.d.ts.map
@@ -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"}