@titan-design/code-graph 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +350 -15
- package/dist/change-coupling-CyqHgRsm.d.ts +73 -0
- package/dist/chunk-PFI5XMUG.js +332 -0
- package/dist/chunk-PFI5XMUG.js.map +1 -0
- package/dist/history/index.d.ts +56 -0
- package/dist/history/index.js +29 -0
- package/dist/history/index.js.map +1 -0
- package/dist/index.d.ts +941 -38
- package/dist/index.js +2982 -231
- package/dist/index.js.map +1 -1
- package/package.json +9 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { Db, Migration } from '@titan-design/store-sqlite';
|
|
2
|
-
import {
|
|
2
|
+
import { Extractor, ParsedFile } from '@titan-design/code-parser';
|
|
3
|
+
export { Extractor, ParsedFile, getLanguageFromPath, getSupportedLanguages, parseFile, shouldIncludeFile } from '@titan-design/code-parser';
|
|
3
4
|
import { Project } from 'ts-morph';
|
|
5
|
+
import { c as CoEditPair, C as ChurnEntry, a as ChurnWindow } from './change-coupling-CyqHgRsm.js';
|
|
6
|
+
import { Embedder } from '@titan-design/embed';
|
|
4
7
|
|
|
5
8
|
type NodeKind = "package" | "module" | "file" | "symbol" | "external";
|
|
6
9
|
type EdgeKind = "imports" | "re-exports" | "calls" | "extends" | "implements" | "references" | "depends-on";
|
|
7
|
-
|
|
10
|
+
/** `requalify` maps a bare-name symbol id from before index version 0.14.0 to its scope-qualified successor. */
|
|
11
|
+
type IdAliasReason = "rename" | "move" | "merge" | "requalify";
|
|
8
12
|
type NodeRole = "test" | "fixture" | "barrel" | "types" | "config" | "script" | "entry" | "generated" | "source";
|
|
9
13
|
interface GraphNode {
|
|
10
14
|
id: string;
|
|
@@ -54,6 +58,25 @@ interface FileFingerprint {
|
|
|
54
58
|
structuralHash?: string;
|
|
55
59
|
}
|
|
56
60
|
|
|
61
|
+
/** One metric's values over the nodes of one kind in one snapshot; `count` excludes null values. */
|
|
62
|
+
interface MetricAggregate {
|
|
63
|
+
name: string;
|
|
64
|
+
nodeKind: NodeKind;
|
|
65
|
+
count: number;
|
|
66
|
+
sum: number | null;
|
|
67
|
+
min: number | null;
|
|
68
|
+
max: number | null;
|
|
69
|
+
}
|
|
70
|
+
/** One node's value for one metric, joined to the node's own vocabulary columns. */
|
|
71
|
+
interface TopMetricRow {
|
|
72
|
+
nodeId: string;
|
|
73
|
+
name: string;
|
|
74
|
+
kind: string;
|
|
75
|
+
role: string | null;
|
|
76
|
+
value: number | null;
|
|
77
|
+
unit: string | null;
|
|
78
|
+
}
|
|
79
|
+
|
|
57
80
|
interface SnapshotInsert {
|
|
58
81
|
ref: string;
|
|
59
82
|
commitHash?: string;
|
|
@@ -69,11 +92,18 @@ interface SnapshotInsert {
|
|
|
69
92
|
declare class CodeGraphStore {
|
|
70
93
|
readonly db: Db;
|
|
71
94
|
private readonly statements;
|
|
95
|
+
private readonly targeted;
|
|
72
96
|
constructor(db: Db);
|
|
73
97
|
createSnapshot(input: SnapshotInsert): number;
|
|
74
98
|
insertNodes(snapshotId: number, nodes: readonly GraphNode[]): void;
|
|
75
99
|
insertEdges(snapshotId: number, edges: readonly GraphEdge[]): void;
|
|
76
100
|
insertMetrics(snapshotId: number, metrics: readonly GraphMetric[]): void;
|
|
101
|
+
/**
|
|
102
|
+
* Replace every metric of one `name` for a snapshot in a single transaction —
|
|
103
|
+
* for an overlay such as coverage, which is re-ingested wholesale and must not
|
|
104
|
+
* accumulate stale rows across runs.
|
|
105
|
+
*/
|
|
106
|
+
replaceMetricsByName(snapshotId: number, name: string, metrics: readonly GraphMetric[]): void;
|
|
77
107
|
insertAliases(snapshotId: number, aliases: readonly IdAlias[]): void;
|
|
78
108
|
insertFingerprints(snapshotId: number, fingerprints: readonly FileFingerprint[]): void;
|
|
79
109
|
getSnapshot(id: number): SnapshotRow | null;
|
|
@@ -96,8 +126,31 @@ declare class CodeGraphStore {
|
|
|
96
126
|
includeReferences?: boolean;
|
|
97
127
|
}): GraphEdge[];
|
|
98
128
|
listMetrics(snapshotId: number): GraphMetric[];
|
|
129
|
+
/** Every metric on one node, from the primary key instead of a whole-snapshot read. */
|
|
130
|
+
listMetricsForNode(snapshotId: number, nodeId: string): GraphMetric[];
|
|
131
|
+
/** Distinct metric names stored for a snapshot, ascending. */
|
|
132
|
+
listMetricNames(snapshotId: number): string[];
|
|
133
|
+
/** The highest-valued nodes for one metric, descending; `limit` defaults to 20. */
|
|
134
|
+
topByMetric(opts: {
|
|
135
|
+
snapshotId: number;
|
|
136
|
+
metric: string;
|
|
137
|
+
limit?: number;
|
|
138
|
+
kind?: string;
|
|
139
|
+
}): TopMetricRow[];
|
|
140
|
+
/** Edges into or out of one node; `references` edges are excluded unless asked, as in {@link listEdges}. */
|
|
141
|
+
listEdgesTouching(snapshotId: number, nodeId: string, opts?: {
|
|
142
|
+
includeReferences?: boolean;
|
|
143
|
+
}): GraphEdge[];
|
|
144
|
+
/** Count, sum, min, and max per metric name and node kind; pass `name` for one metric. */
|
|
145
|
+
aggregateMetrics(snapshotId: number, opts?: {
|
|
146
|
+
name?: string;
|
|
147
|
+
}): MetricAggregate[];
|
|
99
148
|
listAliases(snapshotId: number): IdAlias[];
|
|
100
149
|
listFingerprints(snapshotId: number): FileFingerprint[];
|
|
150
|
+
/** Drop whole snapshots. The domain tables carry no foreign key, so each is cleared by hand. */
|
|
151
|
+
deleteSnapshots(ids: readonly number[]): void;
|
|
152
|
+
vacuum(): void;
|
|
153
|
+
countRowsByTable(tables: readonly string[]): Record<string, number>;
|
|
101
154
|
close(): void;
|
|
102
155
|
}
|
|
103
156
|
/** Open (creating if absent) a code graph database and bring it to the current schema. */
|
|
@@ -122,14 +175,37 @@ declare const KIT: {
|
|
|
122
175
|
* `file_fingerprint` is the reuse basis the incremental indexer diffs against.
|
|
123
176
|
*/
|
|
124
177
|
declare const DOMAIN_DDL = "\n CREATE TABLE IF NOT EXISTS edge (\n snapshot_id INTEGER NOT NULL,\n src_id TEXT NOT NULL,\n dst_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n attrs TEXT,\n PRIMARY KEY (snapshot_id, src_id, dst_id, kind)\n );\n CREATE INDEX IF NOT EXISTS idx_edge_dst ON edge(snapshot_id, dst_id);\n CREATE INDEX IF NOT EXISTS idx_edge_kind ON edge(snapshot_id, kind);\n\n CREATE TABLE IF NOT EXISTS metric (\n snapshot_id INTEGER NOT NULL,\n node_id TEXT NOT NULL,\n name TEXT NOT NULL,\n value REAL,\n unit TEXT,\n PRIMARY KEY (snapshot_id, node_id, name)\n );\n CREATE INDEX IF NOT EXISTS idx_metric_name ON metric(snapshot_id, name);\n\n CREATE TABLE IF NOT EXISTS id_alias (\n snapshot_id INTEGER NOT NULL,\n old_id TEXT NOT NULL,\n new_id TEXT NOT NULL,\n reason TEXT NOT NULL,\n PRIMARY KEY (snapshot_id, old_id, new_id)\n );\n\n CREATE TABLE IF NOT EXISTS file_fingerprint (\n snapshot_id INTEGER NOT NULL,\n file_id TEXT NOT NULL,\n content_hash TEXT NOT NULL,\n structural_hash TEXT,\n PRIMARY KEY (snapshot_id, file_id)\n );\n";
|
|
178
|
+
/** Every table keyed by `snapshot_id`. No DDL above declares a foreign key, so dropping a snapshot walks this list. */
|
|
179
|
+
declare const SNAPSHOT_SCOPED_TABLES: readonly ["node", "edge", "metric", "id_alias", "file_fingerprint"];
|
|
125
180
|
declare const MIGRATIONS: Migration[];
|
|
181
|
+
/** The top of this package's schema. A code graph database is never shared, so this is the top of one. */
|
|
182
|
+
declare const SCHEMA_VERSION: number;
|
|
183
|
+
|
|
184
|
+
interface PrunePlan {
|
|
185
|
+
keep: SnapshotRow[];
|
|
186
|
+
remove: SnapshotRow[];
|
|
187
|
+
}
|
|
188
|
+
interface PruneOptions {
|
|
189
|
+
keep?: number;
|
|
190
|
+
keepRefs?: readonly string[];
|
|
191
|
+
}
|
|
192
|
+
declare function planPrune(store: CodeGraphStore, options?: PruneOptions): PrunePlan;
|
|
193
|
+
interface PruneResult {
|
|
194
|
+
plan: PrunePlan;
|
|
195
|
+
rowsBefore: Record<string, number>;
|
|
196
|
+
rowsAfter: Record<string, number>;
|
|
197
|
+
vacuumed: boolean;
|
|
198
|
+
}
|
|
199
|
+
declare function runPrune(store: CodeGraphStore, options?: PruneOptions & {
|
|
200
|
+
vacuum?: boolean;
|
|
201
|
+
}): PruneResult;
|
|
126
202
|
|
|
127
203
|
/**
|
|
128
204
|
* Bumping this invalidates every reuse basis: a snapshot written by a different
|
|
129
|
-
* index version is never reused, so a change to node/edge shape
|
|
130
|
-
* carried forward from an incompatible graph.
|
|
205
|
+
* index version is never reused, so a change to node/edge shape or to a metric's
|
|
206
|
+
* value for the same bytes can never be carried forward from an incompatible graph.
|
|
131
207
|
*/
|
|
132
|
-
declare const INDEX_VERSION = "0.
|
|
208
|
+
declare const INDEX_VERSION = "0.15.0";
|
|
133
209
|
interface IndexOptions {
|
|
134
210
|
/** Roots to walk. Node ids are still rooted at the git toplevel, so importers across roots share an id space. */
|
|
135
211
|
paths: string[];
|
|
@@ -145,6 +221,14 @@ interface IndexOptions {
|
|
|
145
221
|
* reason to disable it is to rebuild from scratch.
|
|
146
222
|
*/
|
|
147
223
|
incremental?: boolean;
|
|
224
|
+
/** Git churn, recency, and ownership metrics. Defaults to `true`; history is skipped silently outside git. */
|
|
225
|
+
computeChurn?: boolean;
|
|
226
|
+
/** Primary churn window in days (default 30); scopes ownership. */
|
|
227
|
+
churnWindowDays?: number;
|
|
228
|
+
/** Windows to store churn for (default 30, 90, 180); the primary window is always included. */
|
|
229
|
+
churnWindows?: number[];
|
|
230
|
+
/** Also store an all-time `lifetime` churn and ownership window over full git history. */
|
|
231
|
+
lifetime?: boolean;
|
|
148
232
|
}
|
|
149
233
|
interface IndexResult {
|
|
150
234
|
snapshotId: number;
|
|
@@ -170,23 +254,6 @@ interface IndexResult {
|
|
|
170
254
|
*/
|
|
171
255
|
declare function indexPaths(store: CodeGraphStore, options: IndexOptions): Promise<IndexResult>;
|
|
172
256
|
|
|
173
|
-
interface ParsedFile {
|
|
174
|
-
tree: Tree;
|
|
175
|
-
content: string;
|
|
176
|
-
filePath: string;
|
|
177
|
-
language: string;
|
|
178
|
-
}
|
|
179
|
-
interface Extractor<T> {
|
|
180
|
-
name: string;
|
|
181
|
-
extract(file: ParsedFile): T[];
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
declare function parseFile(content: string, filePath: string, language: string): Promise<ParsedFile>;
|
|
185
|
-
declare function getSupportedLanguages(): string[];
|
|
186
|
-
|
|
187
|
-
declare function shouldIncludeFile(filePath: string, languages: string[]): boolean;
|
|
188
|
-
declare function getLanguageFromPath(filePath: string): string | null;
|
|
189
|
-
|
|
190
257
|
interface LanguageExtractorOptions {
|
|
191
258
|
repoRoot: string;
|
|
192
259
|
tsConfigPath?: string;
|
|
@@ -293,15 +360,60 @@ declare class TsMorphGraphExtractor implements Extractor<GraphFragment> {
|
|
|
293
360
|
*/
|
|
294
361
|
declare function buildFileModuleNodes(repoRoot: string, absPath: string): GraphNode[];
|
|
295
362
|
|
|
363
|
+
/**
|
|
364
|
+
* C-81 — **deep AST on-pull**. Structural facts too heavy to persist at index
|
|
365
|
+
* time (class members, per-parameter types, return type) are recomputed lazily
|
|
366
|
+
* here from the working-tree source when a consumer actually pulls a target.
|
|
367
|
+
* Persisting them would bloat every symbol node and break the incremental reuse
|
|
368
|
+
* basis (inferred types embed absolute `import("…")` paths); computing on demand
|
|
369
|
+
* keeps the index lean while still answering "what are the members / params of
|
|
370
|
+
* this" for the one target being read.
|
|
371
|
+
*
|
|
372
|
+
* A single-file in-memory ts-morph project (no tsconfig, no dependency walk) —
|
|
373
|
+
* so the extraction is cheap and reads only explicit syntactic annotations.
|
|
374
|
+
*/
|
|
375
|
+
interface ParamInfo {
|
|
376
|
+
name: string;
|
|
377
|
+
type: string | null;
|
|
378
|
+
}
|
|
379
|
+
interface MemberInfo {
|
|
380
|
+
name: string;
|
|
381
|
+
memberKind: string;
|
|
382
|
+
signature: string | null;
|
|
383
|
+
isStatic: boolean;
|
|
384
|
+
}
|
|
385
|
+
interface DeepAst {
|
|
386
|
+
target: string;
|
|
387
|
+
kind: "file" | "symbol";
|
|
388
|
+
declarationKind: string | null;
|
|
389
|
+
signature: string | null;
|
|
390
|
+
purpose: string | null;
|
|
391
|
+
params: ParamInfo[];
|
|
392
|
+
returnType: string | null;
|
|
393
|
+
/** Class/interface members for a symbol; exported declarations for a file. */
|
|
394
|
+
members: MemberInfo[];
|
|
395
|
+
note?: string;
|
|
396
|
+
}
|
|
397
|
+
interface DeepAstInput {
|
|
398
|
+
/** Repo-relative file id, e.g. `src/a.ts`. */
|
|
399
|
+
filePath: string;
|
|
400
|
+
/** Absolute path to the file on disk. */
|
|
401
|
+
absPath: string;
|
|
402
|
+
/** Symbol name for a symbol target; omit for a file target. */
|
|
403
|
+
symbolName?: string;
|
|
404
|
+
}
|
|
405
|
+
/** Deep structural facts for one target, or null when the source is unreadable. */
|
|
406
|
+
declare function computeDeepAst(input: DeepAstInput): DeepAst | null;
|
|
407
|
+
|
|
296
408
|
declare function fileId(repoRoot: string, absPath: string): string;
|
|
297
409
|
declare function moduleId(repoRoot: string, absPath: string): string;
|
|
298
410
|
declare function parentModuleId(id: string): string | null;
|
|
299
411
|
declare function packageId(name: string): string;
|
|
300
412
|
declare const SYMBOL_ID_SEP = "#";
|
|
301
|
-
declare function symbolId(fileId: string,
|
|
413
|
+
declare function symbolId(fileId: string, qualifiedName: string): string;
|
|
302
414
|
/**
|
|
303
415
|
* Inverse of {@link symbolId}: split a `<fileId>#<name>` symbol id back into its
|
|
304
|
-
* declaring file and
|
|
416
|
+
* declaring file and qualified name. Returns null for an id with no separator (a
|
|
305
417
|
* plain file id), so callers can filter the symbol layer cleanly. `#` is illegal
|
|
306
418
|
* in both posix paths and JS identifiers, so the first occurrence is the split.
|
|
307
419
|
*/
|
|
@@ -368,15 +480,10 @@ interface LineSpan {
|
|
|
368
480
|
endLine: number;
|
|
369
481
|
}
|
|
370
482
|
/**
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
* their complexity + coverage) even though nothing imports them. Names come from
|
|
376
|
-
* the same tree-sitter walk that computes complexity, so they never drift.
|
|
377
|
-
* Anonymous declarations (a default-exported arrow, inline callbacks) contribute
|
|
378
|
-
* no name and are skipped. A name declared more than once keeps its last span
|
|
379
|
-
* (overloads / same-named methods are rare; range lookup still resolves most).
|
|
483
|
+
* Qualified declared names mapped to their 1-based line span (C-63 coverage
|
|
484
|
+
* range-containment). One scope binds a name once, as TypeScript and Python do,
|
|
485
|
+
* so a getter/setter pair, a Python property's accessors, and `@overload` stubs
|
|
486
|
+
* share one entry; when a qualified name repeats, the last span wins.
|
|
380
487
|
*/
|
|
381
488
|
declare function collectDeclaredSpans(file: ParsedFile): Map<string, LineSpan>;
|
|
382
489
|
/** Declared names only — the Set view over {@link collectDeclaredSpans}. */
|
|
@@ -458,6 +565,8 @@ declare function canonicalMetricName(name: string): string;
|
|
|
458
565
|
declare function canonicalRole(name: string): NodeRole;
|
|
459
566
|
declare function canonicalEdgeKind(name: string): EdgeKind;
|
|
460
567
|
|
|
568
|
+
declare function detectGitToplevel(cwd: string): string | null;
|
|
569
|
+
|
|
461
570
|
interface RenamePair {
|
|
462
571
|
oldPath: string;
|
|
463
572
|
newPath: string;
|
|
@@ -471,10 +580,85 @@ interface DetectRenamesOptions {
|
|
|
471
580
|
}
|
|
472
581
|
declare function detectGitHead(repoRoot: string): string | null;
|
|
473
582
|
declare function isInsideGitRepo(repoRoot: string): boolean;
|
|
474
|
-
|
|
583
|
+
|
|
584
|
+
/** Resolve a ref (branch, tag, sha) to its current commit sha, or null. */
|
|
585
|
+
declare function resolveGitRef(repoRoot: string, ref: string): string | null;
|
|
475
586
|
declare function detectRenames(options: DetectRenamesOptions): RenamePair[];
|
|
476
587
|
declare function buildAliases(repoRoot: string, pairs: readonly RenamePair[]): IdAlias[];
|
|
477
588
|
|
|
589
|
+
/** Snapshot attrs key naming the snapshot its id aliases were computed against; written from index version 0.15.0. */
|
|
590
|
+
declare const ALIAS_BASE_ATTR = "aliasBase";
|
|
591
|
+
type LineageSnapshot = Pick<SnapshotRow, "id" | "commitHash" | "attrs">;
|
|
592
|
+
/** Each snapshot's alias base, or null for a root: the tree the id_alias rows form across snapshots. */
|
|
593
|
+
type Lineage = ReadonlyMap<number, number | null>;
|
|
594
|
+
interface LineageStep {
|
|
595
|
+
snapshotId: number;
|
|
596
|
+
/** `forward` applies the snapshot's aliases (base to snapshot); `backward` undoes them. */
|
|
597
|
+
direction: "forward" | "backward";
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* The recorded base per snapshot. A snapshot written before 0.15.0 records none,
|
|
601
|
+
* so it gets the newest earlier snapshot with a commit: the one the indexer diffed against then.
|
|
602
|
+
*/
|
|
603
|
+
declare function buildLineage(snapshots: readonly LineageSnapshot[]): Lineage;
|
|
604
|
+
/** Steps from one snapshot to another through their nearest common base, or null when they share none. */
|
|
605
|
+
declare function lineagePath(lineage: Lineage, fromId: number, toId: number, maxHops?: number): LineageStep[] | null;
|
|
606
|
+
|
|
607
|
+
type AliasLoader = (snapshotId: number) => readonly IdAlias[];
|
|
608
|
+
interface AliasResolution {
|
|
609
|
+
requestedId: string;
|
|
610
|
+
/** The id in the target snapshot's id space; equal to `requestedId` when nothing moved. */
|
|
611
|
+
id: string;
|
|
612
|
+
/** Each alias applied in walk order; a backward step lists the alias it undid. */
|
|
613
|
+
hops: IdAlias[];
|
|
614
|
+
/** `move` when any hop changed directory, otherwise the last hop's reason; absent without hops. */
|
|
615
|
+
reason?: IdAliasReason;
|
|
616
|
+
}
|
|
617
|
+
interface AliasChain {
|
|
618
|
+
fromSnapshotId: number | null;
|
|
619
|
+
toSnapshotId: number;
|
|
620
|
+
/** False when the snapshots share no alias base; only the target's own aliases apply then, as before 0.15.0. */
|
|
621
|
+
connected: boolean;
|
|
622
|
+
steps: readonly LineageStep[];
|
|
623
|
+
resolve(id: string): string;
|
|
624
|
+
trace(id: string): AliasResolution;
|
|
625
|
+
}
|
|
626
|
+
interface AliasChainInput {
|
|
627
|
+
lineage: Lineage;
|
|
628
|
+
loadAliases: AliasLoader;
|
|
629
|
+
/** Null resolves an id from any ancestor of `to`. */
|
|
630
|
+
from: number | null;
|
|
631
|
+
to: number;
|
|
632
|
+
maxHops?: number;
|
|
633
|
+
}
|
|
634
|
+
/** Carry node ids from one snapshot into another across every rename between them. */
|
|
635
|
+
declare function createAliasChain(input: AliasChainInput): AliasChain;
|
|
636
|
+
|
|
637
|
+
interface AliasChainOptions {
|
|
638
|
+
maxHops?: number;
|
|
639
|
+
}
|
|
640
|
+
interface ResolveAliasOptions extends AliasChainOptions {
|
|
641
|
+
/** The snapshot the id was read in; omitted, the id may come from any ancestor of the target. */
|
|
642
|
+
fromSnapshotId?: number;
|
|
643
|
+
}
|
|
644
|
+
interface PriorSnapshotOptions {
|
|
645
|
+
/** Only snapshots older than this id count; omitted, every snapshot does. */
|
|
646
|
+
before?: number;
|
|
647
|
+
/** A git checkout to resolve `ref` in; without it only the snapshot's `ref` label matches. */
|
|
648
|
+
repoRoot?: string;
|
|
649
|
+
}
|
|
650
|
+
/** The alias-base tree over every snapshot in the store. */
|
|
651
|
+
declare function loadLineage(store: CodeGraphStore): Lineage;
|
|
652
|
+
/** Carry node ids from `fromSnapshotId` into `toSnapshotId` through every alias between them, in either direction. */
|
|
653
|
+
declare function aliasChain(store: CodeGraphStore, fromSnapshotId: number | null, toSnapshotId: number, options?: AliasChainOptions): AliasChain;
|
|
654
|
+
/** Resolve an id to its form in `toSnapshotId`: `a.ts` renamed to `b.ts` then `c.ts` resolves to `c.ts`. */
|
|
655
|
+
declare function resolveAlias(store: CodeGraphStore, id: string, toSnapshotId: number, options?: ResolveAliasOptions): AliasResolution;
|
|
656
|
+
/**
|
|
657
|
+
* The newest snapshot a ref denotes: first the snapshot of the commit git resolves
|
|
658
|
+
* `ref` to (with `repoRoot`), else the newest snapshot whose `ref` label is `ref`.
|
|
659
|
+
*/
|
|
660
|
+
declare function priorSnapshotForRef(store: CodeGraphStore, ref: string, options?: PriorSnapshotOptions): SnapshotRow | null;
|
|
661
|
+
|
|
478
662
|
declare function computeMetrics(nodes: readonly GraphNode[], edges: readonly GraphEdge[]): GraphMetric[];
|
|
479
663
|
|
|
480
664
|
/**
|
|
@@ -494,6 +678,73 @@ declare const SOURCE_METRIC_NAMES: ReadonlySet<string>;
|
|
|
494
678
|
*/
|
|
495
679
|
declare function computeSourceMetrics(files: readonly ParsedFile[], fileIdOf: (filePath: string) => string, symbolNamesByFile?: ReadonlyMap<string, ReadonlySet<string>>): GraphMetric[];
|
|
496
680
|
|
|
681
|
+
/** How a test↔source pairing was inferred. */
|
|
682
|
+
type LinkMethod = "path" | "coedit";
|
|
683
|
+
interface TestSourceLink {
|
|
684
|
+
/** Node id of the test file. */
|
|
685
|
+
testId: string;
|
|
686
|
+
/** Node id of the (non-test) file it covers. */
|
|
687
|
+
sourceId: string;
|
|
688
|
+
method: LinkMethod;
|
|
689
|
+
}
|
|
690
|
+
interface LinkTestsOptions {
|
|
691
|
+
/** Minimum co-edit count for a pass-2 (coedit) link. Default 2. */
|
|
692
|
+
minCoEditCount?: number;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Two-pass test↔source linker. Pass 1 pairs each test file with non-test files
|
|
696
|
+
* matching its path conventions (high confidence). Pass 2 supplements tests
|
|
697
|
+
* left unpaired by pass 1 with their strongest co-edited non-test partner from
|
|
698
|
+
* change-coupling. Handles orphan tests (no pairing), orphan/untested sources
|
|
699
|
+
* (no incoming link), and one-to-many pairings (a test matching several
|
|
700
|
+
* sources, or a source covered by several tests).
|
|
701
|
+
*/
|
|
702
|
+
declare function linkTestsToSources(nodes: readonly GraphNode[], coEditPairs: readonly CoEditPair[], options?: LinkTestsOptions): TestSourceLink[];
|
|
703
|
+
/**
|
|
704
|
+
* Per-source coverage breadth: how many distinct test files link to each
|
|
705
|
+
* covered source. Emitted only for sources with at least one linked test.
|
|
706
|
+
*/
|
|
707
|
+
declare function testCoverageCountMetrics(links: readonly TestSourceLink[]): GraphMetric[];
|
|
708
|
+
/** Map each covered source to the set of test files that link to it. */
|
|
709
|
+
declare function groupTestsBySource(links: readonly TestSourceLink[]): Map<string, Set<string>>;
|
|
710
|
+
|
|
711
|
+
interface HistoryMetricsOptions {
|
|
712
|
+
/** Primary window: scopes ownership. Default 30. */
|
|
713
|
+
churnWindowDays?: number;
|
|
714
|
+
/** Windows to store churn and recency for; default {@link DEFAULT_CHURN_WINDOWS}, primary always included. */
|
|
715
|
+
churnWindows?: number[];
|
|
716
|
+
/** Also store an all-time `lifetime` window over full git history. */
|
|
717
|
+
includeLifetime?: boolean;
|
|
718
|
+
/** Epoch seconds that windows end at; defaults to the current time. */
|
|
719
|
+
nowEpoch?: number;
|
|
720
|
+
}
|
|
721
|
+
/** Windows the dashboard switcher offers; churn is stored for each by default. */
|
|
722
|
+
declare const DEFAULT_CHURN_WINDOWS: number[];
|
|
723
|
+
/** De-duped, ascending windows including the primary, with `lifetime` last (widest) when requested. */
|
|
724
|
+
declare function resolveChurnWindows(requested: number[] | undefined, primaryWindow: number, includeLifetime: boolean): ChurnWindow[];
|
|
725
|
+
interface LoadedHistory {
|
|
726
|
+
metrics: GraphMetric[];
|
|
727
|
+
/** Churn entries inside the primary window, which also scopes test-coverage linking and ownership. */
|
|
728
|
+
primaryEntries: readonly ChurnEntry[];
|
|
729
|
+
}
|
|
730
|
+
/** {@link buildHistoryMetrics} plus the primary-window entries it read; null when git or history is unavailable. */
|
|
731
|
+
declare function loadHistoryMetrics(nodes: Iterable<GraphNode>, idRoot: string, options?: HistoryMetricsOptions): LoadedHistory | null;
|
|
732
|
+
interface TestCoverageOwnershipOptions {
|
|
733
|
+
/** Window named in the metric suffix. Default 30. */
|
|
734
|
+
windowDays?: ChurnWindow;
|
|
735
|
+
/** Coverage threshold for bus factor (default 0.5 = 50% of churn). */
|
|
736
|
+
busFactorThreshold?: number;
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Bus-factor / top-author-share of the *test coverage* for each source, keyed
|
|
740
|
+
* on the source node. Aggregates churn authorship across all test files linked
|
|
741
|
+
* to a source (via the two-pass linker) and summarises it the same way as
|
|
742
|
+
* production ownership — so a file can read as well-spread on production code
|
|
743
|
+
* yet a single-author silo on its tests (or vice versa). Emitted only for
|
|
744
|
+
* sources with at least one linked test that has churn in the window.
|
|
745
|
+
*/
|
|
746
|
+
declare function computeTestCoverageOwnership(entries: readonly ChurnEntry[], links: readonly TestSourceLink[], options?: TestCoverageOwnershipOptions): GraphMetric[];
|
|
747
|
+
|
|
497
748
|
interface IndexerMetricsInput {
|
|
498
749
|
nodes: Map<string, GraphNode>;
|
|
499
750
|
edges: Map<string, GraphEdge>;
|
|
@@ -502,6 +753,8 @@ interface IndexerMetricsInput {
|
|
|
502
753
|
/** Source metrics carried forward verbatim for reused (unchanged) files. */
|
|
503
754
|
reusedSourceMetrics: GraphMetric[];
|
|
504
755
|
idRoot: string;
|
|
756
|
+
/** Git-history metrics (churn, recency, ownership); omitted means none. */
|
|
757
|
+
history?: HistoryMetricsOptions;
|
|
505
758
|
}
|
|
506
759
|
/**
|
|
507
760
|
* Assemble the metric set for a snapshot: graph-wide degree metrics over the
|
|
@@ -510,12 +763,324 @@ interface IndexerMetricsInput {
|
|
|
510
763
|
* reused source metrics is recomputed over the full set, so the result matches a
|
|
511
764
|
* full index regardless of how much was reused.
|
|
512
765
|
*
|
|
513
|
-
* Git-history metrics
|
|
514
|
-
*
|
|
515
|
-
* the rest of codewatch's analyses.
|
|
766
|
+
* Git-history metrics come from the path-based engine in `./history/` through
|
|
767
|
+
* the `history-metrics.ts` adapter. Test-coverage metrics run with or without it.
|
|
516
768
|
*/
|
|
517
769
|
declare function buildIndexerMetrics(input: IndexerMetricsInput): GraphMetric[];
|
|
518
770
|
|
|
771
|
+
/**
|
|
772
|
+
* Function-local dead-code metrics (C-65 Phase 1). Pure functions of one file's
|
|
773
|
+
* bytes — the same class as the source metrics in source-metrics.ts — so they
|
|
774
|
+
* ride the content-hash incremental reuse gate. Kept in their own module (not
|
|
775
|
+
* appended to source-metrics.ts) so the already-churn-hot source-metrics.ts is
|
|
776
|
+
* not touched; the reuse machinery folds these names in alongside
|
|
777
|
+
* SOURCE_METRIC_NAMES (see incremental.ts) and index-metrics.ts computes them
|
|
778
|
+
* fresh for (re)parsed files.
|
|
779
|
+
*/
|
|
780
|
+
declare const DEAD_CODE_METRIC_NAMES: ReadonlySet<string>;
|
|
781
|
+
/**
|
|
782
|
+
* Per-file dead-code metrics for TypeScript files. Emitted sparsely — only when
|
|
783
|
+
* a count is > 0 — so a clean file adds no rows (a full index and an incremental
|
|
784
|
+
* re-index therefore produce the identical metric set). Non-TypeScript files are
|
|
785
|
+
* skipped for now.
|
|
786
|
+
*/
|
|
787
|
+
declare function computeDeadCodeMetrics(files: readonly ParsedFile[], fileIdOf: (filePath: string) => string): GraphMetric[];
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* Growth-risk / scaling-smell metrics (C-66 Phase 2). Cheap, function-local
|
|
791
|
+
* *heuristics* — NOT Big-O or a proven complexity class (real asymptotic
|
|
792
|
+
* inference is undecidable; see the roadmap's hard NO). Pure functions of one
|
|
793
|
+
* file's bytes, so they ride the content-hash incremental reuse gate, folded
|
|
794
|
+
* into the carry-forward set in incremental.ts alongside the source/dead-code
|
|
795
|
+
* metric names. Emitted sparsely (only when a smell is present).
|
|
796
|
+
*/
|
|
797
|
+
declare const GROWTH_RISK_METRIC_NAMES: ReadonlySet<string>;
|
|
798
|
+
/**
|
|
799
|
+
* Per-file growth-risk metrics for TS/Python files, all SMELLS not bounds:
|
|
800
|
+
* - `loop_depth` — max *lexical* loop nesting (triple-nested → 3), emitted at
|
|
801
|
+
* depth ≥ 2 (depth-2 loops over two *different* collections are actually linear).
|
|
802
|
+
* - `recursive_functions` — named functions that call themselves directly.
|
|
803
|
+
* - `search_in_loop` — linear-scan method calls (`.includes`/`.find`/…) inside a
|
|
804
|
+
* loop (an O(n) scan per iteration; `.includes` on a `Set` is O(1)).
|
|
805
|
+
* All emitted sparsely (only when present). Non-TS/Python files are skipped.
|
|
806
|
+
*/
|
|
807
|
+
declare function computeGrowthRiskMetrics(files: readonly ParsedFile[], fileIdOf: (filePath: string) => string): GraphMetric[];
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Coverage is a whole-suite DYNAMIC artifact — a function of *which tests ran*,
|
|
811
|
+
* not of any file's bytes — so it must NOT ride the content-hash reuse gate. It
|
|
812
|
+
* is emitted as a `coverage_pct` metric that is deliberately absent from every
|
|
813
|
+
* *_METRIC_NAMES reuse set, so an incremental index never carries it forward: a
|
|
814
|
+
* later index produces a snapshot with NO coverage until re-ingested. That is the
|
|
815
|
+
* overlay semantics — coverage is attached to the snapshot it was measured
|
|
816
|
+
* against and never inferred for another.
|
|
817
|
+
*/
|
|
818
|
+
declare const COVERAGE_METRIC_NAME = "coverage_pct";
|
|
819
|
+
/** Minimal Istanbul `coverage-final.json` shape we read (function-level). */
|
|
820
|
+
interface IstanbulFn {
|
|
821
|
+
loc: {
|
|
822
|
+
start: {
|
|
823
|
+
line: number;
|
|
824
|
+
};
|
|
825
|
+
end: {
|
|
826
|
+
line: number;
|
|
827
|
+
};
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
interface IstanbulFileCoverage {
|
|
831
|
+
fnMap: Record<string, IstanbulFn>;
|
|
832
|
+
/** Per-function hit counts, keyed to fnMap ids. */
|
|
833
|
+
f: Record<string, number>;
|
|
834
|
+
}
|
|
835
|
+
type IstanbulCoverage = Record<string, IstanbulFileCoverage>;
|
|
836
|
+
/** A symbol node's 1-based line span, for range-containment attribution. */
|
|
837
|
+
interface SymbolSpan {
|
|
838
|
+
id: string;
|
|
839
|
+
startLine: number;
|
|
840
|
+
endLine: number;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Attribute an Istanbul coverage report to graph nodes as `coverage_pct` metrics:
|
|
844
|
+
* one per covered FILE (covered functions / total functions), and one per SYMBOL
|
|
845
|
+
* a covered function maps into by RANGE containment (symbol spans) — matching
|
|
846
|
+
* by range, not name, so anonymous/mangled Istanbul function names are handled.
|
|
847
|
+
* A symbol spanning several functions (a class) reports its methods' coverage
|
|
848
|
+
* ratio. Files Istanbul reports but the graph doesn't know are skipped.
|
|
849
|
+
*/
|
|
850
|
+
declare function attributeCoverage(coverage: IstanbulCoverage, fileIdOf: (absPath: string) => string | null, symbolsByFile: ReadonlyMap<string, readonly SymbolSpan[]>): GraphMetric[];
|
|
851
|
+
|
|
852
|
+
/** Metric-name suffix for a window: `30d`, `180d`, or `lifetime`. */
|
|
853
|
+
declare function windowSuffix(window: ChurnWindow): string;
|
|
854
|
+
/**
|
|
855
|
+
* Age-discount metrics: `recency_{w}` = min(1, age/w) for each file that churned
|
|
856
|
+
* in window `w`, plus one window-independent `file_age_days` per file. Multiplying
|
|
857
|
+
* a hotspot score by recency stops a young file's burst of churn from reading as
|
|
858
|
+
* decay. Recency is emitted (as 1) even when the age is unknown, so a rule that
|
|
859
|
+
* needs every hotspot factor is never silently disabled; `file_age_days` only when known.
|
|
860
|
+
*/
|
|
861
|
+
declare function computeRecencyWindows(firstSeen: ReadonlyMap<string, number>, churnedIdsByWindow: ReadonlyMap<ChurnWindow, ReadonlySet<string>>, nowEpoch: number): GraphMetric[];
|
|
862
|
+
|
|
863
|
+
interface PageRankOptions {
|
|
864
|
+
/** Per-node teleport weight. Unset or empty → uniform teleport across all nodes. */
|
|
865
|
+
personalization?: ReadonlyMap<string, number>;
|
|
866
|
+
/** Probability of following an edge vs teleporting (default 0.85). */
|
|
867
|
+
damping?: number;
|
|
868
|
+
/** L1 convergence threshold (default 1e-6). */
|
|
869
|
+
tolerance?: number;
|
|
870
|
+
/** Cap on power-iteration steps (default 100). */
|
|
871
|
+
maxIterations?: number;
|
|
872
|
+
/** Per-kind edge weight; missing kinds default to 1.0. */
|
|
873
|
+
edgeWeights?: Partial<Record<EdgeKind, number>>;
|
|
874
|
+
}
|
|
875
|
+
interface PageRankRow {
|
|
876
|
+
nodeId: string;
|
|
877
|
+
score: number;
|
|
878
|
+
}
|
|
879
|
+
interface PageRankResult {
|
|
880
|
+
/** Sorted descending by score; ties broken by node id ascending. */
|
|
881
|
+
rows: PageRankRow[];
|
|
882
|
+
iterations: number;
|
|
883
|
+
converged: boolean;
|
|
884
|
+
}
|
|
885
|
+
/** Edge weight used by PageRank for a given edge kind, honoring user overrides. */
|
|
886
|
+
declare function getEdgeWeight(kind: EdgeKind, overrides?: Partial<Record<EdgeKind, number>>): number;
|
|
887
|
+
declare function computePageRank(nodes: readonly GraphNode[], edges: readonly GraphEdge[], options?: PageRankOptions): PageRankResult;
|
|
888
|
+
|
|
889
|
+
interface RelevanceOptions {
|
|
890
|
+
/** Probability of following an edge vs teleporting back to the seeds (default 0.85). */
|
|
891
|
+
damping?: number;
|
|
892
|
+
/** Per-kind edge weight override, forwarded to PageRank. */
|
|
893
|
+
edgeWeights?: PageRankOptions["edgeWeights"];
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* C-89 — **seeded (personalized) PageRank as a relevance-to-target proximity
|
|
897
|
+
* measure** (Aider RepoMap-style). The teleport vector is concentrated on
|
|
898
|
+
* `seedIds`, so the stationary distribution scores every node by how tightly it
|
|
899
|
+
* couples to the seeds through the resolved dependency graph: near neighbours
|
|
900
|
+
* score high, decaying with graph distance. This is "relevance to what I'm
|
|
901
|
+
* looking at," distinct from global PageRank centrality ("globally famous"),
|
|
902
|
+
* which stays the no-seed cold path.
|
|
903
|
+
*
|
|
904
|
+
* The edge set is **symmetrized** (each edge added in both directions) so
|
|
905
|
+
* relevance flows to a target's callers AND its dependencies — a purely forward
|
|
906
|
+
* walk from the seed would only reach what the seed depends on, never who
|
|
907
|
+
* depends on it. Edge kind (and therefore weight) is preserved on the reversed
|
|
908
|
+
* copy, so a heavier `calls` edge stays heavier in both directions.
|
|
909
|
+
*
|
|
910
|
+
* Returns a Map from node id to relevance score (seeds included). An empty seed
|
|
911
|
+
* set returns an empty map — callers then fall back to global centrality.
|
|
912
|
+
*/
|
|
913
|
+
declare function computeRelevance(nodes: readonly GraphNode[], edges: readonly GraphEdge[], seedIds: readonly string[], options?: RelevanceOptions): Map<string, number>;
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* Symbol-level change coupling (C-60). Decomposes a god-file the file-level
|
|
917
|
+
* coupling view rolls up as one blob (e.g. `types.ts`) into *which symbol* is
|
|
918
|
+
* used where. Built on the C-53 `references` edge substrate: `src` is the
|
|
919
|
+
* importing file, `dst` is the imported symbol node id (`<fileId>#<name>`).
|
|
920
|
+
*
|
|
921
|
+
* Two slices, both pure functions of the assembled reference edge set (a
|
|
922
|
+
* whole-graph rollup like utilization/PageRank, sound under incremental reuse
|
|
923
|
+
* since it reads the reassembled edges, not a per-file cache):
|
|
924
|
+
*
|
|
925
|
+
* - **Slice C — per-symbol consumers**: invert the edges by `dst`, giving the
|
|
926
|
+
* set of files that import each symbol. Directly answers "what IN this file is
|
|
927
|
+
* used where"; covers span-less types/consts that a git-hunk approach cannot.
|
|
928
|
+
* - **Slice B — co-import coupling**: group edges by `src`, and every pair of
|
|
929
|
+
* symbols co-imported by the same file is a coupling pair. Two symbols that
|
|
930
|
+
* are always imported together travel together — structural (used-together),
|
|
931
|
+
* drift-free coupling, as opposed to the temporal (changed-together) git
|
|
932
|
+
* co-edit signal.
|
|
933
|
+
*/
|
|
934
|
+
/** The minimal shape of a `references` edge this module consumes. */
|
|
935
|
+
interface ReferenceEdgeLite {
|
|
936
|
+
/** Importing file id. */
|
|
937
|
+
srcId: string;
|
|
938
|
+
/** Imported symbol node id (`<fileId>#<name>`). */
|
|
939
|
+
dstId: string;
|
|
940
|
+
}
|
|
941
|
+
/** One symbol's consumer set (Slice C). */
|
|
942
|
+
interface SymbolConsumers {
|
|
943
|
+
symbolId: string;
|
|
944
|
+
/** Declaring file, parsed from the symbol id. */
|
|
945
|
+
fileId: string;
|
|
946
|
+
/** Export name. */
|
|
947
|
+
name: string;
|
|
948
|
+
/** Distinct importing file ids, sorted. */
|
|
949
|
+
consumers: string[];
|
|
950
|
+
}
|
|
951
|
+
/** A pair of symbols co-imported by the same file (Slice B). */
|
|
952
|
+
interface SymbolCouplingPair {
|
|
953
|
+
aId: string;
|
|
954
|
+
aFile: string;
|
|
955
|
+
aName: string;
|
|
956
|
+
bId: string;
|
|
957
|
+
bFile: string;
|
|
958
|
+
bName: string;
|
|
959
|
+
/** Distinct files that import both symbols. */
|
|
960
|
+
coImports: number;
|
|
961
|
+
/** True when the two symbols are declared in different files. */
|
|
962
|
+
crossFile: boolean;
|
|
963
|
+
}
|
|
964
|
+
interface SymbolCouplingOptions {
|
|
965
|
+
/** Skip pairs co-imported by fewer than this many files. Default 2. */
|
|
966
|
+
minCoImports?: number;
|
|
967
|
+
/**
|
|
968
|
+
* Skip importing files that reference more than this many distinct symbols —
|
|
969
|
+
* a wide barrel-style importer would otherwise explode into O(n²) noise
|
|
970
|
+
* pairs, mirroring change-coupling's large-commit guard. Default 40.
|
|
971
|
+
*/
|
|
972
|
+
largeImporterThreshold?: number;
|
|
973
|
+
}
|
|
974
|
+
/**
|
|
975
|
+
* Group reference edges by imported symbol, yielding each symbol's distinct
|
|
976
|
+
* consuming files (Slice C). Sorted by consumer count desc, then symbol id, so
|
|
977
|
+
* the most broadly-depended-on exports lead.
|
|
978
|
+
*/
|
|
979
|
+
declare function computeSymbolConsumers(edges: readonly ReferenceEdgeLite[]): SymbolConsumers[];
|
|
980
|
+
/**
|
|
981
|
+
* Every pair of symbols co-imported by the same file becomes a coupling pair,
|
|
982
|
+
* counted by how many distinct files co-import them (Slice B). Wide importers
|
|
983
|
+
* are dropped to keep the pairing near-linear. Sorted by co-import count desc,
|
|
984
|
+
* cross-file pairs preferred at a tie (they are the actionable ones — a
|
|
985
|
+
* same-file pair is just cohesion within one module).
|
|
986
|
+
*/
|
|
987
|
+
declare function computeSymbolCoupling(edges: readonly ReferenceEdgeLite[], options?: SymbolCouplingOptions): SymbolCouplingPair[];
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* Per-package and per-pair structural quality metrics, plus an overall
|
|
991
|
+
* Newman-Girvan modularity Q for the package partition.
|
|
992
|
+
*
|
|
993
|
+
* Operates on a barrel-resolved edge set by default: edges that land on a
|
|
994
|
+
* file with role="barrel" are rewritten to land on the underlying files
|
|
995
|
+
* the barrel re-exports from (transitively). The intent is to measure the
|
|
996
|
+
* real dependency surface, not the re-export plumbing.
|
|
997
|
+
*
|
|
998
|
+
* See C-8 task notes for the design rationale and empirical calibration
|
|
999
|
+
* data from the 2026-05-21 codewatch dogfood.
|
|
1000
|
+
*/
|
|
1001
|
+
interface PartitionQualityInput {
|
|
1002
|
+
/** Logical packages — at minimum needs an id. */
|
|
1003
|
+
packages: ReadonlyArray<{
|
|
1004
|
+
id: string;
|
|
1005
|
+
}>;
|
|
1006
|
+
/** Package id → list of file ids assigned to that package. */
|
|
1007
|
+
fileByPackage: ReadonlyMap<string, ReadonlyArray<string>>;
|
|
1008
|
+
/** All file/module/external nodes for the snapshot. Used to identify role="barrel". */
|
|
1009
|
+
nodes: readonly GraphNode[];
|
|
1010
|
+
/** All edges for the snapshot. */
|
|
1011
|
+
edges: readonly GraphEdge[];
|
|
1012
|
+
/**
|
|
1013
|
+
* When true, edges landing on a barrel file are resolved through its
|
|
1014
|
+
* re-export chain to the underlying source files. The cheap implementation
|
|
1015
|
+
* fans each barrel import into N synthetic edges (one per re-export
|
|
1016
|
+
* target), which over-attributes — a single `import { x } from "./pkg"`
|
|
1017
|
+
* becomes N edges as if every re-export were used. Default false until
|
|
1018
|
+
* a weighted or symbol-tracking version is available.
|
|
1019
|
+
*/
|
|
1020
|
+
resolveBarrels?: boolean;
|
|
1021
|
+
}
|
|
1022
|
+
type PackageFlag = "weak-boundary";
|
|
1023
|
+
type PairFlag = "tight" | "moderate" | "none";
|
|
1024
|
+
type PackageLayer = "top" | "middle" | "foundation";
|
|
1025
|
+
interface PackageStats {
|
|
1026
|
+
pkgId: string;
|
|
1027
|
+
fileCount: number;
|
|
1028
|
+
internalEdges: number;
|
|
1029
|
+
outgoingEdges: number;
|
|
1030
|
+
incomingEdges: number;
|
|
1031
|
+
/** internal / (internal + outgoing) — higher = more self-contained. */
|
|
1032
|
+
cohesion: number;
|
|
1033
|
+
/** outgoing / (outgoing + incoming) — Martin's I metric at the package level. */
|
|
1034
|
+
instability: number;
|
|
1035
|
+
/**
|
|
1036
|
+
* Abstractness proxy A ∈ [0,1]: share of the package's files with role
|
|
1037
|
+
* "types" (dedicated type/interface definitions). codewatch has no
|
|
1038
|
+
* symbol-level abstract/concrete counts, so this file-role ratio stands in
|
|
1039
|
+
* for Martin's A. Enables the instability×abstractness main-sequence plot.
|
|
1040
|
+
*/
|
|
1041
|
+
abstractness: number;
|
|
1042
|
+
layer: PackageLayer;
|
|
1043
|
+
flags: PackageFlag[];
|
|
1044
|
+
}
|
|
1045
|
+
interface PairCoupling {
|
|
1046
|
+
from: string;
|
|
1047
|
+
to: string;
|
|
1048
|
+
edges: number;
|
|
1049
|
+
/** edges / files(from) — fraction of from-side files contributing dependencies into `to`. */
|
|
1050
|
+
intensity: number;
|
|
1051
|
+
flag: PairFlag;
|
|
1052
|
+
}
|
|
1053
|
+
interface PartitionQualityResult {
|
|
1054
|
+
modularityQ: number;
|
|
1055
|
+
totalEdges: number;
|
|
1056
|
+
perPackage: PackageStats[];
|
|
1057
|
+
pairCoupling: PairCoupling[];
|
|
1058
|
+
/** Total raised flags across packages + pairs (excluding "moderate"). */
|
|
1059
|
+
flagsCount: number;
|
|
1060
|
+
}
|
|
1061
|
+
declare function computePartitionQuality(input: PartitionQualityInput): PartitionQualityResult;
|
|
1062
|
+
/**
|
|
1063
|
+
* Invert a package→files bucket map into a file→package lookup, skipping the
|
|
1064
|
+
* empty-string "unassigned" bucket. Shared by partition-quality and the CLI's
|
|
1065
|
+
* arch/wiki package rollups, which all need the same file→package direction.
|
|
1066
|
+
*/
|
|
1067
|
+
declare function invertBuckets(fileByPackage: ReadonlyMap<string, ReadonlyArray<string>>): Map<string, string>;
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* PageRank over one snapshot's file-level graph (symbol nodes and `references`
|
|
1071
|
+
* edges excluded, as codewatch's `graph relevant` reads it). Pass
|
|
1072
|
+
* `personalization` to seed the walk toward target node ids.
|
|
1073
|
+
*/
|
|
1074
|
+
declare function snapshotPageRank(store: CodeGraphStore, snapshotId: number, options?: PageRankOptions): PageRankResult;
|
|
1075
|
+
/** Relevance of every file-level node to `seedIds`, as codewatch's `graph context` computes it. */
|
|
1076
|
+
declare function snapshotRelevance(store: CodeGraphStore, snapshotId: number, seedIds: readonly string[], options?: RelevanceOptions): Map<string, number>;
|
|
1077
|
+
/** The snapshot's `references` edges: importing file to imported symbol. */
|
|
1078
|
+
declare function snapshotReferenceEdges(store: CodeGraphStore, snapshotId: number): ReferenceEdgeLite[];
|
|
1079
|
+
/** Per-symbol consumer files for one snapshot. */
|
|
1080
|
+
declare function snapshotSymbolConsumers(store: CodeGraphStore, snapshotId: number): SymbolConsumers[];
|
|
1081
|
+
/** Co-import symbol coupling pairs for one snapshot. */
|
|
1082
|
+
declare function snapshotSymbolCoupling(store: CodeGraphStore, snapshotId: number, options?: SymbolCouplingOptions): SymbolCouplingPair[];
|
|
1083
|
+
|
|
519
1084
|
/**
|
|
520
1085
|
* The free-function reading surface named in the package API. Each delegates to
|
|
521
1086
|
* the store's method of the same name, so a caller that only reads a snapshot
|
|
@@ -528,5 +1093,343 @@ declare function listEdges(store: CodeGraphStore, snapshotId: number, opts?: {
|
|
|
528
1093
|
includeReferences?: boolean;
|
|
529
1094
|
}): GraphEdge[];
|
|
530
1095
|
declare function listMetrics(store: CodeGraphStore, snapshotId: number): GraphMetric[];
|
|
1096
|
+
declare function listMetricsForNode(store: CodeGraphStore, snapshotId: number, nodeId: string): GraphMetric[];
|
|
1097
|
+
declare function listEdgesTouching(store: CodeGraphStore, snapshotId: number, nodeId: string, opts?: {
|
|
1098
|
+
includeReferences?: boolean;
|
|
1099
|
+
}): GraphEdge[];
|
|
1100
|
+
declare function aggregateMetrics(store: CodeGraphStore, snapshotId: number, opts?: {
|
|
1101
|
+
name?: string;
|
|
1102
|
+
}): MetricAggregate[];
|
|
1103
|
+
|
|
1104
|
+
/** The `unit` a metric row is stored with; every row of one metric name carries the same unit. */
|
|
1105
|
+
type MetricUnit = "count" | "lines" | "ratio" | "days" | "percent";
|
|
1106
|
+
/** How file values combine into a directory; `none` means no rollup reproduces the group's true value. */
|
|
1107
|
+
type MetricRollup = "sum" | "max" | "mean" | "none";
|
|
1108
|
+
/** Which way is worse, for ranking and colouring; `neutral` makes no value judgement. */
|
|
1109
|
+
type MetricDirection = "higher-worse" | "lower-worse" | "neutral";
|
|
1110
|
+
/** A missing row reads as zero (a sparse writer's floor) or is left out of means, percentiles, and ranks. */
|
|
1111
|
+
type MetricAbsence = "zero" | "exclude";
|
|
1112
|
+
/** The code-graph module that writes the metric, for provenance. */
|
|
1113
|
+
type MetricSource = "degree" | "source-metrics" | "lcom" | "dead-code" | "growth-risk" | "history" | "test-linker" | "coverage";
|
|
1114
|
+
interface MetricDescriptor {
|
|
1115
|
+
/** The stored name, or a template such as `churn_{w}` when {@link windowed} is set. */
|
|
1116
|
+
name: string;
|
|
1117
|
+
unit: MetricUnit;
|
|
1118
|
+
/** Node kinds the writer attaches this metric to. */
|
|
1119
|
+
appliesTo: readonly NodeKind[];
|
|
1120
|
+
rollup: MetricRollup;
|
|
1121
|
+
direction: MetricDirection;
|
|
1122
|
+
absent: MetricAbsence;
|
|
1123
|
+
source: MetricSource;
|
|
1124
|
+
description: string;
|
|
1125
|
+
/** Set on templates: `{w}` in `name` and `description` stands for a window such as `30d` or `lifetime`. */
|
|
1126
|
+
windowed?: true;
|
|
1127
|
+
/** Set on a resolved windowed descriptor: the window its name carries. */
|
|
1128
|
+
window?: string;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
/** Every metric name code-graph writes, with windowed names as `{w}` templates. */
|
|
1132
|
+
declare const METRIC_CATALOGUE: readonly MetricDescriptor[];
|
|
1133
|
+
|
|
1134
|
+
/** The descriptor for a stored metric name, resolving windowed names such as `churn_90d`; null when uncatalogued. */
|
|
1135
|
+
declare function describeMetric(name: string): MetricDescriptor | null;
|
|
1136
|
+
/** Descriptors for a set of stored names, in the order given; uncatalogued names are returned separately. */
|
|
1137
|
+
declare function describeMetrics(names: Iterable<string>): {
|
|
1138
|
+
described: MetricDescriptor[];
|
|
1139
|
+
unknown: string[];
|
|
1140
|
+
};
|
|
1141
|
+
|
|
1142
|
+
type Severity = "error" | "warning";
|
|
1143
|
+
interface MetricMaxRule {
|
|
1144
|
+
type: "metric-max";
|
|
1145
|
+
id: string;
|
|
1146
|
+
metric: string;
|
|
1147
|
+
max: number;
|
|
1148
|
+
kind?: NodeKind;
|
|
1149
|
+
severity?: Severity;
|
|
1150
|
+
exclude?: string[];
|
|
1151
|
+
excludeRoles?: NodeRole[];
|
|
1152
|
+
}
|
|
1153
|
+
interface MetricMinRule {
|
|
1154
|
+
type: "metric-min";
|
|
1155
|
+
id: string;
|
|
1156
|
+
metric: string;
|
|
1157
|
+
min: number;
|
|
1158
|
+
kind?: NodeKind;
|
|
1159
|
+
severity?: Severity;
|
|
1160
|
+
exclude?: string[];
|
|
1161
|
+
excludeRoles?: NodeRole[];
|
|
1162
|
+
}
|
|
1163
|
+
interface MetricProductMaxRule {
|
|
1164
|
+
type: "metric-product-max";
|
|
1165
|
+
id: string;
|
|
1166
|
+
metrics: string[];
|
|
1167
|
+
max: number;
|
|
1168
|
+
kind?: NodeKind;
|
|
1169
|
+
severity?: Severity;
|
|
1170
|
+
exclude?: string[];
|
|
1171
|
+
excludeRoles?: NodeRole[];
|
|
1172
|
+
}
|
|
1173
|
+
interface ForbidImportRule {
|
|
1174
|
+
type: "forbid-import";
|
|
1175
|
+
id: string;
|
|
1176
|
+
from: string;
|
|
1177
|
+
to: string;
|
|
1178
|
+
severity?: Severity;
|
|
1179
|
+
}
|
|
1180
|
+
interface LayeredDepsRule {
|
|
1181
|
+
type: "layered-deps";
|
|
1182
|
+
id: string;
|
|
1183
|
+
layers: string[][];
|
|
1184
|
+
severity?: Severity;
|
|
1185
|
+
}
|
|
1186
|
+
interface NoInternalOnlyBarrelsRule {
|
|
1187
|
+
type: "no-internal-only-barrels";
|
|
1188
|
+
id: string;
|
|
1189
|
+
/** Path prefixes marking package roots; node ids carry no intrinsic package membership. */
|
|
1190
|
+
packageRoots: string[];
|
|
1191
|
+
severity?: Severity;
|
|
1192
|
+
/** Globs or substrings to skip, such as CLI bin entries the role classifier calls barrels. */
|
|
1193
|
+
exclude?: string[];
|
|
1194
|
+
}
|
|
1195
|
+
type CheckRule = MetricMaxRule | MetricMinRule | MetricProductMaxRule | ForbidImportRule | LayeredDepsRule | NoInternalOnlyBarrelsRule;
|
|
1196
|
+
interface CheckRulesFile {
|
|
1197
|
+
rules: CheckRule[];
|
|
1198
|
+
}
|
|
1199
|
+
interface CheckViolation {
|
|
1200
|
+
ruleId: string;
|
|
1201
|
+
severity: Severity;
|
|
1202
|
+
nodeId: string;
|
|
1203
|
+
message: string;
|
|
1204
|
+
metric?: string;
|
|
1205
|
+
value?: number;
|
|
1206
|
+
threshold?: number;
|
|
1207
|
+
destinationId?: string;
|
|
1208
|
+
isCarryover?: boolean;
|
|
1209
|
+
}
|
|
1210
|
+
interface CheckResult {
|
|
1211
|
+
snapshotId: number;
|
|
1212
|
+
baselineSnapshotId?: number;
|
|
1213
|
+
rulesEvaluated: number;
|
|
1214
|
+
nodesEvaluated: number;
|
|
1215
|
+
violations: CheckViolation[];
|
|
1216
|
+
newErrors: number;
|
|
1217
|
+
newWarnings: number;
|
|
1218
|
+
carryoverErrors: number;
|
|
1219
|
+
carryoverWarnings: number;
|
|
1220
|
+
passed: boolean;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
/** The three whole-snapshot reads rule evaluation needs; any store with them can be checked. */
|
|
1224
|
+
type RuleStore = Pick<CodeGraphStore, "listNodes" | "listEdges" | "listMetrics">;
|
|
1225
|
+
|
|
1226
|
+
interface RunChecksOptions {
|
|
1227
|
+
snapshotId: number;
|
|
1228
|
+
rules: readonly CheckRule[];
|
|
1229
|
+
baselineSnapshotId?: number;
|
|
1230
|
+
}
|
|
1231
|
+
declare function runChecks(store: CodeGraphStore, options: RunChecksOptions): CheckResult;
|
|
1232
|
+
/** Every rule's violations in one snapshot with no baseline; needs only the three whole-snapshot reads. */
|
|
1233
|
+
declare function snapshotViolations(store: RuleStore, snapshotId: number, rules: readonly CheckRule[]): CheckViolation[];
|
|
1234
|
+
/** Identity of a violation across snapshots: severity, value and message may change, the key does not. */
|
|
1235
|
+
declare function violationKey(v: CheckViolation): string;
|
|
1236
|
+
/** {@link violationKey} with both node ids carried into another snapshot's id space; unmoved ids key as before. */
|
|
1237
|
+
declare function rebasedViolationKey(v: CheckViolation, resolve: (id: string) => string): string;
|
|
1238
|
+
|
|
1239
|
+
/** Glob when the pattern has a `*` (`**` crosses directories, `*` stays in a segment); otherwise a case-sensitive substring. */
|
|
1240
|
+
declare function patternToRegex(pattern: string): RegExp;
|
|
1241
|
+
declare function compilePatterns(patterns: readonly string[] | undefined): RegExp[];
|
|
1242
|
+
declare function matchesAny(value: string, patterns: readonly RegExp[]): boolean;
|
|
1243
|
+
|
|
1244
|
+
interface ValidateRulesOptions {
|
|
1245
|
+
/** Called with a human-readable message when a deprecated alias is healed. */
|
|
1246
|
+
onWarn?: (message: string) => void;
|
|
1247
|
+
}
|
|
1248
|
+
declare function validateRules(input: unknown, options?: ValidateRulesOptions): readonly CheckRule[];
|
|
1249
|
+
|
|
1250
|
+
/** A snapshot id, or a ref name resolved to that ref's newest snapshot. */
|
|
1251
|
+
type SnapshotSpec = number | string;
|
|
1252
|
+
interface CheckSnapshotOptions {
|
|
1253
|
+
snapshot: SnapshotSpec;
|
|
1254
|
+
rules: readonly CheckRule[];
|
|
1255
|
+
baseline?: SnapshotSpec;
|
|
1256
|
+
}
|
|
1257
|
+
interface CheckSnapshotResult {
|
|
1258
|
+
snapshot: SnapshotRow;
|
|
1259
|
+
baselineSnapshot?: SnapshotRow;
|
|
1260
|
+
result: CheckResult;
|
|
1261
|
+
}
|
|
1262
|
+
declare function resolveSnapshot(store: CodeGraphStore, spec: SnapshotSpec): SnapshotRow;
|
|
1263
|
+
/** Check one snapshot against a rule set, marking violations already present in the baseline as carryover. */
|
|
1264
|
+
declare function checkSnapshot(store: CodeGraphStore, options: CheckSnapshotOptions): CheckSnapshotResult;
|
|
1265
|
+
/** Read and validate a `check.json` rules file; deprecated aliases heal through `onWarn`. */
|
|
1266
|
+
declare function loadCheckRules(path: string, options?: ValidateRulesOptions): Promise<readonly CheckRule[]>;
|
|
1267
|
+
|
|
1268
|
+
interface MetricDelta {
|
|
1269
|
+
nodeId: string;
|
|
1270
|
+
name: string;
|
|
1271
|
+
before: number | null;
|
|
1272
|
+
after: number | null;
|
|
1273
|
+
delta: number | null;
|
|
1274
|
+
}
|
|
1275
|
+
interface NodeRename {
|
|
1276
|
+
oldId: string;
|
|
1277
|
+
newId: string;
|
|
1278
|
+
reason: IdAliasReason;
|
|
1279
|
+
node: GraphNode;
|
|
1280
|
+
}
|
|
1281
|
+
interface GraphDiffSummary {
|
|
1282
|
+
fromSnapshotId: number;
|
|
1283
|
+
toSnapshotId: number;
|
|
1284
|
+
addedNodes: number;
|
|
1285
|
+
removedNodes: number;
|
|
1286
|
+
renamedNodes: number;
|
|
1287
|
+
unchangedNodes: number;
|
|
1288
|
+
addedEdges: number;
|
|
1289
|
+
removedEdges: number;
|
|
1290
|
+
metricChanges: number;
|
|
1291
|
+
}
|
|
1292
|
+
interface GraphDiff {
|
|
1293
|
+
summary: GraphDiffSummary;
|
|
1294
|
+
addedNodes: GraphNode[];
|
|
1295
|
+
removedNodes: GraphNode[];
|
|
1296
|
+
renamedNodes: NodeRename[];
|
|
1297
|
+
addedEdges: GraphEdge[];
|
|
1298
|
+
removedEdges: GraphEdge[];
|
|
1299
|
+
metricDeltas: MetricDelta[];
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
interface DiffSnapshotsOptions {
|
|
1303
|
+
fromSnapshotId: number;
|
|
1304
|
+
toSnapshotId: number;
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Structural diff of two snapshots. Ids follow the alias chain between them, across
|
|
1308
|
+
* every rename in between, so a move is not a delete plus an add.
|
|
1309
|
+
*/
|
|
1310
|
+
declare function diffSnapshots(store: CodeGraphStore, options: DiffSnapshotsOptions): GraphDiff;
|
|
1311
|
+
|
|
1312
|
+
interface UnchangedViolation {
|
|
1313
|
+
from: CheckViolation;
|
|
1314
|
+
to: CheckViolation;
|
|
1315
|
+
delta: number | null;
|
|
1316
|
+
}
|
|
1317
|
+
interface CheckDiff {
|
|
1318
|
+
fromSnapshotId: number;
|
|
1319
|
+
toSnapshotId: number;
|
|
1320
|
+
rulesEvaluated: number;
|
|
1321
|
+
newViolations: CheckViolation[];
|
|
1322
|
+
resolvedViolations: CheckViolation[];
|
|
1323
|
+
unchanged: UnchangedViolation[];
|
|
1324
|
+
worsened: UnchangedViolation[];
|
|
1325
|
+
improved: UnchangedViolation[];
|
|
1326
|
+
}
|
|
1327
|
+
interface DiffCheckResultsOptions {
|
|
1328
|
+
fromSnapshotId: number;
|
|
1329
|
+
toSnapshotId: number;
|
|
1330
|
+
rules: readonly CheckRule[];
|
|
1331
|
+
}
|
|
1332
|
+
/**
|
|
1333
|
+
* Run the rules on both snapshots and bucket each violation as new, resolved, or
|
|
1334
|
+
* unchanged (worsened or improved by value). From-side ids follow the alias chain
|
|
1335
|
+
* into the to-snapshot, so a moved file's violations stay unchanged.
|
|
1336
|
+
*/
|
|
1337
|
+
declare function diffCheckResults(store: CodeGraphStore, options: DiffCheckResultsOptions): CheckDiff;
|
|
1338
|
+
|
|
1339
|
+
interface EmbeddableSymbol {
|
|
1340
|
+
id: string;
|
|
1341
|
+
name: string;
|
|
1342
|
+
file: string;
|
|
1343
|
+
signature: string;
|
|
1344
|
+
purpose?: string;
|
|
1345
|
+
text: string;
|
|
1346
|
+
textHash: string;
|
|
1347
|
+
}
|
|
1348
|
+
interface EmbedCoverage {
|
|
1349
|
+
/** Embeddable exported symbols in the snapshot. */
|
|
1350
|
+
symbols: number;
|
|
1351
|
+
/** How many symbols have a stored vector for this model. */
|
|
1352
|
+
embedded: number;
|
|
1353
|
+
/** How many carry docstring purpose text (where recall is strongest). */
|
|
1354
|
+
withPurpose: number;
|
|
1355
|
+
}
|
|
1356
|
+
interface EmbedSnapshotResult extends EmbedCoverage {
|
|
1357
|
+
model: string;
|
|
1358
|
+
/** Unique new texts sent to the embedder (symbols can share a text). */
|
|
1359
|
+
newlyEmbedded: number;
|
|
1360
|
+
/** Symbols whose vector was already stored (content-addressed cache hits). */
|
|
1361
|
+
reused: number;
|
|
1362
|
+
}
|
|
1363
|
+
/** Outcome of the non-fatal indexing pass: a down backend is reported, never thrown. */
|
|
1364
|
+
type EmbedAttempt = {
|
|
1365
|
+
ok: true;
|
|
1366
|
+
result: EmbedSnapshotResult;
|
|
1367
|
+
} | {
|
|
1368
|
+
ok: false;
|
|
1369
|
+
model: string;
|
|
1370
|
+
error: string;
|
|
1371
|
+
};
|
|
1372
|
+
interface SimilarCandidate {
|
|
1373
|
+
id: string;
|
|
1374
|
+
name: string;
|
|
1375
|
+
file: string;
|
|
1376
|
+
signature: string;
|
|
1377
|
+
purpose?: string;
|
|
1378
|
+
/** Cosine similarity to the query, in [-1, 1]. */
|
|
1379
|
+
score: number;
|
|
1380
|
+
}
|
|
1381
|
+
interface SimilarResult {
|
|
1382
|
+
query: string;
|
|
1383
|
+
model: string;
|
|
1384
|
+
coverage: EmbedCoverage;
|
|
1385
|
+
candidates: SimilarCandidate[];
|
|
1386
|
+
}
|
|
1387
|
+
/** Query prefixes are the embedder's to apply; configure them with its `prefixes` option. */
|
|
1388
|
+
interface FindSimilarOptions {
|
|
1389
|
+
limit?: number;
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
/** Mirrors the gate harness: purpose text is appended to the signature when present. */
|
|
1393
|
+
declare function buildEmbedText(signature: string, purpose?: string | null): string;
|
|
1394
|
+
declare function hashEmbedText(text: string): string;
|
|
1395
|
+
/**
|
|
1396
|
+
* The embeddable corpus of a snapshot: exported symbols that carry a signature,
|
|
1397
|
+
* excluding test/fixture/generated code (matching the validated gate corpus).
|
|
1398
|
+
*/
|
|
1399
|
+
declare function listEmbeddableSymbols(store: CodeGraphStore, snapshotId: number): EmbeddableSymbol[];
|
|
1400
|
+
|
|
1401
|
+
/** The blob_cache namespace for symbol vectors; the model column holds `embedder.model`, which names the vector space including its prefixes. */
|
|
1402
|
+
declare const SYMBOL_EMBEDDING_NAMESPACE = "code-graph/symbol-embedding";
|
|
1403
|
+
interface CachedEmbedResult {
|
|
1404
|
+
/** L2-normalized vectors for every input text, keyed by its text hash. */
|
|
1405
|
+
byHash: Map<string, number[]>;
|
|
1406
|
+
/** Hashes that had no stored vector and were embedded on this call. */
|
|
1407
|
+
newHashes: Set<string>;
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* Embed texts through the content-addressed store: only texts whose hash has
|
|
1411
|
+
* no vector for this model reach the embedder; new vectors are normalized and
|
|
1412
|
+
* persisted batch by batch so the next call (or a retry after a failure) is a cache hit.
|
|
1413
|
+
*/
|
|
1414
|
+
declare function embedTextsCached(store: CodeGraphStore, embedder: Embedder, texts: readonly string[]): Promise<CachedEmbedResult>;
|
|
1415
|
+
|
|
1416
|
+
/**
|
|
1417
|
+
* Precompute capability embeddings for a snapshot. Only texts whose hash has no
|
|
1418
|
+
* stored vector are sent to the embedder, so re-runs and unchanged symbols cost
|
|
1419
|
+
* nothing: the content-addressed store is the incremental-reuse mechanism.
|
|
1420
|
+
*/
|
|
1421
|
+
declare function embedSnapshot(store: CodeGraphStore, snapshotId: number, embedder: Embedder): Promise<EmbedSnapshotResult>;
|
|
1422
|
+
/**
|
|
1423
|
+
* The post-index pass. A backend failure (ollama down, model missing) must not
|
|
1424
|
+
* fail the index: the snapshot is already persisted and valid without vectors.
|
|
1425
|
+
*/
|
|
1426
|
+
declare function tryEmbedSnapshot(store: CodeGraphStore, snapshotId: number, embedder: Embedder): Promise<EmbedAttempt>;
|
|
1427
|
+
/**
|
|
1428
|
+
* The query-time "about to write X: does it exist?" surface. Embeds the query
|
|
1429
|
+
* (an intent sentence, a pseudo-signature, or both as `sig -- intent`), ranks
|
|
1430
|
+
* the snapshot's embedded symbols by cosine similarity, and returns the top-K
|
|
1431
|
+
* with coverage so the caller can weigh how much of the repo was searchable.
|
|
1432
|
+
*/
|
|
1433
|
+
declare function findSimilarCapability(store: CodeGraphStore, snapshotId: number, query: string, embedder: Embedder, opts?: FindSimilarOptions): Promise<SimilarResult>;
|
|
531
1434
|
|
|
532
|
-
export { ALL_ROLES, CodeGraphStore, DOMAIN_DDL, type EdgeKind, type
|
|
1435
|
+
export { ALIAS_BASE_ATTR, ALL_ROLES, type AliasChain, type AliasChainInput, type AliasChainOptions, type AliasLoader, type AliasResolution, COVERAGE_METRIC_NAME, type CachedEmbedResult, type CheckDiff, type CheckResult, type CheckRule, type CheckRulesFile, type CheckSnapshotOptions, type CheckSnapshotResult, type CheckViolation, CodeGraphStore, DEAD_CODE_METRIC_NAMES, DEFAULT_CHURN_WINDOWS, DOMAIN_DDL, type DeepAst, type DeepAstInput, type DiffCheckResultsOptions, type DiffSnapshotsOptions, type EdgeKind, type EmbedAttempt, type EmbedCoverage, type EmbedSnapshotResult, type EmbeddableSymbol, type FileFingerprint, type FindSimilarOptions, type ForbidImportRule, GROWTH_RISK_METRIC_NAMES, type GraphDiff, type GraphDiffSummary, type GraphEdge, type GraphFragment, type GraphMetric, type GraphNode, type HistoryMetricsOptions, INDEX_VERSION, type IdAlias, type IdAliasReason, type IndexOptions, type IndexResult, type IstanbulCoverage, KIT, LanguageExtractor, type LanguageExtractorOptions, type LayeredDepsRule, type LineSpan, type Lineage, type LineageSnapshot, type LineageStep, type LinkMethod, type LinkTestsOptions, type LoadedHistory, METRIC_CATALOGUE, MIGRATIONS, type MemberInfo, type MetricAbsence, type MetricAggregate, type MetricDelta, type MetricDescriptor, type MetricDirection, type MetricMaxRule, type MetricMinRule, type MetricProductMaxRule, type MetricRollup, type MetricSource, type MetricUnit, type NoInternalOnlyBarrelsRule, type NodeKind, type NodeRename, type NodeRole, type PackageFlag, type PackageLayer, type PackageStats, type PageRankOptions, type PageRankResult, type PageRankRow, type PairCoupling, type PairFlag, type ParamInfo, type PartitionQualityInput, type PartitionQualityResult, type PriorSnapshotOptions, type PruneOptions, type PrunePlan, type PruneResult, PythonGraphExtractor, type ReadFile, type ReferenceEdgeLite, type RelevanceOptions, type ResolveAliasOptions, type ReuseBasis, type RuleStore, type RunChecksOptions, SCHEMA_VERSION, SNAPSHOT_SCOPED_TABLES, SOURCE_METRIC_NAMES, SYMBOL_EMBEDDING_NAMESPACE, SYMBOL_ID_SEP, type Severity, type SimilarCandidate, type SimilarResult, type SnapshotInsert, type SnapshotRow, type SnapshotSpec, type SourceLanguage, type SymbolConsumers, type SymbolCouplingOptions, type SymbolCouplingPair, type SymbolSpan, type TestCoverageOwnershipOptions, type TestSourceLink, type TopMetricRow, TsMorphGraphExtractor, type TsMorphGraphExtractorOptions, type UnchangedViolation, type ValidateRulesOptions, aggregateMetrics, aliasChain, annotateRoles, attributeCoverage, buildAliases, buildEmbedText, buildFileModuleNodes, buildIndexerMetrics, buildLineage, canonicalEdgeKind, canonicalMetricName, canonicalRole, checkSnapshot, classifyRole, collectDeclaredNames, collectDeclaredSpans, compilePatterns, computeDeadCodeMetrics, computeDeepAst, computeGrowthRiskMetrics, computeMetrics, computePageRank, computePartitionQuality, computeRecencyWindows, computeRelevance, computeRoleHints, computeSourceMetrics, computeSymbolConsumers, computeSymbolCoupling, computeTestCoverageOwnership, createAliasChain, describeMetric, describeMetrics, detectGitHead, detectGitToplevel, detectRenames, diffCheckResults, diffSnapshots, edgeWeight, embedSnapshot, embedTextsCached, externalId, fileId, findSimilarCapability, getEdgeWeight, groupTestsBySource, hashContent, hashEmbedText, indexPaths, invertBuckets, isGeneratedByHeuristic, isGeneratedFile, isInsideGitRepo, lineagePath, linkTestsToSources, listEdges, listEdgesTouching, listEmbeddableSymbols, listMetrics, listMetricsForNode, listNodes, loadCheckRules, loadGeneratedPatterns, loadHistoryMetrics, loadLineage, matchesAny, moduleId, openCodeGraph, packageId, parentModuleId, parseSymbolId, patternToRegex, planPrune, priorSnapshotForRef, pruneDanglingReferences, readSourceFiles, rebasedViolationKey, resolveAlias, resolveBarrelEdges, resolveChurnWindows, resolveGitRef, resolveSnapshot, runChecks, runPrune, snapshotPageRank, snapshotReferenceEdges, snapshotRelevance, snapshotSymbolConsumers, snapshotSymbolCoupling, snapshotViolations, structuralSignature, symbolId, testCoverageCountMetrics, tryEmbedSnapshot, validateRules, violationKey, walkSourceFiles, windowSuffix };
|