grepmax 0.10.3 → 0.11.0
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/context.js +223 -0
- package/dist/commands/diff.js +176 -0
- package/dist/commands/doctor.js +223 -47
- package/dist/commands/impact.js +138 -0
- package/dist/commands/mcp.js +304 -0
- package/dist/commands/project.js +3 -8
- package/dist/commands/related.js +3 -8
- package/dist/commands/similar.js +175 -0
- package/dist/commands/test-find.js +109 -0
- package/dist/index.js +10 -0
- package/dist/lib/graph/impact.js +117 -0
- package/dist/lib/store/vector-db.js +2 -2
- package/dist/lib/utils/arrow.js +13 -0
- package/dist/lib/utils/git.js +53 -0
- package/dist/lib/utils/lock.js +3 -0
- package/package.json +1 -1
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
- package/plugins/grepmax/agents/semantic-explore.md +86 -0
- package/plugins/grepmax/commands/gmax-add.md +7 -0
- package/plugins/grepmax/commands/gmax-doctor.md +6 -0
- package/plugins/grepmax/commands/gmax-reindex.md +6 -0
- package/plugins/grepmax/commands/gmax-status.md +6 -0
- package/plugins/grepmax/hooks/cwd-changed.js +84 -0
- package/plugins/grepmax/hooks/pre-grep.js +99 -0
- package/plugins/grepmax/hooks/start.js +1 -1
- package/plugins/grepmax/hooks/subagent-start.js +61 -0
- package/plugins/grepmax/hooks.json +34 -0
- package/plugins/grepmax/skills/grepmax/SKILL.md +45 -2
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.context = void 0;
|
|
46
|
+
const fs = __importStar(require("node:fs"));
|
|
47
|
+
const path = __importStar(require("node:path"));
|
|
48
|
+
const commander_1 = require("commander");
|
|
49
|
+
const searcher_1 = require("../lib/search/searcher");
|
|
50
|
+
const skeleton_1 = require("../lib/skeleton");
|
|
51
|
+
const vector_db_1 = require("../lib/store/vector-db");
|
|
52
|
+
const filter_builder_1 = require("../lib/utils/filter-builder");
|
|
53
|
+
const exit_1 = require("../lib/utils/exit");
|
|
54
|
+
const project_root_1 = require("../lib/utils/project-root");
|
|
55
|
+
const arrow_1 = require("../lib/utils/arrow");
|
|
56
|
+
function estimateTokens(text) {
|
|
57
|
+
return Math.ceil(text.length / 4);
|
|
58
|
+
}
|
|
59
|
+
exports.context = new commander_1.Command("context")
|
|
60
|
+
.description("Generate a token-budgeted topic summary (search + skeleton + extract)")
|
|
61
|
+
.argument("<topic>", "Natural language topic or directory path")
|
|
62
|
+
.option("--budget <tokens>", "Max tokens for output (default 4000)", "4000")
|
|
63
|
+
.option("-m, --max-results <n>", "Initial search result limit (default 10)", "10")
|
|
64
|
+
.option("--root <dir>", "Project root directory")
|
|
65
|
+
.option("--agent", "Compact output for AI agents", false)
|
|
66
|
+
.action((topic, opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
67
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
68
|
+
const budget = Number.parseInt(opts.budget || "4000", 10) || 4000;
|
|
69
|
+
const maxResults = Number.parseInt(opts.maxResults || "10", 10) || 10;
|
|
70
|
+
let vectorDb = null;
|
|
71
|
+
try {
|
|
72
|
+
const root = opts.root ? path.resolve(opts.root) : process.cwd();
|
|
73
|
+
const projectRoot = (_a = (0, project_root_1.findProjectRoot)(root)) !== null && _a !== void 0 ? _a : root;
|
|
74
|
+
const paths = (0, project_root_1.ensureProjectPaths)(projectRoot);
|
|
75
|
+
vectorDb = new vector_db_1.VectorDB(paths.lancedbDir);
|
|
76
|
+
const searcher = new searcher_1.Searcher(vectorDb);
|
|
77
|
+
const rel = (p) => p.startsWith(`${projectRoot}/`) ? p.slice(projectRoot.length + 1) : p;
|
|
78
|
+
// Phase 1: Semantic search
|
|
79
|
+
const response = yield searcher.search(topic, maxResults, { rerank: true }, {}, projectRoot);
|
|
80
|
+
if (response.data.length === 0) {
|
|
81
|
+
console.log(`No results found for "${topic}".`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
let tokensUsed = 0;
|
|
85
|
+
const sections = [];
|
|
86
|
+
// Header
|
|
87
|
+
const header = `=== Context: "${topic}" ===`;
|
|
88
|
+
sections.push(header);
|
|
89
|
+
tokensUsed += estimateTokens(header);
|
|
90
|
+
// Phase 2: Entry points (ORCHESTRATION role results)
|
|
91
|
+
const orchestrators = response.data.filter((r) => r.role === "ORCHESTRATION");
|
|
92
|
+
const entryPoints = orchestrators.length > 0 ? orchestrators : response.data.slice(0, 3);
|
|
93
|
+
const epSection = ["\n## Entry Points"];
|
|
94
|
+
for (const r of entryPoints.slice(0, 5)) {
|
|
95
|
+
const p = String(r.path || ((_b = r.metadata) === null || _b === void 0 ? void 0 : _b.path) || "");
|
|
96
|
+
const line = Number((_c = r.start_line) !== null && _c !== void 0 ? _c : 0);
|
|
97
|
+
const sym = (_e = (_d = (0, arrow_1.toArr)(r.defined_symbols)) === null || _d === void 0 ? void 0 : _d[0]) !== null && _e !== void 0 ? _e : "";
|
|
98
|
+
const role = String(r.role || "IMPLEMENTATION");
|
|
99
|
+
epSection.push(`${rel(p)}:${line + 1} ${sym} [${role}]`);
|
|
100
|
+
}
|
|
101
|
+
const epText = epSection.join("\n");
|
|
102
|
+
if (tokensUsed + estimateTokens(epText) <= budget) {
|
|
103
|
+
sections.push(epText);
|
|
104
|
+
tokensUsed += estimateTokens(epText);
|
|
105
|
+
}
|
|
106
|
+
// Phase 3: Key function bodies (top 2-3 results)
|
|
107
|
+
const topChunks = entryPoints.slice(0, 3);
|
|
108
|
+
const bodySection = ["\n## Key Functions"];
|
|
109
|
+
for (const r of topChunks) {
|
|
110
|
+
const absP = String(r.path || "");
|
|
111
|
+
const startLine = Number((_f = r.start_line) !== null && _f !== void 0 ? _f : 0);
|
|
112
|
+
const endLine = Number((_g = r.end_line) !== null && _g !== void 0 ? _g : startLine);
|
|
113
|
+
const sym = (_j = (_h = (0, arrow_1.toArr)(r.defined_symbols)) === null || _h === void 0 ? void 0 : _h[0]) !== null && _j !== void 0 ? _j : "";
|
|
114
|
+
try {
|
|
115
|
+
const content = fs.readFileSync(absP, "utf-8");
|
|
116
|
+
const allLines = content.split("\n");
|
|
117
|
+
const body = allLines
|
|
118
|
+
.slice(startLine, Math.min(endLine + 1, allLines.length))
|
|
119
|
+
.join("\n");
|
|
120
|
+
const blob = `\n--- ${rel(absP)}:${startLine + 1} ${sym} ---\n${body}`;
|
|
121
|
+
const blobTokens = estimateTokens(blob);
|
|
122
|
+
if (tokensUsed + blobTokens > budget)
|
|
123
|
+
break;
|
|
124
|
+
bodySection.push(blob);
|
|
125
|
+
tokensUsed += blobTokens;
|
|
126
|
+
}
|
|
127
|
+
catch (_k) {
|
|
128
|
+
// File not readable — skip
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (bodySection.length > 1) {
|
|
132
|
+
sections.push(bodySection.join(""));
|
|
133
|
+
}
|
|
134
|
+
// Phase 4: File skeletons for unique files
|
|
135
|
+
const uniqueFiles = [
|
|
136
|
+
...new Set(response.data
|
|
137
|
+
.map((r) => String(r.path || ""))
|
|
138
|
+
.filter(Boolean)),
|
|
139
|
+
].slice(0, 5);
|
|
140
|
+
const skelSection = ["\n## File Structure"];
|
|
141
|
+
const skeletonizer = new skeleton_1.Skeletonizer();
|
|
142
|
+
yield skeletonizer.init();
|
|
143
|
+
for (const absP of uniqueFiles) {
|
|
144
|
+
if (!skeletonizer.isSupported(absP).supported)
|
|
145
|
+
continue;
|
|
146
|
+
try {
|
|
147
|
+
const content = fs.readFileSync(absP, "utf-8");
|
|
148
|
+
const result = yield skeletonizer.skeletonizeFile(absP, content);
|
|
149
|
+
if (!result.success)
|
|
150
|
+
continue;
|
|
151
|
+
const blob = `\n--- ${rel(absP)} (skeleton, ~${result.tokenEstimate} tokens) ---\n${result.skeleton}`;
|
|
152
|
+
const blobTokens = estimateTokens(blob);
|
|
153
|
+
if (tokensUsed + blobTokens > budget)
|
|
154
|
+
break;
|
|
155
|
+
skelSection.push(blob);
|
|
156
|
+
tokensUsed += blobTokens;
|
|
157
|
+
}
|
|
158
|
+
catch (_l) {
|
|
159
|
+
// Skip unreadable files
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (skelSection.length > 1) {
|
|
163
|
+
sections.push(skelSection.join(""));
|
|
164
|
+
}
|
|
165
|
+
// Phase 5: Related files summary
|
|
166
|
+
const table = yield vectorDb.ensureTable();
|
|
167
|
+
const allSymbols = new Set();
|
|
168
|
+
for (const r of response.data) {
|
|
169
|
+
for (const s of (0, arrow_1.toArr)(r.defined_symbols))
|
|
170
|
+
allSymbols.add(s);
|
|
171
|
+
}
|
|
172
|
+
if (allSymbols.size > 0) {
|
|
173
|
+
const pathScope = `path LIKE '${(0, filter_builder_1.escapeSqlString)(projectRoot)}/%'`;
|
|
174
|
+
const relatedCounts = new Map();
|
|
175
|
+
const searchedFiles = new Set(uniqueFiles);
|
|
176
|
+
for (const sym of [...allSymbols].slice(0, 20)) {
|
|
177
|
+
const rows = yield table
|
|
178
|
+
.query()
|
|
179
|
+
.select(["path"])
|
|
180
|
+
.where(`array_contains(referenced_symbols, '${(0, filter_builder_1.escapeSqlString)(sym)}') AND ${pathScope}`)
|
|
181
|
+
.limit(5)
|
|
182
|
+
.toArray();
|
|
183
|
+
for (const row of rows) {
|
|
184
|
+
const p = String(row.path || "");
|
|
185
|
+
if (searchedFiles.has(p))
|
|
186
|
+
continue;
|
|
187
|
+
relatedCounts.set(p, (relatedCounts.get(p) || 0) + 1);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const topRelated = Array.from(relatedCounts.entries())
|
|
191
|
+
.sort((a, b) => b[1] - a[1])
|
|
192
|
+
.slice(0, 5);
|
|
193
|
+
if (topRelated.length > 0) {
|
|
194
|
+
const relSection = ["\n## Related Files"];
|
|
195
|
+
for (const [p, count] of topRelated) {
|
|
196
|
+
relSection.push(`${rel(p)} — ${count} shared symbol${count > 1 ? "s" : ""}`);
|
|
197
|
+
}
|
|
198
|
+
const relText = relSection.join("\n");
|
|
199
|
+
if (tokensUsed + estimateTokens(relText) <= budget) {
|
|
200
|
+
sections.push(relText);
|
|
201
|
+
tokensUsed += estimateTokens(relText);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// Footer
|
|
206
|
+
sections.push(`\n(~${tokensUsed}/${budget} tokens used)`);
|
|
207
|
+
console.log(sections.join("\n"));
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
211
|
+
console.error("Context generation failed:", msg);
|
|
212
|
+
process.exitCode = 1;
|
|
213
|
+
}
|
|
214
|
+
finally {
|
|
215
|
+
if (vectorDb) {
|
|
216
|
+
try {
|
|
217
|
+
yield vectorDb.close();
|
|
218
|
+
}
|
|
219
|
+
catch (_m) { }
|
|
220
|
+
}
|
|
221
|
+
yield (0, exit_1.gracefulExit)();
|
|
222
|
+
}
|
|
223
|
+
}));
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.diff = void 0;
|
|
46
|
+
const path = __importStar(require("node:path"));
|
|
47
|
+
const commander_1 = require("commander");
|
|
48
|
+
const searcher_1 = require("../lib/search/searcher");
|
|
49
|
+
const vector_db_1 = require("../lib/store/vector-db");
|
|
50
|
+
const filter_builder_1 = require("../lib/utils/filter-builder");
|
|
51
|
+
const exit_1 = require("../lib/utils/exit");
|
|
52
|
+
const git_1 = require("../lib/utils/git");
|
|
53
|
+
const project_root_1 = require("../lib/utils/project-root");
|
|
54
|
+
const arrow_1 = require("../lib/utils/arrow");
|
|
55
|
+
exports.diff = new commander_1.Command("diff")
|
|
56
|
+
.description("Search code scoped to git changes")
|
|
57
|
+
.argument("[ref]", "Git ref to diff against (e.g. main, HEAD~5)")
|
|
58
|
+
.option("-q, --query <query>", "Semantic search within changed files")
|
|
59
|
+
.option("-m, --max-count <n>", "Max results (default 10)", "10")
|
|
60
|
+
.option("--role <role>", "Filter by role: ORCHESTRATION, DEFINITION, IMPLEMENTATION")
|
|
61
|
+
.option("--root <dir>", "Project root directory")
|
|
62
|
+
.option("--agent", "Compact output for AI agents", false)
|
|
63
|
+
.action((ref, opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
65
|
+
const limit = Math.min(Math.max(Number.parseInt(opts.maxCount || "10", 10), 1), 50);
|
|
66
|
+
let vectorDb = null;
|
|
67
|
+
try {
|
|
68
|
+
const root = opts.root ? path.resolve(opts.root) : process.cwd();
|
|
69
|
+
const projectRoot = (_a = (0, project_root_1.findProjectRoot)(root)) !== null && _a !== void 0 ? _a : root;
|
|
70
|
+
const paths = (0, project_root_1.ensureProjectPaths)(projectRoot);
|
|
71
|
+
vectorDb = new vector_db_1.VectorDB(paths.lancedbDir);
|
|
72
|
+
const changedFiles = (0, git_1.getChangedFiles)(ref, projectRoot);
|
|
73
|
+
if (changedFiles.length === 0) {
|
|
74
|
+
console.log(ref ? `No changes found relative to ${ref}.` : "No uncommitted changes found.");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const rel = (p) => p.startsWith(`${projectRoot}/`) ? p.slice(projectRoot.length + 1) : p;
|
|
78
|
+
if (opts.query) {
|
|
79
|
+
// Semantic search scoped to changed files
|
|
80
|
+
const searcher = new searcher_1.Searcher(vectorDb);
|
|
81
|
+
const response = yield searcher.search(opts.query, limit, { rerank: true }, Object.assign({}, (opts.role ? { role: opts.role } : {})), projectRoot);
|
|
82
|
+
// Filter results to only changed files
|
|
83
|
+
const changedSet = new Set(changedFiles);
|
|
84
|
+
const filtered = response.data.filter((r) => {
|
|
85
|
+
var _a;
|
|
86
|
+
const p = ((_a = r.metadata) === null || _a === void 0 ? void 0 : _a.path) || r.path || "";
|
|
87
|
+
return changedSet.has(p);
|
|
88
|
+
});
|
|
89
|
+
if (filtered.length === 0) {
|
|
90
|
+
console.log("No indexed results found in changed files for that query.");
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (opts.agent) {
|
|
94
|
+
for (const r of filtered.slice(0, limit)) {
|
|
95
|
+
const p = String(r.path || ((_b = r.metadata) === null || _b === void 0 ? void 0 : _b.path) || "");
|
|
96
|
+
const line = Number((_c = r.start_line) !== null && _c !== void 0 ? _c : 0);
|
|
97
|
+
const sym = (_e = (_d = (0, arrow_1.toArr)(r.defined_symbols)) === null || _d === void 0 ? void 0 : _d[0]) !== null && _e !== void 0 ? _e : "";
|
|
98
|
+
const role = String(r.role || "IMPL");
|
|
99
|
+
console.log(`${rel(p)}:${line + 1} ${sym} [${role}]`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
console.log(`Changed files matching "${opts.query}":\n`);
|
|
104
|
+
for (const r of filtered.slice(0, limit)) {
|
|
105
|
+
const p = String(r.path || ((_f = r.metadata) === null || _f === void 0 ? void 0 : _f.path) || "");
|
|
106
|
+
const line = Number((_g = r.start_line) !== null && _g !== void 0 ? _g : 0);
|
|
107
|
+
const sym = (_j = (_h = (0, arrow_1.toArr)(r.defined_symbols)) === null || _h === void 0 ? void 0 : _h[0]) !== null && _j !== void 0 ? _j : "";
|
|
108
|
+
const role = String(r.role || "IMPLEMENTATION");
|
|
109
|
+
const score = (_l = (_k = r.score) === null || _k === void 0 ? void 0 : _k.toFixed(3)) !== null && _l !== void 0 ? _l : "?";
|
|
110
|
+
console.log(` ${rel(p)}:${line + 1} ${sym} [${role}] (${score})`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// No query — list changed files with their indexed symbols
|
|
116
|
+
const table = yield vectorDb.ensureTable();
|
|
117
|
+
if (opts.agent) {
|
|
118
|
+
for (const file of changedFiles) {
|
|
119
|
+
const chunks = yield table
|
|
120
|
+
.query()
|
|
121
|
+
.select(["path", "start_line", "defined_symbols", "role"])
|
|
122
|
+
.where(`path = '${(0, filter_builder_1.escapeSqlString)(file)}'`)
|
|
123
|
+
.limit(50)
|
|
124
|
+
.toArray();
|
|
125
|
+
if (chunks.length === 0) {
|
|
126
|
+
console.log(`${rel(file)}\t(not indexed)`);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
for (const chunk of chunks) {
|
|
130
|
+
const sym = (_o = (_m = (0, arrow_1.toArr)(chunk.defined_symbols)) === null || _m === void 0 ? void 0 : _m[0]) !== null && _o !== void 0 ? _o : "";
|
|
131
|
+
const line = (_p = chunk.start_line) !== null && _p !== void 0 ? _p : 0;
|
|
132
|
+
const role = (chunk.role || "IMPL").slice(0, 4);
|
|
133
|
+
if (sym) {
|
|
134
|
+
console.log(`${rel(file)}:${line + 1}\t${sym}\t[${role}]`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
console.log(`${changedFiles.length} changed file${changedFiles.length === 1 ? "" : "s"}${ref ? ` (vs ${ref})` : ""}:\n`);
|
|
142
|
+
for (const file of changedFiles) {
|
|
143
|
+
const chunks = yield table
|
|
144
|
+
.query()
|
|
145
|
+
.select(["defined_symbols", "role"])
|
|
146
|
+
.where(`path = '${(0, filter_builder_1.escapeSqlString)(file)}'`)
|
|
147
|
+
.limit(50)
|
|
148
|
+
.toArray();
|
|
149
|
+
const symbols = chunks
|
|
150
|
+
.flatMap((c) => (0, arrow_1.toArr)(c.defined_symbols))
|
|
151
|
+
.filter(Boolean);
|
|
152
|
+
if (symbols.length > 0) {
|
|
153
|
+
console.log(` ${rel(file)} (${symbols.length} symbol${symbols.length === 1 ? "" : "s"}: ${symbols.slice(0, 5).join(", ")}${symbols.length > 5 ? "..." : ""})`);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
console.log(` ${rel(file)}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
164
|
+
console.error("Diff failed:", msg);
|
|
165
|
+
process.exitCode = 1;
|
|
166
|
+
}
|
|
167
|
+
finally {
|
|
168
|
+
if (vectorDb) {
|
|
169
|
+
try {
|
|
170
|
+
yield vectorDb.close();
|
|
171
|
+
}
|
|
172
|
+
catch (_q) { }
|
|
173
|
+
}
|
|
174
|
+
yield (0, exit_1.gracefulExit)();
|
|
175
|
+
}
|
|
176
|
+
}));
|