@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,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module indexer/db
|
|
3
|
+
*
|
|
4
|
+
* Opens (or creates) a SQLite knowledge-base database and ensures all
|
|
5
|
+
* required tables exist. Vector embedding tables (vec0 virtual tables)
|
|
6
|
+
* are created separately via `createVec0Tables()` once the embedding
|
|
7
|
+
* dimensions are known.
|
|
8
|
+
*/
|
|
9
|
+
import Database from 'better-sqlite3';
|
|
10
|
+
import { createRequire } from 'node:module';
|
|
11
|
+
const esmRequire = createRequire(import.meta.url);
|
|
12
|
+
// ─── DDL ─────────────────────────────────────────────────────────────────────
|
|
13
|
+
const DDL = `
|
|
14
|
+
-- Indexed source files.
|
|
15
|
+
CREATE TABLE IF NOT EXISTS files (
|
|
16
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
17
|
+
path TEXT NOT NULL,
|
|
18
|
+
branch TEXT NOT NULL DEFAULT '',
|
|
19
|
+
language TEXT NOT NULL,
|
|
20
|
+
size_bytes INTEGER NOT NULL DEFAULT 0,
|
|
21
|
+
last_hash TEXT,
|
|
22
|
+
indexed_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
23
|
+
UNIQUE(path, branch)
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
-- Named symbols extracted from source files.
|
|
27
|
+
CREATE TABLE IF NOT EXISTS symbols (
|
|
28
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
29
|
+
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
30
|
+
name TEXT NOT NULL,
|
|
31
|
+
kind TEXT NOT NULL,
|
|
32
|
+
start_line INTEGER NOT NULL,
|
|
33
|
+
end_line INTEGER NOT NULL,
|
|
34
|
+
signature TEXT,
|
|
35
|
+
doc_comment TEXT
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
-- File-linked annotations extracted from comments (e.g. TODO/FIXME/NOTE).
|
|
39
|
+
CREATE TABLE IF NOT EXISTS annotations (
|
|
40
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
41
|
+
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
42
|
+
kind TEXT NOT NULL,
|
|
43
|
+
line INTEGER NOT NULL,
|
|
44
|
+
text TEXT NOT NULL,
|
|
45
|
+
symbol_id INTEGER REFERENCES symbols(id) ON DELETE SET NULL,
|
|
46
|
+
author TEXT,
|
|
47
|
+
created_at INTEGER
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
-- Import / use declarations found in source files.
|
|
51
|
+
CREATE TABLE IF NOT EXISTS file_imports (
|
|
52
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
53
|
+
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
54
|
+
raw_import TEXT NOT NULL,
|
|
55
|
+
resolved_id INTEGER REFERENCES files(id)
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
-- Test file to source file mappings derived during indexing.
|
|
59
|
+
CREATE TABLE IF NOT EXISTS test_mappings (
|
|
60
|
+
test_file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
61
|
+
source_file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
62
|
+
confidence TEXT NOT NULL DEFAULT 'heuristic',
|
|
63
|
+
UNIQUE(test_file_id, source_file_id)
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
-- Call-site references from one symbol to another.
|
|
67
|
+
CREATE TABLE IF NOT EXISTS symbol_refs (
|
|
68
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
69
|
+
caller_id INTEGER NOT NULL REFERENCES symbols(id) ON DELETE CASCADE,
|
|
70
|
+
callee_id INTEGER REFERENCES symbols(id),
|
|
71
|
+
callee_name TEXT NOT NULL,
|
|
72
|
+
call_line INTEGER NOT NULL
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
-- External (third-party / stdlib) dependencies inferred from imports.
|
|
76
|
+
CREATE TABLE IF NOT EXISTS external_deps (
|
|
77
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
78
|
+
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
79
|
+
package TEXT NOT NULL,
|
|
80
|
+
version TEXT,
|
|
81
|
+
UNIQUE(file_id, package)
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
-- Logical modules grouping related files (e.g. Rust crates, Python packages).
|
|
85
|
+
CREATE TABLE IF NOT EXISTS modules (
|
|
86
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
87
|
+
name TEXT NOT NULL UNIQUE,
|
|
88
|
+
kind TEXT NOT NULL,
|
|
89
|
+
manifest TEXT
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
-- Many-to-many mapping between files and modules.
|
|
93
|
+
CREATE TABLE IF NOT EXISTS file_modules (
|
|
94
|
+
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
95
|
+
module_id INTEGER NOT NULL REFERENCES modules(id) ON DELETE CASCADE,
|
|
96
|
+
PRIMARY KEY (file_id, module_id)
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
-- LLM-generated natural-language summaries for symbols.
|
|
100
|
+
CREATE TABLE IF NOT EXISTS symbol_summaries (
|
|
101
|
+
symbol_id INTEGER PRIMARY KEY REFERENCES symbols(id) ON DELETE CASCADE,
|
|
102
|
+
summary TEXT NOT NULL,
|
|
103
|
+
model TEXT NOT NULL,
|
|
104
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
-- Per-symbol complexity metrics.
|
|
108
|
+
CREATE TABLE IF NOT EXISTS symbol_metrics (
|
|
109
|
+
symbol_id INTEGER PRIMARY KEY REFERENCES symbols(id) ON DELETE CASCADE,
|
|
110
|
+
line_count INTEGER NOT NULL,
|
|
111
|
+
param_count INTEGER NOT NULL,
|
|
112
|
+
cyclomatic INTEGER NOT NULL,
|
|
113
|
+
max_nesting INTEGER NOT NULL
|
|
114
|
+
);
|
|
115
|
+
CREATE INDEX IF NOT EXISTS idx_symbol_metrics_cyclomatic ON symbol_metrics(cyclomatic);
|
|
116
|
+
|
|
117
|
+
-- Key-value store for knowledge-base metadata (schema version, embedding model, etc.).
|
|
118
|
+
CREATE TABLE IF NOT EXISTS kb_meta (
|
|
119
|
+
key TEXT PRIMARY KEY,
|
|
120
|
+
value TEXT NOT NULL
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
-- User and system notes scoped by key/scope pair.
|
|
124
|
+
CREATE TABLE IF NOT EXISTS notes (
|
|
125
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
126
|
+
key TEXT NOT NULL,
|
|
127
|
+
scope TEXT NOT NULL DEFAULT 'global',
|
|
128
|
+
content TEXT NOT NULL,
|
|
129
|
+
model TEXT NOT NULL DEFAULT '',
|
|
130
|
+
source_hash TEXT,
|
|
131
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
132
|
+
updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
133
|
+
UNIQUE(key, scope)
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
-- Full-text search index over symbol names, signatures, and kinds (BM25 via FTS5).
|
|
137
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS symbols_fts USING fts5(
|
|
138
|
+
name, signature, kind
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
-- Git commit metadata.
|
|
142
|
+
CREATE TABLE IF NOT EXISTS commits (
|
|
143
|
+
sha TEXT PRIMARY KEY,
|
|
144
|
+
author TEXT NOT NULL,
|
|
145
|
+
author_email TEXT NOT NULL,
|
|
146
|
+
timestamp INTEGER NOT NULL,
|
|
147
|
+
message TEXT NOT NULL,
|
|
148
|
+
parents TEXT NOT NULL DEFAULT '[]'
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
-- Files touched by each commit (with diff stats).
|
|
152
|
+
CREATE TABLE IF NOT EXISTS commit_files (
|
|
153
|
+
commit_sha TEXT NOT NULL REFERENCES commits(sha) ON DELETE CASCADE,
|
|
154
|
+
file_path TEXT NOT NULL,
|
|
155
|
+
change_type TEXT NOT NULL,
|
|
156
|
+
insertions INTEGER,
|
|
157
|
+
deletions INTEGER,
|
|
158
|
+
PRIMARY KEY (commit_sha, file_path)
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
CREATE TABLE IF NOT EXISTS commit_refs (
|
|
162
|
+
commit_sha TEXT NOT NULL REFERENCES commits(sha) ON DELETE CASCADE,
|
|
163
|
+
ref_name TEXT NOT NULL,
|
|
164
|
+
ref_type TEXT NOT NULL,
|
|
165
|
+
PRIMARY KEY (commit_sha, ref_name)
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
-- Coverage ingestion runs.
|
|
169
|
+
CREATE TABLE IF NOT EXISTS coverage_runs (
|
|
170
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
171
|
+
commit_sha TEXT NOT NULL,
|
|
172
|
+
source_path TEXT NOT NULL,
|
|
173
|
+
format TEXT NOT NULL,
|
|
174
|
+
ingested_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
175
|
+
source_mtime INTEGER
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
-- Per-file coverage aggregates for each ingestion run.
|
|
179
|
+
CREATE TABLE IF NOT EXISTS coverage_files (
|
|
180
|
+
run_id INTEGER NOT NULL REFERENCES coverage_runs(id) ON DELETE CASCADE,
|
|
181
|
+
file_path TEXT NOT NULL,
|
|
182
|
+
lines_found INTEGER NOT NULL DEFAULT 0,
|
|
183
|
+
lines_hit INTEGER NOT NULL DEFAULT 0,
|
|
184
|
+
PRIMARY KEY (run_id, file_path)
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
-- Per-line hit counts for each file in an ingestion run.
|
|
188
|
+
CREATE TABLE IF NOT EXISTS coverage_lines (
|
|
189
|
+
run_id INTEGER NOT NULL REFERENCES coverage_runs(id) ON DELETE CASCADE,
|
|
190
|
+
file_path TEXT NOT NULL,
|
|
191
|
+
line_number INTEGER NOT NULL,
|
|
192
|
+
hit_count INTEGER NOT NULL DEFAULT 0,
|
|
193
|
+
PRIMARY KEY (run_id, file_path, line_number),
|
|
194
|
+
FOREIGN KEY (run_id, file_path) REFERENCES coverage_files(run_id, file_path) ON DELETE CASCADE
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
CREATE TABLE IF NOT EXISTS api_routes (
|
|
198
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
199
|
+
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
200
|
+
method TEXT NOT NULL,
|
|
201
|
+
path TEXT NOT NULL,
|
|
202
|
+
handler_id INTEGER REFERENCES symbols(id) ON DELETE SET NULL,
|
|
203
|
+
handler_name TEXT NOT NULL,
|
|
204
|
+
framework TEXT NOT NULL,
|
|
205
|
+
line INTEGER NOT NULL,
|
|
206
|
+
middleware TEXT,
|
|
207
|
+
UNIQUE(file_id, method, path)
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
CREATE INDEX IF NOT EXISTS idx_api_routes_method ON api_routes(method);
|
|
211
|
+
CREATE INDEX IF NOT EXISTS idx_api_routes_path ON api_routes(path);
|
|
212
|
+
CREATE INDEX IF NOT EXISTS idx_annotations_kind ON annotations(kind);
|
|
213
|
+
CREATE INDEX IF NOT EXISTS idx_annotations_file_id ON annotations(file_id);
|
|
214
|
+
CREATE INDEX IF NOT EXISTS idx_coverage_runs_ingested_at ON coverage_runs(ingested_at);
|
|
215
|
+
CREATE INDEX IF NOT EXISTS idx_coverage_files_path ON coverage_files(file_path);
|
|
216
|
+
CREATE INDEX IF NOT EXISTS idx_coverage_lines_path_line ON coverage_lines(file_path, line_number);
|
|
217
|
+
`;
|
|
218
|
+
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
219
|
+
/**
|
|
220
|
+
* Opens (or creates) the SQLite database at `path` and initialises the schema.
|
|
221
|
+
*
|
|
222
|
+
* The returned `Database` instance is opened with WAL mode enabled for
|
|
223
|
+
* better concurrent read performance.
|
|
224
|
+
*/
|
|
225
|
+
export function openDb(path) {
|
|
226
|
+
const db = new Database(path);
|
|
227
|
+
// WAL mode: readers don't block writers, writers don't block readers.
|
|
228
|
+
db.pragma('journal_mode = WAL');
|
|
229
|
+
db.pragma('foreign_keys = ON');
|
|
230
|
+
// Create all tables in a single transaction.
|
|
231
|
+
db.exec(DDL);
|
|
232
|
+
return db;
|
|
233
|
+
}
|
|
234
|
+
// ─── kb_meta helpers ──────────────────────────────────────────────────────────
|
|
235
|
+
export const KB_META_INDEX_CHECKPOINT = 'index_checkpoint';
|
|
236
|
+
export const KB_META_LAST_HEAD_SHA = 'last_known_head_sha';
|
|
237
|
+
export const KB_META_COVERAGE_LAST_SOURCE_PATH = 'coverage_last_source_path';
|
|
238
|
+
export const KB_META_COVERAGE_LAST_SOURCE_MTIME = 'coverage_last_source_mtime';
|
|
239
|
+
/** Write (or overwrite) a key-value pair in `kb_meta`. */
|
|
240
|
+
export function setKbMeta(db, key, value) {
|
|
241
|
+
db.prepare('INSERT OR REPLACE INTO kb_meta (key, value) VALUES (?, ?)').run(key, value);
|
|
242
|
+
}
|
|
243
|
+
/** Read a value from `kb_meta`; returns `undefined` if the key is absent. */
|
|
244
|
+
export function getKbMeta(db, key) {
|
|
245
|
+
const row = db.prepare('SELECT value FROM kb_meta WHERE key = ?').get(key);
|
|
246
|
+
return row?.value;
|
|
247
|
+
}
|
|
248
|
+
// ─── Vec0 virtual tables ──────────────────────────────────────────────────────
|
|
249
|
+
/**
|
|
250
|
+
* Loads the sqlite-vec extension and creates the `symbol_embeddings` and
|
|
251
|
+
* `symbol_semantic_embeddings` vec0 virtual tables with the given dimension.
|
|
252
|
+
* Also stores `embedding_dims` in `kb_meta` for validation on reopen.
|
|
253
|
+
*
|
|
254
|
+
* This function is idempotent: it is safe to call multiple times with the
|
|
255
|
+
* same `dims` value.
|
|
256
|
+
*
|
|
257
|
+
* @param db An open better-sqlite3 database instance.
|
|
258
|
+
* @param dims Embedding dimensionality (e.g. 1024 for Qwen3-Embedding-0.6B).
|
|
259
|
+
*/
|
|
260
|
+
export function createVec0Tables(db, dims) {
|
|
261
|
+
// Load the sqlite-vec native extension.
|
|
262
|
+
// Use createRequire for ESM compatibility (native addons cannot be loaded via import()).
|
|
263
|
+
const sqliteVec = esmRequire('sqlite-vec');
|
|
264
|
+
sqliteVec.load(db);
|
|
265
|
+
db.exec(`
|
|
266
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS symbol_embeddings USING vec0(
|
|
267
|
+
embedding FLOAT[${dims}]
|
|
268
|
+
);
|
|
269
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS symbol_semantic_embeddings USING vec0(
|
|
270
|
+
embedding FLOAT[${dims}]
|
|
271
|
+
);
|
|
272
|
+
`);
|
|
273
|
+
setKbMeta(db, 'embedding_dims', String(dims));
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/indexer/db.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAKlD,gFAAgF;AAEhF,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4MX,CAAC;AAEF,iFAAiF;AAEjF;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE9B,sEAAsE;IACtE,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAE/B,6CAA6C;IAC7C,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,iFAAiF;AAEjF,MAAM,CAAC,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;AAC3D,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAC;AAC3D,MAAM,CAAC,MAAM,iCAAiC,GAAG,2BAA2B,CAAC;AAC7E,MAAM,CAAC,MAAM,kCAAkC,GAAG,4BAA4B,CAAC;AAE/E,0DAA0D;AAC1D,MAAM,UAAU,SAAS,CAAC,EAAqB,EAAE,GAAW,EAAE,KAAa;IACzE,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AAC1F,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,SAAS,CAAC,EAAqB,EAAE,GAAW;IAC1D,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC,GAAG,CAAC,GAAG,CAE5D,CAAC;IACd,OAAO,GAAG,EAAE,KAAK,CAAC;AACpB,CAAC;AAED,iFAAiF;AAEjF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAqB,EAAE,IAAY;IAClE,wCAAwC;IACxC,yFAAyF;IACzF,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,CAA0C,CAAC;IACpF,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEnB,EAAE,CAAC,IAAI,CAAC;;wBAEc,IAAI;;;wBAGJ,IAAI;;GAEzB,CAAC,CAAC;IAEH,SAAS,CAAC,EAAE,EAAE,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module indexer/embedder
|
|
3
|
+
*
|
|
4
|
+
* Provides an `EmbeddingProvider` abstraction for generating dense vector
|
|
5
|
+
* embeddings from text. The primary implementation (`SentenceTransformersProvider`)
|
|
6
|
+
* delegates to a Python subprocess that runs a sentence-transformers model,
|
|
7
|
+
* communicating over stdin/stdout using newline-delimited JSON (NDJSON).
|
|
8
|
+
*
|
|
9
|
+
* The model's embedding dimensionality is auto-detected at startup — the
|
|
10
|
+
* Python script writes a `{"dims": N}` line before entering the request loop.
|
|
11
|
+
*/
|
|
12
|
+
export interface EmbeddingProvider {
|
|
13
|
+
/** Embed a batch of texts; returns one float vector per input. */
|
|
14
|
+
embed(texts: string[]): Promise<number[][]>;
|
|
15
|
+
/** Human-readable model identifier. */
|
|
16
|
+
readonly modelName: string;
|
|
17
|
+
/**
|
|
18
|
+
* Dimensionality of the returned vectors.
|
|
19
|
+
* Only valid after `init()` resolves (throws before that).
|
|
20
|
+
*/
|
|
21
|
+
readonly dims: number;
|
|
22
|
+
/**
|
|
23
|
+
* Spawn the Python subprocess, load the model, and detect dim size.
|
|
24
|
+
* Must be called (and awaited) before the first `embed()` call.
|
|
25
|
+
*/
|
|
26
|
+
init(): Promise<void>;
|
|
27
|
+
/** Release the underlying process / resources. */
|
|
28
|
+
dispose(): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Communicates with a Python subprocess via stdin/stdout NDJSON to produce
|
|
32
|
+
* embeddings using a sentence-transformers compatible model.
|
|
33
|
+
*
|
|
34
|
+
* Call `init()` first to spawn the process and detect the model's embedding
|
|
35
|
+
* dimensionality. The subprocess is kept alive for the lifetime of the
|
|
36
|
+
* provider for efficiency.
|
|
37
|
+
*/
|
|
38
|
+
export declare class SentenceTransformersProvider implements EmbeddingProvider {
|
|
39
|
+
readonly modelName: string;
|
|
40
|
+
private _dims;
|
|
41
|
+
private proc;
|
|
42
|
+
private rl;
|
|
43
|
+
private readonly pendingRequests;
|
|
44
|
+
private readonly pythonBin;
|
|
45
|
+
/** Whether the first stdout line (dims handshake) has been consumed. */
|
|
46
|
+
private initialized;
|
|
47
|
+
constructor(modelName: string, pythonBin?: string);
|
|
48
|
+
/** Embedding dimensionality — available only after `init()`. */
|
|
49
|
+
get dims(): number;
|
|
50
|
+
/**
|
|
51
|
+
* Spawn the Python subprocess, load the model, and read the `{"dims": N}`
|
|
52
|
+
* handshake line. This may take a while on first run (model download).
|
|
53
|
+
*/
|
|
54
|
+
init(): Promise<void>;
|
|
55
|
+
embed(texts: string[]): Promise<number[][]>;
|
|
56
|
+
dispose(): Promise<void>;
|
|
57
|
+
/** Spawn the Python subprocess and wire up the readline interface. */
|
|
58
|
+
private spawnProcess;
|
|
59
|
+
}
|
|
60
|
+
/** Default embedding model used when no model is explicitly specified. */
|
|
61
|
+
export declare const DEFAULT_EMBEDDING_MODEL = "Qwen/Qwen3-Embedding-4B";
|
|
62
|
+
/**
|
|
63
|
+
* Creates a `SentenceTransformersProvider` pre-configured for the specified
|
|
64
|
+
* Qwen3-Embedding model size.
|
|
65
|
+
*
|
|
66
|
+
* @param size Model size variant: `'0.6B'`, `'4B'`, or `'8B'`.
|
|
67
|
+
* @param pythonBin Path to the Python executable (default: `'python3'`).
|
|
68
|
+
*/
|
|
69
|
+
export declare function Qwen3EmbeddingProvider(size: '0.6B' | '4B' | '8B', pythonBin?: string): SentenceTransformersProvider;
|
|
70
|
+
//# sourceMappingURL=embedder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedder.d.ts","sourceRoot":"","sources":["../../src/indexer/embedder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5C,uCAAuC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,kDAAkD;IAClD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAoCD;;;;;;;GAOG;AACH,qBAAa,4BAA6B,YAAW,iBAAiB;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,KAAK,CAAuB;IAEpC,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,EAAE,CAAmC;IAC7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAwB;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,wEAAwE;IACxE,OAAO,CAAC,WAAW,CAAS;gBAEhB,SAAS,EAAE,MAAM,EAAE,SAAS,SAAY;IAKpD,gEAAgE;IAChE,IAAI,IAAI,IAAI,MAAM,CAKjB;IAED;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgCrB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAW3C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAa9B,sEAAsE;IACtE,OAAO,CAAC,YAAY;CAuCrB;AAID,0EAA0E;AAC1E,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,EAC1B,SAAS,SAAY,GACpB,4BAA4B,CAG9B"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module indexer/embedder
|
|
3
|
+
*
|
|
4
|
+
* Provides an `EmbeddingProvider` abstraction for generating dense vector
|
|
5
|
+
* embeddings from text. The primary implementation (`SentenceTransformersProvider`)
|
|
6
|
+
* delegates to a Python subprocess that runs a sentence-transformers model,
|
|
7
|
+
* communicating over stdin/stdout using newline-delimited JSON (NDJSON).
|
|
8
|
+
*
|
|
9
|
+
* The model's embedding dimensionality is auto-detected at startup — the
|
|
10
|
+
* Python script writes a `{"dims": N}` line before entering the request loop.
|
|
11
|
+
*/
|
|
12
|
+
import { spawn } from 'node:child_process';
|
|
13
|
+
import * as readline from 'node:readline';
|
|
14
|
+
// ─── Python bootstrap script ──────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Inline Python script that:
|
|
17
|
+
* 1. Loads the model.
|
|
18
|
+
* 2. Prints `{"dims": <N>}` on the first stdout line.
|
|
19
|
+
* 3. Enters an NDJSON request loop (stdin → stdout).
|
|
20
|
+
*
|
|
21
|
+
* Model name is received as sys.argv[1].
|
|
22
|
+
*/
|
|
23
|
+
const BOOTSTRAP_SCRIPT = `
|
|
24
|
+
import sys, json
|
|
25
|
+
from sentence_transformers import SentenceTransformer
|
|
26
|
+
model = SentenceTransformer(sys.argv[1], trust_remote_code=True)
|
|
27
|
+
dims = model.get_sentence_embedding_dimension()
|
|
28
|
+
sys.stdout.write(json.dumps({"dims": dims}) + "\\n")
|
|
29
|
+
sys.stdout.flush()
|
|
30
|
+
for line in sys.stdin:
|
|
31
|
+
line = line.strip()
|
|
32
|
+
if not line:
|
|
33
|
+
continue
|
|
34
|
+
req = json.loads(line)
|
|
35
|
+
vecs = model.encode(req.get('texts', []), normalize_embeddings=True).tolist()
|
|
36
|
+
sys.stdout.write(json.dumps({'embeddings': vecs}) + '\\n')
|
|
37
|
+
sys.stdout.flush()
|
|
38
|
+
`.trimStart();
|
|
39
|
+
/**
|
|
40
|
+
* Communicates with a Python subprocess via stdin/stdout NDJSON to produce
|
|
41
|
+
* embeddings using a sentence-transformers compatible model.
|
|
42
|
+
*
|
|
43
|
+
* Call `init()` first to spawn the process and detect the model's embedding
|
|
44
|
+
* dimensionality. The subprocess is kept alive for the lifetime of the
|
|
45
|
+
* provider for efficiency.
|
|
46
|
+
*/
|
|
47
|
+
export class SentenceTransformersProvider {
|
|
48
|
+
modelName;
|
|
49
|
+
_dims = null;
|
|
50
|
+
proc = null;
|
|
51
|
+
rl = null;
|
|
52
|
+
pendingRequests = [];
|
|
53
|
+
pythonBin;
|
|
54
|
+
/** Whether the first stdout line (dims handshake) has been consumed. */
|
|
55
|
+
initialized = false;
|
|
56
|
+
constructor(modelName, pythonBin = 'python3') {
|
|
57
|
+
this.modelName = modelName;
|
|
58
|
+
this.pythonBin = pythonBin;
|
|
59
|
+
}
|
|
60
|
+
/** Embedding dimensionality — available only after `init()`. */
|
|
61
|
+
get dims() {
|
|
62
|
+
if (this._dims === null) {
|
|
63
|
+
throw new Error('EmbeddingProvider not initialised — call init() first');
|
|
64
|
+
}
|
|
65
|
+
return this._dims;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Spawn the Python subprocess, load the model, and read the `{"dims": N}`
|
|
69
|
+
* handshake line. This may take a while on first run (model download).
|
|
70
|
+
*/
|
|
71
|
+
async init() {
|
|
72
|
+
if (this.initialized)
|
|
73
|
+
return;
|
|
74
|
+
this.spawnProcess();
|
|
75
|
+
// The very first line from the subprocess is the dims handshake.
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
const onLine = (line) => {
|
|
78
|
+
try {
|
|
79
|
+
const msg = JSON.parse(line);
|
|
80
|
+
if (typeof msg.dims === 'number') {
|
|
81
|
+
this._dims = msg.dims;
|
|
82
|
+
this.initialized = true;
|
|
83
|
+
resolve();
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
reject(new Error(`Unexpected handshake from embedding subprocess: ${line}`));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
reject(new Error(`Failed to parse embedding handshake: ${line}`));
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
// Read exactly one line for the handshake, then re-wire for embed requests.
|
|
94
|
+
this.rl.once('line', onLine);
|
|
95
|
+
// If the process dies before the handshake, reject.
|
|
96
|
+
this.proc.once('exit', (code) => {
|
|
97
|
+
if (!this.initialized) {
|
|
98
|
+
reject(new Error(`Embedding subprocess exited with code ${code} before handshake`));
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async embed(texts) {
|
|
104
|
+
if (texts.length === 0)
|
|
105
|
+
return [];
|
|
106
|
+
if (!this.initialized) {
|
|
107
|
+
throw new Error('EmbeddingProvider not initialised — call init() first');
|
|
108
|
+
}
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
this.pendingRequests.push({ resolve, reject });
|
|
111
|
+
this.proc.stdin.write(JSON.stringify({ texts }) + '\n');
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
async dispose() {
|
|
115
|
+
if (!this.proc)
|
|
116
|
+
return;
|
|
117
|
+
const proc = this.proc;
|
|
118
|
+
this.proc = null;
|
|
119
|
+
this.rl?.close();
|
|
120
|
+
this.rl = null;
|
|
121
|
+
proc.stdin?.end();
|
|
122
|
+
await new Promise(resolve => {
|
|
123
|
+
const timeout = setTimeout(() => { proc.kill(); resolve(); }, 5_000);
|
|
124
|
+
proc.once('close', () => { clearTimeout(timeout); resolve(); });
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/** Spawn the Python subprocess and wire up the readline interface. */
|
|
128
|
+
spawnProcess() {
|
|
129
|
+
if (this.proc)
|
|
130
|
+
return;
|
|
131
|
+
this.proc = spawn(this.pythonBin, ['-c', BOOTSTRAP_SCRIPT, this.modelName], {
|
|
132
|
+
stdio: ['pipe', 'pipe', 'inherit'],
|
|
133
|
+
});
|
|
134
|
+
this.rl = readline.createInterface({ input: this.proc.stdout });
|
|
135
|
+
// After init(), all subsequent lines are embed responses.
|
|
136
|
+
this.rl.on('line', (line) => {
|
|
137
|
+
// Skip lines until init handshake is done (handled by init's once listener).
|
|
138
|
+
if (!this.initialized)
|
|
139
|
+
return;
|
|
140
|
+
const pending = this.pendingRequests.shift();
|
|
141
|
+
if (!pending)
|
|
142
|
+
return;
|
|
143
|
+
try {
|
|
144
|
+
const { embeddings } = JSON.parse(line);
|
|
145
|
+
pending.resolve(embeddings);
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
pending.reject(err);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
this.proc.on('error', (err) => {
|
|
152
|
+
const reqs = this.pendingRequests.splice(0);
|
|
153
|
+
this.proc = null;
|
|
154
|
+
this.rl = null;
|
|
155
|
+
for (const r of reqs)
|
|
156
|
+
r.reject(err);
|
|
157
|
+
});
|
|
158
|
+
this.proc.on('exit', (code) => {
|
|
159
|
+
if (code !== 0 && this.pendingRequests.length > 0) {
|
|
160
|
+
const err = new Error(`Embedding subprocess exited with code ${code}`);
|
|
161
|
+
const reqs = this.pendingRequests.splice(0);
|
|
162
|
+
for (const r of reqs)
|
|
163
|
+
r.reject(err);
|
|
164
|
+
}
|
|
165
|
+
if (this.proc) {
|
|
166
|
+
this.proc = null;
|
|
167
|
+
this.rl = null;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// ─── Qwen3 factory ────────────────────────────────────────────────────────────
|
|
173
|
+
/** Default embedding model used when no model is explicitly specified. */
|
|
174
|
+
export const DEFAULT_EMBEDDING_MODEL = 'Qwen/Qwen3-Embedding-4B';
|
|
175
|
+
/**
|
|
176
|
+
* Creates a `SentenceTransformersProvider` pre-configured for the specified
|
|
177
|
+
* Qwen3-Embedding model size.
|
|
178
|
+
*
|
|
179
|
+
* @param size Model size variant: `'0.6B'`, `'4B'`, or `'8B'`.
|
|
180
|
+
* @param pythonBin Path to the Python executable (default: `'python3'`).
|
|
181
|
+
*/
|
|
182
|
+
export function Qwen3EmbeddingProvider(size, pythonBin = 'python3') {
|
|
183
|
+
const modelName = `Qwen/Qwen3-Embedding-${size}`;
|
|
184
|
+
return new SentenceTransformersProvider(modelName, pythonBin);
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=embedder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedder.js","sourceRoot":"","sources":["../../src/indexer/embedder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module indexer/ensure-python-deps
|
|
3
|
+
*
|
|
4
|
+
* Validates that the Python environment has the packages required for
|
|
5
|
+
* embedding generation (`sentence-transformers`, `torch`). If missing,
|
|
6
|
+
* attempts an automatic `pip install` before the first embedding run.
|
|
7
|
+
*
|
|
8
|
+
* This is only used when `kbIndex.embeddings.enabled` is `true` in the
|
|
9
|
+
* migration config.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Checks whether each of `REQUIRED_PACKAGES` is importable by the given Python
|
|
13
|
+
* binary. For any missing package, runs `pip install sentence-transformers`
|
|
14
|
+
* (which pulls in `torch` as a transitive dependency).
|
|
15
|
+
*
|
|
16
|
+
* Throws if the Python binary is not found or if `pip install` fails.
|
|
17
|
+
*
|
|
18
|
+
* @param pythonBin Path to the Python 3 interpreter (default: `'python3'`).
|
|
19
|
+
* @param timeout Maximum milliseconds to wait for the install (default: 5 min).
|
|
20
|
+
*/
|
|
21
|
+
export declare function ensurePythonDeps(pythonBin?: string, timeout?: number): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=ensure-python-deps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-python-deps.d.ts","sourceRoot":"","sources":["../../src/indexer/ensure-python-deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,SAAY,EACrB,OAAO,SAAa,GACnB,OAAO,CAAC,IAAI,CAAC,CAyBf"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module indexer/ensure-python-deps
|
|
3
|
+
*
|
|
4
|
+
* Validates that the Python environment has the packages required for
|
|
5
|
+
* embedding generation (`sentence-transformers`, `torch`). If missing,
|
|
6
|
+
* attempts an automatic `pip install` before the first embedding run.
|
|
7
|
+
*
|
|
8
|
+
* This is only used when `kbIndex.embeddings.enabled` is `true` in the
|
|
9
|
+
* migration config.
|
|
10
|
+
*/
|
|
11
|
+
import { execFile } from 'node:child_process';
|
|
12
|
+
import { promisify } from 'node:util';
|
|
13
|
+
const execFileAsync = promisify(execFile);
|
|
14
|
+
/** Python packages required by the sentence-transformers embedding provider. */
|
|
15
|
+
const REQUIRED_PACKAGES = ['sentence_transformers', 'torch'];
|
|
16
|
+
/**
|
|
17
|
+
* Checks whether each of `REQUIRED_PACKAGES` is importable by the given Python
|
|
18
|
+
* binary. For any missing package, runs `pip install sentence-transformers`
|
|
19
|
+
* (which pulls in `torch` as a transitive dependency).
|
|
20
|
+
*
|
|
21
|
+
* Throws if the Python binary is not found or if `pip install` fails.
|
|
22
|
+
*
|
|
23
|
+
* @param pythonBin Path to the Python 3 interpreter (default: `'python3'`).
|
|
24
|
+
* @param timeout Maximum milliseconds to wait for the install (default: 5 min).
|
|
25
|
+
*/
|
|
26
|
+
export async function ensurePythonDeps(pythonBin = 'python3', timeout = 5 * 60_000) {
|
|
27
|
+
// Probe which packages are already available.
|
|
28
|
+
const missing = [];
|
|
29
|
+
for (const pkg of REQUIRED_PACKAGES) {
|
|
30
|
+
try {
|
|
31
|
+
await execFileAsync(pythonBin, ['-c', `import ${pkg}`], { timeout: 10_000 });
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
missing.push(pkg);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (missing.length === 0)
|
|
38
|
+
return;
|
|
39
|
+
// `sentence-transformers` transitively installs torch, so a single pip
|
|
40
|
+
// install call is sufficient.
|
|
41
|
+
await execFileAsync(pythonBin, ['-m', 'pip', 'install', '--quiet', 'sentence-transformers'], { timeout });
|
|
42
|
+
// Verify the install succeeded.
|
|
43
|
+
for (const pkg of REQUIRED_PACKAGES) {
|
|
44
|
+
await execFileAsync(pythonBin, ['-c', `import ${pkg}`], { timeout: 10_000 });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=ensure-python-deps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-python-deps.js","sourceRoot":"","sources":["../../src/indexer/ensure-python-deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,gFAAgF;AAChF,MAAM,iBAAiB,GAAG,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;AAE7D;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAS,GAAG,SAAS,EACrB,OAAO,GAAG,CAAC,GAAG,MAAM;IAEpB,8CAA8C;IAC9C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEjC,uEAAuE;IACvE,8BAA8B;IAC9B,MAAM,aAAa,CACjB,SAAS,EACT,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,uBAAuB,CAAC,EAC5D,EAAE,OAAO,EAAE,CACZ,CAAC;IAEF,gCAAgC;IAChC,KAAK,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACpC,MAAM,aAAa,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module indexer/extractors/bash
|
|
3
|
+
*
|
|
4
|
+
* Bash/Shell language extractor. Extracts function definitions and `source`
|
|
5
|
+
* / `.` commands as imports.
|
|
6
|
+
*/
|
|
7
|
+
import type Parser from 'tree-sitter';
|
|
8
|
+
import { type ExtractionResult, type SymbolExtractor } from './types.js';
|
|
9
|
+
export declare class BashExtractor implements SymbolExtractor {
|
|
10
|
+
extract(tree: Parser.Tree, _source: string, _filePath: string): ExtractionResult;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=bash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/indexer/extractors/bash.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,EACL,KAAK,gBAAgB,EAGrB,KAAK,eAAe,EAIrB,MAAM,YAAY,CAAC;AAIpB,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,gBAAgB;CAkBjF"}
|