@curie-agent/tools 0.2.5 → 0.3.3

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/dist/src/edit.js CHANGED
@@ -4,12 +4,21 @@ import { z } from 'zod';
4
4
  import { createTool, expandPath } from './tool.js';
5
5
  import { resolveSafePath, parseAllowlist } from '@curie-agent/core/safety/path-guard.js';
6
6
  const EditSchema = z.object({
7
- file_path: z.string().describe('The absolute path to the file to modify'),
8
- old_string: z.string().describe('The text to replace'),
9
- new_string: z.string().describe('The text to replace it with'),
10
- replace_all: z.boolean().optional().describe('Replace all occurrences'),
7
+ file_path: z
8
+ .string()
9
+ .describe('The path to the file to modify (absolute, or relative to the working directory)'),
10
+ old_string: z
11
+ .string()
12
+ .describe('The exact text to replace, including whitespace and indentation. Must be unique in the file unless replace_all is set.'),
13
+ new_string: z.string().describe('The text to replace it with (must differ from old_string)'),
14
+ replace_all: z.boolean().optional().describe('Replace every occurrence of old_string (default false)'),
11
15
  });
12
- export const editTool = createTool('Edit', 'Performs exact string replacements in files. Use replace_all to change every instance.', EditSchema, async (input, ctx) => {
16
+ export const editTool = createTool('Edit', [
17
+ 'Performs an exact string replacement in an existing file.',
18
+ '`old_string` must match the file contents exactly — including whitespace and indentation — and must be unique in the file;',
19
+ 'if it appears more than once, include more surrounding context to make it unique or pass `replace_all: true` to change every instance.',
20
+ 'Read the file first to get the exact text.',
21
+ ].join(' '), EditSchema, async (input, ctx) => {
13
22
  let filePath;
14
23
  if (ctx.settings.safety?.path_guard !== 'off') {
15
24
  const check = resolveSafePath(input.file_path, ctx.cwd, parseAllowlist(ctx.settings.safety?.path_allowlist ?? ''));
@@ -23,27 +32,46 @@ export const editTool = createTool('Edit', 'Performs exact string replacements i
23
32
  if (!fs.existsSync(filePath)) {
24
33
  return { output: null, error: `File not found: ${filePath}. Read it first before editing.` };
25
34
  }
35
+ if (input.old_string === '') {
36
+ return { output: null, error: 'old_string is empty — provide the exact text to replace.' };
37
+ }
38
+ if (input.old_string === input.new_string) {
39
+ return { output: null, error: 'old_string and new_string are identical — nothing to change.' };
40
+ }
26
41
  const content = fs.readFileSync(filePath, 'utf-8');
42
+ const count = content.split(input.old_string).length - 1;
43
+ if (count === 0) {
44
+ return {
45
+ output: null,
46
+ error: `String not found in ${filePath}: "${input.old_string.slice(0, 80)}". ` +
47
+ 'old_string must match the file contents exactly, including whitespace and indentation. ' +
48
+ 'Read the file again to get the exact text.',
49
+ };
50
+ }
27
51
  if (input.replace_all) {
28
- const count = (content.match(new RegExp(escapeRegex(input.old_string), 'g')) || []).length;
29
- if (count === 0) {
30
- return { output: null, error: `String not found in file: ${input.old_string.slice(0, 50)}` };
31
- }
32
52
  const newContent = content.split(input.old_string).join(input.new_string);
33
53
  fs.writeFileSync(filePath, newContent, 'utf-8');
34
54
  return { output: { path: filePath, replacements: count } };
35
55
  }
36
- else {
37
- const idx = content.indexOf(input.old_string);
38
- if (idx === -1) {
39
- return { output: null, error: `String not found in file. The old_string must match exactly.` };
40
- }
41
- const newContent = content.slice(0, idx) + input.new_string + content.slice(idx + input.old_string.length);
42
- fs.writeFileSync(filePath, newContent, 'utf-8');
43
- return { output: { path: filePath, replacements: 1 } };
56
+ if (count > 1) {
57
+ return {
58
+ output: null,
59
+ error: `Found ${String(count)} occurrences of old_string in ${filePath}. ` +
60
+ 'Include more surrounding context to make it unique, or pass replace_all: true to replace every occurrence.',
61
+ };
44
62
  }
63
+ const idx = content.indexOf(input.old_string);
64
+ const newContent = content.slice(0, idx) + input.new_string + content.slice(idx + input.old_string.length);
65
+ fs.writeFileSync(filePath, newContent, 'utf-8');
66
+ return { output: { path: filePath, replacements: 1 } };
67
+ }, undefined, {
68
+ aliases: {
69
+ path: 'file_path',
70
+ filename: 'file_path',
71
+ filepath: 'file_path',
72
+ file: 'file_path',
73
+ old_str: 'old_string',
74
+ new_str: 'new_string',
75
+ },
45
76
  });
46
- function escapeRegex(s) {
47
- return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
48
- }
49
77
  //# sourceMappingURL=edit.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/edit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAoB,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAEzF,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;IACzE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IACtD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;IAC9D,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;CACxE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,MAAM,EACN,wFAAwF,EACxF,UAAU,EACV,KAAK,EAAE,KAAK,EAAE,GAAgB,EAAE,EAAE;IAChC,IAAI,QAAgB,CAAC;IAErB,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,KAAK,KAAK,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,eAAe,CAC3B,KAAK,CAAC,SAAS,EACf,GAAG,CAAC,GAAG,EACP,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,IAAI,EAAE,CAAC,CAC1D,CAAC;QACF,IAAI,OAAO,IAAI,KAAK;YAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;QAClE,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,mBAAmB,QAAQ,iCAAiC,EAAE,CAAC;IAC/F,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEnD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QAC3F,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,6BAA6B,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/F,CAAC;QACD,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC1E,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAChD,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,CAAC;IAC7D,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,8DAA8D,EAAE,CAAC;QACjG,CAAC;QACD,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC3G,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAChD,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;IACzD,CAAC;AACH,CAAC,CACF,CAAC;AAEF,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/edit.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,7 @@
1
+ export declare function minimatch(pattern: string, str: string): boolean;
2
+ export declare function globToRegex(pattern: string): RegExp;
3
+ export declare function readGitignore(cwd: string): string[];
4
+ export declare function shouldIgnore(relPath: string, patterns: string[]): boolean;
1
5
  export declare const globTool: import("./tool.js").Tool & {
2
6
  validate: (raw: Record<string, unknown>) => {
3
7
  pattern: string;
@@ -1 +1 @@
1
- {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/glob.ts"],"names":[],"mappings":"AAiDA,eAAO,MAAM,QAAQ;;;;;CA4DpB,CAAC"}
1
+ {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/glob.ts"],"names":[],"mappings":"AAmBA,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAG/D;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAWnD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAQnD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAezE;AAED,eAAO,MAAM,QAAQ;;;;;CAwEpB,CAAC"}
package/dist/src/glob.js CHANGED
@@ -4,14 +4,20 @@ import { z } from 'zod';
4
4
  import { isPathAllowed, parseAllowlist } from '@curie-agent/core/safety/path-guard.js';
5
5
  import { createTool, expandPath } from './tool.js';
6
6
  const GlobSchema = z.object({
7
- pattern: z.string().describe('The glob pattern to match files against'),
8
- path: z.string().optional().describe('The directory to search in'),
7
+ pattern: z
8
+ .string()
9
+ .describe('Glob pattern to match against. Use forward slashes on all platforms. ' +
10
+ '`*` = one level, `**` = any depth. Pattern is relative to `path` (or cwd if omitted).'),
11
+ path: z
12
+ .string()
13
+ .optional()
14
+ .describe('Directory to search in. Defaults to cwd. Accepts forward or backward slashes.'),
9
15
  });
10
- function minimatch(pattern, str) {
16
+ export function minimatch(pattern, str) {
11
17
  const regex = globToRegex(pattern);
12
18
  return regex.test(str);
13
19
  }
14
- function globToRegex(pattern) {
20
+ export function globToRegex(pattern) {
15
21
  // Use unique Unicode placeholders instead of backslash-escaping to avoid conflicts
16
22
  // between the ** protection and single-* replacement steps.
17
23
  const placeholder = '';
@@ -23,7 +29,7 @@ function globToRegex(pattern) {
23
29
  .replace(/\?/g, '[^/]');
24
30
  return new RegExp(`^${regex}$`);
25
31
  }
26
- function readGitignore(cwd) {
32
+ export function readGitignore(cwd) {
27
33
  const gitignorePath = path.join(cwd, '.gitignore');
28
34
  if (!fs.existsSync(gitignorePath))
29
35
  return [];
@@ -33,19 +39,38 @@ function readGitignore(cwd) {
33
39
  .map((l) => l.trim())
34
40
  .filter((l) => l && !l.startsWith('#'));
35
41
  }
36
- function shouldIgnore(relPath, patterns) {
42
+ export function shouldIgnore(relPath, patterns) {
37
43
  for (const p of patterns) {
38
- if (minimatch(p, relPath))
39
- return true;
40
- // Also match as directory prefix: "node_modules" should ignore node_modules/foo/bar
41
- const dirPrefix = p.replace(/\/$/, '') + '/';
42
- if (relPath.startsWith(dirPrefix))
43
- return true;
44
+ const clean = p.replace(/\/$/, '');
45
+ if (!clean)
46
+ continue;
47
+ if (clean.includes('/')) {
48
+ // Anchored pattern: match the relative path itself or as a directory prefix.
49
+ if (minimatch(clean, relPath))
50
+ return true;
51
+ if (relPath.startsWith(clean + '/'))
52
+ return true;
53
+ }
54
+ else {
55
+ // Bare pattern (gitignore semantics): matches any path segment at any depth,
56
+ // e.g. "dist" ignores dist/ and packages/foo/dist/.
57
+ if (relPath.split('/').some((segment) => minimatch(clean, segment)))
58
+ return true;
59
+ }
44
60
  }
45
61
  return false;
46
62
  }
47
- export const globTool = createTool('Glob', 'Fast file pattern matching. Gitignore-aware file pattern matching.', GlobSchema, async (input, ctx) => {
48
- const searchDir = input.path ? path.resolve(ctx.cwd, expandPath(input.path)) : ctx.cwd;
63
+ export const globTool = createTool('Glob', [
64
+ 'Fast, gitignore-aware recursive file search by glob pattern (finds files by NAME — use Grep to search file contents).',
65
+ 'Pattern syntax: `*` matches anything within one directory level; `**` matches across any depth.',
66
+ 'Always use forward slashes in patterns, even on Windows (e.g., `src/**/*.ts`).',
67
+ 'When `path` is supplied, the pattern matches relative to that directory.',
68
+ 'Results are returned as absolute paths, sorted alphabetically.',
69
+ 'Examples: `**/*.ts` (all TypeScript files), `src/*/index.ts` (index files one level deep in src/).',
70
+ ].join(' '), GlobSchema, async (input, ctx) => {
71
+ // Normalize backslashes in path input so Windows-style paths work correctly.
72
+ const rawPath = input.path ? input.path.replace(/\\/g, '/') : undefined;
73
+ const searchDir = rawPath ? path.resolve(ctx.cwd, expandPath(rawPath)) : ctx.cwd;
49
74
  // Safety: refuse searches outside allowed directories.
50
75
  if (ctx.settings.safety?.path_guard !== 'off') {
51
76
  const allowlist = parseAllowlist(ctx.settings.safety?.path_allowlist ?? '');
@@ -53,8 +78,10 @@ export const globTool = createTool('Glob', 'Fast file pattern matching. Gitignor
53
78
  return { output: null, error: 'PathGuard: glob blocked — path is outside allowed directories' };
54
79
  }
55
80
  }
56
- // Read .gitignore from both cwd (global filters) and searchDir (local filters).
81
+ // Read .gitignore from cwd (global filters) and searchDir if different (local filters).
57
82
  const cwdGitignorePatterns = readGitignore(ctx.cwd);
83
+ const searchDirGitignorePatterns = searchDir !== ctx.cwd ? readGitignore(searchDir) : [];
84
+ const allIgnorePatterns = [...cwdGitignorePatterns, ...searchDirGitignorePatterns];
58
85
  const results = [];
59
86
  // Track visited real directories to prevent symlink cycle loops.
60
87
  const visitedDirs = new Set();
@@ -80,17 +107,18 @@ export const globTool = createTool('Glob', 'Fast file pattern matching. Gitignor
80
107
  }
81
108
  for (const entry of entries) {
82
109
  const fullPath = path.join(dir, entry.name);
83
- // Normalize to forward slashes so globToRegex patterns work on all platforms.
110
+ // relPath is cwd-relative (for gitignore filtering); patternPath is searchDir-relative (for matching).
84
111
  const relPath = path.relative(ctx.cwd, fullPath).replace(/\\/g, '/');
112
+ const patternPath = path.relative(searchDir, fullPath).replace(/\\/g, '/');
85
113
  if (entry.isDirectory()) {
86
- if (shouldIgnore(relPath, cwdGitignorePatterns))
114
+ if (shouldIgnore(relPath, allIgnorePatterns))
87
115
  continue;
88
116
  walk(fullPath, depth + 1);
89
117
  }
90
118
  else {
91
- if (shouldIgnore(relPath, cwdGitignorePatterns))
119
+ if (shouldIgnore(relPath, allIgnorePatterns))
92
120
  continue;
93
- if (minimatch(input.pattern, relPath)) {
121
+ if (minimatch(input.pattern, patternPath)) {
94
122
  results.push(fullPath);
95
123
  }
96
124
  }
@@ -1 +1 @@
1
- {"version":3,"file":"glob.js","sourceRoot":"","sources":["../../src/glob.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"glob.js","sourceRoot":"","sources":["../../src/glob.ts"],"names":[],"mappings":"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"}
@@ -4,9 +4,10 @@ export declare const grepTool: import("./tool.js").Tool & {
4
4
  path?: string | undefined;
5
5
  glob?: string | undefined;
6
6
  type?: string | undefined;
7
- '-i'?: boolean | undefined;
8
- '-n'?: boolean | undefined;
7
+ case_insensitive?: boolean | undefined;
8
+ line_numbers?: boolean | undefined;
9
9
  context?: number | undefined;
10
+ head_limit?: number | undefined;
10
11
  };
11
12
  };
12
13
  //# sourceMappingURL=grep.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../src/grep.ts"],"names":[],"mappings":"AA2BA,eAAO,MAAM,QAAQ;;;;;;;;;;CAkEpB,CAAC"}
1
+ {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../src/grep.ts"],"names":[],"mappings":"AAkFA,eAAO,MAAM,QAAQ;;;;;;;;;;;CAmLpB,CAAC"}
package/dist/src/grep.js CHANGED
@@ -2,28 +2,77 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { z } from 'zod';
4
4
  import { isPathAllowed, parseAllowlist } from '@curie-agent/core/safety/path-guard.js';
5
+ import { minimatch, readGitignore, shouldIgnore } from './glob.js';
5
6
  import { createTool, expandPath } from './tool.js';
6
- const GrepSchema = z.object({
7
- pattern: z.string().describe('The regular expression pattern to search for'),
8
- path: z.string().optional().describe('File or directory to search in'),
9
- glob: z.string().optional().describe('Glob pattern to filter files'),
10
- type: z.string().optional().describe('File type to search (js, py, ts, etc.)'),
11
- '-i': z.boolean().optional().describe('Case insensitive search'),
12
- '-n': z.boolean().optional().describe('Show line numbers'),
13
- context: z.number().optional().describe('Lines of context before and after'),
14
- });
15
7
  const EXT_MAP = {
16
- js: ['.js', '.jsx', '.mjs'],
17
- ts: ['.ts', '.tsx'],
8
+ js: ['.js', '.jsx', '.mjs', '.cjs'],
9
+ ts: ['.ts', '.tsx', '.mts', '.cts'],
18
10
  py: ['.py'],
19
11
  rust: ['.rs'],
12
+ rs: ['.rs'],
20
13
  go: ['.go'],
21
14
  java: ['.java'],
22
15
  rb: ['.rb'],
23
- rs: ['.rs'],
16
+ c: ['.c', '.h'],
17
+ cpp: ['.cpp', '.cc', '.cxx', '.hpp', '.hh'],
18
+ cs: ['.cs'],
19
+ php: ['.php'],
20
+ swift: ['.swift'],
21
+ kotlin: ['.kt', '.kts'],
22
+ scala: ['.scala'],
23
+ sh: ['.sh', '.bash'],
24
+ md: ['.md', '.markdown'],
25
+ json: ['.json', '.jsonc'],
26
+ yaml: ['.yml', '.yaml'],
27
+ html: ['.html', '.htm'],
28
+ css: ['.css', '.scss', '.less'],
29
+ sql: ['.sql'],
30
+ toml: ['.toml'],
31
+ xml: ['.xml'],
24
32
  };
25
- export const grepTool = createTool('Grep', 'Content search with regex support. Searches file contents for matching patterns.', GrepSchema, async (input, ctx) => {
26
- const searchPath = input.path ? path.resolve(ctx.cwd, expandPath(input.path)) : ctx.cwd;
33
+ const FILE_TYPES = Object.keys(EXT_MAP);
34
+ const MAX_FILE_SIZE = 1_000_000; // skip files larger than 1 MB
35
+ const MAX_LINE_LENGTH = 300;
36
+ const DEFAULT_HEAD_LIMIT = 250;
37
+ const GrepSchema = z.object({
38
+ pattern: z
39
+ .string()
40
+ .describe('The regular expression to search for (JavaScript RegExp syntax). ' +
41
+ 'Escape literal characters like ( ) [ ] { } . + * ? with a backslash.'),
42
+ path: z
43
+ .string()
44
+ .optional()
45
+ .describe('File or directory to search in. Defaults to the current working directory.'),
46
+ glob: z
47
+ .string()
48
+ .optional()
49
+ .describe('Glob pattern to filter which files are searched (e.g. "*.ts", "src/**/*.tsx"). ' +
50
+ 'Patterns without "/" match against the file name only.'),
51
+ type: z
52
+ .enum(FILE_TYPES)
53
+ .optional()
54
+ .describe(`File type to search, one of: ${FILE_TYPES.join(', ')}`),
55
+ case_insensitive: z.boolean().optional().describe('Case-insensitive search (default false)'),
56
+ line_numbers: z.boolean().optional().describe('Include 1-based line numbers in results (default true)'),
57
+ context: z.number().optional().describe('Number of lines to include before and after each match'),
58
+ head_limit: z
59
+ .number()
60
+ .optional()
61
+ .describe(`Maximum number of match rows to return (default ${String(DEFAULT_HEAD_LIMIT)})`),
62
+ });
63
+ function truncateLine(line) {
64
+ return line.length > MAX_LINE_LENGTH ? line.slice(0, MAX_LINE_LENGTH) + '…' : line;
65
+ }
66
+ export const grepTool = createTool('Grep', [
67
+ 'Searches file CONTENTS for a regular expression (use Glob to find files by NAME).',
68
+ 'Gitignore-aware: files ignored by .gitignore (plus node_modules/.git) are skipped,',
69
+ 'unless `path` points directly inside an ignored directory (e.g. deliberately searching dist/).',
70
+ 'Filter files with `glob` (e.g. "*.ts") or `type` (e.g. "ts"). `path` may be a directory or a single file.',
71
+ 'Results are grouped by file with cwd-relative forward-slash paths and 1-based line numbers,',
72
+ 'capped at `head_limit` rows (default 250) with an explicit truncation notice — narrow the search when you see one.',
73
+ ].join(' '), GrepSchema, async (input, ctx) => {
74
+ const rawPath = input.path ? input.path.replace(/\\/g, '/') : undefined;
75
+ const searchPath = rawPath ? path.resolve(ctx.cwd, expandPath(rawPath)) : ctx.cwd;
27
76
  // Safety: refuse searches outside allowed directories.
28
77
  if (ctx.settings.safety?.path_guard !== 'off') {
29
78
  const allowlist = parseAllowlist(ctx.settings.safety?.path_allowlist ?? '');
@@ -31,12 +80,113 @@ export const grepTool = createTool('Grep', 'Content search with regex support. S
31
80
  return { output: null, error: 'PathGuard: grep blocked — path is outside allowed directories' };
32
81
  }
33
82
  }
34
- const regexFlags = input['-i'] ? 'gi' : 'g';
35
- const pattern = input.pattern ?? '';
36
- const regex = new RegExp(pattern, regexFlags);
37
- const allowedExts = input.type ? EXT_MAP[input.type] : null;
38
- const results = [];
39
- function walk(dir) {
83
+ let regex;
84
+ try {
85
+ regex = new RegExp(input.pattern, input.case_insensitive ? 'i' : '');
86
+ }
87
+ catch (err) {
88
+ const msg = err instanceof Error ? err.message : String(err);
89
+ return {
90
+ output: null,
91
+ error: `Invalid regular expression "${input.pattern}": ${msg}. ` +
92
+ 'Escape literal characters like ( ) [ ] { } . + * ? with a backslash.',
93
+ };
94
+ }
95
+ let stat;
96
+ try {
97
+ stat = fs.statSync(searchPath);
98
+ }
99
+ catch {
100
+ return { output: null, error: `Path not found: ${searchPath}` };
101
+ }
102
+ const searchDir = stat.isDirectory() ? searchPath : path.dirname(searchPath);
103
+ const searchRel = path.relative(ctx.cwd, searchPath).replace(/\\/g, '/');
104
+ const insideCwd = searchRel === '' || (!searchRel.startsWith('..') && !path.isAbsolute(searchRel));
105
+ // Gitignore filtering: cwd patterns plus local patterns from the search dir.
106
+ // When the caller explicitly targets a path that is itself gitignored
107
+ // (e.g. grepping dist/ on purpose), respect that intent and skip filtering.
108
+ const cwdPatterns = insideCwd ? readGitignore(ctx.cwd) : [];
109
+ const localPatterns = searchDir !== ctx.cwd ? readGitignore(searchDir) : [];
110
+ // Check both "dist" and "dist/" forms so a directory target matches "dist/" patterns.
111
+ const explicitlyIgnored = searchRel !== '' &&
112
+ insideCwd &&
113
+ (shouldIgnore(searchRel, cwdPatterns) || shouldIgnore(searchRel + '/', cwdPatterns));
114
+ const ignoreBase = insideCwd ? ctx.cwd : searchDir;
115
+ const ignorePatterns = explicitlyIgnored ? [] : insideCwd ? [...cwdPatterns, ...localPatterns] : localPatterns;
116
+ const allowedExts = input.type ? EXT_MAP[input.type] : undefined;
117
+ const globPattern = input.glob;
118
+ const headLimit = input.head_limit ?? DEFAULT_HEAD_LIMIT;
119
+ const includeLineNumbers = input.line_numbers !== false;
120
+ const contextLines = input.context ?? 0;
121
+ const files = [];
122
+ let totalMatches = 0;
123
+ let emitted = 0;
124
+ function toRelative(fullPath) {
125
+ const rel = path.relative(ctx.cwd, fullPath).replace(/\\/g, '/');
126
+ return rel === '' || rel.startsWith('..') ? fullPath.replace(/\\/g, '/') : rel;
127
+ }
128
+ function matchesGlob(fullPath) {
129
+ if (!globPattern)
130
+ return true;
131
+ if (globPattern.includes('/')) {
132
+ const rel = path.relative(searchDir, fullPath).replace(/\\/g, '/');
133
+ return minimatch(globPattern, rel);
134
+ }
135
+ return minimatch(globPattern, path.basename(fullPath));
136
+ }
137
+ function scanFile(fullPath) {
138
+ let content;
139
+ try {
140
+ const fileStat = fs.statSync(fullPath);
141
+ if (fileStat.size > MAX_FILE_SIZE)
142
+ return;
143
+ const buf = fs.readFileSync(fullPath);
144
+ if (buf.subarray(0, 8192).includes(0))
145
+ return; // binary file
146
+ content = buf.toString('utf-8');
147
+ }
148
+ catch {
149
+ return; // unreadable file
150
+ }
151
+ const lines = content.split('\n');
152
+ let group;
153
+ for (let i = 0; i < lines.length; i++) {
154
+ const line = lines[i];
155
+ if (line === undefined || line === '' || !regex.test(line))
156
+ continue;
157
+ totalMatches++;
158
+ if (emitted >= headLimit)
159
+ continue; // keep counting, stop emitting
160
+ if (!group) {
161
+ group = { file: toRelative(fullPath), matches: [] };
162
+ files.push(group);
163
+ }
164
+ const row = { text: truncateLine(line) };
165
+ if (includeLineNumbers)
166
+ row.line = i + 1;
167
+ if (contextLines > 0) {
168
+ row.before = lines.slice(Math.max(0, i - contextLines), i).map(truncateLine);
169
+ row.after = lines.slice(i + 1, i + 1 + contextLines).map(truncateLine);
170
+ }
171
+ group.matches.push(row);
172
+ emitted++;
173
+ }
174
+ }
175
+ // Track visited real directories to prevent symlink cycle loops.
176
+ const visitedDirs = new Set();
177
+ function walk(dir, depth) {
178
+ if (depth > 100)
179
+ return; // Safety limit
180
+ let realDir;
181
+ try {
182
+ realDir = fs.realpathSync(dir);
183
+ }
184
+ catch {
185
+ return;
186
+ }
187
+ if (visitedDirs.has(realDir))
188
+ return;
189
+ visitedDirs.add(realDir);
40
190
  let entries;
41
191
  try {
42
192
  entries = fs.readdirSync(dir, { withFileTypes: true });
@@ -46,41 +196,47 @@ export const grepTool = createTool('Grep', 'Content search with regex support. S
46
196
  }
47
197
  for (const entry of entries) {
48
198
  const fullPath = path.join(dir, entry.name);
199
+ const relPath = path.relative(ignoreBase, fullPath).replace(/\\/g, '/');
49
200
  if (entry.isDirectory()) {
50
201
  if (entry.name === 'node_modules' || entry.name === '.git')
51
202
  continue;
52
- walk(fullPath);
203
+ if (shouldIgnore(relPath, ignorePatterns))
204
+ continue;
205
+ walk(fullPath, depth + 1);
53
206
  }
54
207
  else if (entry.isFile()) {
55
- if (allowedExts) {
56
- const ext = path.extname(entry.name).toLowerCase();
57
- if (!allowedExts.includes(ext))
58
- continue;
59
- }
60
- try {
61
- const content = fs.readFileSync(fullPath, 'utf-8');
62
- const lines = content.split('\n');
63
- for (let i = 0; i < lines.length; i++) {
64
- regex.lastIndex = 0;
65
- const line = lines[i];
66
- if (line && regex.test(line)) {
67
- results.push({ file: fullPath, line: i + 1, text: line });
68
- }
69
- }
70
- }
71
- catch {
72
- // skip binary files
73
- }
208
+ if (shouldIgnore(relPath, ignorePatterns))
209
+ continue;
210
+ if (allowedExts && !allowedExts.includes(path.extname(entry.name).toLowerCase()))
211
+ continue;
212
+ if (!matchesGlob(fullPath))
213
+ continue;
214
+ scanFile(fullPath);
74
215
  }
75
216
  }
76
217
  }
77
- walk(searchPath);
78
- return {
79
- output: {
80
- pattern: input.pattern,
81
- matches: results.length,
82
- results: results.slice(0, 250),
83
- },
218
+ if (stat.isFile()) {
219
+ scanFile(searchPath);
220
+ }
221
+ else {
222
+ walk(searchPath, 0);
223
+ }
224
+ const output = {
225
+ pattern: input.pattern,
226
+ total_matches: totalMatches,
227
+ files,
84
228
  };
229
+ if (totalMatches > emitted) {
230
+ output.truncated =
231
+ `Showing first ${String(emitted)} of ${String(totalMatches)} matches. ` +
232
+ 'Narrow the search with glob, path, type, or a more specific pattern, or raise head_limit.';
233
+ }
234
+ return { output };
235
+ }, undefined, {
236
+ aliases: {
237
+ '-i': 'case_insensitive',
238
+ '-n': 'line_numbers',
239
+ regex: 'pattern',
240
+ },
85
241
  });
86
242
  //# sourceMappingURL=grep.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../src/grep.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../src/grep.ts"],"names":[],"mappings":"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"}