@spikedpunch/mast 0.1.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/LICENSE +21 -0
- package/MAST_SPEC.md +2926 -0
- package/README.md +842 -0
- package/assets/skill.md +45 -0
- package/dist/ast/extract.d.ts +65 -0
- package/dist/ast/extract.d.ts.map +1 -0
- package/dist/ast/extract.js +147 -0
- package/dist/ast/extract.js.map +1 -0
- package/dist/ast/extractor.d.ts +85 -0
- package/dist/ast/extractor.d.ts.map +1 -0
- package/dist/ast/extractor.js +2 -0
- package/dist/ast/extractor.js.map +1 -0
- package/dist/ast/extractors/markdown.d.ts +40 -0
- package/dist/ast/extractors/markdown.d.ts.map +1 -0
- package/dist/ast/extractors/markdown.js +175 -0
- package/dist/ast/extractors/markdown.js.map +1 -0
- package/dist/ast/extractors/typescript.d.ts +179 -0
- package/dist/ast/extractors/typescript.d.ts.map +1 -0
- package/dist/ast/extractors/typescript.js +1439 -0
- package/dist/ast/extractors/typescript.js.map +1 -0
- package/dist/ast/parser.d.ts +5 -0
- package/dist/ast/parser.d.ts.map +1 -0
- package/dist/ast/parser.js +21 -0
- package/dist/ast/parser.js.map +1 -0
- package/dist/ast/types.d.ts +586 -0
- package/dist/ast/types.d.ts.map +1 -0
- package/dist/ast/types.js +3 -0
- package/dist/ast/types.js.map +1 -0
- package/dist/cli/docs-cmd.d.ts +22 -0
- package/dist/cli/docs-cmd.d.ts.map +1 -0
- package/dist/cli/docs-cmd.js +100 -0
- package/dist/cli/docs-cmd.js.map +1 -0
- package/dist/cli/index-cmd.d.ts +72 -0
- package/dist/cli/index-cmd.d.ts.map +1 -0
- package/dist/cli/index-cmd.js +263 -0
- package/dist/cli/index-cmd.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +14 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +64 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/install-hooks.d.ts +3 -0
- package/dist/cli/install-hooks.d.ts.map +1 -0
- package/dist/cli/install-hooks.js +34 -0
- package/dist/cli/install-hooks.js.map +1 -0
- package/dist/cli/metrics-cmd.d.ts +3 -0
- package/dist/cli/metrics-cmd.d.ts.map +1 -0
- package/dist/cli/metrics-cmd.js +164 -0
- package/dist/cli/metrics-cmd.js.map +1 -0
- package/dist/cli/program.d.ts +14 -0
- package/dist/cli/program.d.ts.map +1 -0
- package/dist/cli/program.js +44 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/query.d.ts +46 -0
- package/dist/cli/query.d.ts.map +1 -0
- package/dist/cli/query.js +153 -0
- package/dist/cli/query.js.map +1 -0
- package/dist/cli/search-cmd.d.ts +33 -0
- package/dist/cli/search-cmd.d.ts.map +1 -0
- package/dist/cli/search-cmd.js +114 -0
- package/dist/cli/search-cmd.js.map +1 -0
- package/dist/cli/serve.d.ts +3 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +19 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/skill-install.d.ts +39 -0
- package/dist/cli/skill-install.d.ts.map +1 -0
- package/dist/cli/skill-install.js +57 -0
- package/dist/cli/skill-install.js.map +1 -0
- package/dist/cli/status.d.ts +35 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +117 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/upgrade-cmd.d.ts +48 -0
- package/dist/cli/upgrade-cmd.d.ts.map +1 -0
- package/dist/cli/upgrade-cmd.js +129 -0
- package/dist/cli/upgrade-cmd.js.map +1 -0
- package/dist/cli/version.d.ts +3 -0
- package/dist/cli/version.d.ts.map +1 -0
- package/dist/cli/version.js +19 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/env.d.ts +17 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +17 -0
- package/dist/env.js.map +1 -0
- package/dist/graph/checker-resolver.d.ts +156 -0
- package/dist/graph/checker-resolver.d.ts.map +1 -0
- package/dist/graph/checker-resolver.js +458 -0
- package/dist/graph/checker-resolver.js.map +1 -0
- package/dist/graph/db.d.ts +318 -0
- package/dist/graph/db.d.ts.map +1 -0
- package/dist/graph/db.js +266 -0
- package/dist/graph/db.js.map +1 -0
- package/dist/graph/index.d.ts +4 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +5 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/local-type-env.d.ts +45 -0
- package/dist/graph/local-type-env.d.ts.map +1 -0
- package/dist/graph/local-type-env.js +59 -0
- package/dist/graph/local-type-env.js.map +1 -0
- package/dist/graph/path-range.d.ts +40 -0
- package/dist/graph/path-range.d.ts.map +1 -0
- package/dist/graph/path-range.js +42 -0
- package/dist/graph/path-range.js.map +1 -0
- package/dist/graph/populate.d.ts +263 -0
- package/dist/graph/populate.d.ts.map +1 -0
- package/dist/graph/populate.js +984 -0
- package/dist/graph/populate.js.map +1 -0
- package/dist/graph/queries.d.ts +114 -0
- package/dist/graph/queries.d.ts.map +1 -0
- package/dist/graph/queries.js +415 -0
- package/dist/graph/queries.js.map +1 -0
- package/dist/graph/sqliteBatch.d.ts +48 -0
- package/dist/graph/sqliteBatch.d.ts.map +1 -0
- package/dist/graph/sqliteBatch.js +93 -0
- package/dist/graph/sqliteBatch.js.map +1 -0
- package/dist/indexer/freshness.d.ts +48 -0
- package/dist/indexer/freshness.d.ts.map +1 -0
- package/dist/indexer/freshness.js +72 -0
- package/dist/indexer/freshness.js.map +1 -0
- package/dist/indexer/import-resolver.d.ts +50 -0
- package/dist/indexer/import-resolver.d.ts.map +1 -0
- package/dist/indexer/import-resolver.js +318 -0
- package/dist/indexer/import-resolver.js.map +1 -0
- package/dist/indexer/index.d.ts +249 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +560 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/walker.d.ts +60 -0
- package/dist/indexer/walker.d.ts.map +1 -0
- package/dist/indexer/walker.js +128 -0
- package/dist/indexer/walker.js.map +1 -0
- package/dist/indexer/watcher.d.ts +80 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +151 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/mcp/context.d.ts +23 -0
- package/dist/mcp/context.d.ts.map +1 -0
- package/dist/mcp/context.js +2 -0
- package/dist/mcp/context.js.map +1 -0
- package/dist/mcp/register-tools.d.ts +21 -0
- package/dist/mcp/register-tools.d.ts.map +1 -0
- package/dist/mcp/register-tools.js +42 -0
- package/dist/mcp/register-tools.js.map +1 -0
- package/dist/mcp/server.d.ts +58 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +177 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/staleness.d.ts +72 -0
- package/dist/mcp/staleness.d.ts.map +1 -0
- package/dist/mcp/staleness.js +213 -0
- package/dist/mcp/staleness.js.map +1 -0
- package/dist/mcp/startup.d.ts +40 -0
- package/dist/mcp/startup.d.ts.map +1 -0
- package/dist/mcp/startup.js +114 -0
- package/dist/mcp/startup.js.map +1 -0
- package/dist/mcp/tools/_helpers.d.ts +26 -0
- package/dist/mcp/tools/_helpers.d.ts.map +1 -0
- package/dist/mcp/tools/_helpers.js +54 -0
- package/dist/mcp/tools/_helpers.js.map +1 -0
- package/dist/mcp/tools/callers.d.ts +4 -0
- package/dist/mcp/tools/callers.d.ts.map +1 -0
- package/dist/mcp/tools/callers.js +112 -0
- package/dist/mcp/tools/callers.js.map +1 -0
- package/dist/mcp/tools/dependencies.d.ts +4 -0
- package/dist/mcp/tools/dependencies.d.ts.map +1 -0
- package/dist/mcp/tools/dependencies.js +36 -0
- package/dist/mcp/tools/dependencies.js.map +1 -0
- package/dist/mcp/tools/efficiency.d.ts +4 -0
- package/dist/mcp/tools/efficiency.d.ts.map +1 -0
- package/dist/mcp/tools/efficiency.js +39 -0
- package/dist/mcp/tools/efficiency.js.map +1 -0
- package/dist/mcp/tools/exports.d.ts +4 -0
- package/dist/mcp/tools/exports.d.ts.map +1 -0
- package/dist/mcp/tools/exports.js +56 -0
- package/dist/mcp/tools/exports.js.map +1 -0
- package/dist/mcp/tools/implementors.d.ts +4 -0
- package/dist/mcp/tools/implementors.d.ts.map +1 -0
- package/dist/mcp/tools/implementors.js +47 -0
- package/dist/mcp/tools/implementors.js.map +1 -0
- package/dist/mcp/tools/project-skeleton.d.ts +4 -0
- package/dist/mcp/tools/project-skeleton.d.ts.map +1 -0
- package/dist/mcp/tools/project-skeleton.js +61 -0
- package/dist/mcp/tools/project-skeleton.js.map +1 -0
- package/dist/mcp/tools/reindex.d.ts +14 -0
- package/dist/mcp/tools/reindex.d.ts.map +1 -0
- package/dist/mcp/tools/reindex.js +32 -0
- package/dist/mcp/tools/reindex.js.map +1 -0
- package/dist/mcp/tools/rename-impact.d.ts +4 -0
- package/dist/mcp/tools/rename-impact.d.ts.map +1 -0
- package/dist/mcp/tools/rename-impact.js +124 -0
- package/dist/mcp/tools/rename-impact.js.map +1 -0
- package/dist/mcp/tools/search.d.ts +4 -0
- package/dist/mcp/tools/search.d.ts.map +1 -0
- package/dist/mcp/tools/search.js +69 -0
- package/dist/mcp/tools/search.js.map +1 -0
- package/dist/mcp/tools/signature.d.ts +4 -0
- package/dist/mcp/tools/signature.d.ts.map +1 -0
- package/dist/mcp/tools/signature.js +127 -0
- package/dist/mcp/tools/signature.js.map +1 -0
- package/dist/mcp/tools/status.d.ts +4 -0
- package/dist/mcp/tools/status.d.ts.map +1 -0
- package/dist/mcp/tools/status.js +30 -0
- package/dist/mcp/tools/status.js.map +1 -0
- package/dist/search/declex.d.ts +109 -0
- package/dist/search/declex.d.ts.map +1 -0
- package/dist/search/declex.js +242 -0
- package/dist/search/declex.js.map +1 -0
- package/dist/search/fts.d.ts +77 -0
- package/dist/search/fts.d.ts.map +1 -0
- package/dist/search/fts.js +223 -0
- package/dist/search/fts.js.map +1 -0
- package/dist/search/fused.d.ts +110 -0
- package/dist/search/fused.d.ts.map +1 -0
- package/dist/search/fused.js +323 -0
- package/dist/search/fused.js.map +1 -0
- package/dist/search/potential-matches.d.ts +88 -0
- package/dist/search/potential-matches.d.ts.map +1 -0
- package/dist/search/potential-matches.js +83 -0
- package/dist/search/potential-matches.js.map +1 -0
- package/dist/search/scope.d.ts +66 -0
- package/dist/search/scope.d.ts.map +1 -0
- package/dist/search/scope.js +71 -0
- package/dist/search/scope.js.map +1 -0
- package/dist/store/config.d.ts +57 -0
- package/dist/store/config.d.ts.map +1 -0
- package/dist/store/config.js +208 -0
- package/dist/store/config.js.map +1 -0
- package/dist/store/lock.d.ts +101 -0
- package/dist/store/lock.d.ts.map +1 -0
- package/dist/store/lock.js +182 -0
- package/dist/store/lock.js.map +1 -0
- package/dist/store/lockMetrics.d.ts +52 -0
- package/dist/store/lockMetrics.d.ts.map +1 -0
- package/dist/store/lockMetrics.js +29 -0
- package/dist/store/lockMetrics.js.map +1 -0
- package/dist/store/sqliteChunkStore.d.ts +44 -0
- package/dist/store/sqliteChunkStore.d.ts.map +1 -0
- package/dist/store/sqliteChunkStore.js +135 -0
- package/dist/store/sqliteChunkStore.js.map +1 -0
- package/dist/telemetry/lockMetricsSummary.d.ts +42 -0
- package/dist/telemetry/lockMetricsSummary.d.ts.map +1 -0
- package/dist/telemetry/lockMetricsSummary.js +139 -0
- package/dist/telemetry/lockMetricsSummary.js.map +1 -0
- package/dist/telemetry/metrics.d.ts +140 -0
- package/dist/telemetry/metrics.d.ts.map +1 -0
- package/dist/telemetry/metrics.js +312 -0
- package/dist/telemetry/metrics.js.map +1 -0
- package/dist/telemetry/tokenizer.d.ts +125 -0
- package/dist/telemetry/tokenizer.d.ts.map +1 -0
- package/dist/telemetry/tokenizer.js +174 -0
- package/dist/telemetry/tokenizer.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import { Kysely, sql } from 'kysely';
|
|
2
|
+
import type { ColumnType, Generated } from 'kysely';
|
|
3
|
+
/**
|
|
4
|
+
* SQLite stores booleans as INTEGER (0 | 1).
|
|
5
|
+
* `BoolCol` makes this explicit at the type level so callers know to coerce.
|
|
6
|
+
*/
|
|
7
|
+
type BoolCol = ColumnType<number, 0 | 1, 0 | 1>;
|
|
8
|
+
/**
|
|
9
|
+
* One end of the rowid block a file's rows occupy in an FTS5 virtual table
|
|
10
|
+
* (see {@link FilesTable.chunk_fts_lo}). Nullable, and optional on insert, so
|
|
11
|
+
* that a row written before this column existed — or a file that produced no
|
|
12
|
+
* rows at all — reads back as SQL NULL rather than a misleading 0.
|
|
13
|
+
*/
|
|
14
|
+
type FtsRowidCol = ColumnType<number | null, number | null | undefined, number | null>;
|
|
15
|
+
interface FilesTable {
|
|
16
|
+
readonly id: Generated<number>;
|
|
17
|
+
readonly path: string;
|
|
18
|
+
readonly language: string;
|
|
19
|
+
readonly mtime: number;
|
|
20
|
+
/**
|
|
21
|
+
* Inclusive bounds of the contiguous `chunk_fts` rowid block this file owns,
|
|
22
|
+
* or NULL when the file has no rows there (no chunks, or a row written
|
|
23
|
+
* before Stage 4.6 added the column).
|
|
24
|
+
*
|
|
25
|
+
* This exists because FTS5 cannot answer `WHERE file_path = ?` with anything
|
|
26
|
+
* but a full table scan — `xBestIndex` refuses equality constraints on
|
|
27
|
+
* ordinary columns, so the delete on re-index cost O(corpus) per changed
|
|
28
|
+
* file (measured: 3.0 ms at T1 rising to 151.6 ms at T9, exponent 1.32).
|
|
29
|
+
* A rowid is the one column FTS5 *will* seek on, so recording the block
|
|
30
|
+
* turns that delete into O(rows-in-this-file). See `populate.ts`
|
|
31
|
+
* `deleteFtsRowidBlock` for why the deletes are issued one rowid at a time
|
|
32
|
+
* rather than as a single `BETWEEN` range.
|
|
33
|
+
*/
|
|
34
|
+
readonly chunk_fts_lo: FtsRowidCol;
|
|
35
|
+
/** Upper bound of the `chunk_fts` block — see {@link FilesTable.chunk_fts_lo}. */
|
|
36
|
+
readonly chunk_fts_hi: FtsRowidCol;
|
|
37
|
+
/**
|
|
38
|
+
* Bounds of the `identifier_fts` block. Tracked separately from the
|
|
39
|
+
* `chunk_fts` block because the two tables receive different row counts for
|
|
40
|
+
* the same file: markdown chunks produce no identifier rows at all
|
|
41
|
+
* (measured across the E1 ladder — FINDINGS.md §1.4).
|
|
42
|
+
*/
|
|
43
|
+
readonly ident_fts_lo: FtsRowidCol;
|
|
44
|
+
/** Upper bound of the `identifier_fts` block — see {@link FilesTable.ident_fts_lo}. */
|
|
45
|
+
readonly ident_fts_hi: FtsRowidCol;
|
|
46
|
+
}
|
|
47
|
+
interface SymbolsTable {
|
|
48
|
+
readonly id: Generated<number>;
|
|
49
|
+
readonly name: string;
|
|
50
|
+
/** `function | class | interface | type | const | method` */
|
|
51
|
+
readonly kind: string;
|
|
52
|
+
readonly file_id: number;
|
|
53
|
+
readonly line: number;
|
|
54
|
+
readonly is_exported: BoolCol;
|
|
55
|
+
/** sha256 of signature text only (excludes body). Null until first index. */
|
|
56
|
+
readonly declaration_hash: string | null;
|
|
57
|
+
/** sha256 of body text; for class_shell, over sorted member signatures. */
|
|
58
|
+
readonly body_hash: string | null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Edge types:
|
|
62
|
+
* - `POTENTIAL_CALL` — name-resolved call site
|
|
63
|
+
* - `IMPLEMENTS` — class implements interface
|
|
64
|
+
* - `EXTENDS` — class/interface extends another
|
|
65
|
+
* - `RE_EXPORTS` — symbol-to-symbol re-export
|
|
66
|
+
* - `PARENT_OF` — class → method (class body decomposition)
|
|
67
|
+
*/
|
|
68
|
+
interface EdgesTable {
|
|
69
|
+
readonly from_id: number;
|
|
70
|
+
readonly to_id: number;
|
|
71
|
+
readonly edge_type: string;
|
|
72
|
+
/** Resolution rule for POTENTIAL_CALL edges (§10.3.1); null for others. */
|
|
73
|
+
readonly resolution: string | null;
|
|
74
|
+
/** 1-indexed source line of the call site; null for non-call edges. */
|
|
75
|
+
readonly call_line: number | null;
|
|
76
|
+
/** Trimmed source text of the call-site line; null for non-call edges. */
|
|
77
|
+
readonly context: string | null;
|
|
78
|
+
}
|
|
79
|
+
/** File-level re-export: `export * from '...'` */
|
|
80
|
+
interface ReExportFilesTable {
|
|
81
|
+
readonly from_file_id: number;
|
|
82
|
+
readonly to_file_id: number;
|
|
83
|
+
}
|
|
84
|
+
interface ImportsTable {
|
|
85
|
+
readonly file_id: number;
|
|
86
|
+
readonly module: string;
|
|
87
|
+
/** JSON-serialised string[]. Stored as TEXT; parse on read. */
|
|
88
|
+
readonly symbols: string;
|
|
89
|
+
readonly is_external: BoolCol;
|
|
90
|
+
/** Null for external modules; resolved real path for monorepo imports. */
|
|
91
|
+
readonly resolved_path: string | null;
|
|
92
|
+
}
|
|
93
|
+
interface MetricsTable {
|
|
94
|
+
readonly id: Generated<number>;
|
|
95
|
+
readonly tool_name: string;
|
|
96
|
+
readonly call_timestamp: number;
|
|
97
|
+
readonly tokens_returned: number;
|
|
98
|
+
readonly tokens_full_file_upper_bound: number;
|
|
99
|
+
readonly duration_ms: number;
|
|
100
|
+
readonly mode: string | null;
|
|
101
|
+
readonly session_id: string;
|
|
102
|
+
readonly status: string;
|
|
103
|
+
/**
|
|
104
|
+
* JSON of the salient tool arguments (query + filters for search; symbol
|
|
105
|
+
* and/or file_path for signature/exports/callers/etc.), capped at 1,000
|
|
106
|
+
* chars — the linked-chain measurability the capsule instrumentation
|
|
107
|
+
* decision needs (IMPLEMENTATION_PLAN_VEXP.md §P, 2026-07-15). Null for
|
|
108
|
+
* tools that do not yet record argument identity and for pre-migration rows.
|
|
109
|
+
*/
|
|
110
|
+
readonly args_json: string | null;
|
|
111
|
+
/**
|
|
112
|
+
* JSON array of `{file_path, symbol_name}` identity pairs the tool
|
|
113
|
+
* returned, in rank order, capped at 20 entries. Null for tools that do
|
|
114
|
+
* not yet record result identity and for pre-migration rows.
|
|
115
|
+
*/
|
|
116
|
+
readonly results_json: string | null;
|
|
117
|
+
/**
|
|
118
|
+
* JSON of ranker D's (declaration-exact, `../search/declex.ts`) fire
|
|
119
|
+
* diagnostics and window effects on this `mast_search` call — the input
|
|
120
|
+
* signal for the F18 kill-switch and re-entry criteria (M2 decision memo
|
|
121
|
+
* condition 3). Null when D did not fire, or when the
|
|
122
|
+
* `declaration_exact_ranker` flag was off, and for pre-migration rows.
|
|
123
|
+
*/
|
|
124
|
+
readonly declex_json: string | null;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Checker-pass classifications (`mast index --checker`, Stage 1.2). Additive —
|
|
128
|
+
* a brand-new table needs no `CURRENT_SCHEMA_VERSION` bump, per the
|
|
129
|
+
* `openDatabase` additive-migration precedent (§7.4).
|
|
130
|
+
*
|
|
131
|
+
* A verdict is keyed to the exact potential-match candidate it was computed
|
|
132
|
+
* for: `queried_symbol_id` (the symbol collectPotentialMatchCandidates was
|
|
133
|
+
* searching for) + `call_site_file_id`/`call_site_line` (the SAME chunk
|
|
134
|
+
* identity `collectPotentialMatches` dedupes on, §9 mast_callers). This is
|
|
135
|
+
* what lets a future call filter the exact same candidate out without
|
|
136
|
+
* recomputing anything.
|
|
137
|
+
*
|
|
138
|
+
* Staleness: `call_site_file_id REFERENCES files(id) ON DELETE CASCADE` ties a
|
|
139
|
+
* verdict's lifetime to the file row it was computed against — `populateFile`
|
|
140
|
+
* deletes-and-replaces a file's `files` row on every content change (Phase 1
|
|
141
|
+
* and JIT re-parse both go through it), which cascades away every verdict for
|
|
142
|
+
* that file automatically, exactly like `symbols`/`edges`/`imports` already
|
|
143
|
+
* do. `call_site_mtime` is a second, explicit guard checked at read time
|
|
144
|
+
* (`queryCheckerVerdicts`) — defense in depth against any future write path
|
|
145
|
+
* that touches `files.mtime` without a full delete/cascade. A stale verdict
|
|
146
|
+
* silently suppressing a real new call site is this feature's severity-zero
|
|
147
|
+
* failure mode (IMPLEMENTATION_PLAN_VEXP.md Stage 1.2 brief); the CASCADE and
|
|
148
|
+
* the mtime check are two independent ways to close it.
|
|
149
|
+
*/
|
|
150
|
+
interface CheckerVerdictsTable {
|
|
151
|
+
readonly queried_symbol_id: number;
|
|
152
|
+
readonly call_site_file_id: number;
|
|
153
|
+
readonly call_site_line: number;
|
|
154
|
+
/** 'resolves_to_queried' | 'resolves_to_different' | 'non_call_site' — 'unresolved' is never persisted (leaves the candidate as a genuine potential match, no state to track). */
|
|
155
|
+
readonly verdict: string;
|
|
156
|
+
readonly call_site_mtime: number;
|
|
157
|
+
}
|
|
158
|
+
interface MetricsDailyTable {
|
|
159
|
+
readonly day: string;
|
|
160
|
+
readonly tool_name: string;
|
|
161
|
+
readonly calls: number;
|
|
162
|
+
readonly tokens_returned_total: number;
|
|
163
|
+
readonly tokens_full_file_total: number;
|
|
164
|
+
readonly avg_duration_ms: number;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Chunk bodies (M1, `eval/GITNEXUS_COMPARISON.md` §15.1). Lives in `graph.db`
|
|
168
|
+
* — NOT a separate `chunks.db` — so a chunk write joins the same per-file
|
|
169
|
+
* `db.transaction()` as `symbols`/`edges`/`imports`/`chunk_fts`
|
|
170
|
+
* (`graph/populate.ts`'s `populateFile`), closing the two-store consistency
|
|
171
|
+
* seam the spike deliberately left open (`store/sqliteChunkStore.ts`'s
|
|
172
|
+
* original SPIKE comment). Column set mirrors `LanceStore`'s chunk schema
|
|
173
|
+
* (`store/lance.ts:12-26`) so every consumer's `ChunkRecord` shape is
|
|
174
|
+
* unchanged by the store swap.
|
|
175
|
+
*/
|
|
176
|
+
interface ChunksTable {
|
|
177
|
+
readonly chunk_id: string;
|
|
178
|
+
readonly file_path: string;
|
|
179
|
+
readonly start_line: number;
|
|
180
|
+
readonly end_line: number;
|
|
181
|
+
readonly content: string;
|
|
182
|
+
readonly chunk_type: string;
|
|
183
|
+
readonly symbol_name: string | null;
|
|
184
|
+
readonly parent_symbol: string | null;
|
|
185
|
+
readonly is_exported: BoolCol;
|
|
186
|
+
readonly language: string;
|
|
187
|
+
readonly file_mtime: number;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* FTS5 virtual table for BM25 full-text search over chunk content.
|
|
191
|
+
*
|
|
192
|
+
* `content` is the full-text indexed column (trigram tokeniser).
|
|
193
|
+
* All other columns are UNINDEXED — stored but not full-text indexed.
|
|
194
|
+
* `file_path` enables filtered deletes and upserts without a LIKE prefix hack.
|
|
195
|
+
*/
|
|
196
|
+
interface ChunkFtsTable {
|
|
197
|
+
/**
|
|
198
|
+
* FTS5's implicit rowid, surfaced so `populate.ts` can assign it explicitly
|
|
199
|
+
* rather than let SQLite pick. Optional on insert — every writer other than
|
|
200
|
+
* the block allocator lets SQLite assign as before.
|
|
201
|
+
*/
|
|
202
|
+
readonly rowid: ColumnType<number, number | undefined, number>;
|
|
203
|
+
readonly content: string;
|
|
204
|
+
readonly symbol_name: string | null;
|
|
205
|
+
readonly chunk_id: string;
|
|
206
|
+
readonly file_path: string;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* FTS5 virtual table for exact-identifier lookup.
|
|
210
|
+
*
|
|
211
|
+
* `identifiers` is the full-text indexed column (unicode61 with identifier
|
|
212
|
+
* boundary separators). `chunk_id` and `file_path` are UNINDEXED.
|
|
213
|
+
*/
|
|
214
|
+
interface IdentifierFtsTable {
|
|
215
|
+
/** FTS5's implicit rowid — see {@link ChunkFtsTable.rowid}. */
|
|
216
|
+
readonly rowid: ColumnType<number, number | undefined, number>;
|
|
217
|
+
readonly identifiers: string;
|
|
218
|
+
readonly chunk_id: string;
|
|
219
|
+
readonly file_path: string;
|
|
220
|
+
}
|
|
221
|
+
/** Full Kysely database schema for MAST's SQLite store. */
|
|
222
|
+
export interface MastDatabase {
|
|
223
|
+
readonly files: FilesTable;
|
|
224
|
+
readonly symbols: SymbolsTable;
|
|
225
|
+
readonly edges: EdgesTable;
|
|
226
|
+
readonly re_export_files: ReExportFilesTable;
|
|
227
|
+
readonly imports: ImportsTable;
|
|
228
|
+
readonly metrics: MetricsTable;
|
|
229
|
+
readonly metrics_daily: MetricsDailyTable;
|
|
230
|
+
readonly checker_verdicts: CheckerVerdictsTable;
|
|
231
|
+
readonly chunks: ChunksTable;
|
|
232
|
+
readonly chunk_fts: ChunkFtsTable;
|
|
233
|
+
readonly identifier_fts: IdentifierFtsTable;
|
|
234
|
+
}
|
|
235
|
+
export type Db = Kysely<MastDatabase>;
|
|
236
|
+
/**
|
|
237
|
+
* Optional per-connection SQLite tuning for {@link openDatabase}.
|
|
238
|
+
*
|
|
239
|
+
* Exists for the E1-PHASE mechanism A/B: E1 measured a super-linear index cost
|
|
240
|
+
* (`b = 1.75`) and E1-PHASE localised the exponent to the write phase
|
|
241
|
+
* (`b_write = 1.97`, 94% of the clock at the top rung) without identifying the
|
|
242
|
+
* mechanism. A page-cache cliff is one of several indistinguishable candidates,
|
|
243
|
+
* and it cannot be probed at all while these pragmas are unreachable.
|
|
244
|
+
*
|
|
245
|
+
* **Both options are omitted by default and nothing in product code sets them.**
|
|
246
|
+
* That is deliberate and load-bearing: the A/B's control arm is defined as the
|
|
247
|
+
* un-pragma'd binary, so an absent option must leave SQLite's own defaults
|
|
248
|
+
* standing (pinned by a test in `graph/__tests__/storage.test.ts`). No pragma
|
|
249
|
+
* ships on the strength of the probe — a shipped default would have to be
|
|
250
|
+
* justified by re-running E1's full 9-rung ladder.
|
|
251
|
+
*
|
|
252
|
+
* Injected as a parameter rather than read from the environment or from
|
|
253
|
+
* `MastConfig`: an env read inside `openDatabase` would be a hidden global, and
|
|
254
|
+
* a config field would collide with the eval harness's Gate 1
|
|
255
|
+
* (`assertConfigPinned`, `eval/e1-common.mjs`), which fails any run whose
|
|
256
|
+
* resolved config deviates from defaults precisely so config cannot act as a
|
|
257
|
+
* free lever over a measurement.
|
|
258
|
+
*/
|
|
259
|
+
export interface OpenDatabaseOptions {
|
|
260
|
+
/**
|
|
261
|
+
* Page-cache budget in **KiB**, applied as `PRAGMA cache_size = -<kib>`.
|
|
262
|
+
*
|
|
263
|
+
* Denominated in KiB rather than raw pragma units because SQLite overloads
|
|
264
|
+
* the value's sign — positive means pages (whose size varies with
|
|
265
|
+
* `page_size`), negative means KiB. Callers should not have to carry that.
|
|
266
|
+
*/
|
|
267
|
+
readonly cacheSizeKib?: number;
|
|
268
|
+
/** Memory-map budget in **bytes**, applied as `PRAGMA mmap_size = <bytes>`. SQLite may clamp it to its compile-time maximum. */
|
|
269
|
+
readonly mmapSizeBytes?: number;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Open (or create) the MAST graph database.
|
|
273
|
+
*
|
|
274
|
+
* - WAL mode is set on the underlying better-sqlite3 connection before
|
|
275
|
+
* handing it to Kysely; WAL cannot be set via Kysely's query API.
|
|
276
|
+
* - The schema is initialised synchronously on open (DDL is idempotent).
|
|
277
|
+
* - Returns a typed `Kysely<MastDatabase>` instance. Callers must call
|
|
278
|
+
* `await db.destroy()` on shutdown.
|
|
279
|
+
*
|
|
280
|
+
* @param options optional per-connection tuning; see {@link OpenDatabaseOptions}.
|
|
281
|
+
* Omitting it leaves every tunable pragma at SQLite's own default.
|
|
282
|
+
*/
|
|
283
|
+
/**
|
|
284
|
+
* Read one value out of a `PRAGMA` result set, refusing to invent one.
|
|
285
|
+
*
|
|
286
|
+
* The E1-AB registration's Gate A treats these values as evidence of which
|
|
287
|
+
* experimental arm produced a timing — the lever-level analogue of Gate 0's
|
|
288
|
+
* `dist` content hash. The first version coalesced a missing row to `0`, which
|
|
289
|
+
* is the *expected* value of `mmap_size` on three of that experiment's four
|
|
290
|
+
* arms: a failed evidence read would have been indistinguishable from a
|
|
291
|
+
* passing one. A gate that cannot fail is not a gate.
|
|
292
|
+
*
|
|
293
|
+
* @param pragma the pragma name, which is also the result column's name
|
|
294
|
+
* @param rows the `PRAGMA` result rows, as returned by the query layer
|
|
295
|
+
* @throws Error naming the pragma, if there is no row or the value is not a
|
|
296
|
+
* number.
|
|
297
|
+
*/
|
|
298
|
+
export declare function readPragmaValue(pragma: string, rows: readonly Readonly<Record<string, unknown>>[]): number;
|
|
299
|
+
export declare function openDatabase(stateDir: string, options?: OpenDatabaseOptions): Db;
|
|
300
|
+
export declare const EdgeType: {
|
|
301
|
+
readonly POTENTIAL_CALL: "POTENTIAL_CALL";
|
|
302
|
+
readonly IMPLEMENTS: "IMPLEMENTS";
|
|
303
|
+
readonly EXTENDS: "EXTENDS";
|
|
304
|
+
readonly RE_EXPORTS: "RE_EXPORTS";
|
|
305
|
+
readonly PARENT_OF: "PARENT_OF";
|
|
306
|
+
};
|
|
307
|
+
export type EdgeType = (typeof EdgeType)[keyof typeof EdgeType];
|
|
308
|
+
export declare const SymbolKind: {
|
|
309
|
+
readonly FUNCTION: "function";
|
|
310
|
+
readonly CLASS: "class";
|
|
311
|
+
readonly INTERFACE: "interface";
|
|
312
|
+
readonly TYPE: "type";
|
|
313
|
+
readonly CONST: "const";
|
|
314
|
+
readonly METHOD: "method";
|
|
315
|
+
};
|
|
316
|
+
export type SymbolKind = (typeof SymbolKind)[keyof typeof SymbolKind];
|
|
317
|
+
export { sql };
|
|
318
|
+
//# sourceMappingURL=db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/graph/db.ts"],"names":[],"mappings":"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"}
|
package/dist/graph/db.js
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import Sqlite from 'better-sqlite3';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { Kysely, SqliteDialect, sql } from 'kysely';
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Schema initialisation SQL
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
/**
|
|
8
|
+
* Raw DDL for tables Kysely's schema builder cannot express:
|
|
9
|
+
* FTS5 virtual tables and composite primary keys without a surrogate PK.
|
|
10
|
+
*/
|
|
11
|
+
const SCHEMA_DDL = `
|
|
12
|
+
CREATE TABLE IF NOT EXISTS files (
|
|
13
|
+
id INTEGER PRIMARY KEY,
|
|
14
|
+
path TEXT NOT NULL UNIQUE,
|
|
15
|
+
language TEXT NOT NULL,
|
|
16
|
+
mtime REAL NOT NULL,
|
|
17
|
+
chunk_fts_lo INTEGER,
|
|
18
|
+
chunk_fts_hi INTEGER,
|
|
19
|
+
ident_fts_lo INTEGER,
|
|
20
|
+
ident_fts_hi INTEGER
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
CREATE TABLE IF NOT EXISTS symbols (
|
|
24
|
+
id INTEGER PRIMARY KEY,
|
|
25
|
+
name TEXT NOT NULL,
|
|
26
|
+
kind TEXT NOT NULL,
|
|
27
|
+
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
28
|
+
line INTEGER NOT NULL,
|
|
29
|
+
is_exported INTEGER NOT NULL DEFAULT 0,
|
|
30
|
+
declaration_hash TEXT,
|
|
31
|
+
body_hash TEXT
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
CREATE TABLE IF NOT EXISTS edges (
|
|
35
|
+
from_id INTEGER NOT NULL REFERENCES symbols(id) ON DELETE CASCADE,
|
|
36
|
+
to_id INTEGER NOT NULL REFERENCES symbols(id) ON DELETE CASCADE,
|
|
37
|
+
edge_type TEXT NOT NULL,
|
|
38
|
+
resolution TEXT,
|
|
39
|
+
call_line INTEGER,
|
|
40
|
+
context TEXT,
|
|
41
|
+
PRIMARY KEY (from_id, to_id, edge_type)
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
CREATE TABLE IF NOT EXISTS re_export_files (
|
|
45
|
+
from_file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
46
|
+
to_file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
47
|
+
PRIMARY KEY (from_file_id, to_file_id)
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
CREATE TABLE IF NOT EXISTS imports (
|
|
51
|
+
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
52
|
+
module TEXT NOT NULL,
|
|
53
|
+
symbols TEXT NOT NULL,
|
|
54
|
+
is_external INTEGER NOT NULL DEFAULT 0,
|
|
55
|
+
resolved_path TEXT
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
CREATE TABLE IF NOT EXISTS chunks (
|
|
59
|
+
chunk_id TEXT PRIMARY KEY,
|
|
60
|
+
file_path TEXT NOT NULL,
|
|
61
|
+
start_line INTEGER NOT NULL,
|
|
62
|
+
end_line INTEGER NOT NULL,
|
|
63
|
+
content TEXT NOT NULL,
|
|
64
|
+
chunk_type TEXT NOT NULL,
|
|
65
|
+
symbol_name TEXT,
|
|
66
|
+
parent_symbol TEXT,
|
|
67
|
+
is_exported INTEGER NOT NULL DEFAULT 0,
|
|
68
|
+
language TEXT NOT NULL,
|
|
69
|
+
file_mtime REAL NOT NULL
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
CREATE INDEX IF NOT EXISTS idx_chunks_file_path ON chunks(file_path);
|
|
73
|
+
|
|
74
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS chunk_fts USING fts5(
|
|
75
|
+
content,
|
|
76
|
+
symbol_name UNINDEXED,
|
|
77
|
+
chunk_id UNINDEXED,
|
|
78
|
+
file_path UNINDEXED,
|
|
79
|
+
tokenize = 'trigram'
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS identifier_fts USING fts5(
|
|
83
|
+
identifiers,
|
|
84
|
+
chunk_id UNINDEXED,
|
|
85
|
+
file_path UNINDEXED,
|
|
86
|
+
tokenize = "unicode61 separators '.-_/()[]{}<>:;,=+*&|!?'"
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
CREATE INDEX IF NOT EXISTS idx_symbols_lookup ON symbols(name, file_id, line, kind);
|
|
90
|
+
CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_id);
|
|
91
|
+
CREATE INDEX IF NOT EXISTS idx_edges_from ON edges(from_id);
|
|
92
|
+
CREATE INDEX IF NOT EXISTS idx_edges_to ON edges(to_id);
|
|
93
|
+
CREATE INDEX IF NOT EXISTS idx_imports_file ON imports(file_id);
|
|
94
|
+
CREATE INDEX IF NOT EXISTS idx_imports_resolved ON imports(resolved_path);
|
|
95
|
+
|
|
96
|
+
CREATE TABLE IF NOT EXISTS metrics (
|
|
97
|
+
id INTEGER PRIMARY KEY,
|
|
98
|
+
tool_name TEXT NOT NULL,
|
|
99
|
+
call_timestamp REAL NOT NULL,
|
|
100
|
+
tokens_returned INTEGER NOT NULL,
|
|
101
|
+
tokens_full_file_upper_bound INTEGER NOT NULL,
|
|
102
|
+
duration_ms INTEGER NOT NULL,
|
|
103
|
+
mode TEXT, -- pre-Stage-7 rows only; see MetricsTable.mode
|
|
104
|
+
session_id TEXT NOT NULL,
|
|
105
|
+
status TEXT NOT NULL,
|
|
106
|
+
args_json TEXT,
|
|
107
|
+
results_json TEXT,
|
|
108
|
+
declex_json TEXT
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
CREATE INDEX IF NOT EXISTS idx_metrics_timestamp ON metrics(call_timestamp);
|
|
112
|
+
CREATE INDEX IF NOT EXISTS idx_metrics_tool ON metrics(tool_name);
|
|
113
|
+
CREATE INDEX IF NOT EXISTS idx_metrics_session ON metrics(session_id);
|
|
114
|
+
|
|
115
|
+
CREATE TABLE IF NOT EXISTS metrics_daily (
|
|
116
|
+
day TEXT NOT NULL,
|
|
117
|
+
tool_name TEXT NOT NULL,
|
|
118
|
+
calls INTEGER NOT NULL,
|
|
119
|
+
tokens_returned_total INTEGER NOT NULL,
|
|
120
|
+
tokens_full_file_total INTEGER NOT NULL,
|
|
121
|
+
avg_duration_ms REAL NOT NULL,
|
|
122
|
+
PRIMARY KEY (day, tool_name)
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
CREATE TABLE IF NOT EXISTS checker_verdicts (
|
|
126
|
+
queried_symbol_id INTEGER NOT NULL REFERENCES symbols(id) ON DELETE CASCADE,
|
|
127
|
+
call_site_file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
128
|
+
call_site_line INTEGER NOT NULL,
|
|
129
|
+
verdict TEXT NOT NULL,
|
|
130
|
+
call_site_mtime REAL NOT NULL,
|
|
131
|
+
PRIMARY KEY (queried_symbol_id, call_site_file_id, call_site_line)
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
CREATE INDEX IF NOT EXISTS idx_checker_verdicts_file ON checker_verdicts(call_site_file_id);
|
|
135
|
+
`;
|
|
136
|
+
/**
|
|
137
|
+
* Open (or create) the MAST graph database.
|
|
138
|
+
*
|
|
139
|
+
* - WAL mode is set on the underlying better-sqlite3 connection before
|
|
140
|
+
* handing it to Kysely; WAL cannot be set via Kysely's query API.
|
|
141
|
+
* - The schema is initialised synchronously on open (DDL is idempotent).
|
|
142
|
+
* - Returns a typed `Kysely<MastDatabase>` instance. Callers must call
|
|
143
|
+
* `await db.destroy()` on shutdown.
|
|
144
|
+
*
|
|
145
|
+
* @param options optional per-connection tuning; see {@link OpenDatabaseOptions}.
|
|
146
|
+
* Omitting it leaves every tunable pragma at SQLite's own default.
|
|
147
|
+
*/
|
|
148
|
+
/**
|
|
149
|
+
* Read one value out of a `PRAGMA` result set, refusing to invent one.
|
|
150
|
+
*
|
|
151
|
+
* The E1-AB registration's Gate A treats these values as evidence of which
|
|
152
|
+
* experimental arm produced a timing — the lever-level analogue of Gate 0's
|
|
153
|
+
* `dist` content hash. The first version coalesced a missing row to `0`, which
|
|
154
|
+
* is the *expected* value of `mmap_size` on three of that experiment's four
|
|
155
|
+
* arms: a failed evidence read would have been indistinguishable from a
|
|
156
|
+
* passing one. A gate that cannot fail is not a gate.
|
|
157
|
+
*
|
|
158
|
+
* @param pragma the pragma name, which is also the result column's name
|
|
159
|
+
* @param rows the `PRAGMA` result rows, as returned by the query layer
|
|
160
|
+
* @throws Error naming the pragma, if there is no row or the value is not a
|
|
161
|
+
* number.
|
|
162
|
+
*/
|
|
163
|
+
export function readPragmaValue(pragma, rows) {
|
|
164
|
+
const value = rows[0]?.[pragma];
|
|
165
|
+
if (typeof value !== 'number') {
|
|
166
|
+
throw new Error(`PRAGMA ${pragma} read-back returned no usable value (got ${JSON.stringify(value)}). ` +
|
|
167
|
+
`This value is measurement evidence identifying which configuration produced a run, ` +
|
|
168
|
+
`and must never be defaulted.`);
|
|
169
|
+
}
|
|
170
|
+
return value;
|
|
171
|
+
}
|
|
172
|
+
export function openDatabase(stateDir, options = {}) {
|
|
173
|
+
const sqlite = new Sqlite(join(stateDir, 'graph.db'));
|
|
174
|
+
// WAL + FK must be set on the raw connection before Kysely wraps it.
|
|
175
|
+
sqlite.pragma('journal_mode = WAL');
|
|
176
|
+
sqlite.pragma('foreign_keys = ON');
|
|
177
|
+
// busy_timeout was never set (found during E7, eval/GITNEXUS_COMPARISON.md
|
|
178
|
+
// Stage 1 F11 notes): without it, a statement that hits SQLITE_BUSY (e.g. a
|
|
179
|
+
// WAL-mode writer colliding with a checkpoint, or — now that chunks live
|
|
180
|
+
// here too, §15.1 — a second process opening graph.db mid-write) fails
|
|
181
|
+
// IMMEDIATELY instead of waiting, silently making `structure.lock`
|
|
182
|
+
// responsible for contention SQLite itself is equipped to absorb. 5000ms
|
|
183
|
+
// matches the total retry budget of `runIndex`'s own lock options
|
|
184
|
+
// (maxRetries: 5 x retryIntervalMs: 1000 = 5000ms, index.ts's `lockOptions`)
|
|
185
|
+
// and is the conventional WAL default for moderate-concurrency apps (e.g.
|
|
186
|
+
// Prisma's and Rails' SQLite adapters both default busy_timeout to 5000ms).
|
|
187
|
+
// This does not replace `structure.lock` (F11 is a separate, not-yet-done
|
|
188
|
+
// redesign of that mechanism) — it only stops SQLite's own driver from
|
|
189
|
+
// being more impatient than the advisory lock wrapped around it.
|
|
190
|
+
sqlite.pragma('busy_timeout = 5000');
|
|
191
|
+
// Set BEFORE the schema DDL below, so the cache/mmap configuration is already
|
|
192
|
+
// in force for the DDL's own page reads — an arm that only took effect after
|
|
193
|
+
// open would measure a mixture of both arms.
|
|
194
|
+
if (options.cacheSizeKib !== undefined) {
|
|
195
|
+
sqlite.pragma(`cache_size = -${options.cacheSizeKib}`);
|
|
196
|
+
}
|
|
197
|
+
if (options.mmapSizeBytes !== undefined) {
|
|
198
|
+
sqlite.pragma(`mmap_size = ${options.mmapSizeBytes}`);
|
|
199
|
+
}
|
|
200
|
+
// Apply schema DDL synchronously — safe at startup, idempotent.
|
|
201
|
+
sqlite.exec(SCHEMA_DDL);
|
|
202
|
+
// Backward-compatible column additions for the edges table. `CREATE TABLE IF
|
|
203
|
+
// NOT EXISTS` will not add columns to a pre-existing table, so migrate them
|
|
204
|
+
// in explicitly. ADD COLUMN is cheap (no table rewrite) and idempotent here
|
|
205
|
+
// because it is guarded by the current column set.
|
|
206
|
+
const edgeColumns = new Set(sqlite.prepare('PRAGMA table_info(edges)').all().map((c) => c.name));
|
|
207
|
+
for (const [name, ddl] of [
|
|
208
|
+
['resolution', 'ALTER TABLE edges ADD COLUMN resolution TEXT'],
|
|
209
|
+
['call_line', 'ALTER TABLE edges ADD COLUMN call_line INTEGER'],
|
|
210
|
+
['context', 'ALTER TABLE edges ADD COLUMN context TEXT'],
|
|
211
|
+
]) {
|
|
212
|
+
if (!edgeColumns.has(name))
|
|
213
|
+
sqlite.exec(ddl);
|
|
214
|
+
}
|
|
215
|
+
// Same additive-migration precedent for the files table's FTS rowid blocks
|
|
216
|
+
// (Stage 4.6). Databases indexed before these columns existed keep working:
|
|
217
|
+
// the columns read back NULL, and `populate.ts` falls back to the old
|
|
218
|
+
// file_path scan for exactly those rows until the file is next re-indexed.
|
|
219
|
+
const fileColumns = new Set(sqlite.prepare('PRAGMA table_info(files)').all().map((c) => c.name));
|
|
220
|
+
for (const [name, ddl] of [
|
|
221
|
+
['chunk_fts_lo', 'ALTER TABLE files ADD COLUMN chunk_fts_lo INTEGER'],
|
|
222
|
+
['chunk_fts_hi', 'ALTER TABLE files ADD COLUMN chunk_fts_hi INTEGER'],
|
|
223
|
+
['ident_fts_lo', 'ALTER TABLE files ADD COLUMN ident_fts_lo INTEGER'],
|
|
224
|
+
['ident_fts_hi', 'ALTER TABLE files ADD COLUMN ident_fts_hi INTEGER'],
|
|
225
|
+
]) {
|
|
226
|
+
if (!fileColumns.has(name))
|
|
227
|
+
sqlite.exec(ddl);
|
|
228
|
+
}
|
|
229
|
+
// Same additive-migration precedent for the metrics table's argument/result
|
|
230
|
+
// identity columns (§14.3) — added after some databases already had a
|
|
231
|
+
// `metrics` table, so `CREATE TABLE IF NOT EXISTS` alone would not add them.
|
|
232
|
+
const metricsColumns = new Set(sqlite.prepare('PRAGMA table_info(metrics)').all().map((c) => c.name));
|
|
233
|
+
for (const [name, ddl] of [
|
|
234
|
+
['args_json', 'ALTER TABLE metrics ADD COLUMN args_json TEXT'],
|
|
235
|
+
['results_json', 'ALTER TABLE metrics ADD COLUMN results_json TEXT'],
|
|
236
|
+
// Stage 6.3 — D-fire telemetry (§ MetricsTable.declex_json above).
|
|
237
|
+
['declex_json', 'ALTER TABLE metrics ADD COLUMN declex_json TEXT'],
|
|
238
|
+
]) {
|
|
239
|
+
if (!metricsColumns.has(name))
|
|
240
|
+
sqlite.exec(ddl);
|
|
241
|
+
}
|
|
242
|
+
return new Kysely({
|
|
243
|
+
dialect: new SqliteDialect({ database: sqlite }),
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
// Domain constants
|
|
248
|
+
// ---------------------------------------------------------------------------
|
|
249
|
+
export const EdgeType = {
|
|
250
|
+
POTENTIAL_CALL: 'POTENTIAL_CALL',
|
|
251
|
+
IMPLEMENTS: 'IMPLEMENTS',
|
|
252
|
+
EXTENDS: 'EXTENDS',
|
|
253
|
+
RE_EXPORTS: 'RE_EXPORTS',
|
|
254
|
+
PARENT_OF: 'PARENT_OF',
|
|
255
|
+
};
|
|
256
|
+
export const SymbolKind = {
|
|
257
|
+
FUNCTION: 'function',
|
|
258
|
+
CLASS: 'class',
|
|
259
|
+
INTERFACE: 'interface',
|
|
260
|
+
TYPE: 'type',
|
|
261
|
+
CONST: 'const',
|
|
262
|
+
METHOD: 'method',
|
|
263
|
+
};
|
|
264
|
+
// Re-export `sql` so callers (e.g. search/fts.ts) can import it from one place.
|
|
265
|
+
export { sql };
|
|
266
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/graph/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAEA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Public graph/query surface — exported for programmatic consumers (e.g. foldv2's reconcile adapter)
|
|
2
|
+
// so they don't go through the MCP server or the CLI. The queries take an open `Db` (openDatabase).
|
|
3
|
+
export * from "./db.js";
|
|
4
|
+
export * from "./queries.js";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,oGAAoG;AACpG,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { CallerResolution } from '../ast/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Synchronous heuristic resolver for `POTENTIAL_CALL` edges (§10.3.1).
|
|
4
|
+
*
|
|
5
|
+
* Built up per function/method scope during the AST walk, then queried for
|
|
6
|
+
* each call site. It resolves a call's receiver to a callee *symbol name* using
|
|
7
|
+
* a small set of high-frequency, statically-decidable patterns. It does NOT
|
|
8
|
+
* touch the database — whether the resolved name corresponds to a real indexed
|
|
9
|
+
* symbol is decided later, in `insertEdges`' name→id resolution (an unknown
|
|
10
|
+
* name simply yields no edge).
|
|
11
|
+
*
|
|
12
|
+
* Intentionally conservative: false negatives (missed edges) are acceptable;
|
|
13
|
+
* false positives (wrong edges) are not, as they would poison the
|
|
14
|
+
* `verified_callers` contract in `mast_callers`.
|
|
15
|
+
*/
|
|
16
|
+
export declare class LocalTypeEnvironment {
|
|
17
|
+
/** Named imports and same-file top-level symbols, by bare name. */
|
|
18
|
+
private readonly bareCallables;
|
|
19
|
+
/** Receiver expression (`repo`, `this.repo`) → its resolved type name. */
|
|
20
|
+
private readonly receiverTypes;
|
|
21
|
+
/** `import { handleLogin } from './h'` → bare call `handleLogin()` resolves. */
|
|
22
|
+
recordImport(localName: string): void;
|
|
23
|
+
/** A top-level function/const in the same file → bare call resolves to it. */
|
|
24
|
+
recordSameFileSymbol(name: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* A typed receiver binding. `receiver` is the literal receiver expression as
|
|
27
|
+
* it appears before the method call — e.g. `repo` (local/param) or
|
|
28
|
+
* `this.repo` (class field / constructor parameter property).
|
|
29
|
+
*/
|
|
30
|
+
recordReceiverType(receiver: string, type: string, resolution: CallerResolution): void;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve a call to `{ callee, resolution }`, or null when the receiver
|
|
33
|
+
* cannot be statically linked.
|
|
34
|
+
*
|
|
35
|
+
* @param receiver - the receiver expression (`repo`, `this.repo`), or null
|
|
36
|
+
* for a bare call (`foo()`).
|
|
37
|
+
* @param method - the called identifier (the function name for a bare call,
|
|
38
|
+
* the member name for a receiver call).
|
|
39
|
+
*/
|
|
40
|
+
resolveCall(receiver: string | null, method: string): {
|
|
41
|
+
callee: string;
|
|
42
|
+
resolution: CallerResolution;
|
|
43
|
+
} | null;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=local-type-env.d.ts.map
|