@yuaone/tools 0.1.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 (87) hide show
  1. package/LICENSE +663 -0
  2. package/README.md +15 -0
  3. package/dist/__tests__/file-edit.test.d.ts +8 -0
  4. package/dist/__tests__/file-edit.test.d.ts.map +1 -0
  5. package/dist/__tests__/file-edit.test.js +125 -0
  6. package/dist/__tests__/file-edit.test.js.map +1 -0
  7. package/dist/__tests__/registry.test.d.ts +7 -0
  8. package/dist/__tests__/registry.test.d.ts.map +1 -0
  9. package/dist/__tests__/registry.test.js +83 -0
  10. package/dist/__tests__/registry.test.js.map +1 -0
  11. package/dist/__tests__/validators.test.d.ts +8 -0
  12. package/dist/__tests__/validators.test.d.ts.map +1 -0
  13. package/dist/__tests__/validators.test.js +189 -0
  14. package/dist/__tests__/validators.test.js.map +1 -0
  15. package/dist/base-tool.d.ts +45 -0
  16. package/dist/base-tool.d.ts.map +1 -0
  17. package/dist/base-tool.js +87 -0
  18. package/dist/base-tool.js.map +1 -0
  19. package/dist/browser-tool.d.ts +39 -0
  20. package/dist/browser-tool.d.ts.map +1 -0
  21. package/dist/browser-tool.js +518 -0
  22. package/dist/browser-tool.js.map +1 -0
  23. package/dist/code-search.d.ts +42 -0
  24. package/dist/code-search.d.ts.map +1 -0
  25. package/dist/code-search.js +298 -0
  26. package/dist/code-search.js.map +1 -0
  27. package/dist/design-tools.d.ts +70 -0
  28. package/dist/design-tools.d.ts.map +1 -0
  29. package/dist/design-tools.js +471 -0
  30. package/dist/design-tools.js.map +1 -0
  31. package/dist/dev-server-manager.d.ts +32 -0
  32. package/dist/dev-server-manager.d.ts.map +1 -0
  33. package/dist/dev-server-manager.js +183 -0
  34. package/dist/dev-server-manager.js.map +1 -0
  35. package/dist/file-edit.d.ts +19 -0
  36. package/dist/file-edit.d.ts.map +1 -0
  37. package/dist/file-edit.js +217 -0
  38. package/dist/file-edit.js.map +1 -0
  39. package/dist/file-read.d.ts +19 -0
  40. package/dist/file-read.d.ts.map +1 -0
  41. package/dist/file-read.js +142 -0
  42. package/dist/file-read.js.map +1 -0
  43. package/dist/file-write.d.ts +18 -0
  44. package/dist/file-write.d.ts.map +1 -0
  45. package/dist/file-write.js +139 -0
  46. package/dist/file-write.js.map +1 -0
  47. package/dist/git-ops.d.ts +25 -0
  48. package/dist/git-ops.d.ts.map +1 -0
  49. package/dist/git-ops.js +219 -0
  50. package/dist/git-ops.js.map +1 -0
  51. package/dist/glob.d.ts +18 -0
  52. package/dist/glob.d.ts.map +1 -0
  53. package/dist/glob.js +91 -0
  54. package/dist/glob.js.map +1 -0
  55. package/dist/grep.d.ts +19 -0
  56. package/dist/grep.d.ts.map +1 -0
  57. package/dist/grep.js +177 -0
  58. package/dist/grep.js.map +1 -0
  59. package/dist/index.d.ts +27 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +29 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/security-scan.d.ts +62 -0
  64. package/dist/security-scan.d.ts.map +1 -0
  65. package/dist/security-scan.js +445 -0
  66. package/dist/security-scan.js.map +1 -0
  67. package/dist/shell-exec.d.ts +20 -0
  68. package/dist/shell-exec.d.ts.map +1 -0
  69. package/dist/shell-exec.js +206 -0
  70. package/dist/shell-exec.js.map +1 -0
  71. package/dist/test-run.d.ts +51 -0
  72. package/dist/test-run.d.ts.map +1 -0
  73. package/dist/test-run.js +359 -0
  74. package/dist/test-run.js.map +1 -0
  75. package/dist/tool-registry.d.ts +70 -0
  76. package/dist/tool-registry.d.ts.map +1 -0
  77. package/dist/tool-registry.js +181 -0
  78. package/dist/tool-registry.js.map +1 -0
  79. package/dist/types.d.ts +137 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +8 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/validators.d.ts +57 -0
  84. package/dist/validators.d.ts.map +1 -0
  85. package/dist/validators.js +218 -0
  86. package/dist/validators.js.map +1 -0
  87. package/package.json +42 -0
@@ -0,0 +1,139 @@
1
+ /**
2
+ * @yuaone/tools — file_write tool
3
+ *
4
+ * Writes content to a file.
5
+ * - Auto-creates directories (mkdir -p)
6
+ * - Backs up existing files before overwrite (.yuan-backup)
7
+ * - Detects and warns about sensitive files (.env, credentials, etc.)
8
+ */
9
+ import { readFile, mkdir, stat, copyFile, open as fsOpen } from 'node:fs/promises';
10
+ import { constants as fsConstants } from 'node:fs';
11
+ import { dirname } from 'node:path';
12
+ import { BaseTool } from './base-tool.js';
13
+ import { isSensitiveFile } from './validators.js';
14
+ export class FileWriteTool extends BaseTool {
15
+ name = 'file_write';
16
+ description = 'Write content to a file. Creates directories automatically. ' +
17
+ 'Backs up existing files before overwrite.';
18
+ riskLevel = 'high';
19
+ parameters = {
20
+ path: {
21
+ type: 'string',
22
+ description: 'Relative path from project root',
23
+ required: true,
24
+ },
25
+ content: {
26
+ type: 'string',
27
+ description: 'File content to write',
28
+ required: true,
29
+ },
30
+ createDirectories: {
31
+ type: 'boolean',
32
+ description: 'Auto-create intermediate directories (default: true)',
33
+ required: false,
34
+ default: true,
35
+ },
36
+ };
37
+ async execute(args, workDir) {
38
+ const toolCallId = args._toolCallId ?? '';
39
+ const path = args.path;
40
+ const content = args.content;
41
+ const createDirectories = args.createDirectories ?? true;
42
+ if (!path) {
43
+ return this.fail(toolCallId, 'Missing required parameter: path');
44
+ }
45
+ if (content === undefined || content === null) {
46
+ return this.fail(toolCallId, 'Missing required parameter: content');
47
+ }
48
+ let resolvedPath;
49
+ try {
50
+ resolvedPath = this.validatePath(path, workDir);
51
+ }
52
+ catch (err) {
53
+ return this.fail(toolCallId, err.message);
54
+ }
55
+ // Sensitive file warning
56
+ if (isSensitiveFile(path)) {
57
+ return this.fail(toolCallId, `Sensitive file detected: "${path}". ` +
58
+ 'Writing to credential/secret files is blocked for security.');
59
+ }
60
+ // Write size limit (10MB)
61
+ const contentStr = String(content);
62
+ const MAX_WRITE_SIZE = 10 * 1024 * 1024;
63
+ if (Buffer.byteLength(contentStr, 'utf-8') > MAX_WRITE_SIZE) {
64
+ return this.fail(toolCallId, `Content exceeds maximum write size (10MB)`);
65
+ }
66
+ // Check if file already exists
67
+ let existed = false;
68
+ try {
69
+ const s = await stat(resolvedPath);
70
+ if (s.isDirectory()) {
71
+ return this.fail(toolCallId, `Path is a directory: ${path}`);
72
+ }
73
+ existed = true;
74
+ }
75
+ catch {
76
+ // File doesn't exist — will be created
77
+ }
78
+ // Create directories if needed
79
+ if (createDirectories) {
80
+ try {
81
+ await mkdir(dirname(resolvedPath), { recursive: true });
82
+ }
83
+ catch (err) {
84
+ return this.fail(toolCallId, `Failed to create directories: ${err.message}`);
85
+ }
86
+ }
87
+ // Backup existing file
88
+ if (existed) {
89
+ try {
90
+ const backupPath = resolvedPath + '.yuan-backup';
91
+ await copyFile(resolvedPath, backupPath);
92
+ }
93
+ catch {
94
+ // Best-effort backup — don't block write on backup failure
95
+ }
96
+ }
97
+ // Write file using O_NOFOLLOW to atomically prevent symlink TOCTOU attacks.
98
+ // This eliminates the race window between symlink check and write.
99
+ try {
100
+ const flags = existed
101
+ ? fsConstants.O_WRONLY | fsConstants.O_TRUNC | fsConstants.O_NOFOLLOW
102
+ : fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_TRUNC | fsConstants.O_NOFOLLOW;
103
+ const fh = await fsOpen(resolvedPath, flags, 0o644);
104
+ try {
105
+ await fh.writeFile(contentStr, 'utf-8');
106
+ }
107
+ finally {
108
+ await fh.close();
109
+ }
110
+ const bytesWritten = Buffer.byteLength(contentStr, 'utf-8');
111
+ let output = existed
112
+ ? `File overwritten: ${path} (${bytesWritten} bytes, backup created)`
113
+ : `File created: ${path} (${bytesWritten} bytes)`;
114
+ // If the file existed, show a brief diff hint
115
+ if (existed) {
116
+ try {
117
+ const originalContent = await readFile(resolvedPath + '.yuan-backup', 'utf-8');
118
+ const origLines = originalContent.split('\n').length;
119
+ const newLines = contentStr.split('\n').length;
120
+ output += `\nPrevious: ${origLines} lines → New: ${newLines} lines`;
121
+ }
122
+ catch {
123
+ // Backup read failed — skip diff info
124
+ }
125
+ }
126
+ return this.ok(toolCallId, output, {
127
+ bytesWritten,
128
+ created: !existed,
129
+ });
130
+ }
131
+ catch (err) {
132
+ const msg = err.code === 'ELOOP'
133
+ ? `Refusing to write through symlink: ${path}`
134
+ : `Failed to write file: ${err.message}`;
135
+ return this.fail(toolCallId, msg);
136
+ }
137
+ }
138
+ }
139
+ //# sourceMappingURL=file-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-write.js","sourceRoot":"","sources":["../src/file-write.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @yuaone/tools — git_ops tool
3
+ *
4
+ * Git operations: status, diff, log, add, commit, create_branch, stash, restore.
5
+ * - commit/create_branch require approval (riskLevel dynamically elevated)
6
+ * - Uses execFile (no shell interpretation)
7
+ */
8
+ import type { ParameterDef, RiskLevel, ToolResult } from './types.js';
9
+ import { BaseTool } from './base-tool.js';
10
+ export declare class GitOpsTool extends BaseTool {
11
+ readonly name = "git_ops";
12
+ readonly description: string;
13
+ readonly riskLevel: RiskLevel;
14
+ readonly parameters: Record<string, ParameterDef>;
15
+ execute(args: Record<string, unknown>, workDir: string): Promise<ToolResult>;
16
+ private gitStatus;
17
+ private gitDiff;
18
+ private gitLog;
19
+ private gitAdd;
20
+ private gitCommit;
21
+ private gitCreateBranch;
22
+ private gitStash;
23
+ private gitRestore;
24
+ }
25
+ //# sourceMappingURL=git-ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-ops.d.ts","sourceRoot":"","sources":["../src/git-ops.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAK1C,qBAAa,UAAW,SAAQ,QAAQ;IACtC,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,WAAW,SAE2C;IAC/D,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAY;IAEzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CA6B/C;IAEI,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;YAuCpE,SAAS;YAMT,OAAO;YAqBP,MAAM;YAUN,MAAM;YAuCN,SAAS;YA0BT,eAAe;YAcf,QAAQ;YAUR,UAAU;CAkBzB"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * @yuaone/tools — git_ops tool
3
+ *
4
+ * Git operations: status, diff, log, add, commit, create_branch, stash, restore.
5
+ * - commit/create_branch require approval (riskLevel dynamically elevated)
6
+ * - Uses execFile (no shell interpretation)
7
+ */
8
+ import { execFile } from 'node:child_process';
9
+ import { BaseTool } from './base-tool.js';
10
+ import { validatePath, isSensitiveFile } from './validators.js';
11
+ const GIT_TIMEOUT = 15_000; // 15s
12
+ export class GitOpsTool extends BaseTool {
13
+ name = 'git_ops';
14
+ description = 'Perform git operations: status, diff, log, add, commit, create_branch, stash, restore. ' +
15
+ 'commit and create_branch operations require user approval.';
16
+ riskLevel = 'medium';
17
+ parameters = {
18
+ operation: {
19
+ type: 'string',
20
+ description: 'Git operation to perform',
21
+ required: true,
22
+ enum: ['status', 'diff', 'log', 'add', 'commit', 'create_branch', 'stash', 'restore'],
23
+ },
24
+ message: {
25
+ type: 'string',
26
+ description: 'Commit message (required for commit operation)',
27
+ required: false,
28
+ },
29
+ files: {
30
+ type: 'array',
31
+ description: 'Files to add/commit (default: all changed files for add)',
32
+ required: false,
33
+ items: { type: 'string', description: 'File path' },
34
+ },
35
+ count: {
36
+ type: 'number',
37
+ description: 'Number of log entries (default: 10, for log operation)',
38
+ required: false,
39
+ default: 10,
40
+ },
41
+ branch: {
42
+ type: 'string',
43
+ description: 'Branch name (for create_branch operation)',
44
+ required: false,
45
+ },
46
+ };
47
+ async execute(args, workDir) {
48
+ const toolCallId = args._toolCallId ?? '';
49
+ const operation = args.operation;
50
+ if (!operation) {
51
+ return this.fail(toolCallId, 'Missing required parameter: operation');
52
+ }
53
+ const validOps = ['status', 'diff', 'log', 'add', 'commit', 'create_branch', 'stash', 'restore'];
54
+ if (!validOps.includes(operation)) {
55
+ return this.fail(toolCallId, `Invalid operation: ${operation}. Must be one of: ${validOps.join(', ')}`);
56
+ }
57
+ try {
58
+ switch (operation) {
59
+ case 'status':
60
+ return await this.gitStatus(toolCallId, workDir);
61
+ case 'diff':
62
+ return await this.gitDiff(toolCallId, workDir);
63
+ case 'log':
64
+ return await this.gitLog(toolCallId, workDir, args.count ?? 10);
65
+ case 'add':
66
+ return await this.gitAdd(toolCallId, workDir, args.files);
67
+ case 'commit':
68
+ return await this.gitCommit(toolCallId, workDir, args.message, args.files);
69
+ case 'create_branch':
70
+ return await this.gitCreateBranch(toolCallId, workDir, args.branch);
71
+ case 'stash':
72
+ return await this.gitStash(toolCallId, workDir, args.message);
73
+ case 'restore':
74
+ return await this.gitRestore(toolCallId, workDir, args.files);
75
+ default:
76
+ return this.fail(toolCallId, `Unknown operation: ${operation}`);
77
+ }
78
+ }
79
+ catch (err) {
80
+ return this.fail(toolCallId, `Git operation failed: ${err.message}`);
81
+ }
82
+ }
83
+ async gitStatus(toolCallId, cwd) {
84
+ const result = await runGit(['status', '--porcelain', '-u'], cwd);
85
+ const output = result.stdout || '(clean working tree)';
86
+ return this.ok(toolCallId, output, { operation: 'status' });
87
+ }
88
+ async gitDiff(toolCallId, cwd) {
89
+ // Show both staged and unstaged changes
90
+ const [unstaged, staged] = await Promise.all([
91
+ runGit(['diff'], cwd),
92
+ runGit(['diff', '--cached'], cwd),
93
+ ]);
94
+ let output = '';
95
+ if (staged.stdout) {
96
+ output += `[Staged changes]\n${staged.stdout}\n`;
97
+ }
98
+ if (unstaged.stdout) {
99
+ output += `[Unstaged changes]\n${unstaged.stdout}\n`;
100
+ }
101
+ if (!output) {
102
+ output = '(no changes)';
103
+ }
104
+ return this.ok(toolCallId, output, { operation: 'diff' });
105
+ }
106
+ async gitLog(toolCallId, cwd, count) {
107
+ const safeCount = Math.min(Math.max(1, count), 50);
108
+ const result = await runGit(['log', `--max-count=${safeCount}`, '--oneline', '--decorate'], cwd);
109
+ const output = result.stdout || '(no commits)';
110
+ return this.ok(toolCallId, output, { operation: 'log' });
111
+ }
112
+ async gitAdd(toolCallId, cwd, files) {
113
+ const gitArgs = ['add'];
114
+ if (files && files.length > 0) {
115
+ // Validate each file path
116
+ for (const f of files) {
117
+ try {
118
+ validatePath(f, cwd);
119
+ }
120
+ catch (err) {
121
+ return this.fail(toolCallId, err.message);
122
+ }
123
+ }
124
+ gitArgs.push('--', ...files);
125
+ }
126
+ else {
127
+ gitArgs.push('-A');
128
+ }
129
+ await runGit(gitArgs, cwd);
130
+ // Warn about sensitive files when using -A
131
+ if (!files || files.length === 0) {
132
+ const statusResult = await runGit(['status', '--porcelain', '-u'], cwd);
133
+ const stagedFiles = statusResult.stdout.split('\n').filter(Boolean);
134
+ const sensitiveFiles = stagedFiles
135
+ .map((line) => line.slice(3).trim())
136
+ .filter((f) => isSensitiveFile(f));
137
+ if (sensitiveFiles.length > 0) {
138
+ return this.ok(toolCallId, `Files staged.\n${statusResult.stdout}\n\n⚠️ WARNING: Sensitive files staged: ${sensitiveFiles.join(', ')}. Consider unstaging them before commit.`, { operation: 'add', sensitiveFiles });
139
+ }
140
+ return this.ok(toolCallId, `Files staged.\n${statusResult.stdout}`, { operation: 'add' });
141
+ }
142
+ const statusResult = await runGit(['status', '--porcelain', '-u'], cwd);
143
+ return this.ok(toolCallId, `Files staged.\n${statusResult.stdout}`, { operation: 'add' });
144
+ }
145
+ async gitCommit(toolCallId, cwd, message, files) {
146
+ if (!message) {
147
+ return this.fail(toolCallId, 'Missing required parameter: message (for commit operation)');
148
+ }
149
+ // If specific files provided, validate paths and add them first
150
+ if (files && files.length > 0) {
151
+ for (const f of files) {
152
+ try {
153
+ validatePath(f, cwd);
154
+ }
155
+ catch (err) {
156
+ return this.fail(toolCallId, err.message);
157
+ }
158
+ }
159
+ await runGit(['add', '--', ...files], cwd);
160
+ }
161
+ const result = await runGit(['commit', '-m', message], cwd);
162
+ return this.ok(toolCallId, result.stdout || 'Commit created.', { operation: 'commit' });
163
+ }
164
+ async gitCreateBranch(toolCallId, cwd, branch) {
165
+ if (!branch) {
166
+ return this.fail(toolCallId, 'Missing required parameter: branch (for create_branch operation)');
167
+ }
168
+ // Validate branch name: no spaces, no shell metacharacters
169
+ if (!/^[a-zA-Z0-9._\-/]+$/.test(branch)) {
170
+ return this.fail(toolCallId, `Invalid branch name: "${branch}". Use alphanumeric, dots, hyphens, underscores, and slashes only.`);
171
+ }
172
+ const result = await runGit(['checkout', '-b', branch], cwd);
173
+ return this.ok(toolCallId, result.stdout || `Branch "${branch}" created and checked out.`, { operation: 'create_branch' });
174
+ }
175
+ async gitStash(toolCallId, cwd, message) {
176
+ const gitArgs = ['stash', 'push'];
177
+ if (message) {
178
+ gitArgs.push('-m', message);
179
+ }
180
+ const result = await runGit(gitArgs, cwd);
181
+ return this.ok(toolCallId, result.stdout || 'Changes stashed.', { operation: 'stash' });
182
+ }
183
+ async gitRestore(toolCallId, cwd, files) {
184
+ const gitArgs = ['restore'];
185
+ if (files && files.length > 0) {
186
+ // Validate each file path to prevent argument injection
187
+ for (const f of files) {
188
+ try {
189
+ validatePath(f, cwd);
190
+ }
191
+ catch (err) {
192
+ return this.fail(toolCallId, err.message);
193
+ }
194
+ }
195
+ gitArgs.push('--', ...files);
196
+ }
197
+ else {
198
+ gitArgs.push('.');
199
+ }
200
+ const result = await runGit(gitArgs, cwd);
201
+ return this.ok(toolCallId, result.stdout || 'Files restored.', { operation: 'restore' });
202
+ }
203
+ }
204
+ function runGit(args, cwd) {
205
+ return new Promise((resolve, reject) => {
206
+ execFile('git', args, { cwd, timeout: GIT_TIMEOUT, maxBuffer: 1024 * 1024 }, (error, stdout, stderr) => {
207
+ if (error && !stdout && !stderr) {
208
+ reject(error);
209
+ return;
210
+ }
211
+ resolve({
212
+ stdout: String(stdout ?? '').trim(),
213
+ stderr: String(stderr ?? '').trim(),
214
+ exitCode: error ? (typeof error.code === 'number' ? error.code : 1) : 0,
215
+ });
216
+ });
217
+ });
218
+ }
219
+ //# sourceMappingURL=git-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-ops.js","sourceRoot":"","sources":["../src/git-ops.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,MAAM;AAElC,MAAM,OAAO,UAAW,SAAQ,QAAQ;IAC7B,IAAI,GAAG,SAAS,CAAC;IACjB,WAAW,GAClB,yFAAyF;QACzF,4DAA4D,CAAC;IACtD,SAAS,GAAc,QAAQ,CAAC;IAEhC,UAAU,GAAiC;QAClD,SAAS,EAAE;YACT,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,0BAA0B;YACvC,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,CAAC;SACtF;QACD,OAAO,EAAE;YACP,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,gDAAgD;YAC7D,QAAQ,EAAE,KAAK;SAChB;QACD,KAAK,EAAE;YACL,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,0DAA0D;YACvE,QAAQ,EAAE,KAAK;YACf,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE;SACpD;QACD,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,wDAAwD;YACrE,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,EAAE;SACZ;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,2CAA2C;YACxD,QAAQ,EAAE,KAAK;SAChB;KACF,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,IAA6B,EAAE,OAAe;QAC1D,MAAM,UAAU,GAAI,IAAI,CAAC,WAAsB,IAAI,EAAE,CAAC;QACtD,MAAM,SAAS,GAAG,IAAI,CAAC,SAA+B,CAAC;QAEvD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,uCAAuC,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QACjG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,sBAAsB,SAAS,qBAAqB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1G,CAAC;QAED,IAAI,CAAC;YACH,QAAQ,SAAS,EAAE,CAAC;gBAClB,KAAK,QAAQ;oBACX,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBACnD,KAAK,MAAM;oBACT,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBACjD,KAAK,KAAK;oBACR,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,EAAG,IAAI,CAAC,KAAgB,IAAI,EAAE,CAAC,CAAC;gBAC9E,KAAK,KAAK;oBACR,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,KAA6B,CAAC,CAAC;gBACpF,KAAK,QAAQ;oBACX,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,OAA6B,EAAE,IAAI,CAAC,KAA6B,CAAC,CAAC;gBAC3H,KAAK,eAAe;oBAClB,OAAO,MAAM,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,MAA4B,CAAC,CAAC;gBAC5F,KAAK,OAAO;oBACV,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,OAA6B,CAAC,CAAC;gBACtF,KAAK,SAAS;oBACZ,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,KAA6B,CAAC,CAAC;gBACxF;oBACE,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,sBAAsB,SAAS,EAAE,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,yBAA0B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,UAAkB,EAAE,GAAW;QACrD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,sBAAsB,CAAC;QACvD,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC9D,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,UAAkB,EAAE,GAAW;QACnD,wCAAwC;QACxC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC3C,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC;YACrB,MAAM,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,GAAG,CAAC;SAClC,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,qBAAqB,MAAM,CAAC,MAAM,IAAI,CAAC;QACnD,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,uBAAuB,QAAQ,CAAC,MAAM,IAAI,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,cAAc,CAAC;QAC1B,CAAC;QAED,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5D,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,UAAkB,EAAE,GAAW,EAAE,KAAa;QACjE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,MAAM,MAAM,CACzB,CAAC,KAAK,EAAE,eAAe,SAAS,EAAE,EAAE,WAAW,EAAE,YAAY,CAAC,EAC9D,GAAG,CACJ,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,cAAc,CAAC;QAC/C,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,UAAkB,EAAE,GAAW,EAAE,KAAgB;QACpE,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,0BAA0B;YAC1B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC;oBACH,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBACvB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QAED,MAAM,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAE3B,2CAA2C;QAC3C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;YACxE,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACpE,MAAM,cAAc,GAAG,WAAW;iBAC/B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACnC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,OAAO,IAAI,CAAC,EAAE,CACZ,UAAU,EACV,kBAAkB,YAAY,CAAC,MAAM,2CAA2C,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,0CAA0C,EACnJ,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,CACrC,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,kBAAkB,YAAY,CAAC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5F,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACxE,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,kBAAkB,YAAY,CAAC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5F,CAAC;IAEO,KAAK,CAAC,SAAS,CACrB,UAAkB,EAClB,GAAW,EACX,OAAgB,EAChB,KAAgB;QAEhB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,4DAA4D,CAAC,CAAC;QAC7F,CAAC;QAED,gEAAgE;QAChE,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC;oBACH,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBACvB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC;YACD,MAAM,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,IAAI,iBAAiB,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC1F,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,UAAkB,EAAE,GAAW,EAAE,MAAe;QAC5E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,kEAAkE,CAAC,CAAC;QACnG,CAAC;QAED,2DAA2D;QAC3D,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,yBAAyB,MAAM,oEAAoE,CAAC,CAAC;QACpI,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,IAAI,WAAW,MAAM,4BAA4B,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;IAC7H,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,UAAkB,EAAE,GAAW,EAAE,OAAgB;QACtE,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAClC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9B,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,IAAI,kBAAkB,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1F,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,UAAkB,EAAE,GAAW,EAAE,KAAgB;QACxE,MAAM,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC;QAC5B,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,wDAAwD;YACxD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC;oBACH,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBACvB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,IAAI,iBAAiB,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IAC3F,CAAC;CACF;AAQD,SAAS,MAAM,CAAC,IAAc,EAAE,GAAW;IACzC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,QAAQ,CACN,KAAK,EACL,IAAI,EACJ,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI,EAAE,EACrD,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACxB,IAAI,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACd,OAAO;YACT,CAAC;YACD,OAAO,CAAC;gBACN,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;gBACnC,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;gBACnC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aACxE,CAAC,CAAC;QACL,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
package/dist/glob.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @yuaone/tools — glob tool
3
+ *
4
+ * Finds files matching glob patterns.
5
+ * - Uses fast-glob for performance
6
+ * - Auto-excludes node_modules, .git
7
+ * - Max 100 results by default
8
+ */
9
+ import type { ParameterDef, RiskLevel, ToolResult } from './types.js';
10
+ import { BaseTool } from './base-tool.js';
11
+ export declare class GlobTool extends BaseTool {
12
+ readonly name = "glob";
13
+ readonly description: string;
14
+ readonly riskLevel: RiskLevel;
15
+ readonly parameters: Record<string, ParameterDef>;
16
+ execute(args: Record<string, unknown>, workDir: string): Promise<ToolResult>;
17
+ }
18
+ //# sourceMappingURL=glob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../src/glob.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI1C,qBAAa,QAAS,SAAQ,QAAQ;IACpC,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,WAAW,SAEiC;IACrD,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAS;IAEtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAiB/C;IAEI,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CA0DnF"}
package/dist/glob.js ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @yuaone/tools — glob tool
3
+ *
4
+ * Finds files matching glob patterns.
5
+ * - Uses fast-glob for performance
6
+ * - Auto-excludes node_modules, .git
7
+ * - Max 100 results by default
8
+ */
9
+ import fg from 'fast-glob';
10
+ import { BaseTool } from './base-tool.js';
11
+ const DEFAULT_MAX_RESULTS = 100;
12
+ export class GlobTool extends BaseTool {
13
+ name = 'glob';
14
+ description = 'Find files matching a glob pattern. ' +
15
+ 'Auto-excludes node_modules and .git directories.';
16
+ riskLevel = 'low';
17
+ parameters = {
18
+ pattern: {
19
+ type: 'string',
20
+ description: 'Glob pattern (e.g., "src/**/*.tsx", "**/*.test.ts")',
21
+ required: true,
22
+ },
23
+ path: {
24
+ type: 'string',
25
+ description: 'Base directory relative to project root (default: project root)',
26
+ required: false,
27
+ },
28
+ maxResults: {
29
+ type: 'number',
30
+ description: `Maximum results (default: ${DEFAULT_MAX_RESULTS})`,
31
+ required: false,
32
+ default: DEFAULT_MAX_RESULTS,
33
+ },
34
+ };
35
+ async execute(args, workDir) {
36
+ const toolCallId = args._toolCallId ?? '';
37
+ const pattern = args.pattern;
38
+ const basePath = args.path;
39
+ const maxResults = args.maxResults ?? DEFAULT_MAX_RESULTS;
40
+ if (!pattern) {
41
+ return this.fail(toolCallId, 'Missing required parameter: pattern');
42
+ }
43
+ // Resolve base directory
44
+ let cwd = workDir;
45
+ if (basePath) {
46
+ try {
47
+ cwd = this.validatePath(basePath, workDir);
48
+ }
49
+ catch (err) {
50
+ return this.fail(toolCallId, err.message);
51
+ }
52
+ }
53
+ try {
54
+ const allFiles = await fg(pattern, {
55
+ cwd,
56
+ ignore: [
57
+ '**/node_modules/**',
58
+ '**/.git/**',
59
+ '**/dist/**',
60
+ '**/build/**',
61
+ '**/.next/**',
62
+ '**/coverage/**',
63
+ ],
64
+ onlyFiles: true,
65
+ followSymbolicLinks: false,
66
+ });
67
+ const totalMatches = allFiles.length;
68
+ const truncated = totalMatches > maxResults;
69
+ const files = allFiles.slice(0, maxResults);
70
+ let output;
71
+ if (files.length === 0) {
72
+ output = `No files found matching pattern: ${pattern}`;
73
+ }
74
+ else {
75
+ output = files.join('\n');
76
+ if (truncated) {
77
+ output += `\n\n... (showing ${maxResults} of ${totalMatches} total matches)`;
78
+ }
79
+ }
80
+ return this.ok(toolCallId, output, {
81
+ totalMatches,
82
+ filesReturned: files.length,
83
+ truncated,
84
+ });
85
+ }
86
+ catch (err) {
87
+ return this.fail(toolCallId, `Glob search failed: ${err.message}`);
88
+ }
89
+ }
90
+ }
91
+ //# sourceMappingURL=glob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.js","sourceRoot":"","sources":["../src/glob.ts"],"names":[],"mappings":"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"}
package/dist/grep.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @yuaone/tools — grep tool
3
+ *
4
+ * Searches file contents using regex patterns.
5
+ * - Node.js built-in implementation (no ripgrep dependency)
6
+ * - Glob-based file filtering
7
+ * - Context lines support
8
+ * - Max 100 result lines
9
+ */
10
+ import type { ParameterDef, RiskLevel, ToolResult } from './types.js';
11
+ import { BaseTool } from './base-tool.js';
12
+ export declare class GrepTool extends BaseTool {
13
+ readonly name = "grep";
14
+ readonly description: string;
15
+ readonly riskLevel: RiskLevel;
16
+ readonly parameters: Record<string, ParameterDef>;
17
+ execute(args: Record<string, unknown>, workDir: string): Promise<ToolResult>;
18
+ }
19
+ //# sourceMappingURL=grep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../src/grep.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAM1C,qBAAa,QAAS,SAAQ,QAAQ;IACpC,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,WAAW,SAEyC;IAC7D,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAS;IAEtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CA4B/C;IAEI,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAiJnF"}