@octp/cli 0.1.5 → 0.1.7
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 +284 -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 +138 -0
- package/dist/commands/agent/watch.js.map +1 -0
- package/dist/index.js +15 -1
- 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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAapD,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO;AAE3C;;GAEG;AACH,SAAS,eAAe,CAAC,KAAa;IACpC,6BAA6B;IAC7B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;QACxB,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO;QACnE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;QACnE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK;QACjE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ;QACnE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;QACvE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;QACrE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;QACpE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM;QACnE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI;QAC/D,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;QAChE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ;QAChE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK;QAChE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK;KACxC,CAAC,CAAC;IAEH,sCAAsC;IACtC,MAAM,KAAK,GAAG,KAAK;SAChB,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC;SAC1B,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAElE,+CAA+C;IAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACnD,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,oEAAoE;IACpE,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACvE,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,mBAAmB;IACpD,CAAC;IAED,cAAc;IACd,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,SAAS,OAAO,CAAC,OAAe,EAAE,GAAW,EAAE,UAAU,GAAG,EAAE;IAC5D,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,sQAAsQ,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;QACrU,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE;YAC7B,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,SAAS,EAAE,IAAI,GAAG,IAAI;YACtB,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,OAAO,MAAM;aACV,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC;aACf,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;aACpB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,gCAAgC;YAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YAC/C,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC;YACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;gBACvC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;gBAChC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACb,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBAC5B,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;aACzB,CAAC;QACJ,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC5C,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;IAC3C,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK;IAC1C,QAAQ,EAAE,MAAM,EAAE,SAAS;CAC5B,CAAC,CAAC;AAEH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAChD,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ;CACrD,CAAC,CAAC;AAEH;;;GAGG;AACH,SAAS,UAAU,CAAC,OAAe,EAAE,GAAW,EAAE,UAAU,GAAG,EAAE;IAC/D,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;IAEpD,SAAS,IAAI,CAAC,UAAkB;QAC9B,IAAI,OAAO,CAAC,MAAM,IAAI,UAAU;YAAE,OAAO;QAEzC,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,OAAO,CAAC,MAAM,IAAI,UAAU;gBAAE,OAAO;YACzC,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAE5D,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACzC,IAAI,IAAI,CAAC;YACT,IAAI,CAAC;gBACH,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YAED,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjB,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBAChE,4BAA4B;gBAC5B,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO;oBAAE,SAAS;gBAElC,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAClC,IAAI,UAAU,GAAG,CAAC,CAAC;oBAEnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBACtC,IAAI,UAAU,IAAI,CAAC;4BAAE,MAAM;wBAC3B,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;4BACzB,OAAO,CAAC,IAAI,CAAC;gCACX,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC;gCAC7B,IAAI,EAAE,CAAC,GAAG,CAAC;gCACX,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;6BACvC,CAAC,CAAC;4BACH,UAAU,EAAE,CAAC;4BACb,IAAI,OAAO,CAAC,MAAM,IAAI,UAAU;gCAAE,OAAO;wBAC3C,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,wBAAwB;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,QAAQ,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,QAAgB,EAAE,OAAe;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,OAAO,OAAO;aACX,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;aACrC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,OAAe;IACjE,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;IAE9C,4CAA4C;IAC5C,MAAM,UAAU,GAAmB,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IAEnC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;QAC/C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAClB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,4EAA4E;IAC5E,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACvB,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO,MAAM,GAAG,MAAM,CAAC;QAC9C,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,gBAAgB;IAChB,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE5D,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,OAAe;IAC/D,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;IAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;IAC1D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAmB,EAAE,OAAe;IACvE,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,MAAM,EAAE,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,OAAO,EAAE,CAAC;YACZ,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YAC1E,uCAAuC;YACvC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,kBAAkB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC;QACtG,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;IACrE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,OAAuB,EAAE,QAAkB,EAAE,OAAe;IAChF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,yBAAyB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACxD,CAAC;IAED,gBAAgB;IAChB,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1C,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,KAAK,GAAa,CAAC,uBAAuB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEzE,KAAK,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,MAAM,EAAE,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAE1B,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACrC,IAAI,SAAS,GAAoB,IAAI,CAAC;QACtC,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,SAAS,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACxC,IAAI,SAAS,EAAE,CAAC;gBACd,4CAA4C;gBAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;gBACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;gBACnD,MAAM,YAAY,GAAG,SAAS;qBAC3B,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC;qBACjB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;qBACvC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,KAAK,CAAC,IAAI,CAAC,WAAW,YAAY,UAAU,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,OAAO,CAAC,MAAM,GAAG,gBAAgB;QACtC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC;QACpC,CAAC,CAAC,OAAO,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { hostname } from "node:os";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { execSync, spawn } from "node:child_process";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import { apiPost, apiGet } from "../../lib/api-client.js";
|
|
9
|
+
import { getApiToken } from "../../lib/config-store.js";
|
|
10
|
+
import { success, error, warn, info } from "../../lib/output.js";
|
|
11
|
+
import { loadWatchConfig } from "./watch.js";
|
|
12
|
+
import { semanticSearch, grepSearch, fileReadSearch } from "./searcher.js";
|
|
13
|
+
import { hasClaudeCli, claudeSearch } from "./claude-searcher.js";
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
function parseGitRemote(url) {
|
|
16
|
+
const sshMatch = url.match(/git@[^:]+:([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
17
|
+
if (sshMatch)
|
|
18
|
+
return sshMatch[1];
|
|
19
|
+
const httpsMatch = url.match(/https?:\/\/[^/]+\/([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
20
|
+
if (httpsMatch)
|
|
21
|
+
return httpsMatch[1];
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
function getGitRemoteUrl(dirPath) {
|
|
25
|
+
try {
|
|
26
|
+
return execSync("git remote get-url origin", {
|
|
27
|
+
cwd: dirPath,
|
|
28
|
+
encoding: "utf-8",
|
|
29
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
30
|
+
}).trim();
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolve watched directories to repo mappings.
|
|
38
|
+
*/
|
|
39
|
+
function resolveWatchedRepos() {
|
|
40
|
+
const config = loadWatchConfig();
|
|
41
|
+
const repoMap = new Map(); // repoFullName -> localPath
|
|
42
|
+
for (const entry of config.entries) {
|
|
43
|
+
if (!existsSync(entry.path)) {
|
|
44
|
+
warn(`Skipping ${entry.path} — directory not found`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const remoteUrl = getGitRemoteUrl(entry.path);
|
|
48
|
+
if (!remoteUrl) {
|
|
49
|
+
warn(`Skipping ${entry.path} — no git remote`);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const fullName = parseGitRemote(remoteUrl);
|
|
53
|
+
if (!fullName) {
|
|
54
|
+
warn(`Skipping ${entry.path} — could not parse remote: ${remoteUrl}`);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
repoMap.set(fullName, entry.path);
|
|
58
|
+
}
|
|
59
|
+
return repoMap;
|
|
60
|
+
}
|
|
61
|
+
export const startCommand = new Command("start")
|
|
62
|
+
.description("Start the local agent daemon")
|
|
63
|
+
.option("--with-claude", "Enable Claude CLI for deep semantic search")
|
|
64
|
+
.option("--verbose", "Run in foreground with detailed logs")
|
|
65
|
+
.option("--foreground", "Run in foreground (without verbose logs)")
|
|
66
|
+
.action(async (opts) => {
|
|
67
|
+
const token = getApiToken();
|
|
68
|
+
if (!token) {
|
|
69
|
+
error("Not logged in. Run 'octopus login' first.");
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
const runInForeground = opts.verbose || opts.foreground;
|
|
73
|
+
// Default: background mode — spawn detached child and exit
|
|
74
|
+
if (!runInForeground) {
|
|
75
|
+
const binPath = join(__dirname, "..", "..", "..", "bin", "octopus.js");
|
|
76
|
+
const args = [binPath, "agent", "start", "--foreground"];
|
|
77
|
+
if (opts.withClaude)
|
|
78
|
+
args.push("--with-claude");
|
|
79
|
+
const child = spawn(process.execPath, args, {
|
|
80
|
+
detached: true,
|
|
81
|
+
stdio: "ignore",
|
|
82
|
+
});
|
|
83
|
+
child.unref();
|
|
84
|
+
success(`Agent started in background (PID: ${child.pid})`);
|
|
85
|
+
info("Use 'octopus agent status' or 'kill' to manage the process.");
|
|
86
|
+
process.exit(0);
|
|
87
|
+
}
|
|
88
|
+
// Resolve watched repos
|
|
89
|
+
const repoMap = resolveWatchedRepos();
|
|
90
|
+
if (repoMap.size === 0) {
|
|
91
|
+
error("No watched repos found. Run 'octopus agent watch' in a repo directory first.");
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
const repoFullNames = [...repoMap.keys()];
|
|
95
|
+
info(`Found ${repoMap.size} watched repo(s):`);
|
|
96
|
+
for (const [name, path] of repoMap) {
|
|
97
|
+
console.log(` ${chalk.cyan(name)} → ${path}`);
|
|
98
|
+
}
|
|
99
|
+
// Check Claude CLI availability
|
|
100
|
+
const claudeAvailable = opts.withClaude ? hasClaudeCli() : false;
|
|
101
|
+
if (opts.withClaude && !claudeAvailable) {
|
|
102
|
+
warn("Claude CLI not found. Falling back to ripgrep mode.");
|
|
103
|
+
}
|
|
104
|
+
const capabilities = ["code-search"]; // ripgrep or Node.js fallback
|
|
105
|
+
if (claudeAvailable)
|
|
106
|
+
capabilities.push("claude-cli");
|
|
107
|
+
const agentName = `${hostname()}-${process.pid}`;
|
|
108
|
+
// Register with server
|
|
109
|
+
let agentId;
|
|
110
|
+
let orgId;
|
|
111
|
+
try {
|
|
112
|
+
const res = await apiPost("/api/agent/register", {
|
|
113
|
+
name: agentName,
|
|
114
|
+
repoFullNames,
|
|
115
|
+
capabilities,
|
|
116
|
+
machineInfo: {
|
|
117
|
+
os: process.platform,
|
|
118
|
+
hostname: hostname(),
|
|
119
|
+
nodeVersion: process.version,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
agentId = res.agentId;
|
|
123
|
+
orgId = res.orgId;
|
|
124
|
+
success(`Registered as "${agentName}" (${capabilities.join(", ")})`);
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
error(`Failed to register: ${err instanceof Error ? err.message : err}`);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
const verbose = opts.verbose ?? false;
|
|
131
|
+
// Heartbeat interval
|
|
132
|
+
const heartbeatInterval = setInterval(async () => {
|
|
133
|
+
try {
|
|
134
|
+
// Re-scan repos in case they changed
|
|
135
|
+
const freshMap = resolveWatchedRepos();
|
|
136
|
+
const freshNames = [...freshMap.keys()];
|
|
137
|
+
// Update our local map
|
|
138
|
+
for (const [name, path] of freshMap) {
|
|
139
|
+
repoMap.set(name, path);
|
|
140
|
+
}
|
|
141
|
+
await apiPost("/api/agent/heartbeat", {
|
|
142
|
+
agentId,
|
|
143
|
+
repoFullNames: freshNames,
|
|
144
|
+
});
|
|
145
|
+
if (verbose) {
|
|
146
|
+
info(`Heartbeat sent (${freshNames.length} repos)`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
if (verbose) {
|
|
151
|
+
warn(`Heartbeat failed: ${err instanceof Error ? err.message : err}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}, 30_000);
|
|
155
|
+
// Task polling interval (fallback for missed Pubby signals)
|
|
156
|
+
const pollInterval = setInterval(async () => {
|
|
157
|
+
try {
|
|
158
|
+
const res = await apiGet(`/api/agent/tasks?agentId=${agentId}`);
|
|
159
|
+
if (verbose && res.tasks.length > 0) {
|
|
160
|
+
info(`Received ${res.tasks.length} task(s)`);
|
|
161
|
+
}
|
|
162
|
+
for (const task of res.tasks) {
|
|
163
|
+
handleTask(task, repoMap, agentId, claudeAvailable, verbose);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
if (verbose) {
|
|
168
|
+
warn(`Poll failed: ${err instanceof Error ? err.message : err}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}, 2_000);
|
|
172
|
+
// Graceful shutdown
|
|
173
|
+
const cleanup = async () => {
|
|
174
|
+
console.log("\n");
|
|
175
|
+
info("Shutting down...");
|
|
176
|
+
clearInterval(heartbeatInterval);
|
|
177
|
+
clearInterval(pollInterval);
|
|
178
|
+
try {
|
|
179
|
+
await apiPost("/api/agent/disconnect", { agentId });
|
|
180
|
+
success("Disconnected.");
|
|
181
|
+
}
|
|
182
|
+
catch { }
|
|
183
|
+
process.exit(0);
|
|
184
|
+
};
|
|
185
|
+
process.on("SIGINT", cleanup);
|
|
186
|
+
process.on("SIGTERM", cleanup);
|
|
187
|
+
console.log("");
|
|
188
|
+
success(`Agent running. Listening for search requests...`);
|
|
189
|
+
if (verbose) {
|
|
190
|
+
info("Verbose mode enabled — showing all activity logs.");
|
|
191
|
+
info(`Agent ID: ${agentId}`);
|
|
192
|
+
info(`Repos: ${repoFullNames.join(", ")}`);
|
|
193
|
+
info(`Polling every 2s, heartbeat every 30s`);
|
|
194
|
+
info(`Press Ctrl+C to stop.\n`);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
info(`Press Ctrl+C to stop.\n`);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
/**
|
|
201
|
+
* Handle a single search task — claim, execute, submit result.
|
|
202
|
+
*/
|
|
203
|
+
async function handleTask(task, repoMap, agentId, claudeAvailable, verbose) {
|
|
204
|
+
const repoDir = repoMap.get(task.repoFullName);
|
|
205
|
+
if (!repoDir)
|
|
206
|
+
return;
|
|
207
|
+
// Claim the task
|
|
208
|
+
try {
|
|
209
|
+
await apiPost(`/api/agent/tasks/${task.id}/claim`, { agentId });
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
// Already claimed by another agent
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (verbose) {
|
|
216
|
+
info(`Claimed task ${task.id}: "${task.query}" (${task.searchType}) in ${task.repoFullName}`);
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
let resultSummary;
|
|
220
|
+
switch (task.searchType) {
|
|
221
|
+
case "claude": {
|
|
222
|
+
if (claudeAvailable) {
|
|
223
|
+
try {
|
|
224
|
+
resultSummary = await claudeSearch(task.query, repoDir, task.timeoutMs - 2000);
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// Fall back to semantic search
|
|
228
|
+
if (verbose)
|
|
229
|
+
warn("Claude CLI failed, falling back to ripgrep");
|
|
230
|
+
const { summary } = await semanticSearch(task.query, repoDir);
|
|
231
|
+
resultSummary = summary;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
const { summary } = await semanticSearch(task.query, repoDir);
|
|
236
|
+
resultSummary = summary;
|
|
237
|
+
}
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
case "grep": {
|
|
241
|
+
const pattern = task.params.pattern ?? task.query;
|
|
242
|
+
const { summary } = await grepSearch(pattern, repoDir);
|
|
243
|
+
resultSummary = summary;
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
case "file-read": {
|
|
247
|
+
const filePaths = task.params.filePaths ?? [];
|
|
248
|
+
const { summary } = await fileReadSearch(filePaths, repoDir);
|
|
249
|
+
resultSummary = summary;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
case "semantic":
|
|
253
|
+
default: {
|
|
254
|
+
const { summary } = await semanticSearch(task.query, repoDir);
|
|
255
|
+
resultSummary = summary;
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// Submit results
|
|
260
|
+
await apiPost(`/api/agent/tasks/${task.id}/result`, {
|
|
261
|
+
results: [],
|
|
262
|
+
resultSummary,
|
|
263
|
+
});
|
|
264
|
+
if (verbose) {
|
|
265
|
+
success(`Completed task ${task.id} (${resultSummary.length} chars)`);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
console.log(`${chalk.green("✓")} Searched "${task.query.slice(0, 50)}${task.query.length > 50 ? "..." : ""}" in ${chalk.cyan(task.repoFullName)}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
// Submit error
|
|
273
|
+
try {
|
|
274
|
+
await apiPost(`/api/agent/tasks/${task.id}/result`, {
|
|
275
|
+
errorMessage: err instanceof Error ? err.message : "Unknown error",
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
catch { }
|
|
279
|
+
if (verbose) {
|
|
280
|
+
error(`Task ${task.id} failed: ${err instanceof Error ? err.message : err}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/commands/agent/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
interface WatchEntry {
|
|
3
|
+
path: string;
|
|
4
|
+
remoteUrl: string;
|
|
5
|
+
repoFullName: string;
|
|
6
|
+
addedAt: string;
|
|
7
|
+
}
|
|
8
|
+
interface WatchConfig {
|
|
9
|
+
entries: WatchEntry[];
|
|
10
|
+
}
|
|
11
|
+
declare function loadWatchConfig(): WatchConfig;
|
|
12
|
+
export { loadWatchConfig, type WatchEntry };
|
|
13
|
+
export declare const watchCommand: Command;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { execSync, spawn } from "node:child_process";
|
|
4
|
+
import { resolve, join, dirname } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import { success, error, warn, info, heading, table } from "../../lib/output.js";
|
|
9
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const CONFIG_DIR = join(homedir(), ".octopus");
|
|
11
|
+
const WATCH_FILE = join(CONFIG_DIR, "agent-watch.json");
|
|
12
|
+
function loadWatchConfig() {
|
|
13
|
+
try {
|
|
14
|
+
const data = readFileSync(WATCH_FILE, "utf-8");
|
|
15
|
+
return JSON.parse(data);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return { entries: [] };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function saveWatchConfig(config) {
|
|
22
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
23
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
writeFileSync(WATCH_FILE, JSON.stringify(config, null, 2));
|
|
26
|
+
}
|
|
27
|
+
function getGitRemoteUrl(dirPath) {
|
|
28
|
+
try {
|
|
29
|
+
return execSync("git remote get-url origin", {
|
|
30
|
+
cwd: dirPath,
|
|
31
|
+
encoding: "utf-8",
|
|
32
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
33
|
+
}).trim();
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function parseGitRemote(url) {
|
|
40
|
+
// SSH: git@github.com:owner/repo.git
|
|
41
|
+
const sshMatch = url.match(/git@[^:]+:([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
42
|
+
if (sshMatch)
|
|
43
|
+
return sshMatch[1];
|
|
44
|
+
// HTTPS: https://github.com/owner/repo.git
|
|
45
|
+
const httpsMatch = url.match(/https?:\/\/[^/]+\/([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
46
|
+
if (httpsMatch)
|
|
47
|
+
return httpsMatch[1];
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
export { loadWatchConfig };
|
|
51
|
+
export const watchCommand = new Command("watch")
|
|
52
|
+
.description("Manage watched directories for local agent")
|
|
53
|
+
.argument("[path]", "Directory to watch (defaults to current directory)")
|
|
54
|
+
.option("--list", "List all watched directories")
|
|
55
|
+
.option("--remove", "Remove directory from watch list")
|
|
56
|
+
.option("--no-start", "Don't auto-start the agent after adding")
|
|
57
|
+
.option("--verbose", "Start agent in foreground with detailed logs")
|
|
58
|
+
.action(async (pathArg, opts) => {
|
|
59
|
+
if (opts.list) {
|
|
60
|
+
const config = loadWatchConfig();
|
|
61
|
+
if (config.entries.length === 0) {
|
|
62
|
+
info("No watched directories. Run 'octopus agent watch' in a repo directory to add one.");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
heading("Watched Directories");
|
|
66
|
+
const rows = config.entries.map((entry) => {
|
|
67
|
+
const exists = existsSync(entry.path);
|
|
68
|
+
const status = exists ? chalk.green("ok") : chalk.red("missing");
|
|
69
|
+
return [entry.path, chalk.cyan(entry.repoFullName), status];
|
|
70
|
+
});
|
|
71
|
+
table(rows, ["Path", "Repository", "Status"]);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const targetPath = resolve(pathArg ?? ".");
|
|
75
|
+
if (opts.remove) {
|
|
76
|
+
const config = loadWatchConfig();
|
|
77
|
+
const before = config.entries.length;
|
|
78
|
+
config.entries = config.entries.filter((e) => e.path !== targetPath);
|
|
79
|
+
if (config.entries.length === before) {
|
|
80
|
+
warn(`${targetPath} is not in the watch list.`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
saveWatchConfig(config);
|
|
84
|
+
success(`Removed ${targetPath} from watch list.`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// Add directory to watch list
|
|
88
|
+
if (!existsSync(targetPath)) {
|
|
89
|
+
error(`Directory not found: ${targetPath}`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
const remoteUrl = getGitRemoteUrl(targetPath);
|
|
93
|
+
if (!remoteUrl) {
|
|
94
|
+
error(`No git remote found in ${targetPath}. Is this a git repository?`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
const repoFullName = parseGitRemote(remoteUrl);
|
|
98
|
+
if (!repoFullName) {
|
|
99
|
+
error(`Could not parse git remote URL: ${remoteUrl}`);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
const config = loadWatchConfig();
|
|
103
|
+
// Check for duplicates
|
|
104
|
+
const existing = config.entries.find((e) => e.path === targetPath);
|
|
105
|
+
if (existing) {
|
|
106
|
+
if (existing.repoFullName === repoFullName) {
|
|
107
|
+
info(`${targetPath} is already watched as ${chalk.cyan(repoFullName)}.`);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// Update remote if changed
|
|
111
|
+
existing.remoteUrl = remoteUrl;
|
|
112
|
+
existing.repoFullName = repoFullName;
|
|
113
|
+
saveWatchConfig(config);
|
|
114
|
+
success(`Updated ${targetPath} → ${chalk.cyan(repoFullName)} (via git remote)`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
config.entries.push({
|
|
118
|
+
path: targetPath,
|
|
119
|
+
remoteUrl,
|
|
120
|
+
repoFullName,
|
|
121
|
+
addedAt: new Date().toISOString(),
|
|
122
|
+
});
|
|
123
|
+
saveWatchConfig(config);
|
|
124
|
+
success(`Added ${targetPath} → ${chalk.cyan(repoFullName)} (via git remote)`);
|
|
125
|
+
if (opts.start !== false) {
|
|
126
|
+
info("Starting agent...\n");
|
|
127
|
+
const binPath = join(__dirname, "..", "..", "..", "bin", "octopus.js");
|
|
128
|
+
const args = [binPath, "agent", "start"];
|
|
129
|
+
if (opts.verbose)
|
|
130
|
+
args.push("--verbose");
|
|
131
|
+
const child = spawn(process.execPath, args, {
|
|
132
|
+
stdio: "inherit",
|
|
133
|
+
});
|
|
134
|
+
child.on("close", (code) => process.exit(code ?? 0));
|
|
135
|
+
await new Promise(() => { });
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=watch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../../src/commands/agent/watch.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
2
5
|
import { loginCommand } from "./commands/login.js";
|
|
3
6
|
import { logoutCommand } from "./commands/logout.js";
|
|
4
7
|
import { whoamiCommand } from "./commands/whoami.js";
|
|
@@ -9,11 +12,21 @@ import { prCommand } from "./commands/pr/index.js";
|
|
|
9
12
|
import { knowledgeCommand } from "./commands/knowledge/index.js";
|
|
10
13
|
import { analyzeDepsCommand } from "./commands/analyze-deps.js";
|
|
11
14
|
import { skillsCommand } from "./commands/skills.js";
|
|
15
|
+
import { agentCommand } from "./commands/agent/index.js";
|
|
16
|
+
let version = "0.0.0";
|
|
17
|
+
try {
|
|
18
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
|
|
20
|
+
version = pkg.version ?? version;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// fall back to placeholder; CLI remains functional
|
|
24
|
+
}
|
|
12
25
|
const program = new Command();
|
|
13
26
|
program
|
|
14
27
|
.name("octopus")
|
|
15
28
|
.description("Octopus CLI — AI-powered PR review and codebase intelligence")
|
|
16
|
-
.version(
|
|
29
|
+
.version(version);
|
|
17
30
|
program.addCommand(loginCommand);
|
|
18
31
|
program.addCommand(logoutCommand);
|
|
19
32
|
program.addCommand(whoamiCommand);
|
|
@@ -24,5 +37,6 @@ program.addCommand(prCommand);
|
|
|
24
37
|
program.addCommand(knowledgeCommand);
|
|
25
38
|
program.addCommand(analyzeDepsCommand);
|
|
26
39
|
program.addCommand(skillsCommand);
|
|
40
|
+
program.addCommand(agentCommand);
|
|
27
41
|
program.parse();
|
|
28
42
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,IAAI,OAAO,GAAG,OAAO,CAAC;AACtB,IAAI,CAAC;IACH,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IACrF,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;AACnC,CAAC;AAAC,MAAM,CAAC;IACP,mDAAmD;AACrD,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,8DAA8D,CAAC;KAC3E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC9B,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AAEjC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|