@colbymchenry/codegraph-darwin-arm64 1.2.0 → 1.3.1
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/bin/codegraph +5 -0
- package/lib/dist/bin/codegraph.d.ts +1 -1
- package/lib/dist/bin/codegraph.d.ts.map +1 -1
- package/lib/dist/bin/codegraph.js +232 -61
- package/lib/dist/bin/codegraph.js.map +1 -1
- package/lib/dist/bin/command-supervision.d.ts.map +1 -1
- package/lib/dist/bin/command-supervision.js +4 -1
- package/lib/dist/bin/command-supervision.js.map +1 -1
- package/lib/dist/db/index.d.ts +17 -5
- package/lib/dist/db/index.d.ts.map +1 -1
- package/lib/dist/db/index.js +68 -12
- package/lib/dist/db/index.js.map +1 -1
- package/lib/dist/db/migrations.d.ts +1 -1
- package/lib/dist/db/migrations.d.ts.map +1 -1
- package/lib/dist/db/migrations.js +19 -1
- package/lib/dist/db/migrations.js.map +1 -1
- package/lib/dist/db/queries.d.ts +76 -1
- package/lib/dist/db/queries.d.ts.map +1 -1
- package/lib/dist/db/queries.js +180 -0
- package/lib/dist/db/queries.js.map +1 -1
- package/lib/dist/db/schema.sql +19 -0
- package/lib/dist/directory.d.ts +9 -5
- package/lib/dist/directory.d.ts.map +1 -1
- package/lib/dist/directory.js +210 -19
- package/lib/dist/directory.js.map +1 -1
- package/lib/dist/extraction/cfml-extractor.d.ts +107 -0
- package/lib/dist/extraction/cfml-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/cfml-extractor.js +494 -0
- package/lib/dist/extraction/cfml-extractor.js.map +1 -0
- package/lib/dist/extraction/grammars.d.ts +9 -0
- package/lib/dist/extraction/grammars.d.ts.map +1 -1
- package/lib/dist/extraction/grammars.js +115 -3
- package/lib/dist/extraction/grammars.js.map +1 -1
- package/lib/dist/extraction/index.d.ts +46 -1
- package/lib/dist/extraction/index.d.ts.map +1 -1
- package/lib/dist/extraction/index.js +338 -34
- package/lib/dist/extraction/index.js.map +1 -1
- package/lib/dist/extraction/languages/arkts.d.ts +3 -0
- package/lib/dist/extraction/languages/arkts.d.ts.map +1 -0
- package/lib/dist/extraction/languages/arkts.js +127 -0
- package/lib/dist/extraction/languages/arkts.js.map +1 -0
- package/lib/dist/extraction/languages/c-cpp.d.ts +42 -0
- package/lib/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/lib/dist/extraction/languages/c-cpp.js +369 -4
- package/lib/dist/extraction/languages/c-cpp.js.map +1 -1
- package/lib/dist/extraction/languages/cfquery.d.ts +12 -0
- package/lib/dist/extraction/languages/cfquery.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cfquery.js +28 -0
- package/lib/dist/extraction/languages/cfquery.js.map +1 -0
- package/lib/dist/extraction/languages/cfscript.d.ts +3 -0
- package/lib/dist/extraction/languages/cfscript.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cfscript.js +73 -0
- package/lib/dist/extraction/languages/cfscript.js.map +1 -0
- package/lib/dist/extraction/languages/cobol.d.ts +33 -0
- package/lib/dist/extraction/languages/cobol.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cobol.js +499 -0
- package/lib/dist/extraction/languages/cobol.js.map +1 -0
- package/lib/dist/extraction/languages/erlang.d.ts +3 -0
- package/lib/dist/extraction/languages/erlang.d.ts.map +1 -0
- package/lib/dist/extraction/languages/erlang.js +350 -0
- package/lib/dist/extraction/languages/erlang.js.map +1 -0
- package/lib/dist/extraction/languages/index.d.ts.map +1 -1
- package/lib/dist/extraction/languages/index.js +18 -0
- package/lib/dist/extraction/languages/index.js.map +1 -1
- package/lib/dist/extraction/languages/nix.d.ts +3 -0
- package/lib/dist/extraction/languages/nix.d.ts.map +1 -0
- package/lib/dist/extraction/languages/nix.js +294 -0
- package/lib/dist/extraction/languages/nix.js.map +1 -0
- package/lib/dist/extraction/languages/solidity.d.ts +3 -0
- package/lib/dist/extraction/languages/solidity.d.ts.map +1 -0
- package/lib/dist/extraction/languages/solidity.js +293 -0
- package/lib/dist/extraction/languages/solidity.js.map +1 -0
- package/lib/dist/extraction/languages/terraform.d.ts +3 -0
- package/lib/dist/extraction/languages/terraform.d.ts.map +1 -0
- package/lib/dist/extraction/languages/terraform.js +641 -0
- package/lib/dist/extraction/languages/terraform.js.map +1 -0
- package/lib/dist/extraction/languages/vbnet.d.ts +11 -0
- package/lib/dist/extraction/languages/vbnet.d.ts.map +1 -0
- package/lib/dist/extraction/languages/vbnet.js +141 -0
- package/lib/dist/extraction/languages/vbnet.js.map +1 -0
- package/lib/dist/extraction/mybatis-extractor.d.ts +30 -10
- package/lib/dist/extraction/mybatis-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/mybatis-extractor.js +140 -38
- package/lib/dist/extraction/mybatis-extractor.js.map +1 -1
- package/lib/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter-helpers.js +1 -0
- package/lib/dist/extraction/tree-sitter-helpers.js.map +1 -1
- package/lib/dist/extraction/tree-sitter-types.d.ts +3 -1
- package/lib/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter.d.ts +38 -0
- package/lib/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter.js +753 -10
- package/lib/dist/extraction/tree-sitter.js.map +1 -1
- package/lib/dist/extraction/wasm/tree-sitter-arkts.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-terraform.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
- package/lib/dist/index.d.ts +63 -1
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +327 -5
- package/lib/dist/index.js.map +1 -1
- package/lib/dist/installer/index.d.ts.map +1 -1
- package/lib/dist/installer/index.js +3 -1
- package/lib/dist/installer/index.js.map +1 -1
- package/lib/dist/mcp/daemon.d.ts +25 -3
- package/lib/dist/mcp/daemon.d.ts.map +1 -1
- package/lib/dist/mcp/daemon.js +62 -8
- package/lib/dist/mcp/daemon.js.map +1 -1
- package/lib/dist/mcp/dynamic-boundaries.d.ts.map +1 -1
- package/lib/dist/mcp/dynamic-boundaries.js +2 -1
- package/lib/dist/mcp/dynamic-boundaries.js.map +1 -1
- package/lib/dist/mcp/early-ppid.d.ts +26 -0
- package/lib/dist/mcp/early-ppid.d.ts.map +1 -0
- package/lib/dist/mcp/early-ppid.js +29 -0
- package/lib/dist/mcp/early-ppid.js.map +1 -0
- package/lib/dist/mcp/index.d.ts.map +1 -1
- package/lib/dist/mcp/index.js +21 -4
- package/lib/dist/mcp/index.js.map +1 -1
- package/lib/dist/mcp/proxy.d.ts.map +1 -1
- package/lib/dist/mcp/proxy.js +29 -3
- package/lib/dist/mcp/proxy.js.map +1 -1
- package/lib/dist/mcp/query-pool.d.ts +14 -0
- package/lib/dist/mcp/query-pool.d.ts.map +1 -1
- package/lib/dist/mcp/query-pool.js +18 -0
- package/lib/dist/mcp/query-pool.js.map +1 -1
- package/lib/dist/mcp/session.d.ts.map +1 -1
- package/lib/dist/mcp/session.js +6 -0
- package/lib/dist/mcp/session.js.map +1 -1
- package/lib/dist/mcp/startup-handshake.d.ts +44 -0
- package/lib/dist/mcp/startup-handshake.d.ts.map +1 -0
- package/lib/dist/mcp/startup-handshake.js +73 -0
- package/lib/dist/mcp/startup-handshake.js.map +1 -0
- package/lib/dist/mcp/tools.d.ts +22 -0
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +88 -18
- package/lib/dist/mcp/tools.js.map +1 -1
- package/lib/dist/mcp/transport.d.ts.map +1 -1
- package/lib/dist/mcp/transport.js +18 -0
- package/lib/dist/mcp/transport.js.map +1 -1
- package/lib/dist/project-config.d.ts +38 -0
- package/lib/dist/project-config.d.ts.map +1 -1
- package/lib/dist/project-config.js +101 -2
- package/lib/dist/project-config.js.map +1 -1
- package/lib/dist/resolution/c-fnptr-synthesizer.d.ts +2 -1
- package/lib/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/lib/dist/resolution/c-fnptr-synthesizer.js +170 -146
- package/lib/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/lib/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/lib/dist/resolution/callback-synthesizer.js +982 -81
- package/lib/dist/resolution/callback-synthesizer.js.map +1 -1
- package/lib/dist/resolution/frameworks/cics.d.ts +20 -0
- package/lib/dist/resolution/frameworks/cics.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/cics.js +90 -0
- package/lib/dist/resolution/frameworks/cics.js.map +1 -0
- package/lib/dist/resolution/frameworks/index.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/index.js +6 -0
- package/lib/dist/resolution/frameworks/index.js.map +1 -1
- package/lib/dist/resolution/frameworks/java.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/java.js +14 -6
- package/lib/dist/resolution/frameworks/java.js.map +1 -1
- package/lib/dist/resolution/frameworks/terraform.d.ts +38 -0
- package/lib/dist/resolution/frameworks/terraform.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/terraform.js +277 -0
- package/lib/dist/resolution/frameworks/terraform.js.map +1 -0
- package/lib/dist/resolution/goframe-synthesizer.d.ts +2 -1
- package/lib/dist/resolution/goframe-synthesizer.d.ts.map +1 -1
- package/lib/dist/resolution/goframe-synthesizer.js +8 -3
- package/lib/dist/resolution/goframe-synthesizer.js.map +1 -1
- package/lib/dist/resolution/import-resolver.d.ts +7 -0
- package/lib/dist/resolution/import-resolver.d.ts.map +1 -1
- package/lib/dist/resolution/import-resolver.js +129 -4
- package/lib/dist/resolution/import-resolver.js.map +1 -1
- package/lib/dist/resolution/index.d.ts +49 -6
- package/lib/dist/resolution/index.d.ts.map +1 -1
- package/lib/dist/resolution/index.js +342 -65
- package/lib/dist/resolution/index.js.map +1 -1
- package/lib/dist/resolution/name-matcher.d.ts +0 -3
- package/lib/dist/resolution/name-matcher.d.ts.map +1 -1
- package/lib/dist/resolution/name-matcher.js +225 -33
- package/lib/dist/resolution/name-matcher.js.map +1 -1
- package/lib/dist/resolution/strip-comments.d.ts +1 -1
- package/lib/dist/resolution/strip-comments.d.ts.map +1 -1
- package/lib/dist/resolution/strip-comments.js +49 -0
- package/lib/dist/resolution/strip-comments.js.map +1 -1
- package/lib/dist/resolution/types.d.ts +29 -0
- package/lib/dist/resolution/types.d.ts.map +1 -1
- package/lib/dist/resolution/workspace-packages.d.ts +10 -0
- package/lib/dist/resolution/workspace-packages.d.ts.map +1 -1
- package/lib/dist/resolution/workspace-packages.js +142 -4
- package/lib/dist/resolution/workspace-packages.js.map +1 -1
- package/lib/dist/search/identifier-segments.d.ts +60 -0
- package/lib/dist/search/identifier-segments.d.ts.map +1 -0
- package/lib/dist/search/identifier-segments.js +176 -0
- package/lib/dist/search/identifier-segments.js.map +1 -0
- package/lib/dist/sync/git-hooks.d.ts.map +1 -1
- package/lib/dist/sync/git-hooks.js +2 -0
- package/lib/dist/sync/git-hooks.js.map +1 -1
- package/lib/dist/sync/watcher.d.ts +10 -5
- package/lib/dist/sync/watcher.d.ts.map +1 -1
- package/lib/dist/sync/watcher.js +51 -14
- package/lib/dist/sync/watcher.js.map +1 -1
- package/lib/dist/sync/worktree.d.ts.map +1 -1
- package/lib/dist/sync/worktree.js +5 -0
- package/lib/dist/sync/worktree.js.map +1 -1
- package/lib/dist/types.d.ts +19 -1
- package/lib/dist/types.d.ts.map +1 -1
- package/lib/dist/types.js +10 -0
- package/lib/dist/types.js.map +1 -1
- package/lib/node_modules/.package-lock.json +1 -1
- package/lib/package.json +1 -1
- package/package.json +1 -1
- package/lib/dist/reasoning/config.d.ts +0 -45
- package/lib/dist/reasoning/config.d.ts.map +0 -1
- package/lib/dist/reasoning/config.js +0 -171
- package/lib/dist/reasoning/config.js.map +0 -1
- package/lib/dist/reasoning/credentials.d.ts +0 -5
- package/lib/dist/reasoning/credentials.d.ts.map +0 -1
- package/lib/dist/reasoning/credentials.js +0 -83
- package/lib/dist/reasoning/credentials.js.map +0 -1
- package/lib/dist/reasoning/login.d.ts +0 -21
- package/lib/dist/reasoning/login.d.ts.map +0 -1
- package/lib/dist/reasoning/login.js +0 -85
- package/lib/dist/reasoning/login.js.map +0 -1
- package/lib/dist/reasoning/reasoner.d.ts +0 -43
- package/lib/dist/reasoning/reasoner.d.ts.map +0 -1
- package/lib/dist/reasoning/reasoner.js +0 -308
- package/lib/dist/reasoning/reasoner.js.map +0 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* A local-first code intelligence system that builds a semantic
|
|
5
5
|
* knowledge graph from any codebase.
|
|
6
6
|
*/
|
|
7
|
-
import { Node, Edge, FileRecord, ExtractionResult, Subgraph, TraversalOptions, SearchOptions, SearchResult, Context, GraphStats, TaskInput, TaskContext, BuildContextOptions, FindRelevantContextOptions } from './types';
|
|
7
|
+
import { Node, Edge, FileRecord, ExtractionResult, Subgraph, TraversalOptions, SearchOptions, SearchResult, SegmentMatch, Context, GraphStats, TaskInput, TaskContext, BuildContextOptions, FindRelevantContextOptions } from './types';
|
|
8
8
|
import { IndexProgress, IndexResult, SyncResult } from './extraction';
|
|
9
9
|
import { ResolutionResult } from './resolution';
|
|
10
10
|
import { WatchOptions, PendingFile } from './sync';
|
|
@@ -227,6 +227,16 @@ export declare class CodeGraph {
|
|
|
227
227
|
* freshness without shelling out to `codegraph status --json`. (#329)
|
|
228
228
|
*/
|
|
229
229
|
getLastIndexedAt(): number | null;
|
|
230
|
+
/**
|
|
231
|
+
* Completeness of the last full index run. `'complete'` is the only good
|
|
232
|
+
* state. `'indexing'` after the fact means a run was killed mid-index (OOM,
|
|
233
|
+
* SIGKILL, liveness watchdog) and the on-disk index is truncated;
|
|
234
|
+
* `'partial'` means the run finished but silently dropped files
|
|
235
|
+
* (discovered > indexed+skipped+errored); `'failed'` means it reported
|
|
236
|
+
* failure. `null` = index predates this marker. Surfaced by
|
|
237
|
+
* `codegraph status`.
|
|
238
|
+
*/
|
|
239
|
+
getIndexState(): 'indexing' | 'complete' | 'partial' | 'failed' | null;
|
|
230
240
|
/**
|
|
231
241
|
* Which engine built the current index: the package version + extraction
|
|
232
242
|
* version stamped at the last full `indexAll`. Either field is null for an
|
|
@@ -264,6 +274,13 @@ export declare class CodeGraph {
|
|
|
264
274
|
* Processes chunks of unresolved refs, persisting results after each batch.
|
|
265
275
|
*/
|
|
266
276
|
resolveReferencesBatched(onProgress?: (current: number, total: number) => void): Promise<ResolutionResult>;
|
|
277
|
+
/**
|
|
278
|
+
* References extracted but not yet resolved into edges. Zero on a healthy
|
|
279
|
+
* index — a completed resolution pass consumes every row. Non-zero at rest
|
|
280
|
+
* means a pass was interrupted mid-run (killed indexer, crash — #1187), so
|
|
281
|
+
* some files' call edges are missing; the next `sync` sweeps them.
|
|
282
|
+
*/
|
|
283
|
+
getPendingReferenceCount(): number;
|
|
267
284
|
/**
|
|
268
285
|
* Get detected frameworks in the project
|
|
269
286
|
*/
|
|
@@ -307,10 +324,55 @@ export declare class CodeGraph {
|
|
|
307
324
|
* definition the caller wants is never dropped below a search cut.
|
|
308
325
|
*/
|
|
309
326
|
getNodesByName(name: string): Node[];
|
|
327
|
+
/** Nodes whose name starts with `prefix` (index range scan, capped). */
|
|
328
|
+
getNodesByNamePrefix(prefix: string, limit?: number): Node[];
|
|
310
329
|
/**
|
|
311
330
|
* Search nodes by text
|
|
312
331
|
*/
|
|
313
332
|
searchNodes(query: string, options?: SearchOptions): SearchResult[];
|
|
333
|
+
/**
|
|
334
|
+
* Graph-derived prompt matching for the front-load hook's MEDIUM tier:
|
|
335
|
+
* which indexed symbols do these prose words name? "state machine des
|
|
336
|
+
* commandes" → `OrderStateMachine`, in any human language whose technical
|
|
337
|
+
* nouns are Latin script — no keyword list involved.
|
|
338
|
+
*
|
|
339
|
+
* Precision comes from the repo's own naming statistics, not vocabulary:
|
|
340
|
+
* - CO-OCCURRENCE: ≥2 words that are segments of the SAME name ("state" +
|
|
341
|
+
* "machine" → OrderStateMachine) is strong evidence and always qualifies.
|
|
342
|
+
* - RARITY: a single matched word qualifies only when its segment is
|
|
343
|
+
* discriminative here (≤ {@link SEGMENT_RARITY_CEILING} distinct names) —
|
|
344
|
+
* "checkout" in a shop backend yes, "state" in a react app no.
|
|
345
|
+
* Every candidate is re-verified against `nodes` before being returned
|
|
346
|
+
* (vocab rows are proposals; deletions leave orphans by design), so a
|
|
347
|
+
* returned symbol is guaranteed to exist right now.
|
|
348
|
+
*/
|
|
349
|
+
getSegmentMatches(words: string[], limit?: number): SegmentMatch[];
|
|
350
|
+
/** A single word ("state") can match hundreds of names in a big repo — that
|
|
351
|
+
* is noise, not signal. Ceiling for the single-word tier; co-occurrence is
|
|
352
|
+
* exempt because two words on one name is already discriminative. */
|
|
353
|
+
private static readonly SEGMENT_RARITY_CEILING;
|
|
354
|
+
/** Which of the prompt's original words match `name`'s segments (via
|
|
355
|
+
* variants). Segments are recomputed in JS — a name-keyed vocab lookup
|
|
356
|
+
* would scan the (segment, name) primary key. */
|
|
357
|
+
private wordsMatchingName;
|
|
358
|
+
/**
|
|
359
|
+
* One-shot upgrade heal for callers that open the graph WITHOUT syncing —
|
|
360
|
+
* concretely the prompt hook, whose MEDIUM tier reads the segment
|
|
361
|
+
* vocabulary: a database migrated from before the vocab table existed
|
|
362
|
+
* starts with it empty, and the only other backfill lives inside `sync()`,
|
|
363
|
+
* which such callers never run (#1142). Returns true when the vocab is
|
|
364
|
+
* usable (already populated — the overwhelmingly common one-SELECT case —
|
|
365
|
+
* or healed here); false when it isn't (empty graph, or another process
|
|
366
|
+
* holds the index lock — that process's own sync heals it).
|
|
367
|
+
*/
|
|
368
|
+
healSegmentVocabIfEmpty(): Promise<boolean>;
|
|
369
|
+
/**
|
|
370
|
+
* Rebuild the segment vocabulary from the current graph, batched and
|
|
371
|
+
* yielding — the upgrade-heal path for indexes built before the vocab table
|
|
372
|
+
* existed. Runs inside the index mutex/lock (sync and
|
|
373
|
+
* healSegmentVocabIfEmpty hold them).
|
|
374
|
+
*/
|
|
375
|
+
private rebuildNameSegmentVocab;
|
|
314
376
|
/**
|
|
315
377
|
* Normalized project-name tokens (go.mod / package.json / repo dir) used to
|
|
316
378
|
* down-weight the non-discriminative project name in search ranking (#720).
|
package/lib/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,gBAAgB,EAChB,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,OAAO,EACP,UAAU,EACV,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,0BAA0B,EAC3B,MAAM,SAAS,CAAC;AASjB,OAAO,EAEL,aAAa,EACb,WAAW,EACX,UAAU,EAGX,MAAM,cAAc,CAAC;AACtB,OAAO,EAGL,gBAAgB,EACjB,MAAM,cAAc,CAAC;AAItB,OAAO,EAAe,YAAY,EAAE,WAAW,EAAwB,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/dist/index.js
CHANGED
|
@@ -57,6 +57,8 @@ const extraction_version_1 = require("./extraction/extraction-version");
|
|
|
57
57
|
const directory_2 = require("./directory");
|
|
58
58
|
const query_utils_1 = require("./search/query-utils");
|
|
59
59
|
const version_1 = require("./mcp/version");
|
|
60
|
+
const identifier_segments_1 = require("./search/identifier-segments");
|
|
61
|
+
const cooperative_yield_1 = require("./resolution/cooperative-yield");
|
|
60
62
|
// Re-export types for consumers
|
|
61
63
|
__exportStar(require("./types"), exports);
|
|
62
64
|
// Storage building blocks for embedded/SDK consumers that drive the graph
|
|
@@ -370,6 +372,21 @@ class CodeGraph {
|
|
|
370
372
|
}
|
|
371
373
|
try {
|
|
372
374
|
const before = this.queries.getNodeAndEdgeCount();
|
|
375
|
+
// Mark the index as in-flight BEFORE any writes: a run killed
|
|
376
|
+
// mid-index (OOM, SIGKILL, the #850 liveness watchdog) leaves this
|
|
377
|
+
// marker behind, so `codegraph status` can tell a truncated index
|
|
378
|
+
// from a completed one instead of silently serving partial results.
|
|
379
|
+
try {
|
|
380
|
+
this.queries.setMetadata('index_state', 'indexing');
|
|
381
|
+
}
|
|
382
|
+
catch { /* metadata is advisory */ }
|
|
383
|
+
// Segment vocabulary starts empty and is repopulated by the node write
|
|
384
|
+
// path as every file (re-)indexes below — so a full index is also the
|
|
385
|
+
// orphan-cleanup pass for names deleted since the last one.
|
|
386
|
+
try {
|
|
387
|
+
this.queries.clearNameSegmentVocab();
|
|
388
|
+
}
|
|
389
|
+
catch { /* vocab is advisory — never fail an index over it */ }
|
|
373
390
|
const result = await this.orchestrator.indexAll(options.onProgress, options.signal, options.verbose);
|
|
374
391
|
// Re-detect frameworks now that the index is populated. The resolver
|
|
375
392
|
// is constructed with createResolver() before any files exist, so
|
|
@@ -404,21 +421,35 @@ class CodeGraph {
|
|
|
404
421
|
// receiver conforms to (protocol-extension / inherited / default-
|
|
405
422
|
// interface). Needs the implements/extends edges the main pass just
|
|
406
423
|
// built, so it runs after resolution (#750).
|
|
424
|
+
const tChained = Date.now();
|
|
407
425
|
await this.resolver.resolveChainedCallsViaConformance();
|
|
426
|
+
if (process.env.CODEGRAPH_SYNTH_TIMINGS)
|
|
427
|
+
console.error(`[synth-timing] chainedConformance: ${Date.now() - tChained}ms`);
|
|
408
428
|
// Same lifecycle for `this.<member>` callback registrations whose
|
|
409
429
|
// member is inherited from a supertype (#808).
|
|
430
|
+
const tDeferred = Date.now();
|
|
410
431
|
await this.resolver.resolveDeferredThisMemberRefs();
|
|
432
|
+
if (process.env.CODEGRAPH_SYNTH_TIMINGS)
|
|
433
|
+
console.error(`[synth-timing] deferredThisMember: ${Date.now() - tDeferred}ms`);
|
|
411
434
|
}
|
|
412
435
|
// Refresh planner stats + checkpoint the WAL after bulk writes.
|
|
413
|
-
//
|
|
436
|
+
// Off-thread (worker connection): on a multi-GB index this is minutes
|
|
437
|
+
// of IO, and inline it starved the #850 watchdog AFTER a fully
|
|
438
|
+
// successful index. Never load-bearing for correctness.
|
|
414
439
|
if (result.success && result.filesIndexed > 0) {
|
|
415
|
-
|
|
440
|
+
const tMaint = Date.now();
|
|
441
|
+
await this.db.runMaintenance();
|
|
442
|
+
if (process.env.CODEGRAPH_SYNTH_TIMINGS)
|
|
443
|
+
console.error(`[phase-timing] maintenance: ${Date.now() - tMaint}ms`);
|
|
416
444
|
}
|
|
417
445
|
// The orchestrator only sees extraction-phase counts; resolution and
|
|
418
446
|
// synthesizer edges (often >50% of the graph on JVM repos) come later.
|
|
419
447
|
// Recompute against the DB so the CLI summary reports the true totals.
|
|
420
448
|
if (result.success && result.filesIndexed > 0) {
|
|
449
|
+
const tCount = Date.now();
|
|
421
450
|
const after = this.queries.getNodeAndEdgeCount();
|
|
451
|
+
if (process.env.CODEGRAPH_SYNTH_TIMINGS)
|
|
452
|
+
console.error(`[phase-timing] count-recompute: ${Date.now() - tCount}ms`);
|
|
422
453
|
result.nodesCreated = after.nodes - before.nodes;
|
|
423
454
|
result.edgesCreated = after.edges - before.edges;
|
|
424
455
|
}
|
|
@@ -434,6 +465,39 @@ class CodeGraph {
|
|
|
434
465
|
}
|
|
435
466
|
catch { /* metadata is advisory — never fail an index over it */ }
|
|
436
467
|
}
|
|
468
|
+
// Reconcile the scan's ground truth against what the pipeline
|
|
469
|
+
// accounted for. A shortfall means files were silently dropped
|
|
470
|
+
// (observed in the wild: a run under heavy load came up 37 files
|
|
471
|
+
// short with no error) — record it and tell the user, don't let the
|
|
472
|
+
// index pass as complete.
|
|
473
|
+
try {
|
|
474
|
+
if (!result.success) {
|
|
475
|
+
this.queries.setMetadata('index_state', 'failed');
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
const accounted = result.filesIndexed + result.filesSkipped + result.filesErrored;
|
|
479
|
+
const discovered = result.filesDiscovered;
|
|
480
|
+
const shortfall = discovered !== undefined ? discovered - accounted : 0;
|
|
481
|
+
if (discovered !== undefined && shortfall > 0) {
|
|
482
|
+
this.queries.setMetadata('index_state', 'partial');
|
|
483
|
+
this.queries.setMetadata('index_files_discovered', String(discovered));
|
|
484
|
+
this.queries.setMetadata('index_files_accounted', String(accounted));
|
|
485
|
+
result.errors.push({
|
|
486
|
+
message: `Index is missing ${shortfall} of ${discovered} discovered files (indexed ${result.filesIndexed}, skipped ${result.filesSkipped}, errored ${result.filesErrored}). The index is PARTIAL — re-run \`codegraph index\`.`,
|
|
487
|
+
severity: 'warning',
|
|
488
|
+
code: 'index_partial',
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
this.queries.setMetadata('index_state', 'complete');
|
|
493
|
+
if (discovered !== undefined) {
|
|
494
|
+
this.queries.setMetadata('index_files_discovered', String(discovered));
|
|
495
|
+
this.queries.setMetadata('index_files_accounted', String(accounted));
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
catch { /* metadata is advisory — never fail an index over it */ }
|
|
437
501
|
return result;
|
|
438
502
|
}
|
|
439
503
|
finally {
|
|
@@ -476,6 +540,18 @@ class CodeGraph {
|
|
|
476
540
|
return { filesChecked: 0, filesAdded: 0, filesModified: 0, filesRemoved: 0, nodesUpdated: 0, durationMs: 0 };
|
|
477
541
|
}
|
|
478
542
|
try {
|
|
543
|
+
// Captured BEFORE the sync runs: the sync's own incremental writes
|
|
544
|
+
// populate vocab rows for the files it touches, so an end-of-sync
|
|
545
|
+
// emptiness check would see "non-empty" and skip the backfill forever,
|
|
546
|
+
// leaving every unchanged file's names unsegmented.
|
|
547
|
+
const vocabWasEmpty = (() => {
|
|
548
|
+
try {
|
|
549
|
+
return this.queries.isNameSegmentVocabEmpty();
|
|
550
|
+
}
|
|
551
|
+
catch {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
})();
|
|
479
555
|
const result = await this.orchestrator.sync(options.onProgress);
|
|
480
556
|
// Cross-file finalization (e.g. NestJS RouterModule prefixes). Run on
|
|
481
557
|
// every sync that touched files so edits to `app.module.ts` propagate
|
|
@@ -485,10 +561,14 @@ class CodeGraph {
|
|
|
485
561
|
this.resolver.runPostExtract();
|
|
486
562
|
}
|
|
487
563
|
// Resolve references if files were updated
|
|
488
|
-
|
|
564
|
+
const filesChanged = result.filesAdded > 0 || result.filesModified > 0;
|
|
565
|
+
if (filesChanged) {
|
|
489
566
|
if (result.changedFilePaths) {
|
|
490
567
|
// Scope resolution to changed files (git fast path — bounded set)
|
|
568
|
+
const tRefLoad = Date.now();
|
|
491
569
|
const unresolvedRefs = this.queries.getUnresolvedReferencesByFiles(result.changedFilePaths);
|
|
570
|
+
if (process.env.CODEGRAPH_SYNTH_TIMINGS)
|
|
571
|
+
console.error(`[phase-timing] sync-ref-load: ${Date.now() - tRefLoad}ms (${unresolvedRefs.length} refs)`);
|
|
492
572
|
options.onProgress?.({
|
|
493
573
|
phase: 'resolving',
|
|
494
574
|
current: 0,
|
|
@@ -518,6 +598,35 @@ class CodeGraph {
|
|
|
518
598
|
});
|
|
519
599
|
});
|
|
520
600
|
}
|
|
601
|
+
}
|
|
602
|
+
// Orphan sweep (#1187). A resolution pass that dies mid-run — the #850
|
|
603
|
+
// daemon liveness watchdog's SIGKILL (#1122), Ctrl-C, a crash — leaves
|
|
604
|
+
// the refs it never reached in unresolved_refs, and the git-scoped fast
|
|
605
|
+
// path above never revisits them (it reads only the changed files'
|
|
606
|
+
// rows). Those files' call edges were then missing PERMANENTLY, with
|
|
607
|
+
// nothing to see except a too-small blast radius, until a full
|
|
608
|
+
// re-index. A completed pass deletes every row it processed (resolved
|
|
609
|
+
// or not), so any row still present now is such an orphan — or a row
|
|
610
|
+
// parked by an older engine whose scoped pass kept unresolvable refs.
|
|
611
|
+
// Grind them down with the batched resolver; this also makes a bare
|
|
612
|
+
// `codegraph sync` the recovery command for a wedged index. On a
|
|
613
|
+
// healthy index this is one COUNT query.
|
|
614
|
+
const orphanCount = this.queries.getUnresolvedReferencesCount();
|
|
615
|
+
if (orphanCount > 0) {
|
|
616
|
+
options.onProgress?.({
|
|
617
|
+
phase: 'resolving',
|
|
618
|
+
current: 0,
|
|
619
|
+
total: orphanCount,
|
|
620
|
+
});
|
|
621
|
+
await this.resolveReferencesBatched((current, total) => {
|
|
622
|
+
options.onProgress?.({
|
|
623
|
+
phase: 'resolving',
|
|
624
|
+
current,
|
|
625
|
+
total,
|
|
626
|
+
});
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
if (filesChanged || orphanCount > 0) {
|
|
521
630
|
// Second pass: chained calls whose method lives on a supertype the
|
|
522
631
|
// receiver conforms to (protocol-extension / inherited). Needs the
|
|
523
632
|
// implements/extends edges built above (#750).
|
|
@@ -527,9 +636,22 @@ class CodeGraph {
|
|
|
527
636
|
await this.resolver.resolveDeferredThisMemberRefs();
|
|
528
637
|
}
|
|
529
638
|
// Refresh planner stats + checkpoint the WAL after bulk writes.
|
|
530
|
-
|
|
531
|
-
|
|
639
|
+
// Off-thread — see indexAll's call site.
|
|
640
|
+
if (filesChanged || result.filesRemoved > 0 || orphanCount > 0) {
|
|
641
|
+
await this.db.runMaintenance();
|
|
642
|
+
}
|
|
643
|
+
// Heal the segment vocabulary on indexes built before the table
|
|
644
|
+
// existed (upgrade path): incremental writes above only cover changed
|
|
645
|
+
// files, so a vocab that was empty when this sync STARTED means the
|
|
646
|
+
// bulk was never segmented — backfill it (INSERT OR IGNORE, so the
|
|
647
|
+
// rows the sync just wrote are fine). Batched + yielding — sync can
|
|
648
|
+
// run on the daemon's liveness-watchdog thread (#850/#1091).
|
|
649
|
+
try {
|
|
650
|
+
if (vocabWasEmpty && this.queries.getNodeAndEdgeCount().nodes > 0) {
|
|
651
|
+
await this.rebuildNameSegmentVocab();
|
|
652
|
+
}
|
|
532
653
|
}
|
|
654
|
+
catch { /* vocab is advisory — never fail a sync over it */ }
|
|
533
655
|
return result;
|
|
534
656
|
}
|
|
535
657
|
finally {
|
|
@@ -640,6 +762,21 @@ class CodeGraph {
|
|
|
640
762
|
getLastIndexedAt() {
|
|
641
763
|
return this.queries.getLastIndexedAt();
|
|
642
764
|
}
|
|
765
|
+
/**
|
|
766
|
+
* Completeness of the last full index run. `'complete'` is the only good
|
|
767
|
+
* state. `'indexing'` after the fact means a run was killed mid-index (OOM,
|
|
768
|
+
* SIGKILL, liveness watchdog) and the on-disk index is truncated;
|
|
769
|
+
* `'partial'` means the run finished but silently dropped files
|
|
770
|
+
* (discovered > indexed+skipped+errored); `'failed'` means it reported
|
|
771
|
+
* failure. `null` = index predates this marker. Surfaced by
|
|
772
|
+
* `codegraph status`.
|
|
773
|
+
*/
|
|
774
|
+
getIndexState() {
|
|
775
|
+
const raw = this.queries.getMetadata('index_state');
|
|
776
|
+
return raw === 'indexing' || raw === 'complete' || raw === 'partial' || raw === 'failed'
|
|
777
|
+
? raw
|
|
778
|
+
: null;
|
|
779
|
+
}
|
|
643
780
|
/**
|
|
644
781
|
* Which engine built the current index: the package version + extraction
|
|
645
782
|
* version stamped at the last full `indexAll`. Either field is null for an
|
|
@@ -695,6 +832,15 @@ class CodeGraph {
|
|
|
695
832
|
async resolveReferencesBatched(onProgress) {
|
|
696
833
|
return this.resolver.resolveAndPersistBatched(onProgress);
|
|
697
834
|
}
|
|
835
|
+
/**
|
|
836
|
+
* References extracted but not yet resolved into edges. Zero on a healthy
|
|
837
|
+
* index — a completed resolution pass consumes every row. Non-zero at rest
|
|
838
|
+
* means a pass was interrupted mid-run (killed indexer, crash — #1187), so
|
|
839
|
+
* some files' call edges are missing; the next `sync` sweeps them.
|
|
840
|
+
*/
|
|
841
|
+
getPendingReferenceCount() {
|
|
842
|
+
return this.queries.getUnresolvedReferencesCount();
|
|
843
|
+
}
|
|
698
844
|
/**
|
|
699
845
|
* Get detected frameworks in the project
|
|
700
846
|
*/
|
|
@@ -764,12 +910,188 @@ class CodeGraph {
|
|
|
764
910
|
getNodesByName(name) {
|
|
765
911
|
return this.queries.getNodesByName(name);
|
|
766
912
|
}
|
|
913
|
+
/** Nodes whose name starts with `prefix` (index range scan, capped). */
|
|
914
|
+
getNodesByNamePrefix(prefix, limit = 20) {
|
|
915
|
+
return this.queries.getNodesByNamePrefix(prefix, limit);
|
|
916
|
+
}
|
|
767
917
|
/**
|
|
768
918
|
* Search nodes by text
|
|
769
919
|
*/
|
|
770
920
|
searchNodes(query, options) {
|
|
771
921
|
return this.queries.searchNodes(query, options);
|
|
772
922
|
}
|
|
923
|
+
/**
|
|
924
|
+
* Graph-derived prompt matching for the front-load hook's MEDIUM tier:
|
|
925
|
+
* which indexed symbols do these prose words name? "state machine des
|
|
926
|
+
* commandes" → `OrderStateMachine`, in any human language whose technical
|
|
927
|
+
* nouns are Latin script — no keyword list involved.
|
|
928
|
+
*
|
|
929
|
+
* Precision comes from the repo's own naming statistics, not vocabulary:
|
|
930
|
+
* - CO-OCCURRENCE: ≥2 words that are segments of the SAME name ("state" +
|
|
931
|
+
* "machine" → OrderStateMachine) is strong evidence and always qualifies.
|
|
932
|
+
* - RARITY: a single matched word qualifies only when its segment is
|
|
933
|
+
* discriminative here (≤ {@link SEGMENT_RARITY_CEILING} distinct names) —
|
|
934
|
+
* "checkout" in a shop backend yes, "state" in a react app no.
|
|
935
|
+
* Every candidate is re-verified against `nodes` before being returned
|
|
936
|
+
* (vocab rows are proposals; deletions leave orphans by design), so a
|
|
937
|
+
* returned symbol is guaranteed to exist right now.
|
|
938
|
+
*/
|
|
939
|
+
getSegmentMatches(words, limit = 6) {
|
|
940
|
+
if (words.length === 0)
|
|
941
|
+
return [];
|
|
942
|
+
// Variant → original word (plural folding), for coverage accounting.
|
|
943
|
+
const variantToWord = new Map();
|
|
944
|
+
for (const word of words) {
|
|
945
|
+
for (const variant of (0, identifier_segments_1.segmentLookupVariants)(word)) {
|
|
946
|
+
if (!variantToWord.has(variant))
|
|
947
|
+
variantToWord.set(variant, word);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
const variants = [...variantToWord.keys()];
|
|
951
|
+
// Tier A: co-occurrence. The SQL folds variants back to their original
|
|
952
|
+
// word (#1146), so minWords=2 means two distinct PROMPT WORDS — a name
|
|
953
|
+
// matching both `service` and `services` can't tie with (or crowd past
|
|
954
|
+
// the LIMIT) a genuine two-word match. The JS re-check below recomputes
|
|
955
|
+
// the fold from live segments as the honesty layer.
|
|
956
|
+
const variantPairs = [...variantToWord.entries()].map(([segment, word]) => ({ segment, word }));
|
|
957
|
+
const candidates = [];
|
|
958
|
+
for (const hit of this.queries.getSegmentCoOccurrence(variantPairs, 2, 24)) {
|
|
959
|
+
const matched = this.wordsMatchingName(hit.name, variantToWord);
|
|
960
|
+
if (matched.size >= 2)
|
|
961
|
+
candidates.push({ name: hit.name, matchedWords: matched });
|
|
962
|
+
}
|
|
963
|
+
// Tier B: single rare word. Only when co-occurrence found nothing — a
|
|
964
|
+
// co-occurring name is categorically stronger evidence — and under
|
|
965
|
+
// stricter rules, because one word is thin: the word must be ≥5 chars
|
|
966
|
+
// (measured FPs: "this", "typo"); the segment must appear in AT LEAST TWO
|
|
967
|
+
// names (a concept the codebase is about clusters across names —
|
|
968
|
+
// CheckoutService/CheckoutController — while a prose coincidence is a
|
|
969
|
+
// singleton: measured FP "deploy to PRODUCTION" → the one name
|
|
970
|
+
// matchesNonProductionDir); and the candidate name must have ≥2 segments
|
|
971
|
+
// (a bare common verb matching a bare function name — "write" → `write` —
|
|
972
|
+
// is prose coincidence, not the user naming a symbol).
|
|
973
|
+
if (candidates.length === 0) {
|
|
974
|
+
const singleWordVariants = variants.filter((v) => variantToWord.get(v).length >= 5);
|
|
975
|
+
const counts = this.queries.getSegmentNameCounts(singleWordVariants);
|
|
976
|
+
const rare = [...counts.entries()]
|
|
977
|
+
.filter(([, n]) => n >= 2 && n <= CodeGraph.SEGMENT_RARITY_CEILING)
|
|
978
|
+
.sort((a, b) => a[1] - b[1])
|
|
979
|
+
.slice(0, 2);
|
|
980
|
+
for (const [variant] of rare) {
|
|
981
|
+
const word = variantToWord.get(variant);
|
|
982
|
+
for (const name of this.queries.getNamesForSegment(variant, 12)) {
|
|
983
|
+
if ((0, identifier_segments_1.splitIdentifierSegments)(name).length < 2)
|
|
984
|
+
continue;
|
|
985
|
+
candidates.push({ name, matchedWords: new Set([word]) });
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
// Verify against nodes (the honesty gate) and pick a representative
|
|
990
|
+
// definition per name. A name whose only nodes are file/import kind has
|
|
991
|
+
// no real definition to point at — surfacing the import statement instead
|
|
992
|
+
// reads as a matched symbol but isn't one (#1144) — so it's skipped, the
|
|
993
|
+
// same way an orphaned vocab row is. (Import names no longer enter the
|
|
994
|
+
// vocab at write time, but rows written before that exclusion persist
|
|
995
|
+
// until the next full index.)
|
|
996
|
+
const out = [];
|
|
997
|
+
const seen = new Set();
|
|
998
|
+
candidates.sort((a, b) => b.matchedWords.size - a.matchedWords.size || a.name.length - b.name.length);
|
|
999
|
+
for (const candidate of candidates) {
|
|
1000
|
+
if (out.length >= limit)
|
|
1001
|
+
break;
|
|
1002
|
+
if (seen.has(candidate.name))
|
|
1003
|
+
continue;
|
|
1004
|
+
seen.add(candidate.name);
|
|
1005
|
+
const nodes = this.queries.getNodesByName(candidate.name);
|
|
1006
|
+
if (nodes.length === 0)
|
|
1007
|
+
continue; // orphaned vocab row — name no longer exists
|
|
1008
|
+
const rep = nodes.find((n) => n.kind !== 'file' && n.kind !== 'import');
|
|
1009
|
+
if (!rep)
|
|
1010
|
+
continue; // no real definition — don't surface an import/file as one
|
|
1011
|
+
out.push({
|
|
1012
|
+
name: candidate.name,
|
|
1013
|
+
kind: rep.kind,
|
|
1014
|
+
filePath: rep.filePath,
|
|
1015
|
+
startLine: rep.startLine ?? 0,
|
|
1016
|
+
matchedWords: [...candidate.matchedWords].sort(),
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
return out;
|
|
1020
|
+
}
|
|
1021
|
+
/** A single word ("state") can match hundreds of names in a big repo — that
|
|
1022
|
+
* is noise, not signal. Ceiling for the single-word tier; co-occurrence is
|
|
1023
|
+
* exempt because two words on one name is already discriminative. */
|
|
1024
|
+
static SEGMENT_RARITY_CEILING = 25;
|
|
1025
|
+
/** Which of the prompt's original words match `name`'s segments (via
|
|
1026
|
+
* variants). Segments are recomputed in JS — a name-keyed vocab lookup
|
|
1027
|
+
* would scan the (segment, name) primary key. */
|
|
1028
|
+
wordsMatchingName(name, variantToWord) {
|
|
1029
|
+
const segments = new Set((0, identifier_segments_1.splitIdentifierSegments)(name));
|
|
1030
|
+
const matched = new Set();
|
|
1031
|
+
for (const [variant, word] of variantToWord) {
|
|
1032
|
+
if (segments.has(variant))
|
|
1033
|
+
matched.add(word);
|
|
1034
|
+
}
|
|
1035
|
+
return matched;
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* One-shot upgrade heal for callers that open the graph WITHOUT syncing —
|
|
1039
|
+
* concretely the prompt hook, whose MEDIUM tier reads the segment
|
|
1040
|
+
* vocabulary: a database migrated from before the vocab table existed
|
|
1041
|
+
* starts with it empty, and the only other backfill lives inside `sync()`,
|
|
1042
|
+
* which such callers never run (#1142). Returns true when the vocab is
|
|
1043
|
+
* usable (already populated — the overwhelmingly common one-SELECT case —
|
|
1044
|
+
* or healed here); false when it isn't (empty graph, or another process
|
|
1045
|
+
* holds the index lock — that process's own sync heals it).
|
|
1046
|
+
*/
|
|
1047
|
+
async healSegmentVocabIfEmpty() {
|
|
1048
|
+
const empty = (() => {
|
|
1049
|
+
try {
|
|
1050
|
+
return this.queries.isNameSegmentVocabEmpty();
|
|
1051
|
+
}
|
|
1052
|
+
catch {
|
|
1053
|
+
return false;
|
|
1054
|
+
}
|
|
1055
|
+
})();
|
|
1056
|
+
if (!empty)
|
|
1057
|
+
return true;
|
|
1058
|
+
if (this.queries.getNodeAndEdgeCount().nodes === 0)
|
|
1059
|
+
return false;
|
|
1060
|
+
return this.indexMutex.withLock(async () => {
|
|
1061
|
+
try {
|
|
1062
|
+
this.fileLock.acquire();
|
|
1063
|
+
}
|
|
1064
|
+
catch {
|
|
1065
|
+
return false; // an index/sync is running — it backfills the vocab itself
|
|
1066
|
+
}
|
|
1067
|
+
try {
|
|
1068
|
+
if (!this.queries.isNameSegmentVocabEmpty())
|
|
1069
|
+
return true; // raced: healed meanwhile
|
|
1070
|
+
await this.rebuildNameSegmentVocab();
|
|
1071
|
+
return true;
|
|
1072
|
+
}
|
|
1073
|
+
finally {
|
|
1074
|
+
this.fileLock.release();
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
/**
|
|
1079
|
+
* Rebuild the segment vocabulary from the current graph, batched and
|
|
1080
|
+
* yielding — the upgrade-heal path for indexes built before the vocab table
|
|
1081
|
+
* existed. Runs inside the index mutex/lock (sync and
|
|
1082
|
+
* healSegmentVocabIfEmpty hold them).
|
|
1083
|
+
*/
|
|
1084
|
+
async rebuildNameSegmentVocab() {
|
|
1085
|
+
const maybeYield = (0, cooperative_yield_1.createYielder)();
|
|
1086
|
+
const BATCH = 2000;
|
|
1087
|
+
for (let offset = 0;; offset += BATCH) {
|
|
1088
|
+
const names = this.queries.getDistinctNodeNames(BATCH, offset);
|
|
1089
|
+
if (names.length === 0)
|
|
1090
|
+
break;
|
|
1091
|
+
this.queries.insertNameSegmentsBatch(names);
|
|
1092
|
+
await maybeYield();
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
773
1095
|
/**
|
|
774
1096
|
* Normalized project-name tokens (go.mod / package.json / repo dir) used to
|
|
775
1097
|
* down-weight the non-discriminative project name in search ranking (#720).
|