@zaly/agent 0.0.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/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/agent-BaD2kax9.mjs +68 -0
- package/dist/agent-BaD2kax9.mjs.map +1 -0
- package/dist/agent-GDLdDc2w.mjs +902 -0
- package/dist/agent-GDLdDc2w.mjs.map +1 -0
- package/dist/bash-QNMTQ1PD.mjs +142 -0
- package/dist/bash-QNMTQ1PD.mjs.map +1 -0
- package/dist/compactions-3AjPqjeZ.mjs +190 -0
- package/dist/compactions-3AjPqjeZ.mjs.map +1 -0
- package/dist/edit-Qxl4w1C2.mjs +170 -0
- package/dist/edit-Qxl4w1C2.mjs.map +1 -0
- package/dist/env-UUFv5Mye.mjs +30 -0
- package/dist/env-UUFv5Mye.mjs.map +1 -0
- package/dist/fetch-D8cmmA3E.mjs +111 -0
- package/dist/fetch-D8cmmA3E.mjs.map +1 -0
- package/dist/find-Bah9SKWX.mjs +87 -0
- package/dist/find-Bah9SKWX.mjs.map +1 -0
- package/dist/grep-B2Ax7ewy.mjs +244 -0
- package/dist/grep-B2Ax7ewy.mjs.map +1 -0
- package/dist/index-node-esm-D6YQRKEz.mjs +1537 -0
- package/dist/index-node-esm-D6YQRKEz.mjs.map +1 -0
- package/dist/index.d.mts +1605 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +948 -0
- package/dist/index.mjs.map +1 -0
- package/dist/jsonl-Dw_VBp46.mjs +134 -0
- package/dist/jsonl-Dw_VBp46.mjs.map +1 -0
- package/dist/manager-D-lWBTHG.mjs +271 -0
- package/dist/manager-D-lWBTHG.mjs.map +1 -0
- package/dist/markdown-Bv4J8cg3.mjs +53 -0
- package/dist/markdown-Bv4J8cg3.mjs.map +1 -0
- package/dist/masker-Bv9KjkDF.mjs +396 -0
- package/dist/masker-Bv9KjkDF.mjs.map +1 -0
- package/dist/model-_3ZA2xqm.mjs +27 -0
- package/dist/model-_3ZA2xqm.mjs.map +1 -0
- package/dist/notify-DpG_m9iP.mjs +96 -0
- package/dist/notify-DpG_m9iP.mjs.map +1 -0
- package/dist/read-Djsx2NZl.mjs +205 -0
- package/dist/read-Djsx2NZl.mjs.map +1 -0
- package/dist/registry-CFmR5G3J.mjs +564 -0
- package/dist/registry-CFmR5G3J.mjs.map +1 -0
- package/dist/search-CRw247ES.mjs +121 -0
- package/dist/search-CRw247ES.mjs.map +1 -0
- package/dist/session/claude.d.mts +59 -0
- package/dist/session/claude.d.mts.map +1 -0
- package/dist/session/claude.mjs +455 -0
- package/dist/session/claude.mjs.map +1 -0
- package/dist/session-CUUdWFC5.mjs +450 -0
- package/dist/session-CUUdWFC5.mjs.map +1 -0
- package/dist/session-Ds5nJz5A.d.mts +346 -0
- package/dist/session-Ds5nJz5A.d.mts.map +1 -0
- package/dist/session.d.mts +37 -0
- package/dist/session.d.mts.map +1 -0
- package/dist/session.mjs +106 -0
- package/dist/session.mjs.map +1 -0
- package/dist/subagent-baqzjRMc.mjs +136 -0
- package/dist/subagent-baqzjRMc.mjs.map +1 -0
- package/dist/swarm-BJ3gQA1Z.mjs +194 -0
- package/dist/swarm-BJ3gQA1Z.mjs.map +1 -0
- package/dist/swarm-BuFx_xeY.mjs +109 -0
- package/dist/swarm-BuFx_xeY.mjs.map +1 -0
- package/dist/tasks-D8rARHZ1.mjs +65 -0
- package/dist/tasks-D8rARHZ1.mjs.map +1 -0
- package/dist/tasks-WmC270X2.mjs +615 -0
- package/dist/tasks-WmC270X2.mjs.map +1 -0
- package/dist/tools-DW1dbcCz.mjs +695 -0
- package/dist/tools-DW1dbcCz.mjs.map +1 -0
- package/dist/truncate-BSMXgiXj.mjs +102 -0
- package/dist/truncate-BSMXgiXj.mjs.map +1 -0
- package/dist/uuid-ByXP5SO5.mjs +59 -0
- package/dist/uuid-ByXP5SO5.mjs.map +1 -0
- package/dist/wakeup-BYqTnfSp.mjs +29 -0
- package/dist/wakeup-BYqTnfSp.mjs.map +1 -0
- package/dist/write-D3L-92vj.mjs +89 -0
- package/dist/write-D3L-92vj.mjs.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { t as truncate } from "./truncate-BSMXgiXj.mjs";
|
|
2
|
+
import { normPath } from "@zaly/shared";
|
|
3
|
+
import { AiError, defineTool } from "@zaly/ai";
|
|
4
|
+
import { Type } from "typebox";
|
|
5
|
+
import { Spawn, TextStream, which } from "@zaly/shared/process";
|
|
6
|
+
import { cleanTextTui } from "@zaly/shared/text";
|
|
7
|
+
import { defaultExcludes } from "@zaly/shared/find";
|
|
8
|
+
//#region src/tools/grep.ts
|
|
9
|
+
const MAX_BUFFER = 512 * 1024;
|
|
10
|
+
const DEFAULT_LIMIT = 100;
|
|
11
|
+
const MAX_LIMIT = 1e3;
|
|
12
|
+
const MAX_COLUMNS = 200;
|
|
13
|
+
const grepTool = defineTool({
|
|
14
|
+
name: "grep",
|
|
15
|
+
desc: "Search file contents using rg/grep. Respects .gitignore by default when ripgrep is available; prefer this over bash grep/find for code search. Returns human-readable grouped matches with line numbers.",
|
|
16
|
+
parallel: true,
|
|
17
|
+
params: Type.Object({
|
|
18
|
+
pattern: Type.String({
|
|
19
|
+
description: "Text or regex pattern to search for.",
|
|
20
|
+
minLength: 1
|
|
21
|
+
}),
|
|
22
|
+
cwd: Type.Optional(Type.String({ description: "Directory to search from. Defaults to cwd." })),
|
|
23
|
+
paths: Type.Optional(Type.Array(Type.String(), { description: "Optional files/directories to search, relative to cwd or absolute." })),
|
|
24
|
+
glob: Type.Optional(Type.Array(Type.String(), { description: "Ripgrep glob filters, e.g. [`*.ts`, `!dist/**`]." })),
|
|
25
|
+
exclude: Type.Optional(Type.Array(Type.String(), { description: "Patterns to exclude, e.g. [`node_modules`, `dist/**`]." })),
|
|
26
|
+
file_type: Type.Optional(Type.Array(Type.String(), { description: "Ripgrep file types (`-t`), e.g. [`ts`, `rust`, `markdown`]." })),
|
|
27
|
+
fixed_strings: Type.Optional(Type.Boolean({
|
|
28
|
+
default: false,
|
|
29
|
+
description: "Treat all patterns as literals instead of as regular expressions"
|
|
30
|
+
})),
|
|
31
|
+
case_sensitive: Type.Optional(Type.Boolean({
|
|
32
|
+
default: false,
|
|
33
|
+
description: "Case sensitive search. Default false is smart case (case-insensitive if pattern is lowercase)."
|
|
34
|
+
})),
|
|
35
|
+
hidden: Type.Optional(Type.Boolean({
|
|
36
|
+
default: false,
|
|
37
|
+
description: "Search hidden files/directories."
|
|
38
|
+
})),
|
|
39
|
+
ignore: Type.Optional(Type.Boolean({
|
|
40
|
+
default: true,
|
|
41
|
+
description: "Respect .gitignore/.ignore rules."
|
|
42
|
+
})),
|
|
43
|
+
follow: Type.Optional(Type.Boolean({
|
|
44
|
+
default: false,
|
|
45
|
+
description: "Follow symlinks."
|
|
46
|
+
})),
|
|
47
|
+
context: Type.Optional(Type.Integer({
|
|
48
|
+
default: 0,
|
|
49
|
+
description: "Context lines before/after each match. 0-5.",
|
|
50
|
+
maximum: 10,
|
|
51
|
+
minimum: 0
|
|
52
|
+
})),
|
|
53
|
+
limit: Type.Optional(Type.Integer({
|
|
54
|
+
default: DEFAULT_LIMIT,
|
|
55
|
+
description: "Maximum matched lines to keep inline.",
|
|
56
|
+
maximum: MAX_LIMIT,
|
|
57
|
+
minimum: 1
|
|
58
|
+
}))
|
|
59
|
+
}),
|
|
60
|
+
async preflight(args, ctx) {
|
|
61
|
+
const cwd = normPath(ctx.cwd, args.cwd ?? ".");
|
|
62
|
+
await ctx.need?.("read", cwd);
|
|
63
|
+
const paths = (args.paths?.length ? args.paths : ["."]).map((p) => normPath(cwd, p));
|
|
64
|
+
await Promise.all(paths.map((path) => Promise.resolve(ctx.need?.("read", path))));
|
|
65
|
+
},
|
|
66
|
+
async call(args, ctx) {
|
|
67
|
+
const command = resolveGrep();
|
|
68
|
+
if (!command) throw new AiError({
|
|
69
|
+
code: "MISSING_TOOL",
|
|
70
|
+
message: "grep requires rg or grep"
|
|
71
|
+
});
|
|
72
|
+
const cwd = normPath(ctx.cwd, args.cwd ?? ".");
|
|
73
|
+
const paths = args.paths?.length ? args.paths : [];
|
|
74
|
+
const cmdArgs = buildArgs(command.kind, args, paths);
|
|
75
|
+
const result = await new Spawn(command.cmd, cmdArgs, {
|
|
76
|
+
cwd,
|
|
77
|
+
maxBuffer: MAX_BUFFER,
|
|
78
|
+
signal: ctx.signal,
|
|
79
|
+
stderr: new TextStream(),
|
|
80
|
+
stdout: new TextStream(),
|
|
81
|
+
timeout: 6e4
|
|
82
|
+
}).result.catch((error) => {
|
|
83
|
+
throw new AiError({
|
|
84
|
+
cause: error,
|
|
85
|
+
code: "GREP_FAILED",
|
|
86
|
+
message: String(error)
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
if (result.code > 1 && result.killReason !== "maxBuffer") throw new AiError({
|
|
90
|
+
code: "GREP_FAILED",
|
|
91
|
+
data: {
|
|
92
|
+
code: result.code,
|
|
93
|
+
stderr: result.stderr
|
|
94
|
+
},
|
|
95
|
+
message: `${command.cmd} failed (${result.code}): ${result.stderr.slice(0, 500)}`
|
|
96
|
+
});
|
|
97
|
+
const text = cleanTextTui(result.stdout);
|
|
98
|
+
const limit = args.limit ?? DEFAULT_LIMIT;
|
|
99
|
+
const summary = truncate(text, {
|
|
100
|
+
maxLineChars: command.kind === "rg" ? 500 : MAX_COLUMNS,
|
|
101
|
+
maxLines: limit + 1,
|
|
102
|
+
strategy: "head"
|
|
103
|
+
});
|
|
104
|
+
const truncated = summary.truncated || result.killReason === "maxBuffer";
|
|
105
|
+
ctx.meta = {
|
|
106
|
+
cmd: [command.cmd, ...cmdArgs],
|
|
107
|
+
cwd,
|
|
108
|
+
pattern: args.pattern,
|
|
109
|
+
truncated
|
|
110
|
+
};
|
|
111
|
+
const parts = [];
|
|
112
|
+
const stderr = result.stderr.trim();
|
|
113
|
+
if (stderr || result.killReason) {
|
|
114
|
+
const meta = {
|
|
115
|
+
command: command.cmd,
|
|
116
|
+
cwd,
|
|
117
|
+
truncated
|
|
118
|
+
};
|
|
119
|
+
if (result.killReason) meta.killReason = result.killReason;
|
|
120
|
+
if (stderr) meta.stderr = stderr.slice(0, 500);
|
|
121
|
+
parts.push({
|
|
122
|
+
data: meta,
|
|
123
|
+
tag: "grep",
|
|
124
|
+
type: "meta"
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
parts.push({
|
|
128
|
+
text: summary.text || "No matches found.",
|
|
129
|
+
type: "text"
|
|
130
|
+
});
|
|
131
|
+
return parts;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
const FILE_TYPE_EXTENSIONS = {
|
|
135
|
+
c: ["c", "h"],
|
|
136
|
+
cpp: [
|
|
137
|
+
"cpp",
|
|
138
|
+
"cc",
|
|
139
|
+
"cxx",
|
|
140
|
+
"hpp",
|
|
141
|
+
"hh",
|
|
142
|
+
"hxx"
|
|
143
|
+
],
|
|
144
|
+
go: ["go"],
|
|
145
|
+
java: ["java"],
|
|
146
|
+
js: [
|
|
147
|
+
"js",
|
|
148
|
+
"jsx",
|
|
149
|
+
"mjs",
|
|
150
|
+
"cjs"
|
|
151
|
+
],
|
|
152
|
+
json: ["json"],
|
|
153
|
+
lua: ["lua"],
|
|
154
|
+
markdown: ["md", "markdown"],
|
|
155
|
+
md: ["md", "markdown"],
|
|
156
|
+
py: ["py"],
|
|
157
|
+
python: ["py"],
|
|
158
|
+
rs: ["rs"],
|
|
159
|
+
rust: ["rs"],
|
|
160
|
+
toml: ["toml"],
|
|
161
|
+
ts: [
|
|
162
|
+
"ts",
|
|
163
|
+
"tsx",
|
|
164
|
+
"mts",
|
|
165
|
+
"cts"
|
|
166
|
+
],
|
|
167
|
+
yaml: ["yml", "yaml"]
|
|
168
|
+
};
|
|
169
|
+
function fileTypeExtensions(type) {
|
|
170
|
+
return FILE_TYPE_EXTENSIONS[type] ?? [type];
|
|
171
|
+
}
|
|
172
|
+
function fileTypeGlobs(type) {
|
|
173
|
+
return fileTypeExtensions(type).map((e) => `*.${e}`);
|
|
174
|
+
}
|
|
175
|
+
function resolveGrep() {
|
|
176
|
+
const rg = which("rg");
|
|
177
|
+
if (rg) return {
|
|
178
|
+
cmd: rg,
|
|
179
|
+
kind: "rg"
|
|
180
|
+
};
|
|
181
|
+
const grep = which("grep");
|
|
182
|
+
return grep ? {
|
|
183
|
+
cmd: grep,
|
|
184
|
+
kind: "grep"
|
|
185
|
+
} : void 0;
|
|
186
|
+
}
|
|
187
|
+
function buildArgs(kind, args, paths) {
|
|
188
|
+
return kind === "rg" ? buildRgArgs(args, paths) : buildGrepArgs(args, paths);
|
|
189
|
+
}
|
|
190
|
+
function buildRgArgs(args, paths) {
|
|
191
|
+
const ret = [
|
|
192
|
+
"--color=always",
|
|
193
|
+
"--heading",
|
|
194
|
+
"--with-filename",
|
|
195
|
+
"--line-number",
|
|
196
|
+
`--max-columns=${MAX_COLUMNS}`,
|
|
197
|
+
"--max-columns-preview",
|
|
198
|
+
"--path-separator=/"
|
|
199
|
+
];
|
|
200
|
+
if (args.fixed_strings) ret.push("--fixed-strings");
|
|
201
|
+
if (args.case_sensitive) ret.push("--case-sensitive");
|
|
202
|
+
else ret.push("--smart-case");
|
|
203
|
+
if (args.hidden) ret.push("--hidden");
|
|
204
|
+
else ret.push("--no-hidden");
|
|
205
|
+
if (!args.ignore) ret.push("--no-ignore");
|
|
206
|
+
if (args.follow) ret.push("--follow");
|
|
207
|
+
const context = args.context ?? 0;
|
|
208
|
+
if (context > 0) ret.push(`--context=${context}`);
|
|
209
|
+
for (const e of [...defaultExcludes(paths), ...args.exclude ?? []]) ret.push("--glob", `!${e}`);
|
|
210
|
+
for (const g of args.glob ?? []) ret.push("--glob", g);
|
|
211
|
+
for (const t of args.file_type ?? []) ret.push("--type", t);
|
|
212
|
+
ret.push("--", args.pattern, ...paths);
|
|
213
|
+
return ret;
|
|
214
|
+
}
|
|
215
|
+
function buildGrepArgs(args, paths) {
|
|
216
|
+
const ret = [
|
|
217
|
+
"--recursive",
|
|
218
|
+
"--line-number",
|
|
219
|
+
"--with-filename",
|
|
220
|
+
"--binary-files=without-match",
|
|
221
|
+
"--color=always"
|
|
222
|
+
];
|
|
223
|
+
if (args.fixed_strings) ret.push("--fixed-strings");
|
|
224
|
+
else ret.push("--extended-regexp");
|
|
225
|
+
const hasUpper = /[A-Z]/.test(args.pattern);
|
|
226
|
+
if (!args.case_sensitive && !hasUpper) ret.push("--ignore-case");
|
|
227
|
+
const context = args.context ?? 0;
|
|
228
|
+
if (context > 0) ret.push("--context", String(context));
|
|
229
|
+
for (const e of [...defaultExcludes(paths), ...args.exclude ?? []]) ret.push("--exclude-dir", e);
|
|
230
|
+
for (const t of args.file_type ?? []) for (const g of fileTypeGlobs(t)) ret.push("--include", g);
|
|
231
|
+
for (const g of args.glob ?? []) ret.push(...grepGlobArgs(g));
|
|
232
|
+
ret.push("--", args.pattern, ...paths);
|
|
233
|
+
return ret;
|
|
234
|
+
}
|
|
235
|
+
function grepGlobArgs(glob) {
|
|
236
|
+
if (!glob.startsWith("!")) return ["--include", glob];
|
|
237
|
+
const exclude = glob.slice(1);
|
|
238
|
+
if (exclude.endsWith("/**") && !exclude.slice(0, -3).includes("*")) return ["--exclude-dir", exclude.slice(0, -3)];
|
|
239
|
+
return ["--exclude", exclude];
|
|
240
|
+
}
|
|
241
|
+
//#endregion
|
|
242
|
+
export { grepTool };
|
|
243
|
+
|
|
244
|
+
//# sourceMappingURL=grep-B2Ax7ewy.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grep-B2Ax7ewy.mjs","names":[],"sources":["../src/tools/grep.ts"],"sourcesContent":["import type { MetaPart, TextPart, ToolContext } from \"@zaly/ai\"\n\nimport { AiError, defineTool } from \"@zaly/ai\"\nimport { normPath } from \"@zaly/shared\"\nimport { defaultExcludes } from \"@zaly/shared/find\"\nimport { Spawn, TextStream, which } from \"@zaly/shared/process\"\nimport { cleanTextTui } from \"@zaly/shared/text\"\nimport { Type } from \"typebox\"\nimport { truncate } from \"../utils/truncate.ts\"\n\nconst MAX_BUFFER = 512 * 1024\nconst DEFAULT_LIMIT = 100\nconst MAX_LIMIT = 1000\nconst MAX_COLUMNS = 200\n\nexport type GrepTool = typeof grepTool\nexport type GrepToolMeta = {\n cwd: string\n pattern: string\n truncated: boolean\n cmd: string[]\n}\n\n// oxlint-disable-next-line sort-keys -- semantic field order: name, desc, params, call\nexport const grepTool = defineTool({\n name: \"grep\",\n desc:\n `Search file contents using rg/grep. Respects .gitignore by default when ripgrep is available; ` +\n \"prefer this over bash grep/find for code search. Returns human-readable grouped matches with line numbers.\",\n parallel: true,\n // oxlint-disable-next-line sort-keys -- semantic param order\n params: Type.Object({\n pattern: Type.String({ description: \"Text or regex pattern to search for.\", minLength: 1 }),\n cwd: Type.Optional(Type.String({ description: \"Directory to search from. Defaults to cwd.\" })),\n paths: Type.Optional(\n Type.Array(Type.String(), {\n description: \"Optional files/directories to search, relative to cwd or absolute.\",\n })\n ),\n glob: Type.Optional(\n Type.Array(Type.String(), {\n description: \"Ripgrep glob filters, e.g. [`*.ts`, `!dist/**`].\",\n })\n ),\n exclude: Type.Optional(\n Type.Array(Type.String(), {\n description: \"Patterns to exclude, e.g. [`node_modules`, `dist/**`].\",\n })\n ),\n file_type: Type.Optional(\n Type.Array(Type.String(), {\n description: \"Ripgrep file types (`-t`), e.g. [`ts`, `rust`, `markdown`].\",\n })\n ),\n fixed_strings: Type.Optional(\n Type.Boolean({\n default: false,\n description: \"Treat all patterns as literals instead of as regular expressions\",\n })\n ),\n case_sensitive: Type.Optional(\n Type.Boolean({\n default: false,\n description:\n \"Case sensitive search. Default false is smart case (case-insensitive if pattern is lowercase).\",\n })\n ),\n hidden: Type.Optional(\n Type.Boolean({ default: false, description: \"Search hidden files/directories.\" })\n ),\n ignore: Type.Optional(\n Type.Boolean({ default: true, description: \"Respect .gitignore/.ignore rules.\" })\n ),\n follow: Type.Optional(Type.Boolean({ default: false, description: \"Follow symlinks.\" })),\n context: Type.Optional(\n Type.Integer({\n default: 0,\n description: \"Context lines before/after each match. 0-5.\",\n maximum: 10,\n minimum: 0,\n })\n ),\n limit: Type.Optional(\n Type.Integer({\n default: DEFAULT_LIMIT,\n description: \"Maximum matched lines to keep inline.\",\n maximum: MAX_LIMIT,\n minimum: 1,\n })\n ),\n }),\n\n async preflight(args, ctx: ToolContext<GrepToolMeta>) {\n const cwd = normPath(ctx.cwd, args.cwd ?? \".\")\n await ctx.need?.(\"read\", cwd)\n\n const paths = (args.paths?.length ? args.paths : [\".\"]).map((p) => normPath(cwd, p))\n await Promise.all(paths.map((path) => Promise.resolve(ctx.need?.(\"read\", path))))\n },\n\n async call(args, ctx: ToolContext<GrepToolMeta>): Promise<(MetaPart | TextPart)[]> {\n const command = resolveGrep()\n if (!command) throw new AiError({ code: \"MISSING_TOOL\", message: \"grep requires rg or grep\" })\n\n const cwd = normPath(ctx.cwd, args.cwd ?? \".\")\n const paths = args.paths?.length ? args.paths : []\n\n const cmdArgs = buildArgs(command.kind, args, paths)\n const proc = new Spawn(command.cmd, cmdArgs, {\n cwd,\n maxBuffer: MAX_BUFFER,\n signal: ctx.signal,\n stderr: new TextStream(),\n stdout: new TextStream(),\n timeout: 60_000,\n })\n const result = await proc.result.catch((error: unknown) => {\n throw new AiError({ cause: error, code: \"GREP_FAILED\", message: String(error) })\n })\n\n // rg/grep: 0 matches found, 1 no matches, >1 error.\n if (result.code > 1 && result.killReason !== \"maxBuffer\") {\n throw new AiError({\n code: \"GREP_FAILED\",\n data: { code: result.code, stderr: result.stderr },\n message: `${command.cmd} failed (${result.code}): ${result.stderr.slice(0, 500)}`,\n })\n }\n\n const text = cleanTextTui(result.stdout)\n const limit = args.limit ?? DEFAULT_LIMIT\n const summary = truncate(text, {\n maxLineChars: command.kind === \"rg\" ? 500 : MAX_COLUMNS,\n maxLines: limit + 1,\n strategy: \"head\",\n })\n\n const truncated = summary.truncated || result.killReason === \"maxBuffer\"\n ctx.meta = {\n cmd: [command.cmd, ...cmdArgs],\n cwd,\n pattern: args.pattern,\n truncated,\n }\n\n const parts: (MetaPart | TextPart)[] = []\n\n const stderr = result.stderr.trim()\n if (stderr || result.killReason) {\n const meta: Record<string, unknown> = {\n command: command.cmd,\n cwd,\n truncated,\n }\n if (result.killReason) meta.killReason = result.killReason\n if (stderr) meta.stderr = stderr.slice(0, 500)\n parts.push({ data: meta, tag: \"grep\", type: \"meta\" })\n }\n parts.push({ text: summary.text || \"No matches found.\", type: \"text\" })\n return parts\n },\n})\n\ntype GrepArgs = Parameters<GrepTool[\"call\"]>[0]\ntype GrepBackend = { cmd: string; kind: \"rg\" | \"grep\" }\n\nconst FILE_TYPE_EXTENSIONS: Record<string, string[]> = {\n c: [\"c\", \"h\"],\n cpp: [\"cpp\", \"cc\", \"cxx\", \"hpp\", \"hh\", \"hxx\"],\n go: [\"go\"],\n java: [\"java\"],\n js: [\"js\", \"jsx\", \"mjs\", \"cjs\"],\n json: [\"json\"],\n lua: [\"lua\"],\n markdown: [\"md\", \"markdown\"],\n md: [\"md\", \"markdown\"],\n py: [\"py\"],\n python: [\"py\"],\n rs: [\"rs\"],\n rust: [\"rs\"],\n toml: [\"toml\"],\n ts: [\"ts\", \"tsx\", \"mts\", \"cts\"],\n yaml: [\"yml\", \"yaml\"],\n}\n\nfunction fileTypeExtensions(type: string): string[] {\n return FILE_TYPE_EXTENSIONS[type] ?? [type]\n}\n\nfunction fileTypeGlobs(type: string): string[] {\n return fileTypeExtensions(type).map((e) => `*.${e}`)\n}\n\nfunction resolveGrep(): GrepBackend | undefined {\n const rg = which(\"rg\")\n if (rg) return { cmd: rg, kind: \"rg\" }\n const grep = which(\"grep\")\n return grep ? { cmd: grep, kind: \"grep\" } : undefined\n}\n\nfunction buildArgs(kind: GrepBackend[\"kind\"], args: GrepArgs, paths: string[]): string[] {\n return kind === \"rg\" ? buildRgArgs(args, paths) : buildGrepArgs(args, paths)\n}\n\nfunction buildRgArgs(args: GrepArgs, paths: string[]): string[] {\n const ret = [\n \"--color=always\",\n \"--heading\",\n \"--with-filename\",\n \"--line-number\",\n `--max-columns=${MAX_COLUMNS}`,\n \"--max-columns-preview\",\n \"--path-separator=/\",\n ]\n\n if (args.fixed_strings) ret.push(\"--fixed-strings\")\n if (args.case_sensitive) ret.push(\"--case-sensitive\")\n else ret.push(\"--smart-case\")\n if (args.hidden) ret.push(\"--hidden\")\n else ret.push(\"--no-hidden\")\n if (!args.ignore) ret.push(\"--no-ignore\")\n if (args.follow) ret.push(\"--follow\")\n const context = args.context ?? 0\n if (context > 0) ret.push(`--context=${context}`)\n\n for (const e of [...defaultExcludes(paths), ...(args.exclude ?? [])]) ret.push(\"--glob\", `!${e}`)\n for (const g of args.glob ?? []) ret.push(\"--glob\", g)\n for (const t of args.file_type ?? []) ret.push(\"--type\", t)\n\n ret.push(\"--\", args.pattern, ...paths)\n return ret\n}\n\nfunction buildGrepArgs(args: GrepArgs, paths: string[]): string[] {\n const ret = [\n \"--recursive\",\n \"--line-number\",\n \"--with-filename\",\n \"--binary-files=without-match\",\n \"--color=always\",\n ]\n if (args.fixed_strings) ret.push(\"--fixed-strings\")\n else ret.push(\"--extended-regexp\")\n const hasUpper = /[A-Z]/.test(args.pattern)\n if (!args.case_sensitive && !hasUpper) ret.push(\"--ignore-case\")\n const context = args.context ?? 0\n if (context > 0) ret.push(\"--context\", String(context))\n for (const e of [...defaultExcludes(paths), ...(args.exclude ?? [])]) ret.push(\"--exclude-dir\", e)\n for (const t of args.file_type ?? []) {\n for (const g of fileTypeGlobs(t)) ret.push(\"--include\", g)\n }\n for (const g of args.glob ?? []) ret.push(...grepGlobArgs(g))\n ret.push(\"--\", args.pattern, ...paths)\n return ret\n}\n\nfunction grepGlobArgs(glob: string): string[] {\n if (!glob.startsWith(\"!\")) return [\"--include\", glob]\n const exclude = glob.slice(1)\n if (exclude.endsWith(\"/**\") && !exclude.slice(0, -3).includes(\"*\")) {\n return [\"--exclude-dir\", exclude.slice(0, -3)]\n }\n return [\"--exclude\", exclude]\n}\n"],"mappings":"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"}
|