@octp/cli 0.1.6 → 0.1.8
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/commands/agent/claude-searcher.d.ts +9 -0
- package/dist/commands/agent/claude-searcher.js +43 -0
- package/dist/commands/agent/claude-searcher.js.map +1 -0
- package/dist/commands/agent/index.d.ts +2 -0
- package/dist/commands/agent/index.js +8 -0
- package/dist/commands/agent/index.js.map +1 -0
- package/dist/commands/agent/searcher.d.ts +22 -0
- package/dist/commands/agent/searcher.js +301 -0
- package/dist/commands/agent/searcher.js.map +1 -0
- package/dist/commands/agent/start.d.ts +2 -0
- package/dist/commands/agent/start.js +297 -0
- package/dist/commands/agent/start.js.map +1 -0
- package/dist/commands/agent/watch.d.ts +13 -0
- package/dist/commands/agent/watch.js +142 -0
- package/dist/commands/agent/watch.js.map +1 -0
- package/dist/commands/pr/review.d.ts +4 -0
- package/dist/commands/pr/review.js +14 -6
- package/dist/commands/pr/review.js.map +1 -1
- package/dist/commands/skills.d.ts +1 -0
- package/dist/commands/skills.js +284 -99
- package/dist/commands/skills.js.map +1 -1
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if the Claude CLI is available.
|
|
3
|
+
*/
|
|
4
|
+
export declare function hasClaudeCli(): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Run a search query using Claude CLI.
|
|
7
|
+
* Shells out to `claude -p` in the repo directory.
|
|
8
|
+
*/
|
|
9
|
+
export declare function claudeSearch(query: string, repoDir: string, timeoutMs?: number): Promise<string>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
const MAX_SUMMARY_SIZE = 15 * 1024; // 15KB
|
|
3
|
+
/**
|
|
4
|
+
* Check if the Claude CLI is available.
|
|
5
|
+
*/
|
|
6
|
+
export function hasClaudeCli() {
|
|
7
|
+
try {
|
|
8
|
+
execSync("claude --version", {
|
|
9
|
+
encoding: "utf-8",
|
|
10
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
11
|
+
timeout: 5000,
|
|
12
|
+
});
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Run a search query using Claude CLI.
|
|
21
|
+
* Shells out to `claude -p` in the repo directory.
|
|
22
|
+
*/
|
|
23
|
+
export async function claudeSearch(query, repoDir, timeoutMs = 25_000) {
|
|
24
|
+
const prompt = `Search this codebase for information relevant to the following question. Return the most relevant code snippets with file paths and line numbers. Be concise and focus on the most important findings.\n\nQuestion: ${query}`;
|
|
25
|
+
try {
|
|
26
|
+
const result = execSync(`claude -p ${JSON.stringify(prompt)}`, {
|
|
27
|
+
cwd: repoDir,
|
|
28
|
+
encoding: "utf-8",
|
|
29
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
30
|
+
maxBuffer: 2 * 1024 * 1024, // 2MB
|
|
31
|
+
timeout: timeoutMs,
|
|
32
|
+
});
|
|
33
|
+
const summary = result.trim();
|
|
34
|
+
return summary.length > MAX_SUMMARY_SIZE
|
|
35
|
+
? summary.slice(0, MAX_SUMMARY_SIZE)
|
|
36
|
+
: summary;
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
40
|
+
throw new Error(`Claude CLI search failed: ${message}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=claude-searcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-searcher.js","sourceRoot":"","sources":["../../../src/commands/agent/claude-searcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO;AAE3C;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC;QACH,QAAQ,CAAC,kBAAkB,EAAE;YAC3B,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAa,EACb,OAAe,EACf,SAAS,GAAG,MAAM;IAElB,MAAM,MAAM,GAAG,uNAAuN,KAAK,EAAE,CAAC;IAE9O,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CACrB,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EACrC;YACE,GAAG,EAAE,OAAO;YACZ,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,MAAM;YAClC,OAAO,EAAE,SAAS;SACnB,CACF,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC,MAAM,GAAG,gBAAgB;YACtC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC;YACpC,CAAC,CAAC,OAAO,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,6BAA6B,OAAO,EAAE,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { watchCommand } from "./watch.js";
|
|
3
|
+
import { startCommand } from "./start.js";
|
|
4
|
+
export const agentCommand = new Command("agent")
|
|
5
|
+
.description("Local agent for real-time codebase search")
|
|
6
|
+
.addCommand(watchCommand)
|
|
7
|
+
.addCommand(startCommand);
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,2CAA2C,CAAC;KACxD,UAAU,CAAC,YAAY,CAAC;KACxB,UAAU,CAAC,YAAY,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface SearchResult {
|
|
2
|
+
file: string;
|
|
3
|
+
line: number;
|
|
4
|
+
content: string;
|
|
5
|
+
}
|
|
6
|
+
interface SearchResponse {
|
|
7
|
+
results: SearchResult[];
|
|
8
|
+
summary: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Perform a semantic search using keyword extraction + parallel ripgrep.
|
|
12
|
+
*/
|
|
13
|
+
export declare function semanticSearch(query: string, repoDir: string): Promise<SearchResponse>;
|
|
14
|
+
/**
|
|
15
|
+
* Perform a direct grep search.
|
|
16
|
+
*/
|
|
17
|
+
export declare function grepSearch(pattern: string, repoDir: string): Promise<SearchResponse>;
|
|
18
|
+
/**
|
|
19
|
+
* Read specific files.
|
|
20
|
+
*/
|
|
21
|
+
export declare function fileReadSearch(filePaths: string[], repoDir: string): Promise<SearchResponse>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { readFileSync, readdirSync, existsSync, statSync } from "node:fs";
|
|
3
|
+
import { join, extname, relative } from "node:path";
|
|
4
|
+
const MAX_SUMMARY_SIZE = 15 * 1024; // 15KB
|
|
5
|
+
/**
|
|
6
|
+
* Extract likely search keywords from a natural language query.
|
|
7
|
+
*/
|
|
8
|
+
function extractKeywords(query) {
|
|
9
|
+
// Remove common filler words
|
|
10
|
+
const stopWords = new Set([
|
|
11
|
+
"the", "a", "an", "is", "are", "was", "were", "be", "been", "being",
|
|
12
|
+
"have", "has", "had", "do", "does", "did", "will", "would", "could",
|
|
13
|
+
"should", "may", "might", "can", "shall", "to", "of", "in", "for",
|
|
14
|
+
"on", "with", "at", "by", "from", "as", "into", "through", "during",
|
|
15
|
+
"before", "after", "above", "below", "between", "this", "that", "these",
|
|
16
|
+
"those", "i", "you", "he", "she", "it", "we", "they", "what", "which",
|
|
17
|
+
"who", "when", "where", "why", "how", "all", "each", "every", "both",
|
|
18
|
+
"few", "more", "most", "other", "some", "such", "no", "not", "only",
|
|
19
|
+
"same", "so", "than", "too", "very", "just", "but", "and", "or",
|
|
20
|
+
"if", "because", "about", "find", "search", "show", "me", "tell",
|
|
21
|
+
"explain", "code", "function", "file", "used", "using", "called",
|
|
22
|
+
"where", "does", "defined", "nerede", "nasil", "ne", "bu", "bir",
|
|
23
|
+
"ve", "ile", "icin", "mi", "var", "yok",
|
|
24
|
+
]);
|
|
25
|
+
// Split on word boundaries and filter
|
|
26
|
+
const words = query
|
|
27
|
+
.replace(/[^\w\s.-]/g, " ")
|
|
28
|
+
.split(/\s+/)
|
|
29
|
+
.filter((w) => w.length > 2 && !stopWords.has(w.toLowerCase()));
|
|
30
|
+
// Also extract quoted strings as exact phrases
|
|
31
|
+
const quoted = query.match(/"([^"]+)"|'([^']+)'/g);
|
|
32
|
+
if (quoted) {
|
|
33
|
+
words.push(...quoted.map((q) => q.replace(/["']/g, "")));
|
|
34
|
+
}
|
|
35
|
+
// Extract camelCase/PascalCase identifiers (likely code references)
|
|
36
|
+
const identifiers = query.match(/[A-Z][a-z]+[A-Z]\w+|[a-z]+[A-Z]\w+/g);
|
|
37
|
+
if (identifiers) {
|
|
38
|
+
words.unshift(...identifiers); // prioritize these
|
|
39
|
+
}
|
|
40
|
+
// Deduplicate
|
|
41
|
+
return [...new Set(words)].slice(0, 10);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Run ripgrep with a pattern in a directory.
|
|
45
|
+
*/
|
|
46
|
+
function ripgrep(pattern, dir, maxResults = 20) {
|
|
47
|
+
try {
|
|
48
|
+
const rgCmd = `rg --no-heading --line-number --max-count 5 --max-columns 200 --type-add 'code:*.{ts,tsx,js,jsx,py,go,rs,java,rb,php,c,cpp,h,cs,swift,kt,scala,vue,svelte}' --type code --glob '!node_modules' --glob '!dist' --glob '!.git' --glob '!*.lock' --glob '!*.min.*' -- ${JSON.stringify(pattern)} ${JSON.stringify(dir)}`;
|
|
49
|
+
const output = execSync(rgCmd, {
|
|
50
|
+
encoding: "utf-8",
|
|
51
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
52
|
+
maxBuffer: 1024 * 1024,
|
|
53
|
+
timeout: 5000,
|
|
54
|
+
});
|
|
55
|
+
return output
|
|
56
|
+
.split("\n")
|
|
57
|
+
.filter(Boolean)
|
|
58
|
+
.slice(0, maxResults)
|
|
59
|
+
.map((line) => {
|
|
60
|
+
// Format: filepath:line:content
|
|
61
|
+
const match = line.match(/^(.+?):(\d+):(.*)$/);
|
|
62
|
+
if (!match)
|
|
63
|
+
return null;
|
|
64
|
+
const filePath = match[1].startsWith(dir)
|
|
65
|
+
? match[1].slice(dir.length + 1)
|
|
66
|
+
: match[1];
|
|
67
|
+
return {
|
|
68
|
+
file: filePath,
|
|
69
|
+
line: parseInt(match[2], 10),
|
|
70
|
+
content: match[3].trim(),
|
|
71
|
+
};
|
|
72
|
+
})
|
|
73
|
+
.filter((r) => r !== null);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const CODE_EXTENSIONS = new Set([
|
|
80
|
+
".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs",
|
|
81
|
+
".py", ".go", ".rs", ".java", ".rb", ".php",
|
|
82
|
+
".c", ".cpp", ".h", ".cs", ".swift", ".kt",
|
|
83
|
+
".scala", ".vue", ".svelte",
|
|
84
|
+
]);
|
|
85
|
+
const SKIP_DIRS = new Set([
|
|
86
|
+
"node_modules", "dist", ".git", ".next", "build",
|
|
87
|
+
"out", "coverage", "__pycache__", ".turbo", "vendor",
|
|
88
|
+
]);
|
|
89
|
+
/**
|
|
90
|
+
* Pure Node.js fallback search — works on all platforms (macOS, Linux, Windows).
|
|
91
|
+
* Walks the directory tree, reads code files, and matches lines.
|
|
92
|
+
*/
|
|
93
|
+
function nodeSearch(pattern, dir, maxResults = 20) {
|
|
94
|
+
const results = [];
|
|
95
|
+
const regex = new RegExp(escapeRegex(pattern), "i");
|
|
96
|
+
function walk(currentDir) {
|
|
97
|
+
if (results.length >= maxResults)
|
|
98
|
+
return;
|
|
99
|
+
let entries;
|
|
100
|
+
try {
|
|
101
|
+
entries = readdirSync(currentDir);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
for (const entry of entries) {
|
|
107
|
+
if (results.length >= maxResults)
|
|
108
|
+
return;
|
|
109
|
+
if (SKIP_DIRS.has(entry) || entry.startsWith("."))
|
|
110
|
+
continue;
|
|
111
|
+
const fullPath = join(currentDir, entry);
|
|
112
|
+
let stat;
|
|
113
|
+
try {
|
|
114
|
+
stat = statSync(fullPath);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (stat.isDirectory()) {
|
|
120
|
+
walk(fullPath);
|
|
121
|
+
}
|
|
122
|
+
else if (stat.isFile() && CODE_EXTENSIONS.has(extname(entry))) {
|
|
123
|
+
// Skip large files (>200KB)
|
|
124
|
+
if (stat.size > 200_000)
|
|
125
|
+
continue;
|
|
126
|
+
try {
|
|
127
|
+
const content = readFileSync(fullPath, "utf-8");
|
|
128
|
+
const lines = content.split("\n");
|
|
129
|
+
let matchCount = 0;
|
|
130
|
+
for (let i = 0; i < lines.length; i++) {
|
|
131
|
+
if (matchCount >= 5)
|
|
132
|
+
break;
|
|
133
|
+
if (regex.test(lines[i])) {
|
|
134
|
+
results.push({
|
|
135
|
+
file: relative(dir, fullPath),
|
|
136
|
+
line: i + 1,
|
|
137
|
+
content: lines[i].trim().slice(0, 200),
|
|
138
|
+
});
|
|
139
|
+
matchCount++;
|
|
140
|
+
if (results.length >= maxResults)
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Skip unreadable files
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
walk(dir);
|
|
152
|
+
return results;
|
|
153
|
+
}
|
|
154
|
+
function escapeRegex(str) {
|
|
155
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if ripgrep is available.
|
|
159
|
+
*/
|
|
160
|
+
function hasRipgrep() {
|
|
161
|
+
try {
|
|
162
|
+
execSync("rg --version", { stdio: ["pipe", "pipe", "pipe"] });
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Read a file and return content with line numbers.
|
|
171
|
+
*/
|
|
172
|
+
function readFile(filePath, repoDir) {
|
|
173
|
+
const fullPath = join(repoDir, filePath);
|
|
174
|
+
if (!existsSync(fullPath))
|
|
175
|
+
return null;
|
|
176
|
+
try {
|
|
177
|
+
const content = readFileSync(fullPath, "utf-8");
|
|
178
|
+
return content
|
|
179
|
+
.split("\n")
|
|
180
|
+
.map((line, i) => `${i + 1}: ${line}`)
|
|
181
|
+
.join("\n");
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Perform a semantic search using keyword extraction + parallel ripgrep.
|
|
189
|
+
*/
|
|
190
|
+
export async function semanticSearch(query, repoDir) {
|
|
191
|
+
const keywords = extractKeywords(query);
|
|
192
|
+
const useRg = hasRipgrep();
|
|
193
|
+
const searchFn = useRg ? ripgrep : nodeSearch;
|
|
194
|
+
// Run searches for all keywords in parallel
|
|
195
|
+
const allResults = [];
|
|
196
|
+
const seenKeys = new Set();
|
|
197
|
+
for (const keyword of keywords) {
|
|
198
|
+
const results = searchFn(keyword, repoDir, 15);
|
|
199
|
+
for (const r of results) {
|
|
200
|
+
const key = `${r.file}:${r.line}`;
|
|
201
|
+
if (!seenKeys.has(key)) {
|
|
202
|
+
seenKeys.add(key);
|
|
203
|
+
allResults.push(r);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Score results — files matching more keywords rank higher
|
|
208
|
+
const fileScores = new Map();
|
|
209
|
+
for (const r of allResults) {
|
|
210
|
+
fileScores.set(r.file, (fileScores.get(r.file) ?? 0) + 1);
|
|
211
|
+
}
|
|
212
|
+
// Sort by file frequency (multi-keyword matches first), then by line number
|
|
213
|
+
allResults.sort((a, b) => {
|
|
214
|
+
const scoreA = fileScores.get(a.file) ?? 0;
|
|
215
|
+
const scoreB = fileScores.get(b.file) ?? 0;
|
|
216
|
+
if (scoreB !== scoreA)
|
|
217
|
+
return scoreB - scoreA;
|
|
218
|
+
return a.line - b.line;
|
|
219
|
+
});
|
|
220
|
+
// Build summary
|
|
221
|
+
const topResults = allResults.slice(0, 30);
|
|
222
|
+
const summary = buildSummary(topResults, keywords, repoDir);
|
|
223
|
+
return { results: topResults, summary };
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Perform a direct grep search.
|
|
227
|
+
*/
|
|
228
|
+
export async function grepSearch(pattern, repoDir) {
|
|
229
|
+
const useRg = hasRipgrep();
|
|
230
|
+
const searchFn = useRg ? ripgrep : nodeSearch;
|
|
231
|
+
const results = searchFn(pattern, repoDir, 30);
|
|
232
|
+
const summary = buildSummary(results, [pattern], repoDir);
|
|
233
|
+
return { results, summary };
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Read specific files.
|
|
237
|
+
*/
|
|
238
|
+
export async function fileReadSearch(filePaths, repoDir) {
|
|
239
|
+
const results = [];
|
|
240
|
+
const summaryParts = [];
|
|
241
|
+
for (const fp of filePaths.slice(0, 5)) {
|
|
242
|
+
const content = readFile(fp, repoDir);
|
|
243
|
+
if (content) {
|
|
244
|
+
summaryParts.push(`### ${fp}\n\`\`\`\n${content.slice(0, 3000)}\n\`\`\``);
|
|
245
|
+
// Add a synthetic result for each file
|
|
246
|
+
results.push({ file: fp, line: 1, content: `[file content: ${content.split("\n").length} lines]` });
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const summary = summaryParts.join("\n\n").slice(0, MAX_SUMMARY_SIZE);
|
|
250
|
+
return { results, summary };
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Build a context summary from search results.
|
|
254
|
+
* Groups results by file and includes surrounding context.
|
|
255
|
+
*/
|
|
256
|
+
function buildSummary(results, keywords, repoDir) {
|
|
257
|
+
if (results.length === 0) {
|
|
258
|
+
return `No results found for: ${keywords.join(", ")}`;
|
|
259
|
+
}
|
|
260
|
+
// Group by file
|
|
261
|
+
const byFile = new Map();
|
|
262
|
+
for (const r of results) {
|
|
263
|
+
const existing = byFile.get(r.file) ?? [];
|
|
264
|
+
existing.push(r);
|
|
265
|
+
byFile.set(r.file, existing);
|
|
266
|
+
}
|
|
267
|
+
const parts = [`Search results for: ${keywords.join(", ")}\n`];
|
|
268
|
+
for (const [file, fileResults] of byFile) {
|
|
269
|
+
parts.push(`### ${file}`);
|
|
270
|
+
// Try to read surrounding lines for context
|
|
271
|
+
const fullPath = join(repoDir, file);
|
|
272
|
+
let fileLines = null;
|
|
273
|
+
try {
|
|
274
|
+
if (existsSync(fullPath)) {
|
|
275
|
+
fileLines = readFileSync(fullPath, "utf-8").split("\n");
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
catch { }
|
|
279
|
+
for (const r of fileResults.slice(0, 5)) {
|
|
280
|
+
if (fileLines) {
|
|
281
|
+
// Show 2 lines before and after for context
|
|
282
|
+
const start = Math.max(0, r.line - 3);
|
|
283
|
+
const end = Math.min(fileLines.length, r.line + 2);
|
|
284
|
+
const contextLines = fileLines
|
|
285
|
+
.slice(start, end)
|
|
286
|
+
.map((l, i) => `${start + i + 1}: ${l}`)
|
|
287
|
+
.join("\n");
|
|
288
|
+
parts.push(`\`\`\`\n${contextLines}\n\`\`\``);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
parts.push(`L${r.line}: ${r.content}`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
parts.push("");
|
|
295
|
+
}
|
|
296
|
+
const summary = parts.join("\n");
|
|
297
|
+
return summary.length > MAX_SUMMARY_SIZE
|
|
298
|
+
? summary.slice(0, MAX_SUMMARY_SIZE)
|
|
299
|
+
: summary;
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=searcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searcher.js","sourceRoot":"","sources":["../../../src/commands/agent/searcher.ts"],"names":[],"mappings":"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"}
|