@compilr-dev/agents 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1277 -0
- package/dist/agent.d.ts +1272 -0
- package/dist/agent.js +1912 -0
- package/dist/anchors/builtin.d.ts +24 -0
- package/dist/anchors/builtin.js +61 -0
- package/dist/anchors/index.d.ts +6 -0
- package/dist/anchors/index.js +5 -0
- package/dist/anchors/manager.d.ts +115 -0
- package/dist/anchors/manager.js +412 -0
- package/dist/anchors/types.d.ts +168 -0
- package/dist/anchors/types.js +10 -0
- package/dist/context/index.d.ts +12 -0
- package/dist/context/index.js +10 -0
- package/dist/context/manager.d.ts +224 -0
- package/dist/context/manager.js +770 -0
- package/dist/context/types.d.ts +377 -0
- package/dist/context/types.js +7 -0
- package/dist/costs/index.d.ts +8 -0
- package/dist/costs/index.js +7 -0
- package/dist/costs/tracker.d.ts +121 -0
- package/dist/costs/tracker.js +295 -0
- package/dist/costs/types.d.ts +157 -0
- package/dist/costs/types.js +8 -0
- package/dist/errors.d.ts +178 -0
- package/dist/errors.js +249 -0
- package/dist/guardrails/builtin.d.ts +27 -0
- package/dist/guardrails/builtin.js +223 -0
- package/dist/guardrails/index.d.ts +6 -0
- package/dist/guardrails/index.js +5 -0
- package/dist/guardrails/manager.d.ts +117 -0
- package/dist/guardrails/manager.js +288 -0
- package/dist/guardrails/types.d.ts +159 -0
- package/dist/guardrails/types.js +7 -0
- package/dist/hooks/index.d.ts +31 -0
- package/dist/hooks/index.js +29 -0
- package/dist/hooks/manager.d.ts +147 -0
- package/dist/hooks/manager.js +600 -0
- package/dist/hooks/types.d.ts +368 -0
- package/dist/hooks/types.js +12 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +73 -0
- package/dist/mcp/client.d.ts +93 -0
- package/dist/mcp/client.js +287 -0
- package/dist/mcp/errors.d.ts +60 -0
- package/dist/mcp/errors.js +78 -0
- package/dist/mcp/index.d.ts +43 -0
- package/dist/mcp/index.js +45 -0
- package/dist/mcp/manager.d.ts +120 -0
- package/dist/mcp/manager.js +276 -0
- package/dist/mcp/tools.d.ts +54 -0
- package/dist/mcp/tools.js +99 -0
- package/dist/mcp/types.d.ts +150 -0
- package/dist/mcp/types.js +40 -0
- package/dist/memory/index.d.ts +8 -0
- package/dist/memory/index.js +7 -0
- package/dist/memory/loader.d.ts +114 -0
- package/dist/memory/loader.js +463 -0
- package/dist/memory/types.d.ts +182 -0
- package/dist/memory/types.js +8 -0
- package/dist/messages/index.d.ts +82 -0
- package/dist/messages/index.js +155 -0
- package/dist/permissions/index.d.ts +5 -0
- package/dist/permissions/index.js +4 -0
- package/dist/permissions/manager.d.ts +125 -0
- package/dist/permissions/manager.js +379 -0
- package/dist/permissions/types.d.ts +162 -0
- package/dist/permissions/types.js +7 -0
- package/dist/providers/claude.d.ts +90 -0
- package/dist/providers/claude.js +348 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.js +11 -0
- package/dist/providers/mock.d.ts +133 -0
- package/dist/providers/mock.js +204 -0
- package/dist/providers/types.d.ts +168 -0
- package/dist/providers/types.js +4 -0
- package/dist/rate-limit/index.d.ts +45 -0
- package/dist/rate-limit/index.js +47 -0
- package/dist/rate-limit/limiter.d.ts +104 -0
- package/dist/rate-limit/limiter.js +326 -0
- package/dist/rate-limit/provider-wrapper.d.ts +112 -0
- package/dist/rate-limit/provider-wrapper.js +201 -0
- package/dist/rate-limit/retry.d.ts +108 -0
- package/dist/rate-limit/retry.js +287 -0
- package/dist/rate-limit/types.d.ts +181 -0
- package/dist/rate-limit/types.js +22 -0
- package/dist/rehearsal/file-analyzer.d.ts +22 -0
- package/dist/rehearsal/file-analyzer.js +351 -0
- package/dist/rehearsal/git-analyzer.d.ts +22 -0
- package/dist/rehearsal/git-analyzer.js +472 -0
- package/dist/rehearsal/index.d.ts +35 -0
- package/dist/rehearsal/index.js +36 -0
- package/dist/rehearsal/manager.d.ts +100 -0
- package/dist/rehearsal/manager.js +290 -0
- package/dist/rehearsal/types.d.ts +235 -0
- package/dist/rehearsal/types.js +8 -0
- package/dist/skills/index.d.ts +160 -0
- package/dist/skills/index.js +282 -0
- package/dist/state/agent-state.d.ts +41 -0
- package/dist/state/agent-state.js +88 -0
- package/dist/state/checkpointer.d.ts +110 -0
- package/dist/state/checkpointer.js +362 -0
- package/dist/state/errors.d.ts +66 -0
- package/dist/state/errors.js +88 -0
- package/dist/state/index.d.ts +35 -0
- package/dist/state/index.js +37 -0
- package/dist/state/serializer.d.ts +55 -0
- package/dist/state/serializer.js +172 -0
- package/dist/state/types.d.ts +312 -0
- package/dist/state/types.js +14 -0
- package/dist/tools/builtin/bash-output.d.ts +61 -0
- package/dist/tools/builtin/bash-output.js +90 -0
- package/dist/tools/builtin/bash.d.ts +150 -0
- package/dist/tools/builtin/bash.js +354 -0
- package/dist/tools/builtin/edit.d.ts +50 -0
- package/dist/tools/builtin/edit.js +215 -0
- package/dist/tools/builtin/glob.d.ts +62 -0
- package/dist/tools/builtin/glob.js +244 -0
- package/dist/tools/builtin/grep.d.ts +74 -0
- package/dist/tools/builtin/grep.js +363 -0
- package/dist/tools/builtin/index.d.ts +44 -0
- package/dist/tools/builtin/index.js +69 -0
- package/dist/tools/builtin/kill-shell.d.ts +44 -0
- package/dist/tools/builtin/kill-shell.js +80 -0
- package/dist/tools/builtin/read-file.d.ts +57 -0
- package/dist/tools/builtin/read-file.js +184 -0
- package/dist/tools/builtin/shell-manager.d.ts +176 -0
- package/dist/tools/builtin/shell-manager.js +337 -0
- package/dist/tools/builtin/task.d.ts +202 -0
- package/dist/tools/builtin/task.js +350 -0
- package/dist/tools/builtin/todo.d.ts +207 -0
- package/dist/tools/builtin/todo.js +453 -0
- package/dist/tools/builtin/utils.d.ts +27 -0
- package/dist/tools/builtin/utils.js +70 -0
- package/dist/tools/builtin/web-fetch.d.ts +96 -0
- package/dist/tools/builtin/web-fetch.js +290 -0
- package/dist/tools/builtin/write-file.d.ts +54 -0
- package/dist/tools/builtin/write-file.js +147 -0
- package/dist/tools/define.d.ts +60 -0
- package/dist/tools/define.js +65 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.js +37 -0
- package/dist/tools/registry.d.ts +79 -0
- package/dist/tools/registry.js +151 -0
- package/dist/tools/types.d.ts +59 -0
- package/dist/tools/types.js +4 -0
- package/dist/tracing/hooks.d.ts +58 -0
- package/dist/tracing/hooks.js +377 -0
- package/dist/tracing/index.d.ts +51 -0
- package/dist/tracing/index.js +55 -0
- package/dist/tracing/logging.d.ts +78 -0
- package/dist/tracing/logging.js +310 -0
- package/dist/tracing/manager.d.ts +160 -0
- package/dist/tracing/manager.js +468 -0
- package/dist/tracing/otel.d.ts +102 -0
- package/dist/tracing/otel.js +246 -0
- package/dist/tracing/types.d.ts +346 -0
- package/dist/tracing/types.js +38 -0
- package/dist/utils/index.d.ts +23 -0
- package/dist/utils/index.js +44 -0
- package/package.json +79 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grep Tool - Search for patterns in files using regex
|
|
3
|
+
*/
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
5
|
+
import { readdir, stat } from 'node:fs/promises';
|
|
6
|
+
import { join, relative } from 'node:path';
|
|
7
|
+
import { defineTool, createSuccessResult, createErrorResult } from '../define.js';
|
|
8
|
+
import { isNodeError, isExtensionAllowed } from './utils.js';
|
|
9
|
+
/**
|
|
10
|
+
* Grep tool definition
|
|
11
|
+
*/
|
|
12
|
+
export const grepTool = defineTool({
|
|
13
|
+
name: 'grep',
|
|
14
|
+
description: 'Search for patterns in files using regular expressions. ' +
|
|
15
|
+
'Can search a single file or recursively through directories. ' +
|
|
16
|
+
'Returns matching lines with optional context.',
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: {
|
|
20
|
+
pattern: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
description: 'Regular expression pattern to search for',
|
|
23
|
+
},
|
|
24
|
+
path: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
description: 'Path to file or directory to search in',
|
|
27
|
+
},
|
|
28
|
+
ignoreCase: {
|
|
29
|
+
type: 'boolean',
|
|
30
|
+
description: 'Case insensitive search (default: false)',
|
|
31
|
+
},
|
|
32
|
+
lineNumbers: {
|
|
33
|
+
type: 'boolean',
|
|
34
|
+
description: 'Include line numbers in output (default: true)',
|
|
35
|
+
},
|
|
36
|
+
before: {
|
|
37
|
+
type: 'number',
|
|
38
|
+
description: 'Number of context lines before match',
|
|
39
|
+
},
|
|
40
|
+
after: {
|
|
41
|
+
type: 'number',
|
|
42
|
+
description: 'Number of context lines after match',
|
|
43
|
+
},
|
|
44
|
+
filesOnly: {
|
|
45
|
+
type: 'boolean',
|
|
46
|
+
description: 'Only return filenames with matches',
|
|
47
|
+
},
|
|
48
|
+
includeHidden: {
|
|
49
|
+
type: 'boolean',
|
|
50
|
+
description: 'Include hidden files/directories',
|
|
51
|
+
},
|
|
52
|
+
extensions: {
|
|
53
|
+
type: 'array',
|
|
54
|
+
items: { type: 'string' },
|
|
55
|
+
description: 'File extensions to include (e.g., [".ts", ".js"])',
|
|
56
|
+
},
|
|
57
|
+
maxMatches: {
|
|
58
|
+
type: 'number',
|
|
59
|
+
description: 'Maximum number of matches to return (default: 100)',
|
|
60
|
+
},
|
|
61
|
+
recursive: {
|
|
62
|
+
type: 'boolean',
|
|
63
|
+
description: 'Search recursively in directories (default: true)',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
required: ['pattern', 'path'],
|
|
67
|
+
},
|
|
68
|
+
execute: executeGrep,
|
|
69
|
+
});
|
|
70
|
+
/**
|
|
71
|
+
* Test if a regex pattern is potentially dangerous (ReDoS)
|
|
72
|
+
* This is a heuristic check - not comprehensive but catches common cases
|
|
73
|
+
*/
|
|
74
|
+
function isPotentiallyDangerousRegex(pattern) {
|
|
75
|
+
// Check for nested quantifiers which are common ReDoS patterns
|
|
76
|
+
// e.g., (a+)+, (a*)*, (a+)*, .*.*
|
|
77
|
+
const dangerousPatterns = [
|
|
78
|
+
/\([^)]*[+*][^)]*\)[+*]/, // Nested quantifiers like (a+)+
|
|
79
|
+
/\([^)]*\|[^)]*\)[+*]/, // Alternation with quantifier like (a|b)+
|
|
80
|
+
/\.[*+].*\.[*+]/, // Multiple .* or .+ patterns
|
|
81
|
+
];
|
|
82
|
+
for (const dangerous of dangerousPatterns) {
|
|
83
|
+
if (dangerous.test(pattern)) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Safely test a regex against a string with input length protection.
|
|
91
|
+
* Note: True timeout-based protection would require worker threads.
|
|
92
|
+
*/
|
|
93
|
+
function safeRegexTest(regex, text) {
|
|
94
|
+
// For very long lines, truncate to prevent ReDoS on long input
|
|
95
|
+
const maxLineLength = 10000;
|
|
96
|
+
const truncatedText = text.length > maxLineLength ? text.substring(0, maxLineLength) : text;
|
|
97
|
+
// Reset lastIndex before testing
|
|
98
|
+
regex.lastIndex = 0;
|
|
99
|
+
return regex.test(truncatedText);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Execute the grep tool
|
|
103
|
+
*/
|
|
104
|
+
async function executeGrep(input) {
|
|
105
|
+
try {
|
|
106
|
+
const { pattern, path, ignoreCase = false, lineNumbers = true, before = 0, after = 0, filesOnly = false, includeHidden = false, extensions, maxMatches = 100, recursive = true, } = input;
|
|
107
|
+
// Check for potentially dangerous regex patterns
|
|
108
|
+
if (isPotentiallyDangerousRegex(pattern)) {
|
|
109
|
+
return createErrorResult(`Potentially dangerous regex pattern detected (ReDoS risk). ` +
|
|
110
|
+
`Avoid nested quantifiers like (a+)+ or multiple .* patterns.`);
|
|
111
|
+
}
|
|
112
|
+
// Compile regex
|
|
113
|
+
let regex;
|
|
114
|
+
try {
|
|
115
|
+
regex = new RegExp(pattern, ignoreCase ? 'gi' : 'g');
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return createErrorResult(`Invalid regular expression: ${pattern}`);
|
|
119
|
+
}
|
|
120
|
+
// Determine if path is file or directory
|
|
121
|
+
const stats = await stat(path);
|
|
122
|
+
const files = [];
|
|
123
|
+
if (stats.isFile()) {
|
|
124
|
+
files.push(path);
|
|
125
|
+
}
|
|
126
|
+
else if (stats.isDirectory()) {
|
|
127
|
+
await collectFiles(path, files, {
|
|
128
|
+
recursive,
|
|
129
|
+
includeHidden,
|
|
130
|
+
extensions,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
return createErrorResult(`Path is neither a file nor directory: ${path}`);
|
|
135
|
+
}
|
|
136
|
+
// Search files
|
|
137
|
+
const matches = [];
|
|
138
|
+
const filesWithMatches = new Set();
|
|
139
|
+
let totalMatches = 0;
|
|
140
|
+
for (const file of files) {
|
|
141
|
+
if (totalMatches >= maxMatches)
|
|
142
|
+
break;
|
|
143
|
+
const fileMatches = await searchFile(file, regex, {
|
|
144
|
+
before,
|
|
145
|
+
after,
|
|
146
|
+
maxMatches: maxMatches - totalMatches,
|
|
147
|
+
});
|
|
148
|
+
if (fileMatches.length > 0) {
|
|
149
|
+
filesWithMatches.add(file);
|
|
150
|
+
if (!filesOnly) {
|
|
151
|
+
matches.push(...fileMatches);
|
|
152
|
+
}
|
|
153
|
+
totalMatches += fileMatches.length;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Format output
|
|
157
|
+
if (filesOnly) {
|
|
158
|
+
const relativePaths = Array.from(filesWithMatches).map((f) => f.startsWith(path) ? relative(path, f) || f : f);
|
|
159
|
+
return createSuccessResult({
|
|
160
|
+
files: relativePaths,
|
|
161
|
+
count: relativePaths.length,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
// Format matches with line numbers and context
|
|
165
|
+
const output = formatMatches(matches, { lineNumbers, path });
|
|
166
|
+
return createSuccessResult({
|
|
167
|
+
matches: output,
|
|
168
|
+
count: matches.length,
|
|
169
|
+
filesSearched: files.length,
|
|
170
|
+
truncated: totalMatches >= maxMatches,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
if (isNodeError(error)) {
|
|
175
|
+
switch (error.code) {
|
|
176
|
+
case 'ENOENT':
|
|
177
|
+
return createErrorResult(`Path not found: ${input.path}`);
|
|
178
|
+
case 'EACCES':
|
|
179
|
+
return createErrorResult(`Permission denied: ${input.path}`);
|
|
180
|
+
default:
|
|
181
|
+
return createErrorResult(`Grep failed: ${error.message}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return createErrorResult(error instanceof Error ? error.message : String(error));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Recursively collect files from a directory
|
|
189
|
+
*/
|
|
190
|
+
async function collectFiles(dir, files, options) {
|
|
191
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
192
|
+
for (const entry of entries) {
|
|
193
|
+
// Skip hidden files unless included
|
|
194
|
+
if (!options.includeHidden && entry.name.startsWith('.')) {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
const fullPath = join(dir, entry.name);
|
|
198
|
+
if (entry.isFile()) {
|
|
199
|
+
// Check extension filter
|
|
200
|
+
if (options.extensions && options.extensions.length > 0) {
|
|
201
|
+
if (!isExtensionAllowed(entry.name, options.extensions)) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
files.push(fullPath);
|
|
206
|
+
}
|
|
207
|
+
else if (entry.isDirectory() && options.recursive) {
|
|
208
|
+
await collectFiles(fullPath, files, options);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Search a single file for pattern matches
|
|
214
|
+
*/
|
|
215
|
+
async function searchFile(filePath, regex, options) {
|
|
216
|
+
const matches = [];
|
|
217
|
+
try {
|
|
218
|
+
const content = await readFile(filePath, 'utf-8');
|
|
219
|
+
// Skip likely binary files (files with null bytes in first 8KB)
|
|
220
|
+
if (content.length > 0 && content.slice(0, 8000).includes('\0')) {
|
|
221
|
+
return matches;
|
|
222
|
+
}
|
|
223
|
+
const lines = content.split('\n');
|
|
224
|
+
for (let i = 0; i < lines.length; i++) {
|
|
225
|
+
if (matches.length >= options.maxMatches)
|
|
226
|
+
break;
|
|
227
|
+
// Use safe regex test with line length protection
|
|
228
|
+
if (safeRegexTest(regex, lines[i])) {
|
|
229
|
+
const match = {
|
|
230
|
+
file: filePath,
|
|
231
|
+
line: i + 1, // 1-indexed
|
|
232
|
+
content: lines[i],
|
|
233
|
+
};
|
|
234
|
+
// Add context if requested
|
|
235
|
+
if (options.before > 0 || options.after > 0) {
|
|
236
|
+
match.context = {
|
|
237
|
+
before: lines.slice(Math.max(0, i - options.before), i),
|
|
238
|
+
after: lines.slice(i + 1, i + 1 + options.after),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
matches.push(match);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
// Skip files that can't be read (binary files, permission issues, etc.)
|
|
247
|
+
}
|
|
248
|
+
return matches;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Format matches for output
|
|
252
|
+
*/
|
|
253
|
+
function formatMatches(matches, options) {
|
|
254
|
+
return matches.map((match) => {
|
|
255
|
+
const relativePath = match.file.startsWith(options.path)
|
|
256
|
+
? relative(options.path, match.file) || match.file
|
|
257
|
+
: match.file;
|
|
258
|
+
let output = '';
|
|
259
|
+
// Add context before
|
|
260
|
+
if (match.context?.before) {
|
|
261
|
+
for (let i = 0; i < match.context.before.length; i++) {
|
|
262
|
+
const lineNum = match.line - match.context.before.length + i;
|
|
263
|
+
output += options.lineNumbers
|
|
264
|
+
? `${relativePath}:${String(lineNum)}-${match.context.before[i]}\n`
|
|
265
|
+
: `${relativePath}-${match.context.before[i]}\n`;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Add the matching line
|
|
269
|
+
output += options.lineNumbers
|
|
270
|
+
? `${relativePath}:${String(match.line)}:${match.content}`
|
|
271
|
+
: `${relativePath}:${match.content}`;
|
|
272
|
+
// Add context after
|
|
273
|
+
if (match.context?.after) {
|
|
274
|
+
for (let i = 0; i < match.context.after.length; i++) {
|
|
275
|
+
const lineNum = match.line + 1 + i;
|
|
276
|
+
output += options.lineNumbers
|
|
277
|
+
? `\n${relativePath}:${String(lineNum)}-${match.context.after[i]}`
|
|
278
|
+
: `\n${relativePath}-${match.context.after[i]}`;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return output;
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Factory function to create a grep tool with custom options
|
|
286
|
+
*
|
|
287
|
+
* TODO: Future enhancements could include:
|
|
288
|
+
* - maxFileSize: Skip files larger than specified size
|
|
289
|
+
* - excludeDirs: Exclude directories by name (e.g., node_modules, .git)
|
|
290
|
+
*/
|
|
291
|
+
export function createGrepTool(options) {
|
|
292
|
+
return defineTool({
|
|
293
|
+
name: 'grep',
|
|
294
|
+
description: 'Search for patterns in files using regular expressions. ' +
|
|
295
|
+
'Can search a single file or recursively through directories. ' +
|
|
296
|
+
'Returns matching lines with optional context.',
|
|
297
|
+
inputSchema: {
|
|
298
|
+
type: 'object',
|
|
299
|
+
properties: {
|
|
300
|
+
pattern: {
|
|
301
|
+
type: 'string',
|
|
302
|
+
description: 'Regular expression pattern to search for',
|
|
303
|
+
},
|
|
304
|
+
path: {
|
|
305
|
+
type: 'string',
|
|
306
|
+
description: 'Path to file or directory to search in',
|
|
307
|
+
},
|
|
308
|
+
ignoreCase: {
|
|
309
|
+
type: 'boolean',
|
|
310
|
+
description: 'Case insensitive search (default: false)',
|
|
311
|
+
},
|
|
312
|
+
lineNumbers: {
|
|
313
|
+
type: 'boolean',
|
|
314
|
+
description: 'Include line numbers in output (default: true)',
|
|
315
|
+
},
|
|
316
|
+
before: {
|
|
317
|
+
type: 'number',
|
|
318
|
+
description: 'Number of context lines before match',
|
|
319
|
+
},
|
|
320
|
+
after: {
|
|
321
|
+
type: 'number',
|
|
322
|
+
description: 'Number of context lines after match',
|
|
323
|
+
},
|
|
324
|
+
filesOnly: {
|
|
325
|
+
type: 'boolean',
|
|
326
|
+
description: 'Only return filenames with matches',
|
|
327
|
+
},
|
|
328
|
+
includeHidden: {
|
|
329
|
+
type: 'boolean',
|
|
330
|
+
description: 'Include hidden files/directories',
|
|
331
|
+
},
|
|
332
|
+
extensions: {
|
|
333
|
+
type: 'array',
|
|
334
|
+
items: { type: 'string' },
|
|
335
|
+
description: 'File extensions to include (e.g., [".ts", ".js"])',
|
|
336
|
+
},
|
|
337
|
+
maxMatches: {
|
|
338
|
+
type: 'number',
|
|
339
|
+
description: 'Maximum number of matches to return (default: 100)',
|
|
340
|
+
},
|
|
341
|
+
recursive: {
|
|
342
|
+
type: 'boolean',
|
|
343
|
+
description: 'Search recursively in directories (default: true)',
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
required: ['pattern', 'path'],
|
|
347
|
+
},
|
|
348
|
+
execute: async (input) => {
|
|
349
|
+
let searchPath = input.path;
|
|
350
|
+
// Resolve relative paths
|
|
351
|
+
if (options?.baseDir && !searchPath.startsWith('/')) {
|
|
352
|
+
searchPath = join(options.baseDir, searchPath);
|
|
353
|
+
}
|
|
354
|
+
// Apply default extensions if none specified
|
|
355
|
+
const extensions = input.extensions ?? options?.defaultExtensions;
|
|
356
|
+
return executeGrep({
|
|
357
|
+
...input,
|
|
358
|
+
path: searchPath,
|
|
359
|
+
extensions,
|
|
360
|
+
});
|
|
361
|
+
},
|
|
362
|
+
});
|
|
363
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in tools for common operations
|
|
3
|
+
*/
|
|
4
|
+
export { readFileTool, createReadFileTool } from './read-file.js';
|
|
5
|
+
export type { ReadFileInput } from './read-file.js';
|
|
6
|
+
export { writeFileTool, createWriteFileTool } from './write-file.js';
|
|
7
|
+
export type { WriteFileInput } from './write-file.js';
|
|
8
|
+
export { bashTool, createBashTool, execStream, detectFifoUsage } from './bash.js';
|
|
9
|
+
export type { BashInput, BashResult, FifoDetectionResult } from './bash.js';
|
|
10
|
+
export { bashOutputTool, createBashOutputTool } from './bash-output.js';
|
|
11
|
+
export type { BashOutputInput, BashOutputResult } from './bash-output.js';
|
|
12
|
+
export { killShellTool, createKillShellTool } from './kill-shell.js';
|
|
13
|
+
export type { KillShellInput, KillShellResult } from './kill-shell.js';
|
|
14
|
+
export { ShellManager, getDefaultShellManager, setDefaultShellManager } from './shell-manager.js';
|
|
15
|
+
export type { ShellStatus, BackgroundShell, ShellOutput, ShellManagerOptions, } from './shell-manager.js';
|
|
16
|
+
export { grepTool, createGrepTool } from './grep.js';
|
|
17
|
+
export type { GrepInput } from './grep.js';
|
|
18
|
+
export { globTool, createGlobTool } from './glob.js';
|
|
19
|
+
export type { GlobInput } from './glob.js';
|
|
20
|
+
export { editTool, createEditTool } from './edit.js';
|
|
21
|
+
export type { EditInput } from './edit.js';
|
|
22
|
+
export { todoWriteTool, todoReadTool, createTodoTools, TodoStore, resetDefaultTodoStore, getDefaultTodoStore, createIsolatedTodoStore, cleanupTodoContextMessages, getTodoContextStats, } from './todo.js';
|
|
23
|
+
export type { TodoWriteInput, TodoReadInput, TodoItem, TodoStatus, TodoContextCleanupOptions, } from './todo.js';
|
|
24
|
+
export { createTaskTool, defaultAgentTypes } from './task.js';
|
|
25
|
+
export type { TaskInput, TaskResult, AgentTypeConfig, TaskToolOptions, ContextMode, ThoroughnessLevel, SubAgentEventInfo, } from './task.js';
|
|
26
|
+
export { webFetchTool, createWebFetchTool } from './web-fetch.js';
|
|
27
|
+
export type { WebFetchInput, WebFetchResult, WebFetchOptions } from './web-fetch.js';
|
|
28
|
+
export declare const builtinTools: {
|
|
29
|
+
readonly readFile: import("../types.js").Tool<import("./read-file.js").ReadFileInput>;
|
|
30
|
+
readonly writeFile: import("../types.js").Tool<import("./write-file.js").WriteFileInput>;
|
|
31
|
+
readonly bash: import("../types.js").Tool<import("./bash.js").BashInput>;
|
|
32
|
+
readonly bashOutput: import("../types.js").Tool<import("./bash-output.js").BashOutputInput>;
|
|
33
|
+
readonly killShell: import("../types.js").Tool<import("./kill-shell.js").KillShellInput>;
|
|
34
|
+
readonly grep: import("../types.js").Tool<import("./grep.js").GrepInput>;
|
|
35
|
+
readonly glob: import("../types.js").Tool<import("./glob.js").GlobInput>;
|
|
36
|
+
readonly edit: import("../types.js").Tool<import("./edit.js").EditInput>;
|
|
37
|
+
readonly todoWrite: import("../types.js").Tool<import("./todo.js").TodoWriteInput>;
|
|
38
|
+
readonly todoRead: import("../types.js").Tool<import("./todo.js").TodoReadInput>;
|
|
39
|
+
readonly webFetch: import("../types.js").Tool<import("./web-fetch.js").WebFetchInput>;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Array of all built-in tools
|
|
43
|
+
*/
|
|
44
|
+
export declare const allBuiltinTools: readonly [import("../types.js").Tool<import("./read-file.js").ReadFileInput>, import("../types.js").Tool<import("./write-file.js").WriteFileInput>, import("../types.js").Tool<import("./bash.js").BashInput>, import("../types.js").Tool<import("./bash-output.js").BashOutputInput>, import("../types.js").Tool<import("./kill-shell.js").KillShellInput>, import("../types.js").Tool<import("./grep.js").GrepInput>, import("../types.js").Tool<import("./glob.js").GlobInput>, import("../types.js").Tool<import("./edit.js").EditInput>, import("../types.js").Tool<import("./todo.js").TodoWriteInput>, import("../types.js").Tool<import("./todo.js").TodoReadInput>, import("../types.js").Tool<import("./web-fetch.js").WebFetchInput>];
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in tools for common operations
|
|
3
|
+
*/
|
|
4
|
+
// Read file tool
|
|
5
|
+
export { readFileTool, createReadFileTool } from './read-file.js';
|
|
6
|
+
// Write file tool
|
|
7
|
+
export { writeFileTool, createWriteFileTool } from './write-file.js';
|
|
8
|
+
// Bash tool
|
|
9
|
+
export { bashTool, createBashTool, execStream, detectFifoUsage } from './bash.js';
|
|
10
|
+
// Bash output tool (background shell monitoring)
|
|
11
|
+
export { bashOutputTool, createBashOutputTool } from './bash-output.js';
|
|
12
|
+
// Kill shell tool
|
|
13
|
+
export { killShellTool, createKillShellTool } from './kill-shell.js';
|
|
14
|
+
// Shell manager (for background processes)
|
|
15
|
+
export { ShellManager, getDefaultShellManager, setDefaultShellManager } from './shell-manager.js';
|
|
16
|
+
// Grep tool
|
|
17
|
+
export { grepTool, createGrepTool } from './grep.js';
|
|
18
|
+
// Glob tool
|
|
19
|
+
export { globTool, createGlobTool } from './glob.js';
|
|
20
|
+
// Edit tool
|
|
21
|
+
export { editTool, createEditTool } from './edit.js';
|
|
22
|
+
// Todo tools
|
|
23
|
+
export { todoWriteTool, todoReadTool, createTodoTools, TodoStore, resetDefaultTodoStore, getDefaultTodoStore, createIsolatedTodoStore, cleanupTodoContextMessages, getTodoContextStats, } from './todo.js';
|
|
24
|
+
// Task tool (sub-agent spawning)
|
|
25
|
+
export { createTaskTool, defaultAgentTypes } from './task.js';
|
|
26
|
+
// WebFetch tool
|
|
27
|
+
export { webFetchTool, createWebFetchTool } from './web-fetch.js';
|
|
28
|
+
/**
|
|
29
|
+
* Collection of all built-in tools for easy registration
|
|
30
|
+
*/
|
|
31
|
+
import { readFileTool } from './read-file.js';
|
|
32
|
+
import { writeFileTool } from './write-file.js';
|
|
33
|
+
import { bashTool } from './bash.js';
|
|
34
|
+
import { bashOutputTool } from './bash-output.js';
|
|
35
|
+
import { killShellTool } from './kill-shell.js';
|
|
36
|
+
import { grepTool } from './grep.js';
|
|
37
|
+
import { globTool } from './glob.js';
|
|
38
|
+
import { editTool } from './edit.js';
|
|
39
|
+
import { todoWriteTool, todoReadTool } from './todo.js';
|
|
40
|
+
import { webFetchTool } from './web-fetch.js';
|
|
41
|
+
export const builtinTools = {
|
|
42
|
+
readFile: readFileTool,
|
|
43
|
+
writeFile: writeFileTool,
|
|
44
|
+
bash: bashTool,
|
|
45
|
+
bashOutput: bashOutputTool,
|
|
46
|
+
killShell: killShellTool,
|
|
47
|
+
grep: grepTool,
|
|
48
|
+
glob: globTool,
|
|
49
|
+
edit: editTool,
|
|
50
|
+
todoWrite: todoWriteTool,
|
|
51
|
+
todoRead: todoReadTool,
|
|
52
|
+
webFetch: webFetchTool,
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Array of all built-in tools
|
|
56
|
+
*/
|
|
57
|
+
export const allBuiltinTools = [
|
|
58
|
+
readFileTool,
|
|
59
|
+
writeFileTool,
|
|
60
|
+
bashTool,
|
|
61
|
+
bashOutputTool,
|
|
62
|
+
killShellTool,
|
|
63
|
+
grepTool,
|
|
64
|
+
globTool,
|
|
65
|
+
editTool,
|
|
66
|
+
todoWriteTool,
|
|
67
|
+
todoReadTool,
|
|
68
|
+
webFetchTool,
|
|
69
|
+
];
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KillShell Tool - Terminate background shell processes
|
|
3
|
+
*/
|
|
4
|
+
import type { Tool } from '../types.js';
|
|
5
|
+
import { type ShellManager } from './shell-manager.js';
|
|
6
|
+
/**
|
|
7
|
+
* Input parameters for killShell tool
|
|
8
|
+
*/
|
|
9
|
+
export interface KillShellInput {
|
|
10
|
+
/**
|
|
11
|
+
* The ID of the background shell to kill
|
|
12
|
+
*/
|
|
13
|
+
shell_id: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Result of killShell tool
|
|
17
|
+
*/
|
|
18
|
+
export interface KillShellResult {
|
|
19
|
+
/**
|
|
20
|
+
* Whether the shell was successfully killed
|
|
21
|
+
*/
|
|
22
|
+
success: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Shell ID
|
|
25
|
+
*/
|
|
26
|
+
id: string;
|
|
27
|
+
/**
|
|
28
|
+
* Message describing the result
|
|
29
|
+
*/
|
|
30
|
+
message: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* KillShell tool definition
|
|
34
|
+
*/
|
|
35
|
+
export declare const killShellTool: Tool<KillShellInput>;
|
|
36
|
+
/**
|
|
37
|
+
* Factory function to create a killShell tool with custom shell manager
|
|
38
|
+
*/
|
|
39
|
+
export declare function createKillShellTool(options?: {
|
|
40
|
+
/**
|
|
41
|
+
* Custom shell manager to use
|
|
42
|
+
*/
|
|
43
|
+
shellManager?: ShellManager;
|
|
44
|
+
}): Tool<KillShellInput>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KillShell Tool - Terminate background shell processes
|
|
3
|
+
*/
|
|
4
|
+
import { defineTool, createSuccessResult, createErrorResult } from '../define.js';
|
|
5
|
+
import { getDefaultShellManager } from './shell-manager.js';
|
|
6
|
+
/**
|
|
7
|
+
* KillShell tool definition
|
|
8
|
+
*/
|
|
9
|
+
export const killShellTool = defineTool({
|
|
10
|
+
name: 'kill_shell',
|
|
11
|
+
description: 'Kill a running background bash shell by its ID. ' +
|
|
12
|
+
'Use this to terminate long-running commands that are no longer needed.',
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {
|
|
16
|
+
shell_id: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
description: 'The ID of the background shell to kill',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
required: ['shell_id'],
|
|
22
|
+
},
|
|
23
|
+
execute: (input) => {
|
|
24
|
+
const manager = getDefaultShellManager();
|
|
25
|
+
return Promise.resolve(executeKillShell(input, manager));
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Execute the killShell tool
|
|
30
|
+
*/
|
|
31
|
+
function executeKillShell(input, manager) {
|
|
32
|
+
const { shell_id } = input;
|
|
33
|
+
// Check if shell exists
|
|
34
|
+
const shell = manager.get(shell_id);
|
|
35
|
+
if (!shell) {
|
|
36
|
+
return createErrorResult(`Shell '${shell_id}' not found. It may have been cleaned up or never existed.`);
|
|
37
|
+
}
|
|
38
|
+
// Check if already completed
|
|
39
|
+
if (shell.status !== 'running') {
|
|
40
|
+
return createSuccessResult({
|
|
41
|
+
success: false,
|
|
42
|
+
id: shell_id,
|
|
43
|
+
message: `Shell '${shell_id}' is already ${shell.status} (exit code: ${String(shell.exitCode ?? 'N/A')})`,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// Kill the shell
|
|
47
|
+
const killed = manager.kill(shell_id);
|
|
48
|
+
if (killed) {
|
|
49
|
+
return createSuccessResult({
|
|
50
|
+
success: true,
|
|
51
|
+
id: shell_id,
|
|
52
|
+
message: `Shell '${shell_id}' has been terminated`,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
return createErrorResult(`Failed to kill shell '${shell_id}'`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Factory function to create a killShell tool with custom shell manager
|
|
61
|
+
*/
|
|
62
|
+
export function createKillShellTool(options) {
|
|
63
|
+
const manager = options?.shellManager ?? getDefaultShellManager();
|
|
64
|
+
return defineTool({
|
|
65
|
+
name: 'kill_shell',
|
|
66
|
+
description: 'Kill a running background bash shell by its ID. ' +
|
|
67
|
+
'Use this to terminate long-running commands that are no longer needed.',
|
|
68
|
+
inputSchema: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: {
|
|
71
|
+
shell_id: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
description: 'The ID of the background shell to kill',
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
required: ['shell_id'],
|
|
77
|
+
},
|
|
78
|
+
execute: (input) => Promise.resolve(executeKillShell(input, manager)),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read File Tool - Read contents of a file from the filesystem
|
|
3
|
+
*/
|
|
4
|
+
import type { Tool } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Input parameters for read_file tool
|
|
7
|
+
*/
|
|
8
|
+
export interface ReadFileInput {
|
|
9
|
+
/**
|
|
10
|
+
* Path to the file to read
|
|
11
|
+
*/
|
|
12
|
+
path: string;
|
|
13
|
+
/**
|
|
14
|
+
* Encoding to use (default: utf-8)
|
|
15
|
+
*/
|
|
16
|
+
encoding?: BufferEncoding;
|
|
17
|
+
/**
|
|
18
|
+
* Maximum number of lines to read (default: all)
|
|
19
|
+
*/
|
|
20
|
+
maxLines?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Line offset to start reading from (1-indexed, default: 1)
|
|
23
|
+
*/
|
|
24
|
+
startLine?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Read file tool definition
|
|
28
|
+
*/
|
|
29
|
+
export declare const readFileTool: Tool<ReadFileInput>;
|
|
30
|
+
/**
|
|
31
|
+
* Factory function to create a read_file tool with custom options
|
|
32
|
+
*/
|
|
33
|
+
export declare function createReadFileTool(options?: {
|
|
34
|
+
/**
|
|
35
|
+
* Base directory to resolve relative paths against
|
|
36
|
+
*/
|
|
37
|
+
baseDir?: string;
|
|
38
|
+
/**
|
|
39
|
+
* List of allowed file extensions (e.g., ['.ts', '.js', '.json'])
|
|
40
|
+
*/
|
|
41
|
+
allowedExtensions?: string[];
|
|
42
|
+
/**
|
|
43
|
+
* Maximum file size to read in bytes (default: 10MB).
|
|
44
|
+
* Files larger than this are rejected entirely.
|
|
45
|
+
*/
|
|
46
|
+
maxFileSize?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Maximum content size returned to agent in bytes (default: 100KB).
|
|
49
|
+
* Content larger than this is truncated.
|
|
50
|
+
*/
|
|
51
|
+
maxContentSize?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Whether to truncate large content (true) or reject (false).
|
|
54
|
+
* Default: true
|
|
55
|
+
*/
|
|
56
|
+
truncateIfLarge?: boolean;
|
|
57
|
+
}): Tool<ReadFileInput>;
|