@kage-core/kage-graph-mcp 1.1.19 → 1.1.20
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/README.md +20 -17
- package/dist/cli.js +8 -3
- package/dist/index.js +4 -3
- package/dist/kernel.js +177 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,18 +9,16 @@ This package exposes two surfaces:
|
|
|
9
9
|
|
|
10
10
|
## Latest Release
|
|
11
11
|
|
|
12
|
-
`1.1.
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
- `kage init` remains a packet-only bootstrap path; full graph generation stays
|
|
23
|
-
with `kage refresh` and `kage index`.
|
|
12
|
+
`1.1.20` publishes the large-repo indexing pass:
|
|
13
|
+
|
|
14
|
+
- repeated `kage refresh` calls reuse unchanged code graph artifacts by source
|
|
15
|
+
stat fingerprint, with `kage refresh --full` available for intentional clean
|
|
16
|
+
rebuilds.
|
|
17
|
+
- `kage code-index` prefers SCIP via `scip-typescript` plus the `scip` CLI when
|
|
18
|
+
those tools are installed, then falls back to Kage's built-in LSP-compatible
|
|
19
|
+
symbol index.
|
|
20
|
+
- read-only commands and MCP sessions reuse current graph artifacts instead of
|
|
21
|
+
rebuilding them when inputs are fresh.
|
|
24
22
|
|
|
25
23
|
`1.1.17` publishes content-based graph freshness:
|
|
26
24
|
|
|
@@ -116,6 +114,7 @@ kage policy --project /path/to/repo
|
|
|
116
114
|
kage doctor --project /path/to/repo
|
|
117
115
|
kage index --project /path/to/repo
|
|
118
116
|
kage refresh --project /path/to/repo
|
|
117
|
+
kage refresh --project /path/to/repo --full
|
|
119
118
|
kage branch --project /path/to/repo
|
|
120
119
|
kage code-index --project /path/to/repo
|
|
121
120
|
kage code-graph --project /path/to/repo
|
|
@@ -206,11 +205,13 @@ generic extraction in metrics and file parser coverage. This keeps installation
|
|
|
206
205
|
light while allowing teams to plug in the strongest indexer available for their
|
|
207
206
|
language stack.
|
|
208
207
|
|
|
209
|
-
`kage code-index --project <repo>`
|
|
210
|
-
|
|
208
|
+
`kage code-index --project <repo>` now tries the best external indexer first for
|
|
209
|
+
the common JS/TS case: if `scip-typescript` and the `scip` CLI are on the repo or
|
|
210
|
+
shell path, it writes `.agent_memory/code_index/scip.json` from the generated
|
|
211
|
+
SCIP index. If those tools are unavailable, it writes
|
|
212
|
+
`.agent_memory/code_index/lsp-symbols.json` using Kage's local parser. The CI,
|
|
211
213
|
PR, and sync workflows run it before refresh so the code graph has a committed
|
|
212
|
-
precise-index slot
|
|
213
|
-
artifacts from their preferred toolchain.
|
|
214
|
+
precise-index slot without making first-run setup depend on external binaries.
|
|
214
215
|
|
|
215
216
|
The memory graph follows the same product direction as temporal context graph
|
|
216
217
|
systems such as Graphiti: immutable ingestion episodes, derived entities and
|
|
@@ -258,7 +259,9 @@ Use `kage refresh --project <repo>` or the `kage_refresh` MCP tool after
|
|
|
258
259
|
meaningful file/content changes. Refresh rebuilds indexes, code graph, memory
|
|
259
260
|
graph, metrics, and stale-memory metadata. Memory is marked stale when status or
|
|
260
261
|
feedback says it is stale, its TTL expires, or grounded paths disappear. Pushes
|
|
261
|
-
and empty/same-tree commits do not need another refresh.
|
|
262
|
+
and empty/same-tree commits do not need another refresh. Use `--full` or
|
|
263
|
+
`kage_refresh` with `full: true` only when you intentionally want to bypass
|
|
264
|
+
unchanged-graph reuse and rebuild the code graph from scratch.
|
|
262
265
|
|
|
263
266
|
Use `kage gc --project <repo> --dry-run` to preview stale packet cleanup.
|
|
264
267
|
`kage gc --project <repo>` marks stale repo packets deprecated, rebuilds
|
package/dist/cli.js
CHANGED
|
@@ -24,7 +24,7 @@ Usage:
|
|
|
24
24
|
kage daemon status --project <dir> [--json]
|
|
25
25
|
kage daemon doctor --project <dir> [--json]
|
|
26
26
|
kage viewer --project <dir> [--port 3113]
|
|
27
|
-
kage refresh --project <dir> [--json]
|
|
27
|
+
kage refresh --project <dir> [--full] [--json]
|
|
28
28
|
kage gc --project <dir> [--dry-run] [--force] [--json]
|
|
29
29
|
kage pr summarize --project <dir> [--json]
|
|
30
30
|
kage pr check --project <dir> [--json]
|
|
@@ -335,7 +335,7 @@ async function main() {
|
|
|
335
335
|
return;
|
|
336
336
|
}
|
|
337
337
|
if (command === "refresh") {
|
|
338
|
-
const result = (0, kernel_js_1.refreshProject)(projectArg(args));
|
|
338
|
+
const result = (0, kernel_js_1.refreshProject)(projectArg(args), { full: args.includes("--full") });
|
|
339
339
|
if (args.includes("--json")) {
|
|
340
340
|
console.log(JSON.stringify(result, null, 2));
|
|
341
341
|
if (!result.ok)
|
|
@@ -506,7 +506,7 @@ async function main() {
|
|
|
506
506
|
return;
|
|
507
507
|
}
|
|
508
508
|
if (command === "code-index") {
|
|
509
|
-
const result = (0, kernel_js_1.
|
|
509
|
+
const result = (0, kernel_js_1.writeCodeIndex)(projectArg(args));
|
|
510
510
|
if (args.includes("--json")) {
|
|
511
511
|
console.log(JSON.stringify(result, null, 2));
|
|
512
512
|
return;
|
|
@@ -516,6 +516,11 @@ async function main() {
|
|
|
516
516
|
console.log(`Path: ${result.path}`);
|
|
517
517
|
console.log(`Documents: ${result.documents}`);
|
|
518
518
|
console.log(`Symbols: ${result.symbols}`);
|
|
519
|
+
if (result.warnings.length) {
|
|
520
|
+
console.log("\nWarnings:");
|
|
521
|
+
for (const warning of result.warnings)
|
|
522
|
+
console.log(` - ${warning}`);
|
|
523
|
+
}
|
|
519
524
|
if (result.errors.length) {
|
|
520
525
|
console.log("\nErrors:");
|
|
521
526
|
for (const error of result.errors)
|
package/dist/index.js
CHANGED
|
@@ -153,6 +153,7 @@ function listTools() {
|
|
|
153
153
|
type: "object",
|
|
154
154
|
properties: {
|
|
155
155
|
project_dir: { type: "string" },
|
|
156
|
+
full: { type: "boolean", description: "Force a full code graph rebuild instead of reusing unchanged graph artifacts." },
|
|
156
157
|
},
|
|
157
158
|
required: ["project_dir"],
|
|
158
159
|
},
|
|
@@ -173,7 +174,7 @@ function listTools() {
|
|
|
173
174
|
},
|
|
174
175
|
{
|
|
175
176
|
name: "kage_code_index",
|
|
176
|
-
description: "Write
|
|
177
|
+
description: "Write external code index artifacts consumed by the code graph. Prefers SCIP when scip-typescript and scip are installed, then falls back to the built-in LSP-compatible symbol index.",
|
|
177
178
|
inputSchema: {
|
|
178
179
|
type: "object",
|
|
179
180
|
properties: {
|
|
@@ -725,7 +726,7 @@ async function callTool(name, args) {
|
|
|
725
726
|
};
|
|
726
727
|
}
|
|
727
728
|
if (name === "kage_code_index") {
|
|
728
|
-
const result = (0, kernel_js_1.
|
|
729
|
+
const result = (0, kernel_js_1.writeCodeIndex)(String(args?.project_dir ?? ""));
|
|
729
730
|
return {
|
|
730
731
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
731
732
|
isError: !result.ok,
|
|
@@ -752,7 +753,7 @@ async function callTool(name, args) {
|
|
|
752
753
|
};
|
|
753
754
|
}
|
|
754
755
|
if (name === "kage_refresh") {
|
|
755
|
-
const result = (0, kernel_js_1.refreshProject)(String(args?.project_dir ?? ""));
|
|
756
|
+
const result = (0, kernel_js_1.refreshProject)(String(args?.project_dir ?? ""), { full: Boolean(args?.full) });
|
|
756
757
|
return {
|
|
757
758
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
758
759
|
isError: !result.ok,
|
package/dist/kernel.js
CHANGED
|
@@ -64,6 +64,7 @@ exports.ensureMemoryDirs = ensureMemoryDirs;
|
|
|
64
64
|
exports.loadApprovedPackets = loadApprovedPackets;
|
|
65
65
|
exports.loadPendingPackets = loadPendingPackets;
|
|
66
66
|
exports.writeLspSymbolIndex = writeLspSymbolIndex;
|
|
67
|
+
exports.writeCodeIndex = writeCodeIndex;
|
|
67
68
|
exports.buildCodeGraph = buildCodeGraph;
|
|
68
69
|
exports.buildKnowledgeGraph = buildKnowledgeGraph;
|
|
69
70
|
exports.buildIndexes = buildIndexes;
|
|
@@ -2177,6 +2178,8 @@ function externalSymbol(projectDir, parser, input) {
|
|
|
2177
2178
|
}
|
|
2178
2179
|
function parseKageExternalIndex(projectDir, parser, path) {
|
|
2179
2180
|
const raw = readJson(path);
|
|
2181
|
+
if (Array.isArray(raw.documents))
|
|
2182
|
+
return parseScipJsonObject(projectDir, raw);
|
|
2180
2183
|
const symbols = Array.isArray(raw.symbols)
|
|
2181
2184
|
? raw.symbols.flatMap((item) => isRecord(item) ? [externalSymbol(projectDir, parser, item)].filter(Boolean) : [])
|
|
2182
2185
|
: [];
|
|
@@ -2208,6 +2211,62 @@ function parseKageExternalIndex(projectDir, parser, path) {
|
|
|
2208
2211
|
: [];
|
|
2209
2212
|
return { symbols, imports, calls };
|
|
2210
2213
|
}
|
|
2214
|
+
function scipSymbolName(symbol) {
|
|
2215
|
+
const local = symbol.trim().split(/\s+/).at(-1) ?? symbol;
|
|
2216
|
+
const segment = local.split(/[\/#.`:]/).filter(Boolean).at(-1) ?? local;
|
|
2217
|
+
return segment.replace(/\(\)?$/, "").replace(/\.$/, "") || symbol;
|
|
2218
|
+
}
|
|
2219
|
+
function scipRangeLine(input) {
|
|
2220
|
+
if (Array.isArray(input) && typeof input[0] === "number")
|
|
2221
|
+
return Math.max(1, input[0] + 1);
|
|
2222
|
+
if (isRecord(input) && isRecord(input.start) && typeof input.start.line === "number")
|
|
2223
|
+
return Math.max(1, input.start.line + 1);
|
|
2224
|
+
return 1;
|
|
2225
|
+
}
|
|
2226
|
+
function parseScipJsonObject(projectDir, raw) {
|
|
2227
|
+
const symbols = [];
|
|
2228
|
+
const calls = [];
|
|
2229
|
+
const symbolInfo = new Map();
|
|
2230
|
+
const docs = Array.isArray(raw.documents) ? raw.documents : [];
|
|
2231
|
+
for (const doc of docs) {
|
|
2232
|
+
if (!isRecord(doc))
|
|
2233
|
+
continue;
|
|
2234
|
+
const rel = String(doc.relativePath ?? doc.relative_path ?? doc.path ?? doc.uri ?? "").replace(/^file:\/\//, "").replace(/\\/g, "/");
|
|
2235
|
+
if (!rel)
|
|
2236
|
+
continue;
|
|
2237
|
+
for (const item of Array.isArray(doc.symbols) ? doc.symbols : []) {
|
|
2238
|
+
if (isRecord(item) && typeof item.symbol === "string")
|
|
2239
|
+
symbolInfo.set(item.symbol, item);
|
|
2240
|
+
}
|
|
2241
|
+
for (const occurrence of Array.isArray(doc.occurrences) ? doc.occurrences : []) {
|
|
2242
|
+
if (!isRecord(occurrence) || typeof occurrence.symbol !== "string")
|
|
2243
|
+
continue;
|
|
2244
|
+
const role = Number(occurrence.symbolRoles ?? occurrence.symbol_roles ?? 0);
|
|
2245
|
+
const line = scipRangeLine(occurrence.range);
|
|
2246
|
+
const name = scipSymbolName(occurrence.symbol);
|
|
2247
|
+
if (!name || name === "local")
|
|
2248
|
+
continue;
|
|
2249
|
+
if ((role & 1) === 1) {
|
|
2250
|
+
const info = symbolInfo.get(occurrence.symbol) ?? {};
|
|
2251
|
+
const detail = Array.isArray(info.documentation) ? info.documentation.map(String).find(Boolean) : undefined;
|
|
2252
|
+
const symbol = externalSymbol(projectDir, "scip", {
|
|
2253
|
+
path: rel,
|
|
2254
|
+
name,
|
|
2255
|
+
kind: occurrence.syntaxKind ?? occurrence.syntax_kind ?? info.kind,
|
|
2256
|
+
line,
|
|
2257
|
+
signature: detail ?? name,
|
|
2258
|
+
exported: !occurrence.symbol.startsWith("local "),
|
|
2259
|
+
});
|
|
2260
|
+
if (symbol && !symbols.some((candidate) => candidate.id === symbol.id))
|
|
2261
|
+
symbols.push(symbol);
|
|
2262
|
+
}
|
|
2263
|
+
else {
|
|
2264
|
+
calls.push({ from_symbol: null, to_symbol: name, path: rel, line });
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
return { symbols, imports: [], calls };
|
|
2269
|
+
}
|
|
2211
2270
|
function parseLspDocumentSymbols(projectDir, path) {
|
|
2212
2271
|
const raw = readJson(path);
|
|
2213
2272
|
const docs = Array.isArray(raw) ? raw : isRecord(raw) && Array.isArray(raw.documents) ? raw.documents : [];
|
|
@@ -2280,9 +2339,119 @@ function writeLspSymbolIndex(projectDir) {
|
|
|
2280
2339
|
parser: "lsp",
|
|
2281
2340
|
documents: documents.length,
|
|
2282
2341
|
symbols: symbolCount,
|
|
2342
|
+
warnings: [],
|
|
2283
2343
|
errors,
|
|
2284
2344
|
};
|
|
2285
2345
|
}
|
|
2346
|
+
function executableOnPath(projectDir, command) {
|
|
2347
|
+
const local = (0, node_path_1.join)(projectDir, "node_modules", ".bin", command);
|
|
2348
|
+
if ((0, node_fs_1.existsSync)(local))
|
|
2349
|
+
return local;
|
|
2350
|
+
const localCmd = `${local}.cmd`;
|
|
2351
|
+
if ((0, node_fs_1.existsSync)(localCmd))
|
|
2352
|
+
return localCmd;
|
|
2353
|
+
for (const entry of (process.env.PATH ?? "").split(node_path_1.delimiter).filter(Boolean)) {
|
|
2354
|
+
const candidate = (0, node_path_1.join)(entry, command);
|
|
2355
|
+
if ((0, node_fs_1.existsSync)(candidate))
|
|
2356
|
+
return candidate;
|
|
2357
|
+
const cmdCandidate = `${candidate}.cmd`;
|
|
2358
|
+
if ((0, node_fs_1.existsSync)(cmdCandidate))
|
|
2359
|
+
return cmdCandidate;
|
|
2360
|
+
}
|
|
2361
|
+
return null;
|
|
2362
|
+
}
|
|
2363
|
+
function hasTypeScriptCode(projectDir) {
|
|
2364
|
+
return listCodeFiles(projectDir).some((path) => TS_AST_EXTENSIONS.has(extensionOf(path)));
|
|
2365
|
+
}
|
|
2366
|
+
function scipCliJson(scipCli, scipPath, projectDir) {
|
|
2367
|
+
try {
|
|
2368
|
+
return (0, node_child_process_1.execFileSync)(scipCli, ["print", "--json", scipPath], {
|
|
2369
|
+
cwd: projectDir,
|
|
2370
|
+
encoding: "utf8",
|
|
2371
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
2372
|
+
});
|
|
2373
|
+
}
|
|
2374
|
+
catch {
|
|
2375
|
+
return (0, node_child_process_1.execFileSync)(scipCli, ["print", scipPath, "--json"], {
|
|
2376
|
+
cwd: projectDir,
|
|
2377
|
+
encoding: "utf8",
|
|
2378
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
2379
|
+
});
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
function writeScipTypescriptIndex(projectDir) {
|
|
2383
|
+
if (!hasTypeScriptCode(projectDir))
|
|
2384
|
+
return null;
|
|
2385
|
+
const scipTypescript = executableOnPath(projectDir, "scip-typescript");
|
|
2386
|
+
if (!scipTypescript)
|
|
2387
|
+
return null;
|
|
2388
|
+
const scipCli = executableOnPath(projectDir, "scip");
|
|
2389
|
+
const outDir = (0, node_path_1.join)(memoryRoot(projectDir), "code_index");
|
|
2390
|
+
ensureDir(outDir);
|
|
2391
|
+
const scipPath = (0, node_path_1.join)(outDir, "index.scip");
|
|
2392
|
+
const outPath = (0, node_path_1.join)(outDir, "scip.json");
|
|
2393
|
+
const warnings = [];
|
|
2394
|
+
const errors = [];
|
|
2395
|
+
try {
|
|
2396
|
+
const args = ["index"];
|
|
2397
|
+
if (!(0, node_fs_1.existsSync)((0, node_path_1.join)(projectDir, "tsconfig.json")))
|
|
2398
|
+
args.push("--infer-tsconfig");
|
|
2399
|
+
(0, node_child_process_1.execFileSync)(scipTypescript, args, { cwd: projectDir, stdio: ["ignore", "pipe", "pipe"] });
|
|
2400
|
+
const generatedScipPath = (0, node_path_1.join)(projectDir, "index.scip");
|
|
2401
|
+
if ((0, node_fs_1.existsSync)(generatedScipPath))
|
|
2402
|
+
(0, node_fs_1.renameSync)(generatedScipPath, scipPath);
|
|
2403
|
+
if (!(0, node_fs_1.existsSync)(scipPath))
|
|
2404
|
+
throw new Error("scip-typescript completed but did not write index.scip");
|
|
2405
|
+
}
|
|
2406
|
+
catch (error) {
|
|
2407
|
+
errors.push(`scip-typescript failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2408
|
+
return { ok: false, project_dir: projectDir, path: scipPath, parser: "scip", documents: 0, symbols: 0, warnings, errors };
|
|
2409
|
+
}
|
|
2410
|
+
if (!scipCli) {
|
|
2411
|
+
warnings.push("scip-typescript wrote index.scip, but the scip CLI is not installed so Kage could not convert it into graph facts.");
|
|
2412
|
+
return { ok: false, project_dir: projectDir, path: scipPath, parser: "scip", documents: 0, symbols: 0, warnings, errors };
|
|
2413
|
+
}
|
|
2414
|
+
try {
|
|
2415
|
+
const raw = JSON.parse(scipCliJson(scipCli, scipPath, projectDir));
|
|
2416
|
+
const facts = parseScipJsonObject(projectDir, raw);
|
|
2417
|
+
writeJson(outPath, {
|
|
2418
|
+
schema_version: 1,
|
|
2419
|
+
generator: "scip-typescript",
|
|
2420
|
+
generated_at: nowIso(),
|
|
2421
|
+
source_artifact: (0, node_path_1.relative)(projectDir, scipPath).replace(/\\/g, "/"),
|
|
2422
|
+
symbols: facts.symbols,
|
|
2423
|
+
imports: facts.imports,
|
|
2424
|
+
calls: facts.calls,
|
|
2425
|
+
});
|
|
2426
|
+
return {
|
|
2427
|
+
ok: true,
|
|
2428
|
+
project_dir: projectDir,
|
|
2429
|
+
path: outPath,
|
|
2430
|
+
parser: "scip",
|
|
2431
|
+
documents: Array.isArray(raw.documents) ? raw.documents.length : 0,
|
|
2432
|
+
symbols: facts.symbols.length,
|
|
2433
|
+
warnings,
|
|
2434
|
+
errors,
|
|
2435
|
+
};
|
|
2436
|
+
}
|
|
2437
|
+
catch (error) {
|
|
2438
|
+
errors.push(`scip conversion failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2439
|
+
return { ok: false, project_dir: projectDir, path: scipPath, parser: "scip", documents: 0, symbols: 0, warnings, errors };
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
function writeCodeIndex(projectDir) {
|
|
2443
|
+
const scip = writeScipTypescriptIndex(projectDir);
|
|
2444
|
+
if (scip?.ok)
|
|
2445
|
+
return scip;
|
|
2446
|
+
const lsp = writeLspSymbolIndex(projectDir);
|
|
2447
|
+
return {
|
|
2448
|
+
...lsp,
|
|
2449
|
+
warnings: [
|
|
2450
|
+
...(scip ? [...scip.warnings, ...scip.errors] : ["scip-typescript not found; used built-in LSP-compatible fallback."]),
|
|
2451
|
+
...lsp.warnings,
|
|
2452
|
+
],
|
|
2453
|
+
};
|
|
2454
|
+
}
|
|
2286
2455
|
function parseLsif(projectDir, path) {
|
|
2287
2456
|
const docs = new Map();
|
|
2288
2457
|
const ranges = new Map();
|
|
@@ -2380,7 +2549,7 @@ function extractPackages(projectDir) {
|
|
|
2380
2549
|
}
|
|
2381
2550
|
return packages.sort((a, b) => a.kind.localeCompare(b.kind) || a.name.localeCompare(b.name));
|
|
2382
2551
|
}
|
|
2383
|
-
function buildCodeGraph(projectDir) {
|
|
2552
|
+
function buildCodeGraph(projectDir, options = {}) {
|
|
2384
2553
|
ensureMemoryDirs(projectDir);
|
|
2385
2554
|
const branch = gitBranch(projectDir);
|
|
2386
2555
|
const head = gitHead(projectDir);
|
|
@@ -2389,7 +2558,7 @@ function buildCodeGraph(projectDir) {
|
|
|
2389
2558
|
const selection = codeIndexSelection(projectDir);
|
|
2390
2559
|
const absoluteFiles = selection.files;
|
|
2391
2560
|
const fingerprint = codeGraphStatFingerprint(projectDir, absoluteFiles);
|
|
2392
|
-
const cachedGraph = readCachedCodeGraph(projectDir, fingerprint);
|
|
2561
|
+
const cachedGraph = options.force ? null : readCachedCodeGraph(projectDir, fingerprint);
|
|
2393
2562
|
if (cachedGraph) {
|
|
2394
2563
|
selection.manifest.cache = { hits: absoluteFiles.length, misses: 0 };
|
|
2395
2564
|
selection.manifest.fingerprint = fingerprint;
|
|
@@ -2983,9 +3152,9 @@ function currentOrBuildGraphs(projectDir) {
|
|
|
2983
3152
|
}
|
|
2984
3153
|
return buildGraphIndexes(projectDir);
|
|
2985
3154
|
}
|
|
2986
|
-
function buildGraphIndexes(projectDir) {
|
|
3155
|
+
function buildGraphIndexes(projectDir, options = {}) {
|
|
2987
3156
|
const written = buildPacketIndexes(projectDir);
|
|
2988
|
-
const codeGraph = buildCodeGraph(projectDir);
|
|
3157
|
+
const codeGraph = buildCodeGraph(projectDir, { force: options.forceCodeGraph });
|
|
2989
3158
|
const knowledgeGraph = buildKnowledgeGraph(projectDir, codeGraph);
|
|
2990
3159
|
const graphIndexPath = (0, node_path_1.join)(indexesDir(projectDir), "graph.json");
|
|
2991
3160
|
const codeGraphIndexPath = (0, node_path_1.join)(indexesDir(projectDir), "code-graph.json");
|
|
@@ -3040,7 +3209,7 @@ function indexProjectDetailed(projectDir, options = {}) {
|
|
|
3040
3209
|
const structure = createRepoStructurePacket(projectDir);
|
|
3041
3210
|
if (structure)
|
|
3042
3211
|
upsertGeneratedPacket(projectDir, structure);
|
|
3043
|
-
const built = options.graphs === false ? null : buildGraphIndexes(projectDir);
|
|
3212
|
+
const built = options.graphs === false ? null : buildGraphIndexes(projectDir, { forceCodeGraph: options.full });
|
|
3044
3213
|
const indexes = built?.indexes ?? buildPacketIndexes(projectDir);
|
|
3045
3214
|
return {
|
|
3046
3215
|
result: {
|
|
@@ -3114,15 +3283,15 @@ function refreshPacketStaleness(projectDir) {
|
|
|
3114
3283
|
}
|
|
3115
3284
|
return { findings, updated };
|
|
3116
3285
|
}
|
|
3117
|
-
function refreshProject(projectDir) {
|
|
3118
|
-
const detailedIndex = indexProjectDetailed(projectDir);
|
|
3286
|
+
function refreshProject(projectDir, options = {}) {
|
|
3287
|
+
const detailedIndex = indexProjectDetailed(projectDir, { full: options.full });
|
|
3119
3288
|
const index = detailedIndex.result;
|
|
3120
3289
|
let codeGraph = detailedIndex.codeGraph;
|
|
3121
3290
|
let knowledgeGraph = detailedIndex.knowledgeGraph;
|
|
3122
3291
|
const stale = refreshPacketStaleness(projectDir);
|
|
3123
3292
|
let indexes = index.indexes;
|
|
3124
3293
|
if (stale.updated > 0) {
|
|
3125
|
-
const rebuilt = buildGraphIndexes(projectDir);
|
|
3294
|
+
const rebuilt = buildGraphIndexes(projectDir, { forceCodeGraph: options.full });
|
|
3126
3295
|
codeGraph = rebuilt.codeGraph;
|
|
3127
3296
|
knowledgeGraph = rebuilt.knowledgeGraph;
|
|
3128
3297
|
indexes = rebuilt.indexes.map((path) => (0, node_path_1.relative)(projectDir, path));
|