@wrongstack/tools 1.0.0 → 1.0.2
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/auto-proceed-loop-guard.d.ts +1 -1
- package/dist/auto-proceed-loop-guard.js +1 -1
- package/dist/bash.js +1 -1
- package/dist/builtin.js +15 -15
- package/dist/{chunk-VVZPQPTY.js → chunk-3AU6CZWL.js} +4 -2
- package/dist/{chunk-N3K2SFEI.js → chunk-52UXXQMP.js} +1408 -200
- package/dist/{chunk-NN2SNP2R.js → chunk-6H4ERJP7.js} +137 -21
- package/dist/{chunk-DK4J2WMH.js → chunk-7XUEPBNT.js} +2 -2
- package/dist/{chunk-IYH4OHBP.js → chunk-DKHMPKDG.js} +2 -2
- package/dist/{chunk-NU2IZ72J.js → chunk-DL2ARI4S.js} +7 -5
- package/dist/{chunk-M6UV67BH.js → chunk-EL2NJXSK.js} +2 -2
- package/dist/{chunk-YEISRT4S.js → chunk-HWXIRVKH.js} +1408 -235
- package/dist/{chunk-GKSG5CPH.js → chunk-KVTEIUND.js} +2 -2
- package/dist/{chunk-GDDXX27P.js → chunk-MBR5VAB5.js} +2 -2
- package/dist/{chunk-KDEXUQY7.js → chunk-MGPR7VG3.js} +261 -258
- package/dist/{chunk-YULVUTK5.js → chunk-NFX2IUQA.js} +3 -3
- package/dist/{chunk-37QKUQ2Z.js → chunk-NL2S2CXD.js} +1 -1
- package/dist/{chunk-ZTCJCYLN.js → chunk-TI5COGLY.js} +49 -6
- package/dist/{chunk-CGXTR34H.js → chunk-TU5MTW2S.js} +2 -2
- package/dist/{chunk-AB2CAUOP.js → chunk-UCXFTCAI.js} +186 -36
- package/dist/{chunk-MK2JK35J.js → chunk-UOYRAS4J.js} +3 -3
- package/dist/{chunk-UCYQTZ7F.js → chunk-ZKC5UNGD.js} +56 -2
- package/dist/codebase-index/atlas-brief.d.ts +90 -0
- package/dist/codebase-index/atlas-export.d.ts +38 -0
- package/dist/codebase-index/atlas-projection.d.ts +114 -0
- package/dist/codebase-index/atlas-types.d.ts +90 -0
- package/dist/codebase-index/background-indexer.d.ts +15 -4
- package/dist/codebase-index/codebase-context-tool.d.ts +54 -0
- package/dist/codebase-index/concept-enrichment.d.ts +154 -0
- package/dist/codebase-index/context-retrieval.d.ts +91 -0
- package/dist/codebase-index/embedding-pass.d.ts +95 -0
- package/dist/codebase-index/graph-adjacency-cache.d.ts +36 -0
- package/dist/codebase-index/graph-rank-pass.d.ts +46 -0
- package/dist/codebase-index/graph-rank.d.ts +198 -0
- package/dist/codebase-index/index-service.d.ts +15 -1
- package/dist/codebase-index/index.d.ts +34 -19
- package/dist/codebase-index/index.js +126 -9
- package/dist/codebase-index/parser-worker-script.js +3 -3
- package/dist/codebase-index/perf-metrics.d.ts +19 -0
- package/dist/codebase-index/project-server-protocol.d.ts +2 -0
- package/dist/codebase-index/project-server-query-cache.d.ts +4 -0
- package/dist/codebase-index/project-server.js +54 -7
- package/dist/codebase-index/repo-map-fallback.d.ts +18 -0
- package/dist/codebase-index/repo-map-render.d.ts +42 -0
- package/dist/codebase-index/repo-map-types.d.ts +21 -0
- package/dist/codebase-index/repo-map.d.ts +28 -16
- package/dist/codebase-index/schema.d.ts +20 -0
- package/dist/codebase-index/worker-protocol.d.ts +47 -1
- package/dist/codebase-index/worker.js +11 -5
- package/dist/codebase-index/writer-concepts.d.ts +84 -0
- package/dist/codebase-index/writer-graph-decorate.d.ts +30 -0
- package/dist/codebase-index/writer-graph-reader.d.ts +22 -0
- package/dist/codebase-index/writer-rank.d.ts +78 -0
- package/dist/codebase-index/writer-schema.d.ts +51 -0
- package/dist/codebase-index/writer-vectors.d.ts +53 -0
- package/dist/codebase-index/writer.d.ts +59 -0
- package/dist/edit.js +7 -7
- package/dist/exec.js +1 -1
- package/dist/{go-parser-D7ELWQ7F.js → go-parser-QIEXU3P2.js} +4 -2
- package/dist/index.d.ts +48 -48
- package/dist/index.js +43 -19
- package/dist/pack.js +16 -16
- package/dist/{parser-dispatch-BDVCJXTV.js → parser-dispatch-37FT3EXQ.js} +4 -4
- package/dist/patch.js +7 -7
- package/dist/{py-parser-QC6MR4GB.js → py-parser-6GJTGUXK.js} +3 -3
- package/dist/read.js +7 -7
- package/dist/replace.js +7 -7
- package/dist/tool-tier.js +17 -17
- package/dist/write.js +7 -7
- package/package.json +5 -5
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
contextService,
|
|
2
3
|
fileGraphService,
|
|
3
4
|
incomingCallsService,
|
|
4
5
|
indexService,
|
|
@@ -6,12 +7,13 @@ import {
|
|
|
6
7
|
packageGraphService,
|
|
7
8
|
searchService,
|
|
8
9
|
statsService,
|
|
9
|
-
symbolGraphService
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import "../chunk-
|
|
10
|
+
symbolGraphService,
|
|
11
|
+
vectorSearchService
|
|
12
|
+
} from "../chunk-52UXXQMP.js";
|
|
13
|
+
import "../chunk-DL2ARI4S.js";
|
|
14
|
+
import "../chunk-3AU6CZWL.js";
|
|
13
15
|
import "../chunk-6IEBD27U.js";
|
|
14
|
-
import "../chunk-
|
|
16
|
+
import "../chunk-ZKC5UNGD.js";
|
|
15
17
|
import "../chunk-YOHO4DVT.js";
|
|
16
18
|
import "../chunk-2CTZW6JQ.js";
|
|
17
19
|
import "../chunk-KE7A76VC.js";
|
|
@@ -50,6 +52,10 @@ async function dispatch(msg) {
|
|
|
50
52
|
}
|
|
51
53
|
case "search":
|
|
52
54
|
return searchService(msg.args);
|
|
55
|
+
case "context":
|
|
56
|
+
return contextService(msg.args);
|
|
57
|
+
case "vectorSearch":
|
|
58
|
+
return vectorSearchService(msg.args);
|
|
53
59
|
case "stats":
|
|
54
60
|
return statsService(msg.args);
|
|
55
61
|
case "packageGraph":
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence for the concept layer (`file_concepts`, `subsystems`,
|
|
3
|
+
* `concept_edges`).
|
|
4
|
+
*
|
|
5
|
+
* Unlike the rank tables, these are written incrementally: a summary costs a
|
|
6
|
+
* model call, so the runner checkpoints as it goes and a cancelled or crashed
|
|
7
|
+
* pass must not throw away what it already paid for.
|
|
8
|
+
*/
|
|
9
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
10
|
+
type Statement = ReturnType<DatabaseSync['prepare']>;
|
|
11
|
+
type PrepareStatement = (sql: string) => Statement;
|
|
12
|
+
/**
|
|
13
|
+
* Whether a stored summary describes the file's current bytes.
|
|
14
|
+
*
|
|
15
|
+
* `stale` is kept rather than deleted: an outdated description of a file is
|
|
16
|
+
* still a better starting point than nothing, both for a reader and as a hint
|
|
17
|
+
* to the model on the next pass.
|
|
18
|
+
*/
|
|
19
|
+
export type ConceptState = 'ready' | 'stale' | 'pending';
|
|
20
|
+
export interface FileConcept {
|
|
21
|
+
file: string;
|
|
22
|
+
contentHash: string;
|
|
23
|
+
summary: string;
|
|
24
|
+
/** 1-based inclusive line span of the file's load-bearing lines. */
|
|
25
|
+
cruxStart: number | null;
|
|
26
|
+
cruxEnd: number | null;
|
|
27
|
+
state: ConceptState;
|
|
28
|
+
model: string;
|
|
29
|
+
updatedAt: number;
|
|
30
|
+
}
|
|
31
|
+
export interface Subsystem {
|
|
32
|
+
id: string;
|
|
33
|
+
name: string;
|
|
34
|
+
summary: string;
|
|
35
|
+
memberFiles: string[];
|
|
36
|
+
model: string;
|
|
37
|
+
updatedAt: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Closed vocabulary for concept-to-concept relations.
|
|
41
|
+
*
|
|
42
|
+
* Closed on purpose. An open-ended verb list produces a graph where
|
|
43
|
+
* `configures`, `sets up` and `initialises` are three different edges between
|
|
44
|
+
* the same pair, which nothing downstream can group or filter on.
|
|
45
|
+
*/
|
|
46
|
+
export declare const CONCEPT_RELATIONS: readonly ['uses', 'configures', 'validates', 'extends', 'persists', 'observes'];
|
|
47
|
+
export type ConceptRelation = (typeof CONCEPT_RELATIONS)[number];
|
|
48
|
+
export declare function isConceptRelation(value: string): value is ConceptRelation;
|
|
49
|
+
export interface ConceptEdge {
|
|
50
|
+
fromId: string;
|
|
51
|
+
toId: string;
|
|
52
|
+
relation: ConceptRelation;
|
|
53
|
+
}
|
|
54
|
+
/** Write (or replace) one file's concept. */
|
|
55
|
+
export declare function upsertFileConceptWithStatement(stmt: PrepareStatement, concept: FileConcept): void;
|
|
56
|
+
export declare function getFileConceptWithStatement(stmt: PrepareStatement, file: string): FileConcept | undefined;
|
|
57
|
+
/** All concepts, for whole-index consumers (atlas, embeddings, injection). */
|
|
58
|
+
export declare function getAllFileConceptsWithStatement(stmt: PrepareStatement): FileConcept[];
|
|
59
|
+
/** `file → summary` for the files that currently have a usable description. */
|
|
60
|
+
export declare function getReadyConceptSummariesWithStatement(stmt: PrepareStatement): Map<string, string>;
|
|
61
|
+
export interface ConceptCoverage {
|
|
62
|
+
ready: number;
|
|
63
|
+
stale: number;
|
|
64
|
+
pending: number;
|
|
65
|
+
subsystems: number;
|
|
66
|
+
}
|
|
67
|
+
export declare function getConceptCoverageWithStatement(stmt: PrepareStatement): ConceptCoverage;
|
|
68
|
+
/**
|
|
69
|
+
* Mark every concept whose recorded hash no longer matches the indexed file as
|
|
70
|
+
* `stale`, in one statement.
|
|
71
|
+
*
|
|
72
|
+
* Run before a pass rather than during indexing: the indexer's atomic write is
|
|
73
|
+
* not the place to reason about a layer it does not own, and a summary that is
|
|
74
|
+
* one generation behind harms nothing until someone asks for it.
|
|
75
|
+
*/
|
|
76
|
+
export declare function markStaleConceptsWithStatement(stmt: PrepareStatement): number;
|
|
77
|
+
/** Drop concepts for files that are no longer indexed. */
|
|
78
|
+
export declare function pruneOrphanConceptsWithStatement(stmt: PrepareStatement): number;
|
|
79
|
+
/** Replace the whole subsystem layer. Subsystems are derived as a set. */
|
|
80
|
+
export declare function replaceSubsystemsWithStatement(stmt: PrepareStatement, maxSqlVars: number, subsystems: readonly Subsystem[], edges: readonly ConceptEdge[]): void;
|
|
81
|
+
export declare function getSubsystemsWithStatement(stmt: PrepareStatement): Subsystem[];
|
|
82
|
+
export declare function getConceptEdgesWithStatement(stmt: PrepareStatement): ConceptEdge[];
|
|
83
|
+
export {};
|
|
84
|
+
//# sourceMappingURL=writer-concepts.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atlas enrichment for the CodeMap graph.
|
|
3
|
+
*
|
|
4
|
+
* The three graph getters build their nodes from `symbols` and `files`. Rank,
|
|
5
|
+
* concept summaries and subsystem membership live in tables those queries know
|
|
6
|
+
* nothing about, and each getter reaches its nodes by a different route — one
|
|
7
|
+
* groups by package, one by file, one by symbol id.
|
|
8
|
+
*
|
|
9
|
+
* Rather than thread four more joins through three query shapes and their node
|
|
10
|
+
* builders, this decorates the finished nodes in one pass. That keeps the
|
|
11
|
+
* enrichment strictly additive: an index where no rank or concept pass has run
|
|
12
|
+
* produces exactly the graph it produced before, because every lookup misses
|
|
13
|
+
* and every field stays absent.
|
|
14
|
+
*
|
|
15
|
+
* It also sidesteps `chunkedIdQuery`'s documented rule that `buildSql` may not
|
|
16
|
+
* contain a `LIMIT` — there is no limit to express here.
|
|
17
|
+
*/
|
|
18
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
19
|
+
import type { GraphNode } from './schema.js';
|
|
20
|
+
type Statement = ReturnType<DatabaseSync['prepare']>;
|
|
21
|
+
type PrepareStatement = (sql: string) => Statement;
|
|
22
|
+
/**
|
|
23
|
+
* Stamp rank, concept, crux, subsystem and mtime onto graph nodes.
|
|
24
|
+
*
|
|
25
|
+
* `packageOf` is supplied by the caller because the package labeller already
|
|
26
|
+
* exists at every call site, and rebuilding it here would read `files` twice.
|
|
27
|
+
*/
|
|
28
|
+
export declare function decorateGraphNodes(stmt: PrepareStatement, nodes: GraphNode[], packageOf: (file: string) => string): void;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=writer-graph-decorate.d.ts.map
|
|
@@ -1,7 +1,29 @@
|
|
|
1
1
|
import type { DatabaseSync } from 'node:sqlite';
|
|
2
2
|
import type { CallSite, CodeMapGraph, Ref } from './schema.js';
|
|
3
|
+
import { type WriterSymbolGraphRow } from './writer-graph-helpers.js';
|
|
3
4
|
type Statement = ReturnType<DatabaseSync['prepare']>;
|
|
4
5
|
type PrepareStatement = (sql: string) => Statement;
|
|
6
|
+
/**
|
|
7
|
+
* Hydrate symbol rows for an arbitrary id list.
|
|
8
|
+
*
|
|
9
|
+
* The personalised retrieval walk scores dense graph indices and then needs
|
|
10
|
+
* the declarations behind the winners; this is that lookup. Chunked because
|
|
11
|
+
* the id list is unbounded — the caller decides how many nodes to hydrate.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getSymbolsByIdsWithStatement(stmt: PrepareStatement, ids: readonly number[]): WriterSymbolGraphRow[];
|
|
14
|
+
/**
|
|
15
|
+
* Declarations in one file, in source order.
|
|
16
|
+
*
|
|
17
|
+
* Ordered by line rather than by any score so the list reads the way the file
|
|
18
|
+
* does — the atlas uses it to describe a file, not to rank within it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getFileSymbolsWithStatement(stmt: PrepareStatement, file: string, limit: number): Array<{
|
|
21
|
+
id: number;
|
|
22
|
+
name: string;
|
|
23
|
+
kind: string;
|
|
24
|
+
line: number;
|
|
25
|
+
signature: string;
|
|
26
|
+
}>;
|
|
5
27
|
/**
|
|
6
28
|
* Find all symbols that CALL/USE the named target symbol (incoming callers).
|
|
7
29
|
*
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence for the graph centrality layer (`symbol_rank`, `file_rank`).
|
|
3
|
+
*
|
|
4
|
+
* Ranks are always written as a whole: the score is a property of the entire
|
|
5
|
+
* graph, so a partial update would leave the table describing a graph that no
|
|
6
|
+
* longer exists. Both writers therefore delete and re-insert rather than
|
|
7
|
+
* upserting row by row — at ~66k symbols that is a single fast statement plus
|
|
8
|
+
* a ladder-chunked bulk insert, well inside the index run's existing budget.
|
|
9
|
+
*/
|
|
10
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
11
|
+
import type { FileRankRow, SymbolRankRow } from './graph-rank.js';
|
|
12
|
+
type Statement = ReturnType<DatabaseSync['prepare']>;
|
|
13
|
+
type PrepareStatement = (sql: string) => Statement;
|
|
14
|
+
/** Replace the whole `symbol_rank` table with `rows`. */
|
|
15
|
+
export declare function replaceSymbolRanksWithStatement(stmt: PrepareStatement, maxSqlVars: number, rows: readonly SymbolRankRow[]): void;
|
|
16
|
+
/** Replace the whole `file_rank` table with `rows`. */
|
|
17
|
+
export declare function replaceFileRanksWithStatement(stmt: PrepareStatement, maxSqlVars: number, rows: readonly FileRankRow[]): void;
|
|
18
|
+
/**
|
|
19
|
+
* Highest-ranked files, most central first.
|
|
20
|
+
*
|
|
21
|
+
* `limit` is applied in SQL — this is a plain single-table read, so none of
|
|
22
|
+
* the chunked-query constraints that forbid `LIMIT` elsewhere apply here.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getTopFileRanksWithStatement(stmt: PrepareStatement, limit: number): FileRankRow[];
|
|
25
|
+
/** A ranked file joined with the metadata the repo map needs to group it. */
|
|
26
|
+
export interface RankedFileRow extends FileRankRow {
|
|
27
|
+
/** Code Atlas grouping label from `files.package` — '' when unlabelled. */
|
|
28
|
+
package: string;
|
|
29
|
+
lang: string;
|
|
30
|
+
symbolCount: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Highest-ranked files with their package label, for repo-map clustering.
|
|
34
|
+
*
|
|
35
|
+
* Joined here rather than in two round trips because the repo map always
|
|
36
|
+
* needs both, and `file_rank` is keyed by the same absolute path as `files`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getRankedFilesWithStatement(stmt: PrepareStatement, limit: number): RankedFileRow[];
|
|
39
|
+
/**
|
|
40
|
+
* True indexed-file count per package label.
|
|
41
|
+
*
|
|
42
|
+
* The repo map only fetches its top few hundred ranked files, so counting
|
|
43
|
+
* cluster membership from that slice would report "core has 154 files" for a
|
|
44
|
+
* package with thousands. The count has to come from `files` itself.
|
|
45
|
+
*/
|
|
46
|
+
export declare function getPackageFileCountsWithStatement(stmt: PrepareStatement): Map<string, number>;
|
|
47
|
+
/** Highest-ranked symbols, most central first. */
|
|
48
|
+
export declare function getTopSymbolRanksWithStatement(stmt: PrepareStatement, limit: number): SymbolRankRow[];
|
|
49
|
+
/**
|
|
50
|
+
* How many symbols declare each ambiguous symbol's name, keyed by symbol id.
|
|
51
|
+
*
|
|
52
|
+
* Counted per `(name, language family)` because that is exactly the scope ref
|
|
53
|
+
* resolution matches within (`FAMILY_MATCH_SQL`) — a Go `Read` and a
|
|
54
|
+
* TypeScript `Read` never compete for the same ref, so counting them together
|
|
55
|
+
* would understate the confidence of both.
|
|
56
|
+
*
|
|
57
|
+
* Only names with more than one declaration are returned: on this repo that
|
|
58
|
+
* is roughly a seventh of all names, so the map stays small and every absent
|
|
59
|
+
* id means "unambiguous, full weight".
|
|
60
|
+
*/
|
|
61
|
+
export declare function getSymbolNameCandidatesWithStatement(stmt: PrepareStatement): Map<number, number>;
|
|
62
|
+
/**
|
|
63
|
+
* File-to-file import edges, as `source file → set of imported files`.
|
|
64
|
+
*
|
|
65
|
+
* Built from the import refs the module resolver managed to resolve to a real
|
|
66
|
+
* path (`refs.to_file`). Used by the rank pass to tell a cross-file reference
|
|
67
|
+
* that is genuinely visible from one the resolver merely guessed at.
|
|
68
|
+
*/
|
|
69
|
+
export declare function getImportVisibilityWithStatement(stmt: PrepareStatement): Map<string, Set<string>>;
|
|
70
|
+
/** Whole-table `file → rank` lookup, for joining ranks onto graph reads. */
|
|
71
|
+
export declare function getFileRankMapWithStatement(stmt: PrepareStatement): Map<string, number>;
|
|
72
|
+
/** Row counts, for index stats and for deciding whether the layer is populated. */
|
|
73
|
+
export declare function getRankCountsWithStatement(stmt: PrepareStatement): {
|
|
74
|
+
symbols: number;
|
|
75
|
+
files: number;
|
|
76
|
+
};
|
|
77
|
+
export {};
|
|
78
|
+
//# sourceMappingURL=writer-rank.d.ts.map
|
|
@@ -16,6 +16,57 @@ export declare const LANG_FAMILY_TABLE_SQL = "\n CREATE TABLE IF NOT EXISTS lan
|
|
|
16
16
|
/** Family value that matches every symbol family, used by language-less refs. */
|
|
17
17
|
export declare const LANG_FAMILY_WILDCARD = "*";
|
|
18
18
|
export declare const SYMBOLS_FTS_SQL = "CREATE VIRTUAL TABLE IF NOT EXISTS symbols_fts USING fts5(text, tokenize = 'trigram')";
|
|
19
|
+
/**
|
|
20
|
+
* Graph centrality, computed at index time by `graph-rank.ts` once every ref
|
|
21
|
+
* has its final `to_id` / `to_file`. Two tables rather than columns on
|
|
22
|
+
* `symbols` / `files` so the whole layer is additive: an index written by an
|
|
23
|
+
* older build simply has empty rank tables, and `SCHEMA_VERSION` stays put
|
|
24
|
+
* (a bump drops and rebuilds the entire index — see `initIndexSchema`).
|
|
25
|
+
*
|
|
26
|
+
* `rank` is max-normalised to 1.0 across the run, so scores are comparable
|
|
27
|
+
* within one index but never across two.
|
|
28
|
+
*/
|
|
29
|
+
export declare const RANK_TABLES_SQL = "\n CREATE TABLE IF NOT EXISTS symbol_rank (\n symbol_id INTEGER PRIMARY KEY,\n rank REAL NOT NULL,\n in_deg INTEGER NOT NULL DEFAULT 0,\n out_deg INTEGER NOT NULL DEFAULT 0\n );\n CREATE TABLE IF NOT EXISTS file_rank (\n file TEXT PRIMARY KEY,\n rank REAL NOT NULL,\n in_deg INTEGER NOT NULL DEFAULT 0,\n out_deg INTEGER NOT NULL DEFAULT 0\n );\n";
|
|
30
|
+
export declare const RANK_INDEX_SQL: readonly ['CREATE INDEX IF NOT EXISTS idx_sr_rank ON symbol_rank(rank DESC)', 'CREATE INDEX IF NOT EXISTS idx_fr_rank ON file_rank(rank DESC)'];
|
|
31
|
+
/**
|
|
32
|
+
* Concept layer — plain-English descriptions of what code is *for*, which the
|
|
33
|
+
* structural index cannot express. Symbol names and signatures answer "what is
|
|
34
|
+
* declared"; they cannot answer "where do we back off after a 429".
|
|
35
|
+
*
|
|
36
|
+
* Populated by an optional, explicitly enabled LLM pass. Additive like the rank
|
|
37
|
+
* tables: an index without the pass simply has empty concept tables, and every
|
|
38
|
+
* consumer treats a missing summary as "not described yet" rather than an error.
|
|
39
|
+
*
|
|
40
|
+
* `content_hash` mirrors `files.content_hash`, and is the cache key that keeps
|
|
41
|
+
* the pass affordable — a file whose bytes have not changed is never re-sent to
|
|
42
|
+
* a model. `state` distinguishes a summary that matches the current bytes
|
|
43
|
+
* (`ready`) from one describing an older version (`stale`, still useful as a
|
|
44
|
+
* hint) and one not yet produced (`pending`).
|
|
45
|
+
*
|
|
46
|
+
* `crux_start`/`crux_end` point at the few lines that actually carry the file's
|
|
47
|
+
* meaning. A summary can drift from the truth; a pointer into the source cannot.
|
|
48
|
+
*/
|
|
49
|
+
export declare const CONCEPT_TABLES_SQL = "\n CREATE TABLE IF NOT EXISTS file_concepts (\n file TEXT PRIMARY KEY,\n content_hash TEXT NOT NULL DEFAULT '',\n summary TEXT NOT NULL DEFAULT '',\n crux_start INTEGER,\n crux_end INTEGER,\n state TEXT NOT NULL DEFAULT 'pending',\n model TEXT NOT NULL DEFAULT '',\n updated_at INTEGER NOT NULL DEFAULT 0\n );\n CREATE TABLE IF NOT EXISTS subsystems (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n summary TEXT NOT NULL DEFAULT '',\n member_files TEXT NOT NULL DEFAULT '[]',\n model TEXT NOT NULL DEFAULT '',\n updated_at INTEGER NOT NULL DEFAULT 0\n );\n CREATE TABLE IF NOT EXISTS concept_edges (\n from_id TEXT NOT NULL,\n to_id TEXT NOT NULL,\n relation TEXT NOT NULL,\n PRIMARY KEY (from_id, to_id, relation)\n );\n";
|
|
50
|
+
/**
|
|
51
|
+
* Semantic embeddings, one per file.
|
|
52
|
+
*
|
|
53
|
+
* **Per file, not per symbol.** Embedding a bare signature — `function
|
|
54
|
+
* resolve(id: string): Widget` — captures almost nothing a lexical index does
|
|
55
|
+
* not already have. What carries meaning is the concept layer's description of
|
|
56
|
+
* what the file is *for*, so that is what gets embedded. It is also eight
|
|
57
|
+
* times cheaper on this repository: 8k files against 66k symbols.
|
|
58
|
+
*
|
|
59
|
+
* `source_hash` is a hash of the exact text that was embedded, so a changed
|
|
60
|
+
* summary re-embeds and an unchanged one never does. `provider` records which
|
|
61
|
+
* model produced the vector; vectors from a different model are not comparable,
|
|
62
|
+
* so a provider change invalidates the whole table rather than silently mixing
|
|
63
|
+
* two vector spaces.
|
|
64
|
+
*
|
|
65
|
+
* Separate from `symbol_vectors`, which stores the older synchronous
|
|
66
|
+
* char-trigram vectors and stays behind its own gate.
|
|
67
|
+
*/
|
|
68
|
+
export declare const FILE_VECTORS_TABLE_SQL = "\n CREATE TABLE IF NOT EXISTS file_vectors (\n file TEXT PRIMARY KEY,\n vector BLOB NOT NULL,\n source_hash TEXT NOT NULL DEFAULT '',\n provider TEXT NOT NULL DEFAULT ''\n );\n";
|
|
69
|
+
export declare const CONCEPT_INDEX_SQL: readonly ['CREATE INDEX IF NOT EXISTS idx_fc_state ON file_concepts(state)', 'CREATE INDEX IF NOT EXISTS idx_ce_from ON concept_edges(from_id)'];
|
|
19
70
|
/**
|
|
20
71
|
* Phase 3: stores 384-dimensional float32 embedding vectors for each symbol.
|
|
21
72
|
* Vectors are computed from the symbol's indexable text (name + signature +
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence for file-level semantic embeddings (`file_vectors`).
|
|
3
|
+
*
|
|
4
|
+
* Vectors from two different models are not comparable — the spaces have
|
|
5
|
+
* nothing to do with each other — so the provider id is stored alongside every
|
|
6
|
+
* row and a provider change wipes the table rather than silently mixing them.
|
|
7
|
+
*/
|
|
8
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
9
|
+
type Statement = ReturnType<DatabaseSync['prepare']>;
|
|
10
|
+
type PrepareStatement = (sql: string) => Statement;
|
|
11
|
+
/** Metadata key recording which provider produced the stored vectors. */
|
|
12
|
+
export declare const FILE_VECTOR_PROVIDER_KEY = "file_vector_provider";
|
|
13
|
+
export interface FileVectorRow {
|
|
14
|
+
file: string;
|
|
15
|
+
vector: Float32Array;
|
|
16
|
+
/** Hash of the exact text that was embedded. */
|
|
17
|
+
sourceHash: string;
|
|
18
|
+
provider: string;
|
|
19
|
+
}
|
|
20
|
+
/** What is already embedded, so a pass can skip unchanged text. */
|
|
21
|
+
export interface FileVectorState {
|
|
22
|
+
file: string;
|
|
23
|
+
sourceHash: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function getFileVectorStatesWithStatement(stmt: PrepareStatement, provider: string): Map<string, string>;
|
|
26
|
+
export declare function upsertFileVectorsWithStatement(stmt: PrepareStatement, maxSqlVars: number, rows: readonly FileVectorRow[]): void;
|
|
27
|
+
/**
|
|
28
|
+
* Drop every stored vector when the provider changes.
|
|
29
|
+
*
|
|
30
|
+
* Returns true when a wipe happened, so the caller can report that the next
|
|
31
|
+
* pass is a full re-embed rather than an incremental one.
|
|
32
|
+
*/
|
|
33
|
+
export declare function reconcileVectorProviderWithStatement(stmt: PrepareStatement, getMetadata: (key: string) => string | undefined, setMetadata: (key: string, value: string) => void, provider: string): boolean;
|
|
34
|
+
/** Vectors dropped for files no longer indexed. */
|
|
35
|
+
export declare function pruneOrphanFileVectorsWithStatement(stmt: PrepareStatement): number;
|
|
36
|
+
export declare function countFileVectorsWithStatement(stmt: PrepareStatement): number;
|
|
37
|
+
export interface VectorHit {
|
|
38
|
+
file: string;
|
|
39
|
+
/** Cosine similarity in [-1, 1]. */
|
|
40
|
+
score: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Rank every stored vector against `query` and return the closest files.
|
|
44
|
+
*
|
|
45
|
+
* A brute-force scan, deliberately: at file granularity this repository has
|
|
46
|
+
* roughly eight thousand vectors of 384 floats, which is about twelve
|
|
47
|
+
* megabytes and a few milliseconds to sweep. An approximate-nearest-neighbour
|
|
48
|
+
* index would add a dependency and an accuracy cliff to save time nobody is
|
|
49
|
+
* waiting on.
|
|
50
|
+
*/
|
|
51
|
+
export declare function searchFileVectorsWithStatement(stmt: PrepareStatement, query: Float32Array, limit: number, minScore: number): VectorHit[];
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=writer-vectors.d.ts.map
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import type { FileRankRow, SymbolRankRow } from './graph-rank.js';
|
|
1
2
|
import type { CallSite, CodeMapGraph, FileMeta, IndexStats, Symbol as IndexSymbol, Ref, SearchResult, SymbolKind, SymbolLang } from './schema.js';
|
|
2
3
|
import { type IndexSummary } from './writer-admin.js';
|
|
4
|
+
import type { ConceptCoverage, ConceptEdge, FileConcept, Subsystem } from './writer-concepts.js';
|
|
5
|
+
import type { RankedFileRow } from './writer-rank.js';
|
|
3
6
|
import type { WriterSearchFilter } from './writer-search-helpers.js';
|
|
4
7
|
import { StorePool } from './writer-store-pool.js';
|
|
8
|
+
import type { FileVectorRow, VectorHit } from './writer-vectors.js';
|
|
5
9
|
export { codebaseIndexDirOverride, resolveIndexDir } from './writer-helpers.js';
|
|
6
10
|
export { StorePool } from './writer-store-pool.js';
|
|
7
11
|
export declare class IndexStore {
|
|
@@ -171,11 +175,66 @@ export declare class IndexStore {
|
|
|
171
175
|
kind: SymbolKind;
|
|
172
176
|
line: number;
|
|
173
177
|
}>;
|
|
178
|
+
/** Declarations in one file, in source order. */
|
|
179
|
+
getFileSymbols(file: string, limit: number): Array<{
|
|
180
|
+
id: number;
|
|
181
|
+
name: string;
|
|
182
|
+
kind: string;
|
|
183
|
+
line: number;
|
|
184
|
+
signature: string;
|
|
185
|
+
}>;
|
|
186
|
+
/** Declarations behind an arbitrary id list, for the retrieval walk. */
|
|
187
|
+
getSymbolsByIds(ids: readonly number[]): Array<{
|
|
188
|
+
id: number;
|
|
189
|
+
name: string;
|
|
190
|
+
kind: string;
|
|
191
|
+
lang: string;
|
|
192
|
+
file: string;
|
|
193
|
+
line: number;
|
|
194
|
+
signature: string;
|
|
195
|
+
scope: string;
|
|
196
|
+
}>;
|
|
174
197
|
getAllResolvedRefs(): Array<{
|
|
175
198
|
fromId: number;
|
|
176
199
|
toId: number;
|
|
177
200
|
callType: string;
|
|
178
201
|
}>;
|
|
202
|
+
/**
|
|
203
|
+
* Replace both rank tables in one write. Called once per index run, after
|
|
204
|
+
* ref resolution has settled — a rank computed against half-resolved refs
|
|
205
|
+
* would describe a graph that never existed.
|
|
206
|
+
*/
|
|
207
|
+
replaceRanks(symbols: readonly SymbolRankRow[], files: readonly FileRankRow[]): void;
|
|
208
|
+
/** Wipe stored vectors when the embedding model changed. */
|
|
209
|
+
reconcileVectorProvider(provider: string): boolean;
|
|
210
|
+
getFileVectorStates(provider: string): Map<string, string>;
|
|
211
|
+
upsertFileVectors(rows: readonly FileVectorRow[]): void;
|
|
212
|
+
pruneOrphanFileVectors(): number;
|
|
213
|
+
countFileVectors(): number;
|
|
214
|
+
searchFileVectors(query: Float32Array, limit: number, minScore: number): VectorHit[];
|
|
215
|
+
upsertFileConcept(concept: FileConcept): void;
|
|
216
|
+
getFileConcept(file: string): FileConcept | undefined;
|
|
217
|
+
getAllFileConcepts(): FileConcept[];
|
|
218
|
+
getReadyConceptSummaries(): Map<string, string>;
|
|
219
|
+
getConceptCoverage(): ConceptCoverage;
|
|
220
|
+
/** Flag summaries whose file has changed since they were written. */
|
|
221
|
+
markStaleConcepts(): number;
|
|
222
|
+
/** Drop summaries for files that are no longer indexed. */
|
|
223
|
+
pruneOrphanConcepts(): number;
|
|
224
|
+
replaceSubsystems(subsystems: readonly Subsystem[], edges: readonly ConceptEdge[]): void;
|
|
225
|
+
getSubsystems(): Subsystem[];
|
|
226
|
+
getConceptEdges(): ConceptEdge[];
|
|
227
|
+
getPackageFileCounts(): Map<string, number>;
|
|
228
|
+
getRankedFiles(limit: number): RankedFileRow[];
|
|
229
|
+
getTopFileRanks(limit: number): FileRankRow[];
|
|
230
|
+
getTopSymbolRanks(limit: number): SymbolRankRow[];
|
|
231
|
+
getFileRankMap(): Map<string, number>;
|
|
232
|
+
getRankCounts(): {
|
|
233
|
+
symbols: number;
|
|
234
|
+
files: number;
|
|
235
|
+
};
|
|
236
|
+
getSymbolNameCandidates(): Map<number, number>;
|
|
237
|
+
getImportVisibility(): Map<string, Set<string>>;
|
|
179
238
|
getAllImportRefs(): Array<{
|
|
180
239
|
sourceFile: string | null;
|
|
181
240
|
toName: string;
|
package/dist/edit.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
editTool
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7XUEPBNT.js";
|
|
4
4
|
import "./chunk-MSOAX3GC.js";
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-TI5COGLY.js";
|
|
6
|
+
import "./chunk-MBR5VAB5.js";
|
|
7
|
+
import "./chunk-52UXXQMP.js";
|
|
8
|
+
import "./chunk-DL2ARI4S.js";
|
|
9
|
+
import "./chunk-3AU6CZWL.js";
|
|
10
10
|
import "./chunk-6IEBD27U.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-ZKC5UNGD.js";
|
|
12
12
|
import "./chunk-YOHO4DVT.js";
|
|
13
13
|
import "./chunk-2CTZW6JQ.js";
|
|
14
14
|
import "./chunk-KE7A76VC.js";
|
package/dist/exec.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseParserOutput,
|
|
3
|
+
recordParserSubprocess,
|
|
3
4
|
withSpawnGate
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ZKC5UNGD.js";
|
|
5
6
|
import {
|
|
6
7
|
detectLang
|
|
7
8
|
} from "./chunk-YOHO4DVT.js";
|
|
@@ -408,6 +409,7 @@ async function syncGoParse(filePath, content, lang) {
|
|
|
408
409
|
const goResult = await new Promise(
|
|
409
410
|
(resolve, reject) => {
|
|
410
411
|
let settled = false;
|
|
412
|
+
recordParserSubprocess();
|
|
411
413
|
const proc = spawn(goBinary, ["run", scriptPath], {
|
|
412
414
|
stdio: ["pipe", "pipe", "pipe"],
|
|
413
415
|
windowsHide: true
|
|
@@ -466,4 +468,4 @@ export {
|
|
|
466
468
|
detectLang,
|
|
467
469
|
parseSymbols
|
|
468
470
|
};
|
|
469
|
-
//# sourceMappingURL=go-parser-
|
|
471
|
+
//# sourceMappingURL=go-parser-QIEXU3P2.js.map
|