@jafreck/lore 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/README.md +405 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +345 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/call-graph.d.ts +39 -0
- package/dist/indexer/call-graph.d.ts.map +1 -0
- package/dist/indexer/call-graph.js +193 -0
- package/dist/indexer/call-graph.js.map +1 -0
- package/dist/indexer/complexity.d.ts +9 -0
- package/dist/indexer/complexity.d.ts.map +1 -0
- package/dist/indexer/complexity.js +66 -0
- package/dist/indexer/complexity.js.map +1 -0
- package/dist/indexer/config-parser.d.ts +16 -0
- package/dist/indexer/config-parser.d.ts.map +1 -0
- package/dist/indexer/config-parser.js +261 -0
- package/dist/indexer/config-parser.js.map +1 -0
- package/dist/indexer/coverage.d.ts +13 -0
- package/dist/indexer/coverage.d.ts.map +1 -0
- package/dist/indexer/coverage.js +84 -0
- package/dist/indexer/coverage.js.map +1 -0
- package/dist/indexer/db.d.ts +38 -0
- package/dist/indexer/db.d.ts.map +1 -0
- package/dist/indexer/db.js +275 -0
- package/dist/indexer/db.js.map +1 -0
- package/dist/indexer/embedder.d.ts +70 -0
- package/dist/indexer/embedder.d.ts.map +1 -0
- package/dist/indexer/embedder.js +186 -0
- package/dist/indexer/embedder.js.map +1 -0
- package/dist/indexer/ensure-python-deps.d.ts +22 -0
- package/dist/indexer/ensure-python-deps.d.ts.map +1 -0
- package/dist/indexer/ensure-python-deps.js +47 -0
- package/dist/indexer/ensure-python-deps.js.map +1 -0
- package/dist/indexer/extractors/bash.d.ts +12 -0
- package/dist/indexer/extractors/bash.d.ts.map +1 -0
- package/dist/indexer/extractors/bash.js +57 -0
- package/dist/indexer/extractors/bash.js.map +1 -0
- package/dist/indexer/extractors/c.d.ts +12 -0
- package/dist/indexer/extractors/c.d.ts.map +1 -0
- package/dist/indexer/extractors/c.js +106 -0
- package/dist/indexer/extractors/c.js.map +1 -0
- package/dist/indexer/extractors/cpp.d.ts +12 -0
- package/dist/indexer/extractors/cpp.d.ts.map +1 -0
- package/dist/indexer/extractors/cpp.js +84 -0
- package/dist/indexer/extractors/cpp.js.map +1 -0
- package/dist/indexer/extractors/csharp.d.ts +12 -0
- package/dist/indexer/extractors/csharp.d.ts.map +1 -0
- package/dist/indexer/extractors/csharp.js +79 -0
- package/dist/indexer/extractors/csharp.js.map +1 -0
- package/dist/indexer/extractors/dart.d.ts +12 -0
- package/dist/indexer/extractors/dart.d.ts.map +1 -0
- package/dist/indexer/extractors/dart.js +80 -0
- package/dist/indexer/extractors/dart.js.map +1 -0
- package/dist/indexer/extractors/elixir.d.ts +12 -0
- package/dist/indexer/extractors/elixir.d.ts.map +1 -0
- package/dist/indexer/extractors/elixir.js +87 -0
- package/dist/indexer/extractors/elixir.js.map +1 -0
- package/dist/indexer/extractors/elm.d.ts +12 -0
- package/dist/indexer/extractors/elm.d.ts.map +1 -0
- package/dist/indexer/extractors/elm.js +87 -0
- package/dist/indexer/extractors/elm.js.map +1 -0
- package/dist/indexer/extractors/go.d.ts +12 -0
- package/dist/indexer/extractors/go.d.ts.map +1 -0
- package/dist/indexer/extractors/go.js +158 -0
- package/dist/indexer/extractors/go.js.map +1 -0
- package/dist/indexer/extractors/haskell.d.ts +12 -0
- package/dist/indexer/extractors/haskell.d.ts.map +1 -0
- package/dist/indexer/extractors/haskell.js +104 -0
- package/dist/indexer/extractors/haskell.js.map +1 -0
- package/dist/indexer/extractors/java.d.ts +12 -0
- package/dist/indexer/extractors/java.d.ts.map +1 -0
- package/dist/indexer/extractors/java.js +68 -0
- package/dist/indexer/extractors/java.js.map +1 -0
- package/dist/indexer/extractors/javascript.d.ts +13 -0
- package/dist/indexer/extractors/javascript.d.ts.map +1 -0
- package/dist/indexer/extractors/javascript.js +180 -0
- package/dist/indexer/extractors/javascript.js.map +1 -0
- package/dist/indexer/extractors/julia.d.ts +12 -0
- package/dist/indexer/extractors/julia.d.ts.map +1 -0
- package/dist/indexer/extractors/julia.js +94 -0
- package/dist/indexer/extractors/julia.js.map +1 -0
- package/dist/indexer/extractors/kotlin.d.ts +12 -0
- package/dist/indexer/extractors/kotlin.d.ts.map +1 -0
- package/dist/indexer/extractors/kotlin.js +71 -0
- package/dist/indexer/extractors/kotlin.js.map +1 -0
- package/dist/indexer/extractors/lua.d.ts +12 -0
- package/dist/indexer/extractors/lua.d.ts.map +1 -0
- package/dist/indexer/extractors/lua.js +68 -0
- package/dist/indexer/extractors/lua.js.map +1 -0
- package/dist/indexer/extractors/objc.d.ts +12 -0
- package/dist/indexer/extractors/objc.d.ts.map +1 -0
- package/dist/indexer/extractors/objc.js +129 -0
- package/dist/indexer/extractors/objc.js.map +1 -0
- package/dist/indexer/extractors/ocaml.d.ts +12 -0
- package/dist/indexer/extractors/ocaml.d.ts.map +1 -0
- package/dist/indexer/extractors/ocaml.js +92 -0
- package/dist/indexer/extractors/ocaml.js.map +1 -0
- package/dist/indexer/extractors/php.d.ts +12 -0
- package/dist/indexer/extractors/php.d.ts.map +1 -0
- package/dist/indexer/extractors/php.js +99 -0
- package/dist/indexer/extractors/php.js.map +1 -0
- package/dist/indexer/extractors/python.d.ts +12 -0
- package/dist/indexer/extractors/python.d.ts.map +1 -0
- package/dist/indexer/extractors/python.js +129 -0
- package/dist/indexer/extractors/python.js.map +1 -0
- package/dist/indexer/extractors/ruby.d.ts +12 -0
- package/dist/indexer/extractors/ruby.d.ts.map +1 -0
- package/dist/indexer/extractors/ruby.js +100 -0
- package/dist/indexer/extractors/ruby.js.map +1 -0
- package/dist/indexer/extractors/rust.d.ts +12 -0
- package/dist/indexer/extractors/rust.d.ts.map +1 -0
- package/dist/indexer/extractors/rust.js +82 -0
- package/dist/indexer/extractors/rust.js.map +1 -0
- package/dist/indexer/extractors/scala.d.ts +12 -0
- package/dist/indexer/extractors/scala.d.ts.map +1 -0
- package/dist/indexer/extractors/scala.js +91 -0
- package/dist/indexer/extractors/scala.js.map +1 -0
- package/dist/indexer/extractors/swift.d.ts +12 -0
- package/dist/indexer/extractors/swift.d.ts.map +1 -0
- package/dist/indexer/extractors/swift.js +90 -0
- package/dist/indexer/extractors/swift.js.map +1 -0
- package/dist/indexer/extractors/types.d.ts +118 -0
- package/dist/indexer/extractors/types.d.ts.map +1 -0
- package/dist/indexer/extractors/types.js +43 -0
- package/dist/indexer/extractors/types.js.map +1 -0
- package/dist/indexer/extractors/typescript.d.ts +14 -0
- package/dist/indexer/extractors/typescript.d.ts.map +1 -0
- package/dist/indexer/extractors/typescript.js +172 -0
- package/dist/indexer/extractors/typescript.js.map +1 -0
- package/dist/indexer/extractors/zig.d.ts +12 -0
- package/dist/indexer/extractors/zig.d.ts.map +1 -0
- package/dist/indexer/extractors/zig.js +95 -0
- package/dist/indexer/extractors/zig.js.map +1 -0
- package/dist/indexer/git-history.d.ts +23 -0
- package/dist/indexer/git-history.d.ts.map +1 -0
- package/dist/indexer/git-history.js +144 -0
- package/dist/indexer/git-history.js.map +1 -0
- package/dist/indexer/git-hooks.d.ts +19 -0
- package/dist/indexer/git-hooks.d.ts.map +1 -0
- package/dist/indexer/git-hooks.js +74 -0
- package/dist/indexer/git-hooks.js.map +1 -0
- package/dist/indexer/index.d.ts +83 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +431 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/parser.d.ts +30 -0
- package/dist/indexer/parser.d.ts.map +1 -0
- package/dist/indexer/parser.js +114 -0
- package/dist/indexer/parser.js.map +1 -0
- package/dist/indexer/poller.d.ts +50 -0
- package/dist/indexer/poller.d.ts.map +1 -0
- package/dist/indexer/poller.js +140 -0
- package/dist/indexer/poller.js.map +1 -0
- package/dist/indexer/resolver.d.ts +52 -0
- package/dist/indexer/resolver.d.ts.map +1 -0
- package/dist/indexer/resolver.js +271 -0
- package/dist/indexer/resolver.js.map +1 -0
- package/dist/indexer/test-mapper.d.ts +6 -0
- package/dist/indexer/test-mapper.d.ts.map +1 -0
- package/dist/indexer/test-mapper.js +48 -0
- package/dist/indexer/test-mapper.js.map +1 -0
- package/dist/indexer/walker.d.ts +51 -0
- package/dist/indexer/walker.d.ts.map +1 -0
- package/dist/indexer/walker.js +100 -0
- package/dist/indexer/walker.js.map +1 -0
- package/dist/indexer/watcher.d.ts +51 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +107 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/kb-server/db.d.ts +241 -0
- package/dist/kb-server/db.d.ts.map +1 -0
- package/dist/kb-server/db.js +659 -0
- package/dist/kb-server/db.js.map +1 -0
- package/dist/kb-server/server.d.ts +35 -0
- package/dist/kb-server/server.d.ts.map +1 -0
- package/dist/kb-server/server.js +240 -0
- package/dist/kb-server/server.js.map +1 -0
- package/dist/kb-server/tools/annotations.d.ts +40 -0
- package/dist/kb-server/tools/annotations.d.ts.map +1 -0
- package/dist/kb-server/tools/annotations.js +35 -0
- package/dist/kb-server/tools/annotations.js.map +1 -0
- package/dist/kb-server/tools/architecture.d.ts +60 -0
- package/dist/kb-server/tools/architecture.d.ts.map +1 -0
- package/dist/kb-server/tools/architecture.js +174 -0
- package/dist/kb-server/tools/architecture.js.map +1 -0
- package/dist/kb-server/tools/blame.d.ts +67 -0
- package/dist/kb-server/tools/blame.d.ts.map +1 -0
- package/dist/kb-server/tools/blame.js +162 -0
- package/dist/kb-server/tools/blame.js.map +1 -0
- package/dist/kb-server/tools/coverage.d.ts +67 -0
- package/dist/kb-server/tools/coverage.d.ts.map +1 -0
- package/dist/kb-server/tools/coverage.js +74 -0
- package/dist/kb-server/tools/coverage.js.map +1 -0
- package/dist/kb-server/tools/graph.d.ts +56 -0
- package/dist/kb-server/tools/graph.d.ts.map +1 -0
- package/dist/kb-server/tools/graph.js +188 -0
- package/dist/kb-server/tools/graph.js.map +1 -0
- package/dist/kb-server/tools/history.d.ts +47 -0
- package/dist/kb-server/tools/history.d.ts.map +1 -0
- package/dist/kb-server/tools/history.js +91 -0
- package/dist/kb-server/tools/history.js.map +1 -0
- package/dist/kb-server/tools/lookup.d.ts +36 -0
- package/dist/kb-server/tools/lookup.d.ts.map +1 -0
- package/dist/kb-server/tools/lookup.js +45 -0
- package/dist/kb-server/tools/lookup.js.map +1 -0
- package/dist/kb-server/tools/metrics.d.ts +73 -0
- package/dist/kb-server/tools/metrics.d.ts.map +1 -0
- package/dist/kb-server/tools/metrics.js +79 -0
- package/dist/kb-server/tools/metrics.js.map +1 -0
- package/dist/kb-server/tools/notes.d.ts +165 -0
- package/dist/kb-server/tools/notes.d.ts.map +1 -0
- package/dist/kb-server/tools/notes.js +175 -0
- package/dist/kb-server/tools/notes.js.map +1 -0
- package/dist/kb-server/tools/routes.d.ts +38 -0
- package/dist/kb-server/tools/routes.d.ts.map +1 -0
- package/dist/kb-server/tools/routes.js +38 -0
- package/dist/kb-server/tools/routes.js.map +1 -0
- package/dist/kb-server/tools/search.d.ts +60 -0
- package/dist/kb-server/tools/search.d.ts.map +1 -0
- package/dist/kb-server/tools/search.js +170 -0
- package/dist/kb-server/tools/search.js.map +1 -0
- package/dist/kb-server/tools/snippet.d.ts +44 -0
- package/dist/kb-server/tools/snippet.d.ts.map +1 -0
- package/dist/kb-server/tools/snippet.js +49 -0
- package/dist/kb-server/tools/snippet.js.map +1 -0
- package/dist/kb-server/tools/test-map.d.ts +38 -0
- package/dist/kb-server/tools/test-map.d.ts.map +1 -0
- package/dist/kb-server/tools/test-map.js +32 -0
- package/dist/kb-server/tools/test-map.js.map +1 -0
- package/dist/kb-server/tools/writeback.d.ts +49 -0
- package/dist/kb-server/tools/writeback.d.ts.map +1 -0
- package/dist/kb-server/tools/writeback.js +68 -0
- package/dist/kb-server/tools/writeback.js.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module kb-server/db
|
|
3
|
+
*
|
|
4
|
+
* Read-only SQLite connection wrapper for the KB MCP server.
|
|
5
|
+
* All MCP tool files use `openReadOnly()` to open the knowledge-base database.
|
|
6
|
+
*/
|
|
7
|
+
import Database from 'better-sqlite3';
|
|
8
|
+
import { createRequire } from 'node:module';
|
|
9
|
+
const esmRequire = createRequire(import.meta.url);
|
|
10
|
+
// ─── Connection helpers ───────────────────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Opens the knowledge-base database at `path` in read-only mode.
|
|
13
|
+
* Foreign-key enforcement is enabled for consistency.
|
|
14
|
+
*/
|
|
15
|
+
export function openReadOnly(path) {
|
|
16
|
+
const db = new Database(path, { readonly: true });
|
|
17
|
+
db.pragma('foreign_keys = ON');
|
|
18
|
+
// Load sqlite-vec extension so vec0 virtual tables (symbol_embeddings) can
|
|
19
|
+
// be queried for semantic / fused search.
|
|
20
|
+
try {
|
|
21
|
+
const sqliteVec = esmRequire('sqlite-vec');
|
|
22
|
+
sqliteVec.load(db);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// sqlite-vec not available — vec0 tables won't be queryable.
|
|
26
|
+
}
|
|
27
|
+
return db;
|
|
28
|
+
}
|
|
29
|
+
function hasSymbolMetricsTable(db) {
|
|
30
|
+
const row = db
|
|
31
|
+
.prepare("SELECT 1 AS ok FROM sqlite_master WHERE type = 'table' AND name = 'symbol_metrics' LIMIT 1")
|
|
32
|
+
.get();
|
|
33
|
+
return row?.ok === 1;
|
|
34
|
+
}
|
|
35
|
+
/** Fetch a single symbol by primary key. Returns `undefined` if not found. */
|
|
36
|
+
export function getSymbolById(db, id) {
|
|
37
|
+
if (hasSymbolMetricsTable(db)) {
|
|
38
|
+
return db
|
|
39
|
+
.prepare('SELECT s.*, sm.line_count, sm.param_count, sm.cyclomatic, sm.max_nesting FROM symbols s LEFT JOIN symbol_metrics sm ON sm.symbol_id = s.id WHERE s.id = ?')
|
|
40
|
+
.get(id);
|
|
41
|
+
}
|
|
42
|
+
return db.prepare('SELECT * FROM symbols WHERE id = ?').get(id);
|
|
43
|
+
}
|
|
44
|
+
/** Fetch all symbols whose name matches the given string (case-insensitive). */
|
|
45
|
+
export function getSymbolsByName(db, name, branch) {
|
|
46
|
+
const includeMetrics = hasSymbolMetricsTable(db);
|
|
47
|
+
if (branch !== undefined) {
|
|
48
|
+
return db
|
|
49
|
+
.prepare(includeMetrics
|
|
50
|
+
? 'SELECT s.*, sm.line_count, sm.param_count, sm.cyclomatic, sm.max_nesting FROM symbols s JOIN files f ON s.file_id = f.id LEFT JOIN symbol_metrics sm ON sm.symbol_id = s.id WHERE s.name = ? COLLATE NOCASE AND f.branch = ?'
|
|
51
|
+
: 'SELECT s.* FROM symbols s JOIN files f ON s.file_id = f.id WHERE s.name = ? COLLATE NOCASE AND f.branch = ?')
|
|
52
|
+
.all(name, branch);
|
|
53
|
+
}
|
|
54
|
+
return db
|
|
55
|
+
.prepare(includeMetrics
|
|
56
|
+
? 'SELECT s.*, sm.line_count, sm.param_count, sm.cyclomatic, sm.max_nesting FROM symbols s LEFT JOIN symbol_metrics sm ON sm.symbol_id = s.id WHERE s.name = ? COLLATE NOCASE'
|
|
57
|
+
: 'SELECT * FROM symbols WHERE name = ? COLLATE NOCASE')
|
|
58
|
+
.all(name);
|
|
59
|
+
}
|
|
60
|
+
/** Return all symbols, optionally limited to `limit` rows. */
|
|
61
|
+
export function listSymbols(db, limit = 100, branch) {
|
|
62
|
+
const includeMetrics = hasSymbolMetricsTable(db);
|
|
63
|
+
if (branch !== undefined) {
|
|
64
|
+
return db
|
|
65
|
+
.prepare(includeMetrics
|
|
66
|
+
? 'SELECT s.*, sm.line_count, sm.param_count, sm.cyclomatic, sm.max_nesting FROM symbols s JOIN files f ON s.file_id = f.id LEFT JOIN symbol_metrics sm ON sm.symbol_id = s.id WHERE f.branch = ? LIMIT ?'
|
|
67
|
+
: 'SELECT s.* FROM symbols s JOIN files f ON s.file_id = f.id WHERE f.branch = ? LIMIT ?')
|
|
68
|
+
.all(branch, limit);
|
|
69
|
+
}
|
|
70
|
+
return db
|
|
71
|
+
.prepare(includeMetrics
|
|
72
|
+
? 'SELECT s.*, sm.line_count, sm.param_count, sm.cyclomatic, sm.max_nesting FROM symbols s LEFT JOIN symbol_metrics sm ON sm.symbol_id = s.id LIMIT ?'
|
|
73
|
+
: 'SELECT * FROM symbols LIMIT ?')
|
|
74
|
+
.all(limit);
|
|
75
|
+
}
|
|
76
|
+
/** Fetch a single file row by primary key. */
|
|
77
|
+
export function getFileById(db, id, branch) {
|
|
78
|
+
if (branch !== undefined) {
|
|
79
|
+
return db.prepare('SELECT * FROM files WHERE id = ? AND branch = ?').get(id, branch);
|
|
80
|
+
}
|
|
81
|
+
return db.prepare('SELECT * FROM files WHERE id = ?').get(id);
|
|
82
|
+
}
|
|
83
|
+
/** Fetch a single file row by its path. */
|
|
84
|
+
export function getFileByPath(db, path, branch) {
|
|
85
|
+
if (branch !== undefined) {
|
|
86
|
+
return db.prepare('SELECT * FROM files WHERE path = ? AND branch = ?').get(path, branch);
|
|
87
|
+
}
|
|
88
|
+
return db.prepare('SELECT * FROM files WHERE path = ?').get(path);
|
|
89
|
+
}
|
|
90
|
+
/** Return all indexed files, optionally limited to `limit` rows. */
|
|
91
|
+
export function listFiles(db, limit = 100, branch) {
|
|
92
|
+
if (branch !== undefined) {
|
|
93
|
+
return db.prepare('SELECT * FROM files WHERE branch = ? LIMIT ?').all(branch, limit);
|
|
94
|
+
}
|
|
95
|
+
return db.prepare('SELECT * FROM files LIMIT ?').all(limit);
|
|
96
|
+
}
|
|
97
|
+
/** Return mapped tests (path + confidence) for a source file path. */
|
|
98
|
+
export function listTestMappingsBySourcePath(db, sourcePath, branch) {
|
|
99
|
+
if (branch !== undefined) {
|
|
100
|
+
return db
|
|
101
|
+
.prepare(`SELECT tf.path AS test_path,
|
|
102
|
+
tm.confidence
|
|
103
|
+
FROM files sf
|
|
104
|
+
JOIN test_mappings tm ON tm.source_file_id = sf.id
|
|
105
|
+
JOIN files tf ON tf.id = tm.test_file_id
|
|
106
|
+
WHERE sf.path = ?
|
|
107
|
+
AND sf.branch = ?
|
|
108
|
+
AND tf.branch = ?
|
|
109
|
+
ORDER BY tf.path ASC`)
|
|
110
|
+
.all(sourcePath, branch, branch);
|
|
111
|
+
}
|
|
112
|
+
return db
|
|
113
|
+
.prepare(`SELECT tf.path AS test_path,
|
|
114
|
+
tm.confidence
|
|
115
|
+
FROM files sf
|
|
116
|
+
JOIN test_mappings tm ON tm.source_file_id = sf.id
|
|
117
|
+
JOIN files tf ON tf.id = tm.test_file_id
|
|
118
|
+
WHERE sf.path = ?
|
|
119
|
+
ORDER BY tf.path ASC`)
|
|
120
|
+
.all(sourcePath);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Return config entries joined with their config-file metadata and usage references.
|
|
124
|
+
* Results are ordered deterministically by key and file path.
|
|
125
|
+
*/
|
|
126
|
+
export function listConfigEntries(db, args = {}) {
|
|
127
|
+
const where = [];
|
|
128
|
+
const params = [];
|
|
129
|
+
if (args.key !== undefined) {
|
|
130
|
+
where.push('ce.key = ?');
|
|
131
|
+
params.push(args.key);
|
|
132
|
+
}
|
|
133
|
+
if (args.filePath !== undefined) {
|
|
134
|
+
where.push('f.path = ?');
|
|
135
|
+
params.push(args.filePath);
|
|
136
|
+
}
|
|
137
|
+
if (args.kind !== undefined) {
|
|
138
|
+
where.push('ce.kind = ?');
|
|
139
|
+
params.push(args.kind);
|
|
140
|
+
}
|
|
141
|
+
const whereSql = where.length > 0 ? `WHERE ${where.join(' AND ')}` : '';
|
|
142
|
+
try {
|
|
143
|
+
const entries = db
|
|
144
|
+
.prepare(`SELECT
|
|
145
|
+
ce.id,
|
|
146
|
+
ce.file_id,
|
|
147
|
+
ce.key,
|
|
148
|
+
ce.value,
|
|
149
|
+
ce.default_value,
|
|
150
|
+
ce.inferred_type,
|
|
151
|
+
ce.required,
|
|
152
|
+
ce.description,
|
|
153
|
+
ce.kind,
|
|
154
|
+
f.path AS file_path,
|
|
155
|
+
f.branch AS file_branch
|
|
156
|
+
FROM config_entries ce
|
|
157
|
+
JOIN files f ON f.id = ce.file_id
|
|
158
|
+
${whereSql}
|
|
159
|
+
ORDER BY ce.key COLLATE NOCASE ASC, f.path ASC, ce.id ASC`)
|
|
160
|
+
.all(...params);
|
|
161
|
+
if (entries.length === 0)
|
|
162
|
+
return [];
|
|
163
|
+
const placeholders = entries.map(() => '?').join(', ');
|
|
164
|
+
const refs = db
|
|
165
|
+
.prepare(`SELECT
|
|
166
|
+
cer.config_entry_id,
|
|
167
|
+
cer.line,
|
|
168
|
+
f.path,
|
|
169
|
+
f.branch
|
|
170
|
+
FROM config_entry_refs cer
|
|
171
|
+
JOIN files f ON f.id = cer.file_id
|
|
172
|
+
WHERE cer.config_entry_id IN (${placeholders})
|
|
173
|
+
ORDER BY cer.config_entry_id ASC, f.path ASC, cer.line ASC`)
|
|
174
|
+
.all(...entries.map((entry) => entry.id));
|
|
175
|
+
const refsByEntryId = new Map();
|
|
176
|
+
for (const ref of refs) {
|
|
177
|
+
const current = refsByEntryId.get(ref.config_entry_id) ?? [];
|
|
178
|
+
current.push({ path: ref.path, branch: ref.branch, line: ref.line });
|
|
179
|
+
refsByEntryId.set(ref.config_entry_id, current);
|
|
180
|
+
}
|
|
181
|
+
return entries.map((entry) => ({
|
|
182
|
+
...entry,
|
|
183
|
+
references: refsByEntryId.get(entry.id) ?? [],
|
|
184
|
+
}));
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** Return annotations filtered by kind, with optional path filter and row limit. */
|
|
191
|
+
export function listAnnotations(db, kind, path, limit = 20) {
|
|
192
|
+
if (path !== undefined) {
|
|
193
|
+
return db
|
|
194
|
+
.prepare(`SELECT f.path AS file_path,
|
|
195
|
+
a.line,
|
|
196
|
+
a.kind,
|
|
197
|
+
a.text,
|
|
198
|
+
s.name AS symbol_name,
|
|
199
|
+
s.kind AS symbol_kind
|
|
200
|
+
FROM annotations a
|
|
201
|
+
JOIN files f ON f.id = a.file_id
|
|
202
|
+
LEFT JOIN symbols s ON s.id = a.symbol_id
|
|
203
|
+
WHERE a.kind = ? AND f.path = ?
|
|
204
|
+
ORDER BY a.line ASC, a.id ASC
|
|
205
|
+
LIMIT ?`)
|
|
206
|
+
.all(kind, path, limit);
|
|
207
|
+
}
|
|
208
|
+
return db
|
|
209
|
+
.prepare(`SELECT f.path AS file_path,
|
|
210
|
+
a.line,
|
|
211
|
+
a.kind,
|
|
212
|
+
a.text,
|
|
213
|
+
s.name AS symbol_name,
|
|
214
|
+
s.kind AS symbol_kind
|
|
215
|
+
FROM annotations a
|
|
216
|
+
JOIN files f ON f.id = a.file_id
|
|
217
|
+
LEFT JOIN symbols s ON s.id = a.symbol_id
|
|
218
|
+
WHERE a.kind = ?
|
|
219
|
+
ORDER BY f.path ASC, a.line ASC, a.id ASC
|
|
220
|
+
LIMIT ?`)
|
|
221
|
+
.all(kind, limit);
|
|
222
|
+
}
|
|
223
|
+
export function listApiRoutes(db, args = {}) {
|
|
224
|
+
const clauses = [];
|
|
225
|
+
const params = [];
|
|
226
|
+
if (args.method !== undefined) {
|
|
227
|
+
clauses.push('ar.method = ? COLLATE NOCASE');
|
|
228
|
+
params.push(args.method);
|
|
229
|
+
}
|
|
230
|
+
if (args.pathPrefix !== undefined) {
|
|
231
|
+
clauses.push('ar.path LIKE ?');
|
|
232
|
+
params.push(`${args.pathPrefix}%`);
|
|
233
|
+
}
|
|
234
|
+
if (args.framework !== undefined) {
|
|
235
|
+
clauses.push('ar.framework = ? COLLATE NOCASE');
|
|
236
|
+
params.push(args.framework);
|
|
237
|
+
}
|
|
238
|
+
const where = clauses.length ? `WHERE ${clauses.join(' AND ')}` : '';
|
|
239
|
+
return db
|
|
240
|
+
.prepare(`SELECT ar.method,
|
|
241
|
+
ar.path,
|
|
242
|
+
ar.handler_name AS handler,
|
|
243
|
+
f.path AS file,
|
|
244
|
+
ar.line,
|
|
245
|
+
ar.framework
|
|
246
|
+
FROM api_routes ar
|
|
247
|
+
JOIN files f ON f.id = ar.file_id
|
|
248
|
+
${where}
|
|
249
|
+
ORDER BY ar.method, ar.path, f.path`)
|
|
250
|
+
.all(...params);
|
|
251
|
+
}
|
|
252
|
+
const DEFAULT_STATS_LIMIT = 20;
|
|
253
|
+
const MAX_STATS_LIMIT = 200;
|
|
254
|
+
function clampStatsLimit(limit) {
|
|
255
|
+
if (limit == null)
|
|
256
|
+
return DEFAULT_STATS_LIMIT;
|
|
257
|
+
return Math.min(Math.max(1, Math.floor(limit)), MAX_STATS_LIMIT);
|
|
258
|
+
}
|
|
259
|
+
function isoDateToUnixSeconds(value, endOfDay) {
|
|
260
|
+
if (!value)
|
|
261
|
+
return undefined;
|
|
262
|
+
const hasTime = value.includes('T');
|
|
263
|
+
const normalized = hasTime ? value : `${value}${endOfDay ? 'T23:59:59.999Z' : 'T00:00:00.000Z'}`;
|
|
264
|
+
const millis = Date.parse(normalized);
|
|
265
|
+
if (Number.isNaN(millis))
|
|
266
|
+
return undefined;
|
|
267
|
+
return Math.floor(millis / 1000);
|
|
268
|
+
}
|
|
269
|
+
function buildCommitStatsWhere(filters) {
|
|
270
|
+
const params = [];
|
|
271
|
+
const conditions = [];
|
|
272
|
+
const sinceTs = isoDateToUnixSeconds(filters.since, false);
|
|
273
|
+
if (sinceTs != null) {
|
|
274
|
+
conditions.push('c.timestamp >= ?');
|
|
275
|
+
params.push(sinceTs);
|
|
276
|
+
}
|
|
277
|
+
const untilTs = isoDateToUnixSeconds(filters.until, true);
|
|
278
|
+
if (untilTs != null) {
|
|
279
|
+
conditions.push('c.timestamp <= ?');
|
|
280
|
+
params.push(untilTs);
|
|
281
|
+
}
|
|
282
|
+
if (filters.author?.trim()) {
|
|
283
|
+
const pattern = `%${filters.author.trim()}%`;
|
|
284
|
+
conditions.push('(c.author LIKE ? OR c.author_email LIKE ?)');
|
|
285
|
+
params.push(pattern, pattern);
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
where: conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '',
|
|
289
|
+
params,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
function expandRenamePathVariants(path) {
|
|
293
|
+
if (!path.includes('=>')) {
|
|
294
|
+
return [path];
|
|
295
|
+
}
|
|
296
|
+
const braceMatch = path.match(/^(.*)\{([^{}]+)\s=>\s([^{}]+)\}(.*)$/);
|
|
297
|
+
if (braceMatch) {
|
|
298
|
+
const [, prefix, oldSegment, newSegment, suffix] = braceMatch;
|
|
299
|
+
return [`${prefix}${oldSegment}${suffix}`, `${prefix}${newSegment}${suffix}`];
|
|
300
|
+
}
|
|
301
|
+
const split = path.split(/\s=>\s/, 2);
|
|
302
|
+
if (split.length === 2 && split[0] && split[1]) {
|
|
303
|
+
return [split[0].trim(), split[1].trim()];
|
|
304
|
+
}
|
|
305
|
+
return [path];
|
|
306
|
+
}
|
|
307
|
+
/** Fetch a single commit by its SHA (full or prefix match). */
|
|
308
|
+
export function getCommitBySha(db, sha) {
|
|
309
|
+
return db
|
|
310
|
+
.prepare('SELECT * FROM commits WHERE sha = ? OR sha LIKE ? LIMIT 1')
|
|
311
|
+
.get(sha, `${sha}%`);
|
|
312
|
+
}
|
|
313
|
+
/** Return the most recent commits ordered by timestamp DESC, limited to `limit` rows. */
|
|
314
|
+
export function listRecentCommits(db, limit = 50) {
|
|
315
|
+
return db
|
|
316
|
+
.prepare('SELECT * FROM commits ORDER BY timestamp DESC, sha ASC LIMIT ?')
|
|
317
|
+
.all(limit);
|
|
318
|
+
}
|
|
319
|
+
/** Return commits that touched the given file path, ordered by timestamp DESC. */
|
|
320
|
+
export function listCommitsByFile(db, filePath, limit = 50) {
|
|
321
|
+
const touchedRows = db
|
|
322
|
+
.prepare(`SELECT DISTINCT commit_sha, file_path
|
|
323
|
+
FROM commit_files
|
|
324
|
+
WHERE file_path = ? OR file_path LIKE '%=>%'`)
|
|
325
|
+
.all(filePath);
|
|
326
|
+
const matchingShas = Array.from(new Set(touchedRows
|
|
327
|
+
.filter((row) => expandRenamePathVariants(row.file_path).includes(filePath))
|
|
328
|
+
.map((row) => row.commit_sha)));
|
|
329
|
+
if (matchingShas.length === 0) {
|
|
330
|
+
return [];
|
|
331
|
+
}
|
|
332
|
+
const placeholders = matchingShas.map(() => '?').join(', ');
|
|
333
|
+
return db
|
|
334
|
+
.prepare(`SELECT c.* FROM commits c
|
|
335
|
+
WHERE c.sha IN (${placeholders})
|
|
336
|
+
ORDER BY c.timestamp DESC, c.sha ASC
|
|
337
|
+
LIMIT ?`)
|
|
338
|
+
.all(...matchingShas, limit);
|
|
339
|
+
}
|
|
340
|
+
/** Return commits filtered by author name or email, ordered by timestamp DESC. */
|
|
341
|
+
export function listCommitsByAuthor(db, author, limit = 50) {
|
|
342
|
+
const pattern = `%${author}%`;
|
|
343
|
+
return db
|
|
344
|
+
.prepare(`SELECT * FROM commits
|
|
345
|
+
WHERE author LIKE ? OR author_email LIKE ?
|
|
346
|
+
ORDER BY timestamp DESC, sha ASC
|
|
347
|
+
LIMIT ?`)
|
|
348
|
+
.all(pattern, pattern, limit);
|
|
349
|
+
}
|
|
350
|
+
/** Return all files touched by a given commit SHA. */
|
|
351
|
+
export function listCommitFiles(db, commitSha) {
|
|
352
|
+
return db
|
|
353
|
+
.prepare('SELECT * FROM commit_files WHERE commit_sha = ?')
|
|
354
|
+
.all(commitSha);
|
|
355
|
+
}
|
|
356
|
+
/** Return refs (branches/tags) that currently point to the given commit SHA. */
|
|
357
|
+
export function listCommitRefs(db, commitSha) {
|
|
358
|
+
try {
|
|
359
|
+
return db
|
|
360
|
+
.prepare('SELECT * FROM commit_refs WHERE commit_sha = ? ORDER BY ref_type ASC, ref_name ASC')
|
|
361
|
+
.all(commitSha);
|
|
362
|
+
}
|
|
363
|
+
catch {
|
|
364
|
+
return [];
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/** Return commits associated with a branch/tag ref name or prefix. */
|
|
368
|
+
export function listCommitsByRef(db, refQuery, limit = 50) {
|
|
369
|
+
const exact = refQuery;
|
|
370
|
+
const wildcard = `%${refQuery}%`;
|
|
371
|
+
try {
|
|
372
|
+
if (!refQuery) {
|
|
373
|
+
return db
|
|
374
|
+
.prepare(`SELECT DISTINCT c.* FROM commits c
|
|
375
|
+
JOIN commit_refs cr ON cr.commit_sha = c.sha
|
|
376
|
+
ORDER BY c.timestamp DESC, c.sha ASC
|
|
377
|
+
LIMIT ?`)
|
|
378
|
+
.all(limit);
|
|
379
|
+
}
|
|
380
|
+
return db
|
|
381
|
+
.prepare(`SELECT DISTINCT c.* FROM commits c
|
|
382
|
+
JOIN commit_refs cr ON cr.commit_sha = c.sha
|
|
383
|
+
WHERE cr.ref_name = ? OR cr.ref_name LIKE ?
|
|
384
|
+
ORDER BY c.timestamp DESC, c.sha ASC
|
|
385
|
+
LIMIT ?`)
|
|
386
|
+
.all(exact, wildcard, limit);
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
return [];
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
export function listCommitCadence(db, granularity, filters = {}) {
|
|
393
|
+
const bucketExpr = granularity === 'month'
|
|
394
|
+
? "strftime('%Y-%m', c.timestamp, 'unixepoch')"
|
|
395
|
+
: granularity === 'week'
|
|
396
|
+
? "strftime('%Y-W%W', c.timestamp, 'unixepoch')"
|
|
397
|
+
: "strftime('%Y-%m-%d', c.timestamp, 'unixepoch')";
|
|
398
|
+
const { where, params } = buildCommitStatsWhere(filters);
|
|
399
|
+
return db
|
|
400
|
+
.prepare(`SELECT ${bucketExpr} AS bucket, COUNT(*) AS commits
|
|
401
|
+
FROM commits c
|
|
402
|
+
${where}
|
|
403
|
+
GROUP BY bucket
|
|
404
|
+
ORDER BY bucket ASC`)
|
|
405
|
+
.all(...params);
|
|
406
|
+
}
|
|
407
|
+
export function listCommitSizes(db, filters = {}) {
|
|
408
|
+
const { where, params } = buildCommitStatsWhere(filters);
|
|
409
|
+
const limit = clampStatsLimit(filters.limit);
|
|
410
|
+
return db
|
|
411
|
+
.prepare(`SELECT c.sha, c.author, c.author_email, c.timestamp,
|
|
412
|
+
COALESCE(SUM(COALESCE(cf.insertions, 0)), 0) AS insertions,
|
|
413
|
+
COALESCE(SUM(COALESCE(cf.deletions, 0)), 0) AS deletions
|
|
414
|
+
FROM commits c
|
|
415
|
+
LEFT JOIN commit_files cf ON cf.commit_sha = c.sha
|
|
416
|
+
${where}
|
|
417
|
+
GROUP BY c.sha, c.author, c.author_email, c.timestamp
|
|
418
|
+
ORDER BY c.timestamp DESC, c.sha ASC
|
|
419
|
+
LIMIT ?`)
|
|
420
|
+
.all(...params, limit);
|
|
421
|
+
}
|
|
422
|
+
export function listCommitChurnByFile(db, filters = {}) {
|
|
423
|
+
const { where, params } = buildCommitStatsWhere(filters);
|
|
424
|
+
const limit = clampStatsLimit(filters.limit);
|
|
425
|
+
return db
|
|
426
|
+
.prepare(`SELECT cf.file_path,
|
|
427
|
+
COUNT(DISTINCT c.sha) AS commit_count,
|
|
428
|
+
COALESCE(SUM(COALESCE(cf.insertions, 0)), 0) AS total_insertions,
|
|
429
|
+
COALESCE(SUM(COALESCE(cf.deletions, 0)), 0) AS total_deletions,
|
|
430
|
+
COALESCE(SUM(COALESCE(cf.insertions, 0) + COALESCE(cf.deletions, 0)), 0) AS total_churn
|
|
431
|
+
FROM commits c
|
|
432
|
+
JOIN commit_files cf ON cf.commit_sha = c.sha
|
|
433
|
+
${where}
|
|
434
|
+
GROUP BY cf.file_path
|
|
435
|
+
ORDER BY total_churn DESC, commit_count DESC, cf.file_path ASC
|
|
436
|
+
LIMIT ?`)
|
|
437
|
+
.all(...params, limit);
|
|
438
|
+
}
|
|
439
|
+
export function listCommitAuthorStats(db, filters = {}) {
|
|
440
|
+
const { where, params } = buildCommitStatsWhere(filters);
|
|
441
|
+
const limit = clampStatsLimit(filters.limit);
|
|
442
|
+
return db
|
|
443
|
+
.prepare(`SELECT c.author, c.author_email,
|
|
444
|
+
COUNT(DISTINCT c.sha) AS commit_count,
|
|
445
|
+
COALESCE(SUM(COALESCE(cf.insertions, 0)), 0) AS total_insertions,
|
|
446
|
+
COALESCE(SUM(COALESCE(cf.deletions, 0)), 0) AS total_deletions,
|
|
447
|
+
COALESCE(SUM(COALESCE(cf.insertions, 0) + COALESCE(cf.deletions, 0)), 0) AS total_churn
|
|
448
|
+
FROM commits c
|
|
449
|
+
LEFT JOIN commit_files cf ON cf.commit_sha = c.sha
|
|
450
|
+
${where}
|
|
451
|
+
GROUP BY c.author, c.author_email
|
|
452
|
+
ORDER BY commit_count DESC, total_churn DESC, c.author ASC
|
|
453
|
+
LIMIT ?`)
|
|
454
|
+
.all(...params, limit);
|
|
455
|
+
}
|
|
456
|
+
export function listCommitMessagePrefixes(db, filters = {}) {
|
|
457
|
+
const { where, params } = buildCommitStatsWhere(filters);
|
|
458
|
+
const limit = clampStatsLimit(filters.limit);
|
|
459
|
+
return db
|
|
460
|
+
.prepare(`SELECT LOWER(
|
|
461
|
+
CASE
|
|
462
|
+
WHEN instr(c.message, ':') > 0 THEN substr(c.message, 1, instr(c.message, ':'))
|
|
463
|
+
ELSE '(other)'
|
|
464
|
+
END
|
|
465
|
+
) AS prefix,
|
|
466
|
+
COUNT(*) AS count
|
|
467
|
+
FROM commits c
|
|
468
|
+
${where}
|
|
469
|
+
GROUP BY prefix
|
|
470
|
+
ORDER BY count DESC, prefix ASC
|
|
471
|
+
LIMIT ?`)
|
|
472
|
+
.all(...params, limit);
|
|
473
|
+
}
|
|
474
|
+
export function listCommitSchedule(db, filters = {}) {
|
|
475
|
+
const { where, params } = buildCommitStatsWhere(filters);
|
|
476
|
+
return db
|
|
477
|
+
.prepare(`SELECT CAST(strftime('%w', c.timestamp, 'unixepoch') AS INTEGER) AS day_of_week,
|
|
478
|
+
CAST(strftime('%H', c.timestamp, 'unixepoch') AS INTEGER) AS hour_of_day,
|
|
479
|
+
COUNT(*) AS commits
|
|
480
|
+
FROM commits c
|
|
481
|
+
${where}
|
|
482
|
+
GROUP BY day_of_week, hour_of_day
|
|
483
|
+
ORDER BY day_of_week ASC, hour_of_day ASC`)
|
|
484
|
+
.all(...params);
|
|
485
|
+
}
|
|
486
|
+
export function listCommitBranchActivity(db, filters = {}) {
|
|
487
|
+
const { where, params } = buildCommitStatsWhere(filters);
|
|
488
|
+
const limit = clampStatsLimit(filters.limit);
|
|
489
|
+
try {
|
|
490
|
+
return db
|
|
491
|
+
.prepare(`SELECT cr.ref_name, cr.ref_type, COUNT(DISTINCT c.sha) AS commits
|
|
492
|
+
FROM commits c
|
|
493
|
+
JOIN commit_refs cr ON cr.commit_sha = c.sha
|
|
494
|
+
${where}
|
|
495
|
+
GROUP BY cr.ref_name, cr.ref_type
|
|
496
|
+
ORDER BY commits DESC, cr.ref_name ASC
|
|
497
|
+
LIMIT ?`)
|
|
498
|
+
.all(...params, limit);
|
|
499
|
+
}
|
|
500
|
+
catch {
|
|
501
|
+
return [];
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
/** Return the most recent coverage ingestion run. */
|
|
505
|
+
export function getLatestCoverageRun(db) {
|
|
506
|
+
return db
|
|
507
|
+
.prepare(`SELECT id, commit_sha, source_path, format, ingested_at, source_mtime
|
|
508
|
+
FROM coverage_runs
|
|
509
|
+
ORDER BY ingested_at DESC, id DESC
|
|
510
|
+
LIMIT 1`)
|
|
511
|
+
.get();
|
|
512
|
+
}
|
|
513
|
+
/** Return staleness metadata comparing latest coverage run commit against indexed history. */
|
|
514
|
+
export function getCoverageStaleness(db) {
|
|
515
|
+
const latestRun = getLatestCoverageRun(db);
|
|
516
|
+
const currentCommit = db
|
|
517
|
+
.prepare('SELECT sha FROM commits ORDER BY timestamp DESC, sha ASC LIMIT 1')
|
|
518
|
+
.get();
|
|
519
|
+
if (!latestRun) {
|
|
520
|
+
return {
|
|
521
|
+
coverage_commit: null,
|
|
522
|
+
current_commit: currentCommit?.sha ?? null,
|
|
523
|
+
commits_behind: 0,
|
|
524
|
+
stale: false,
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
if (!currentCommit) {
|
|
528
|
+
return {
|
|
529
|
+
coverage_commit: latestRun.commit_sha,
|
|
530
|
+
current_commit: null,
|
|
531
|
+
commits_behind: 0,
|
|
532
|
+
stale: false,
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
const coverageCommitRow = db
|
|
536
|
+
.prepare('SELECT timestamp FROM commits WHERE sha = ? LIMIT 1')
|
|
537
|
+
.get(latestRun.commit_sha);
|
|
538
|
+
const commitsBehind = coverageCommitRow
|
|
539
|
+
? db
|
|
540
|
+
.prepare('SELECT COUNT(*) AS c FROM commits WHERE timestamp > ?')
|
|
541
|
+
.get(coverageCommitRow.timestamp).c
|
|
542
|
+
: (latestRun.commit_sha === currentCommit.sha ? 0 : 1);
|
|
543
|
+
return {
|
|
544
|
+
coverage_commit: latestRun.commit_sha,
|
|
545
|
+
current_commit: currentCommit.sha,
|
|
546
|
+
commits_behind: commitsBehind,
|
|
547
|
+
stale: commitsBehind > 0,
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
/** Return global line totals for the most recent coverage run. */
|
|
551
|
+
export function getLatestCoverageTotals(db) {
|
|
552
|
+
const latestRun = getLatestCoverageRun(db);
|
|
553
|
+
if (!latestRun) {
|
|
554
|
+
return undefined;
|
|
555
|
+
}
|
|
556
|
+
const totals = db
|
|
557
|
+
.prepare(`SELECT COALESCE(SUM(lines_found), 0) AS lines_found,
|
|
558
|
+
COALESCE(SUM(lines_hit), 0) AS lines_hit
|
|
559
|
+
FROM coverage_files
|
|
560
|
+
WHERE run_id = ?`)
|
|
561
|
+
.get(latestRun.id);
|
|
562
|
+
return {
|
|
563
|
+
lines_found: totals.lines_found,
|
|
564
|
+
lines_hit: totals.lines_hit,
|
|
565
|
+
coverage_percent: totals.lines_found > 0 ? (totals.lines_hit / totals.lines_found) * 100 : null,
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
/** Return symbol-level coverage aggregates computed from the latest coverage run. */
|
|
569
|
+
export function getSymbolCoverageAggregates(db, options = {}) {
|
|
570
|
+
const latestRun = getLatestCoverageRun(db);
|
|
571
|
+
if (!latestRun) {
|
|
572
|
+
return [];
|
|
573
|
+
}
|
|
574
|
+
const whereClauses = [];
|
|
575
|
+
const params = [];
|
|
576
|
+
const limit = options.limit ?? 200;
|
|
577
|
+
if (options.symbolIds && options.symbolIds.length > 0) {
|
|
578
|
+
const placeholders = options.symbolIds.map(() => '?').join(', ');
|
|
579
|
+
whereClauses.push(`s.id IN (${placeholders})`);
|
|
580
|
+
params.push(...options.symbolIds);
|
|
581
|
+
}
|
|
582
|
+
if (options.path !== undefined) {
|
|
583
|
+
whereClauses.push('f.path = ?');
|
|
584
|
+
params.push(options.path);
|
|
585
|
+
}
|
|
586
|
+
if (options.branch !== undefined) {
|
|
587
|
+
whereClauses.push('f.branch = ?');
|
|
588
|
+
params.push(options.branch);
|
|
589
|
+
}
|
|
590
|
+
const whereSql = whereClauses.length > 0 ? `WHERE ${whereClauses.join(' AND ')}` : '';
|
|
591
|
+
const symbols = db
|
|
592
|
+
.prepare(`SELECT s.id AS symbol_id,
|
|
593
|
+
s.name AS symbol_name,
|
|
594
|
+
f.path AS file_path,
|
|
595
|
+
s.start_line,
|
|
596
|
+
s.end_line
|
|
597
|
+
FROM symbols s
|
|
598
|
+
JOIN files f ON f.id = s.file_id
|
|
599
|
+
${whereSql}
|
|
600
|
+
ORDER BY s.id
|
|
601
|
+
LIMIT ?`)
|
|
602
|
+
.all(...params, limit);
|
|
603
|
+
if (symbols.length === 0) {
|
|
604
|
+
return [];
|
|
605
|
+
}
|
|
606
|
+
const filePaths = Array.from(new Set(symbols.map((symbol) => symbol.file_path)));
|
|
607
|
+
const filePlaceholders = filePaths.map(() => '?').join(', ');
|
|
608
|
+
const coverageRows = db
|
|
609
|
+
.prepare(`SELECT file_path, line_number, hit_count
|
|
610
|
+
FROM coverage_lines
|
|
611
|
+
WHERE run_id = ?
|
|
612
|
+
AND file_path IN (${filePlaceholders})`)
|
|
613
|
+
.all(latestRun.id, ...filePaths);
|
|
614
|
+
const lineHitsByFile = new Map();
|
|
615
|
+
for (const row of coverageRows) {
|
|
616
|
+
const existing = lineHitsByFile.get(row.file_path) ?? new Map();
|
|
617
|
+
existing.set(row.line_number, row.hit_count);
|
|
618
|
+
lineHitsByFile.set(row.file_path, existing);
|
|
619
|
+
}
|
|
620
|
+
return symbols.map((symbol) => {
|
|
621
|
+
const fileHits = lineHitsByFile.get(symbol.file_path) ?? new Map();
|
|
622
|
+
let totalLines = 0;
|
|
623
|
+
let coveredLines = 0;
|
|
624
|
+
const uncoveredLines = [];
|
|
625
|
+
for (let line = symbol.start_line; line <= symbol.end_line; line += 1) {
|
|
626
|
+
if (!fileHits.has(line)) {
|
|
627
|
+
continue;
|
|
628
|
+
}
|
|
629
|
+
totalLines += 1;
|
|
630
|
+
const hitCount = fileHits.get(line) ?? 0;
|
|
631
|
+
if (hitCount > 0) {
|
|
632
|
+
coveredLines += 1;
|
|
633
|
+
}
|
|
634
|
+
else {
|
|
635
|
+
uncoveredLines.push(line);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
return {
|
|
639
|
+
symbol_id: symbol.symbol_id,
|
|
640
|
+
symbol_name: symbol.symbol_name,
|
|
641
|
+
file_path: symbol.file_path,
|
|
642
|
+
start_line: symbol.start_line,
|
|
643
|
+
end_line: symbol.end_line,
|
|
644
|
+
total_lines: totalLines,
|
|
645
|
+
covered_lines: coveredLines,
|
|
646
|
+
uncovered_lines: uncoveredLines,
|
|
647
|
+
coverage_percent: totalLines > 0 ? (coveredLines / totalLines) * 100 : null,
|
|
648
|
+
};
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
/** Return symbol coverage percentages for selected symbol ids from latest coverage run. */
|
|
652
|
+
export function getCoveragePercentBySymbolIds(db, symbolIds, branch) {
|
|
653
|
+
if (symbolIds.length === 0) {
|
|
654
|
+
return new Map();
|
|
655
|
+
}
|
|
656
|
+
const rows = getSymbolCoverageAggregates(db, { symbolIds, branch, limit: symbolIds.length });
|
|
657
|
+
return new Map(rows.map((row) => [row.symbol_id, row.coverage_percent]));
|
|
658
|
+
}
|
|
659
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/kb-server/db.ts"],"names":[],"mappings":"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"}
|