@mka-rainmaker/ama 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 +149 -0
- package/dist/analyzers/baseline/analyzer.d.ts +47 -0
- package/dist/analyzers/baseline/analyzer.d.ts.map +1 -0
- package/dist/analyzers/baseline/analyzer.js +84 -0
- package/dist/analyzers/baseline/analyzer.js.map +1 -0
- package/dist/analyzers/baseline/c.d.ts +12 -0
- package/dist/analyzers/baseline/c.d.ts.map +1 -0
- package/dist/analyzers/baseline/c.js +56 -0
- package/dist/analyzers/baseline/c.js.map +1 -0
- package/dist/analyzers/baseline/config.d.ts +21 -0
- package/dist/analyzers/baseline/config.d.ts.map +1 -0
- package/dist/analyzers/baseline/config.js +32 -0
- package/dist/analyzers/baseline/config.js.map +1 -0
- package/dist/analyzers/baseline/csharp.d.ts +9 -0
- package/dist/analyzers/baseline/csharp.d.ts.map +1 -0
- package/dist/analyzers/baseline/csharp.js +107 -0
- package/dist/analyzers/baseline/csharp.js.map +1 -0
- package/dist/analyzers/baseline/go.d.ts +11 -0
- package/dist/analyzers/baseline/go.d.ts.map +1 -0
- package/dist/analyzers/baseline/go.js +66 -0
- package/dist/analyzers/baseline/go.js.map +1 -0
- package/dist/analyzers/baseline/java.d.ts +9 -0
- package/dist/analyzers/baseline/java.d.ts.map +1 -0
- package/dist/analyzers/baseline/java.js +50 -0
- package/dist/analyzers/baseline/java.js.map +1 -0
- package/dist/analyzers/baseline/javascript.d.ts +10 -0
- package/dist/analyzers/baseline/javascript.d.ts.map +1 -0
- package/dist/analyzers/baseline/javascript.js +55 -0
- package/dist/analyzers/baseline/javascript.js.map +1 -0
- package/dist/analyzers/baseline/kotlin.d.ts +11 -0
- package/dist/analyzers/baseline/kotlin.d.ts.map +1 -0
- package/dist/analyzers/baseline/kotlin.js +67 -0
- package/dist/analyzers/baseline/kotlin.js.map +1 -0
- package/dist/analyzers/baseline/paths.d.ts +6 -0
- package/dist/analyzers/baseline/paths.d.ts.map +1 -0
- package/dist/analyzers/baseline/paths.js +17 -0
- package/dist/analyzers/baseline/paths.js.map +1 -0
- package/dist/analyzers/baseline/php.d.ts +11 -0
- package/dist/analyzers/baseline/php.d.ts.map +1 -0
- package/dist/analyzers/baseline/php.js +76 -0
- package/dist/analyzers/baseline/php.js.map +1 -0
- package/dist/analyzers/baseline/python.d.ts +10 -0
- package/dist/analyzers/baseline/python.d.ts.map +1 -0
- package/dist/analyzers/baseline/python.js +63 -0
- package/dist/analyzers/baseline/python.js.map +1 -0
- package/dist/analyzers/baseline/rust.d.ts +10 -0
- package/dist/analyzers/baseline/rust.d.ts.map +1 -0
- package/dist/analyzers/baseline/rust.js +45 -0
- package/dist/analyzers/baseline/rust.js.map +1 -0
- package/dist/analyzers/baseline/swift.d.ts +11 -0
- package/dist/analyzers/baseline/swift.d.ts.map +1 -0
- package/dist/analyzers/baseline/swift.js +19 -0
- package/dist/analyzers/baseline/swift.js.map +1 -0
- package/dist/analyzers/baseline/treesitter.d.ts +11 -0
- package/dist/analyzers/baseline/treesitter.d.ts.map +1 -0
- package/dist/analyzers/baseline/treesitter.js +87 -0
- package/dist/analyzers/baseline/treesitter.js.map +1 -0
- package/dist/analyzers/baseline/walk.d.ts +26 -0
- package/dist/analyzers/baseline/walk.d.ts.map +1 -0
- package/dist/analyzers/baseline/walk.js +76 -0
- package/dist/analyzers/baseline/walk.js.map +1 -0
- package/dist/analyzers/registry.d.ts +19 -0
- package/dist/analyzers/registry.d.ts.map +1 -0
- package/dist/analyzers/registry.js +43 -0
- package/dist/analyzers/registry.js.map +1 -0
- package/dist/analyzers/sfc/analyzer.d.ts +17 -0
- package/dist/analyzers/sfc/analyzer.d.ts.map +1 -0
- package/dist/analyzers/sfc/analyzer.js +141 -0
- package/dist/analyzers/sfc/analyzer.js.map +1 -0
- package/dist/analyzers/sidecar/analyzer.d.ts +29 -0
- package/dist/analyzers/sidecar/analyzer.d.ts.map +1 -0
- package/dist/analyzers/sidecar/analyzer.js +114 -0
- package/dist/analyzers/sidecar/analyzer.js.map +1 -0
- package/dist/analyzers/sidecar/protocol.d.ts +508 -0
- package/dist/analyzers/sidecar/protocol.d.ts.map +1 -0
- package/dist/analyzers/sidecar/protocol.js +102 -0
- package/dist/analyzers/sidecar/protocol.js.map +1 -0
- package/dist/analyzers/types.d.ts +46 -0
- package/dist/analyzers/types.d.ts.map +1 -0
- package/dist/analyzers/types.js +2 -0
- package/dist/analyzers/types.js.map +1 -0
- package/dist/analyzers/typescript/analyzer.d.ts +126 -0
- package/dist/analyzers/typescript/analyzer.d.ts.map +1 -0
- package/dist/analyzers/typescript/analyzer.js +1600 -0
- package/dist/analyzers/typescript/analyzer.js.map +1 -0
- package/dist/cli/commands/cycles.d.ts +6 -0
- package/dist/cli/commands/cycles.d.ts.map +1 -0
- package/dist/cli/commands/cycles.js +27 -0
- package/dist/cli/commands/cycles.js.map +1 -0
- package/dist/cli/commands/files.d.ts +6 -0
- package/dist/cli/commands/files.d.ts.map +1 -0
- package/dist/cli/commands/files.js +33 -0
- package/dist/cli/commands/files.js.map +1 -0
- package/dist/cli/commands/impact.d.ts +18 -0
- package/dist/cli/commands/impact.d.ts.map +1 -0
- package/dist/cli/commands/impact.js +113 -0
- package/dist/cli/commands/impact.js.map +1 -0
- package/dist/cli/commands/lifecycle.d.ts +5 -0
- package/dist/cli/commands/lifecycle.d.ts.map +1 -0
- package/dist/cli/commands/lifecycle.js +83 -0
- package/dist/cli/commands/lifecycle.js.map +1 -0
- package/dist/cli/commands/query.d.ts +31 -0
- package/dist/cli/commands/query.d.ts.map +1 -0
- package/dist/cli/commands/query.js +187 -0
- package/dist/cli/commands/query.js.map +1 -0
- package/dist/cli/commands/search.d.ts +21 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +160 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/status.d.ts +6 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +63 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/sync.d.ts +6 -0
- package/dist/cli/commands/sync.d.ts.map +1 -0
- package/dist/cli/commands/sync.js +57 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/emit.d.ts +9 -0
- package/dist/cli/emit.d.ts.map +1 -0
- package/dist/cli/emit.js +10 -0
- package/dist/cli/emit.js.map +1 -0
- package/dist/cli/index.d.ts +37 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +128 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/paths.d.ts +7 -0
- package/dist/cli/paths.d.ts.map +1 -0
- package/dist/cli/paths.js +10 -0
- package/dist/cli/paths.js.map +1 -0
- package/dist/cli/query-runner.d.ts +13 -0
- package/dist/cli/query-runner.d.ts.map +1 -0
- package/dist/cli/query-runner.js +33 -0
- package/dist/cli/query-runner.js.map +1 -0
- package/dist/graph/dispatch.d.ts +17 -0
- package/dist/graph/dispatch.d.ts.map +1 -0
- package/dist/graph/dispatch.js +82 -0
- package/dist/graph/dispatch.js.map +1 -0
- package/dist/graph/id.d.ts +19 -0
- package/dist/graph/id.d.ts.map +1 -0
- package/dist/graph/id.js +17 -0
- package/dist/graph/id.js.map +1 -0
- package/dist/graph/index.d.ts +6 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +4 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/types.d.ts +71 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +52 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/indexer/debouncer.d.ts +32 -0
- package/dist/indexer/debouncer.d.ts.map +1 -0
- package/dist/indexer/debouncer.js +81 -0
- package/dist/indexer/debouncer.js.map +1 -0
- package/dist/indexer/ignore.d.ts +55 -0
- package/dist/indexer/ignore.d.ts.map +1 -0
- package/dist/indexer/ignore.js +170 -0
- package/dist/indexer/ignore.js.map +1 -0
- package/dist/indexer/indexer.d.ts +112 -0
- package/dist/indexer/indexer.d.ts.map +1 -0
- package/dist/indexer/indexer.js +392 -0
- package/dist/indexer/indexer.js.map +1 -0
- package/dist/indexer/watcher.d.ts +50 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +86 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/mcp/build-info.d.ts +16 -0
- package/dist/mcp/build-info.d.ts.map +1 -0
- package/dist/mcp/build-info.js +54 -0
- package/dist/mcp/build-info.js.map +1 -0
- package/dist/mcp/http.d.ts +18 -0
- package/dist/mcp/http.d.ts.map +1 -0
- package/dist/mcp/http.js +145 -0
- package/dist/mcp/http.js.map +1 -0
- package/dist/mcp/server.d.ts +22 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +401 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/session.d.ts +155 -0
- package/dist/mcp/session.d.ts.map +1 -0
- package/dist/mcp/session.js +319 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/query/service.d.ts +329 -0
- package/dist/query/service.d.ts.map +1 -0
- package/dist/query/service.js +959 -0
- package/dist/query/service.js.map +1 -0
- package/dist/runtime/entrypoint.d.ts +11 -0
- package/dist/runtime/entrypoint.d.ts.map +1 -0
- package/dist/runtime/entrypoint.js +22 -0
- package/dist/runtime/entrypoint.js.map +1 -0
- package/dist/runtime/quiet-sqlite-warning.d.ts +14 -0
- package/dist/runtime/quiet-sqlite-warning.d.ts.map +1 -0
- package/dist/runtime/quiet-sqlite-warning.js +26 -0
- package/dist/runtime/quiet-sqlite-warning.js.map +1 -0
- package/dist/runtime/wasm-tier.d.ts +2 -0
- package/dist/runtime/wasm-tier.d.ts.map +1 -0
- package/dist/runtime/wasm-tier.js +54 -0
- package/dist/runtime/wasm-tier.js.map +1 -0
- package/dist/store/memory.d.ts +54 -0
- package/dist/store/memory.d.ts.map +1 -0
- package/dist/store/memory.js +210 -0
- package/dist/store/memory.js.map +1 -0
- package/dist/store/sqlite.d.ts +38 -0
- package/dist/store/sqlite.d.ts.map +1 -0
- package/dist/store/sqlite.js +298 -0
- package/dist/store/sqlite.js.map +1 -0
- package/dist/store/types.d.ts +76 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +2 -0
- package/dist/store/types.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
// A static `import "node:sqlite"` emits its ExperimentalWarning during ESM *linking* — before
|
|
3
|
+
// any module body runs, too early to filter. So this side-effect import installs the filter
|
|
4
|
+
// first, and node:sqlite is loaded at runtime (below) with the filter already in place. (ama-hee)
|
|
5
|
+
import "../runtime/quiet-sqlite-warning.js";
|
|
6
|
+
/** node:sqlite's `DatabaseSync`, loaded at runtime (not statically) so the quiet filter imported
|
|
7
|
+
* above is installed before its module-load ExperimentalWarning fires. (ama-hee) */
|
|
8
|
+
const { DatabaseSync } = createRequire(import.meta.url)("node:sqlite");
|
|
9
|
+
/**
|
|
10
|
+
* SQLite-backed graph store using Node's built-in {@link DatabaseSync} — no
|
|
11
|
+
* native dependency. Two tables (nodes, edges) mirror the in-memory store; the
|
|
12
|
+
* implicit `rowid` preserves insertion order so query results match the
|
|
13
|
+
* in-memory backend exactly (verified by the shared store contract).
|
|
14
|
+
*
|
|
15
|
+
* Pass a file path to persist across processes, or omit it for an in-memory db.
|
|
16
|
+
*/
|
|
17
|
+
export class SqliteStore {
|
|
18
|
+
db;
|
|
19
|
+
constructor(location = ":memory:") {
|
|
20
|
+
this.db = new DatabaseSync(location);
|
|
21
|
+
// WAL lets readers run concurrently with a writer (no-op for :memory:).
|
|
22
|
+
// synchronous=NORMAL is the safe, fast pairing with WAL; busy_timeout
|
|
23
|
+
// lets concurrent connections wait out a lock instead of failing.
|
|
24
|
+
this.db.exec(`
|
|
25
|
+
PRAGMA journal_mode = WAL;
|
|
26
|
+
PRAGMA synchronous = NORMAL;
|
|
27
|
+
PRAGMA busy_timeout = 5000;
|
|
28
|
+
`);
|
|
29
|
+
this.db.exec(`
|
|
30
|
+
CREATE TABLE IF NOT EXISTS nodes (
|
|
31
|
+
id TEXT PRIMARY KEY,
|
|
32
|
+
kind TEXT NOT NULL,
|
|
33
|
+
name TEXT NOT NULL,
|
|
34
|
+
file TEXT NOT NULL,
|
|
35
|
+
qualified_name TEXT NOT NULL,
|
|
36
|
+
start_line INTEGER,
|
|
37
|
+
end_line INTEGER,
|
|
38
|
+
tier TEXT NOT NULL
|
|
39
|
+
);
|
|
40
|
+
CREATE INDEX IF NOT EXISTS nodes_name ON nodes(name);
|
|
41
|
+
CREATE TABLE IF NOT EXISTS edges (
|
|
42
|
+
from_id TEXT NOT NULL,
|
|
43
|
+
to_id TEXT NOT NULL,
|
|
44
|
+
kind TEXT NOT NULL,
|
|
45
|
+
provenance TEXT,
|
|
46
|
+
at_line INTEGER,
|
|
47
|
+
at_column INTEGER,
|
|
48
|
+
at_sites TEXT
|
|
49
|
+
);
|
|
50
|
+
CREATE INDEX IF NOT EXISTS edges_from ON edges(from_id);
|
|
51
|
+
CREATE INDEX IF NOT EXISTS edges_to ON edges(to_id);
|
|
52
|
+
-- (from, to, kind) identifies an edge; the unique index lets INSERT OR
|
|
53
|
+
-- IGNORE collapse the same fact emitted twice into a single row.
|
|
54
|
+
CREATE UNIQUE INDEX IF NOT EXISTS edges_unique ON edges(from_id, to_id, kind);
|
|
55
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(name, id UNINDEXED);
|
|
56
|
+
CREATE TABLE IF NOT EXISTS files (
|
|
57
|
+
path TEXT PRIMARY KEY,
|
|
58
|
+
size INTEGER NOT NULL,
|
|
59
|
+
mtime_ms REAL NOT NULL,
|
|
60
|
+
hash TEXT NOT NULL
|
|
61
|
+
);
|
|
62
|
+
CREATE TABLE IF NOT EXISTS meta (
|
|
63
|
+
key TEXT PRIMARY KEY,
|
|
64
|
+
value TEXT NOT NULL
|
|
65
|
+
);
|
|
66
|
+
`);
|
|
67
|
+
// Additive migrations for DBs created before a column existed — each `ADD
|
|
68
|
+
// COLUMN` throws if present, so guard each independently (ama-m8k.1, ama-hft.9).
|
|
69
|
+
for (const ddl of [
|
|
70
|
+
"ALTER TABLE edges ADD COLUMN provenance TEXT",
|
|
71
|
+
"ALTER TABLE edges ADD COLUMN at_line INTEGER",
|
|
72
|
+
"ALTER TABLE edges ADD COLUMN at_column INTEGER",
|
|
73
|
+
"ALTER TABLE edges ADD COLUMN at_sites TEXT",
|
|
74
|
+
]) {
|
|
75
|
+
try {
|
|
76
|
+
this.db.exec(ddl);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Column already present — nothing to do.
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
addNode(node) {
|
|
84
|
+
this.db
|
|
85
|
+
.prepare(`INSERT OR REPLACE INTO nodes
|
|
86
|
+
(id, kind, name, file, qualified_name, start_line, end_line, tier)
|
|
87
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
88
|
+
.run(node.id, node.kind, node.name, node.file, node.qualifiedName, node.range?.startLine ?? null, node.range?.endLine ?? null, node.tier);
|
|
89
|
+
// Keep the FTS row idempotent too: re-adding an id (a re-indexed file) must
|
|
90
|
+
// not leave a stale duplicate behind, since fts5 has no INSERT OR REPLACE.
|
|
91
|
+
this.db.prepare("DELETE FROM nodes_fts WHERE id = ?").run(node.id);
|
|
92
|
+
this.db.prepare("INSERT INTO nodes_fts (name, id) VALUES (?, ?)").run(node.name, node.id);
|
|
93
|
+
}
|
|
94
|
+
addEdge(edge) {
|
|
95
|
+
// OR IGNORE drops a duplicate (from, to, kind) via the edges_unique index.
|
|
96
|
+
this.db
|
|
97
|
+
.prepare(`INSERT OR IGNORE INTO edges (from_id, to_id, kind, provenance, at_line, at_column, at_sites)
|
|
98
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`)
|
|
99
|
+
.run(edge.from, edge.to, edge.kind, edge.provenance ?? null, edge.at?.line ?? null, edge.at?.column ?? null, edge.sites ? JSON.stringify(edge.sites) : null);
|
|
100
|
+
}
|
|
101
|
+
getNode(id) {
|
|
102
|
+
const row = this.db.prepare("SELECT * FROM nodes WHERE id = ?").get(id);
|
|
103
|
+
return row ? rowToNode(row) : undefined;
|
|
104
|
+
}
|
|
105
|
+
nodesByName(name) {
|
|
106
|
+
return this.db
|
|
107
|
+
.prepare("SELECT * FROM nodes WHERE name = ? ORDER BY rowid")
|
|
108
|
+
.all(name)
|
|
109
|
+
.map((r) => rowToNode(r));
|
|
110
|
+
}
|
|
111
|
+
searchByName(query, limit = 50) {
|
|
112
|
+
// FTS5 query syntax is permissive; restrict to identifier chars and run a
|
|
113
|
+
// prefix match. Names are single tokens, so this matches by leading prefix.
|
|
114
|
+
const term = query.replace(/[^A-Za-z0-9_]/g, " ").trim();
|
|
115
|
+
if (!term)
|
|
116
|
+
return [];
|
|
117
|
+
const seen = new Set();
|
|
118
|
+
const out = [];
|
|
119
|
+
const collect = (rows) => {
|
|
120
|
+
for (const row of rows) {
|
|
121
|
+
if (seen.has(row.id))
|
|
122
|
+
continue;
|
|
123
|
+
seen.add(row.id);
|
|
124
|
+
const node = this.getNode(row.id);
|
|
125
|
+
if (node)
|
|
126
|
+
out.push(node);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
// FTS5 prefix match on the (single-token) name — fast and ranked.
|
|
130
|
+
collect(this.db
|
|
131
|
+
.prepare("SELECT id FROM nodes_fts WHERE nodes_fts MATCH ? ORDER BY rank LIMIT ?")
|
|
132
|
+
.all(`${term}*`, limit));
|
|
133
|
+
// Substring match on the qualified name, so a dotted ref ("Cls.method") and
|
|
134
|
+
// a container name resolve too — the FTS index only holds the simple name.
|
|
135
|
+
if (out.length < limit) {
|
|
136
|
+
collect(this.db
|
|
137
|
+
.prepare("SELECT id FROM nodes WHERE lower(qualified_name) LIKE ? LIMIT ?")
|
|
138
|
+
.all(`%${query.toLowerCase()}%`, limit));
|
|
139
|
+
}
|
|
140
|
+
return out.slice(0, limit);
|
|
141
|
+
}
|
|
142
|
+
edgesFrom(id, kind) {
|
|
143
|
+
const rows = kind
|
|
144
|
+
? this.db
|
|
145
|
+
.prepare("SELECT * FROM edges WHERE from_id = ? AND kind = ? ORDER BY rowid")
|
|
146
|
+
.all(id, kind)
|
|
147
|
+
: this.db.prepare("SELECT * FROM edges WHERE from_id = ? ORDER BY rowid").all(id);
|
|
148
|
+
return rows.map((r) => rowToEdge(r));
|
|
149
|
+
}
|
|
150
|
+
edgesTo(id, kind) {
|
|
151
|
+
const rows = kind
|
|
152
|
+
? this.db
|
|
153
|
+
.prepare("SELECT * FROM edges WHERE to_id = ? AND kind = ? ORDER BY rowid")
|
|
154
|
+
.all(id, kind)
|
|
155
|
+
: this.db.prepare("SELECT * FROM edges WHERE to_id = ? ORDER BY rowid").all(id);
|
|
156
|
+
return rows.map((r) => rowToEdge(r));
|
|
157
|
+
}
|
|
158
|
+
*allNodes() {
|
|
159
|
+
for (const row of this.db.prepare("SELECT * FROM nodes ORDER BY rowid").all()) {
|
|
160
|
+
yield rowToNode(row);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
allEdges() {
|
|
164
|
+
return this.db
|
|
165
|
+
.prepare("SELECT * FROM edges ORDER BY rowid")
|
|
166
|
+
.all()
|
|
167
|
+
.map((r) => rowToEdge(r));
|
|
168
|
+
}
|
|
169
|
+
replaceEdgesByProvenance(provenance, edges) {
|
|
170
|
+
if (provenance === undefined)
|
|
171
|
+
this.db.prepare("DELETE FROM edges WHERE provenance IS NULL").run();
|
|
172
|
+
else
|
|
173
|
+
this.db.prepare("DELETE FROM edges WHERE provenance = ?").run(provenance);
|
|
174
|
+
for (const e of edges)
|
|
175
|
+
this.addEdge(e);
|
|
176
|
+
}
|
|
177
|
+
get nodeCount() {
|
|
178
|
+
return count(this.db, "nodes");
|
|
179
|
+
}
|
|
180
|
+
get edgeCount() {
|
|
181
|
+
return count(this.db, "edges");
|
|
182
|
+
}
|
|
183
|
+
recordFile(meta) {
|
|
184
|
+
this.db
|
|
185
|
+
.prepare(`INSERT OR REPLACE INTO files (path, size, mtime_ms, hash)
|
|
186
|
+
VALUES (?, ?, ?, ?)`)
|
|
187
|
+
.run(meta.path, meta.size, meta.mtimeMs, meta.hash);
|
|
188
|
+
}
|
|
189
|
+
getFile(path) {
|
|
190
|
+
const row = this.db.prepare("SELECT * FROM files WHERE path = ?").get(path);
|
|
191
|
+
return row ? rowToFile(row) : undefined;
|
|
192
|
+
}
|
|
193
|
+
allFiles() {
|
|
194
|
+
return this.db
|
|
195
|
+
.prepare("SELECT * FROM files ORDER BY rowid")
|
|
196
|
+
.all()
|
|
197
|
+
.map((r) => rowToFile(r));
|
|
198
|
+
}
|
|
199
|
+
removeFile(path) {
|
|
200
|
+
// Order matters: the edge/fts deletes reference the file's nodes, so they
|
|
201
|
+
// must run before the nodes themselves are gone. Edges arriving from other
|
|
202
|
+
// files (to_id in this file) are deliberately left in place.
|
|
203
|
+
const owned = "(SELECT id FROM nodes WHERE file = ?)";
|
|
204
|
+
this.db.prepare(`DELETE FROM edges WHERE from_id IN ${owned}`).run(path);
|
|
205
|
+
this.db.prepare(`DELETE FROM nodes_fts WHERE id IN ${owned}`).run(path);
|
|
206
|
+
this.db.prepare("DELETE FROM nodes WHERE file = ?").run(path);
|
|
207
|
+
this.db.prepare("DELETE FROM files WHERE path = ?").run(path);
|
|
208
|
+
}
|
|
209
|
+
reconcileFile(path, nodes, edges) {
|
|
210
|
+
const newIds = new Set(nodes.map((n) => n.id));
|
|
211
|
+
const oldIds = this.db.prepare("SELECT id FROM nodes WHERE file = ?").all(path).map((r) => r.id);
|
|
212
|
+
// 1. Drop symbols that disappeared (and the edges leaving them).
|
|
213
|
+
const delEdgesFrom = this.db.prepare("DELETE FROM edges WHERE from_id = ?");
|
|
214
|
+
const delFts = this.db.prepare("DELETE FROM nodes_fts WHERE id = ?");
|
|
215
|
+
const delNode = this.db.prepare("DELETE FROM nodes WHERE id = ?");
|
|
216
|
+
for (const id of oldIds) {
|
|
217
|
+
if (newIds.has(id))
|
|
218
|
+
continue;
|
|
219
|
+
delEdgesFrom.run(id);
|
|
220
|
+
delFts.run(id);
|
|
221
|
+
delNode.run(id);
|
|
222
|
+
}
|
|
223
|
+
// 2. Upsert the file's current nodes (addNode is idempotent).
|
|
224
|
+
for (const n of nodes)
|
|
225
|
+
this.addNode(n);
|
|
226
|
+
// 3. Reconcile the edges the file owns to exactly `edges`: delete the ones
|
|
227
|
+
// no longer emitted, then add the rest (INSERT OR IGNORE dedupes).
|
|
228
|
+
const fresh = new Set(edges.map(edgeKey));
|
|
229
|
+
const owned = this.db
|
|
230
|
+
.prepare("SELECT from_id, to_id, kind FROM edges WHERE from_id IN (SELECT id FROM nodes WHERE file = ?)")
|
|
231
|
+
.all(path);
|
|
232
|
+
const delEdge = this.db.prepare("DELETE FROM edges WHERE from_id = ? AND to_id = ? AND kind = ?");
|
|
233
|
+
for (const e of owned) {
|
|
234
|
+
if (!fresh.has(edgeKey(rowToEdge(e))))
|
|
235
|
+
delEdge.run(e.from_id, e.to_id, e.kind);
|
|
236
|
+
}
|
|
237
|
+
for (const e of edges)
|
|
238
|
+
this.addEdge(e);
|
|
239
|
+
}
|
|
240
|
+
setMeta(key, value) {
|
|
241
|
+
this.db.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)").run(key, value);
|
|
242
|
+
}
|
|
243
|
+
getMeta(key) {
|
|
244
|
+
const row = this.db.prepare("SELECT value FROM meta WHERE key = ?").get(key);
|
|
245
|
+
return row ? row.value : undefined;
|
|
246
|
+
}
|
|
247
|
+
clear() {
|
|
248
|
+
// Wipe data but keep the schema, so a re-index into a persistent file starts
|
|
249
|
+
// clean without dropping/recreating tables.
|
|
250
|
+
this.db.exec("DELETE FROM edges; DELETE FROM nodes_fts; DELETE FROM nodes; DELETE FROM files; DELETE FROM meta;");
|
|
251
|
+
}
|
|
252
|
+
/** Close the underlying database. Required for file-backed stores. */
|
|
253
|
+
close() {
|
|
254
|
+
this.db.close();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function rowToNode(r) {
|
|
258
|
+
const node = {
|
|
259
|
+
id: r.id,
|
|
260
|
+
kind: r.kind,
|
|
261
|
+
name: r.name,
|
|
262
|
+
file: r.file,
|
|
263
|
+
qualifiedName: r.qualified_name,
|
|
264
|
+
tier: r.tier,
|
|
265
|
+
};
|
|
266
|
+
if (r.start_line !== null && r.end_line !== null) {
|
|
267
|
+
node.range = { startLine: r.start_line, endLine: r.end_line };
|
|
268
|
+
}
|
|
269
|
+
return node;
|
|
270
|
+
}
|
|
271
|
+
function rowToEdge(r) {
|
|
272
|
+
const edge = { from: r.from_id, to: r.to_id, kind: r.kind };
|
|
273
|
+
if (r.provenance)
|
|
274
|
+
edge.provenance = r.provenance;
|
|
275
|
+
if (r.at_line !== null && r.at_column !== null) {
|
|
276
|
+
edge.at = { line: r.at_line, column: r.at_column };
|
|
277
|
+
}
|
|
278
|
+
if (r.at_sites)
|
|
279
|
+
edge.sites = JSON.parse(r.at_sites);
|
|
280
|
+
return edge;
|
|
281
|
+
}
|
|
282
|
+
/** Canonical identity of an edge: its (from, to, kind) triple, as printable JSON. */
|
|
283
|
+
function edgeKey(e) {
|
|
284
|
+
return JSON.stringify([e.from, e.to, e.kind]);
|
|
285
|
+
}
|
|
286
|
+
function rowToFile(r) {
|
|
287
|
+
return {
|
|
288
|
+
path: r.path,
|
|
289
|
+
size: Number(r.size),
|
|
290
|
+
mtimeMs: Number(r.mtime_ms),
|
|
291
|
+
hash: r.hash,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function count(db, table) {
|
|
295
|
+
const row = db.prepare(`SELECT count(*) AS c FROM ${table}`).get();
|
|
296
|
+
return Number(row.c);
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/store/sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { EdgeKind, GraphEdge, GraphNode } from "../graph/index.js";
|
|
2
|
+
/** Per-file fingerprint used to detect staleness for incremental re-indexing. */
|
|
3
|
+
export interface FileMeta {
|
|
4
|
+
/** Repo-relative path. */
|
|
5
|
+
path: string;
|
|
6
|
+
size: number;
|
|
7
|
+
mtimeMs: number;
|
|
8
|
+
/** Content hash — the exact-change signal when size/mtime are inconclusive. */
|
|
9
|
+
hash: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Storage contract shared by every backend (in-memory today, SQLite next).
|
|
13
|
+
* The query and indexer layers depend only on this interface, so swapping the
|
|
14
|
+
* backing store never touches them.
|
|
15
|
+
*/
|
|
16
|
+
export interface Store {
|
|
17
|
+
addNode(node: GraphNode): void;
|
|
18
|
+
addEdge(edge: GraphEdge): void;
|
|
19
|
+
getNode(id: string): GraphNode | undefined;
|
|
20
|
+
/** Nodes whose simple (unqualified) name matches exactly. */
|
|
21
|
+
nodesByName(name: string): GraphNode[];
|
|
22
|
+
/**
|
|
23
|
+
* Symbols whose name matches `query` by prefix (case-insensitive). Backends
|
|
24
|
+
* may match more loosely (the in-memory store does substring), but every
|
|
25
|
+
* backend must at least return names the query is a prefix of.
|
|
26
|
+
*/
|
|
27
|
+
searchByName(query: string, limit?: number): GraphNode[];
|
|
28
|
+
/** Edges leaving `id`, optionally filtered by kind. */
|
|
29
|
+
edgesFrom(id: string, kind?: EdgeKind): GraphEdge[];
|
|
30
|
+
/** Edges arriving at `id`, optionally filtered by kind. */
|
|
31
|
+
edgesTo(id: string, kind?: EdgeKind): GraphEdge[];
|
|
32
|
+
/** Every node — for stats and full scans. */
|
|
33
|
+
allNodes(): IterableIterator<GraphNode>;
|
|
34
|
+
/** Every edge — for whole-graph derivations (e.g. dispatch re-derivation). */
|
|
35
|
+
allEdges(): GraphEdge[];
|
|
36
|
+
/**
|
|
37
|
+
* Replace every edge with the given provenance by `edges` (drop the old, add the
|
|
38
|
+
* new). Used to re-derive a whole-graph edge class — dispatch fan-out / Overrides
|
|
39
|
+
* (provenance "dispatch") — after an incremental reindex, which a single-file
|
|
40
|
+
* analyze can't reproduce on its own. (ama-tr1)
|
|
41
|
+
*/
|
|
42
|
+
replaceEdgesByProvenance(provenance: GraphEdge["provenance"], edges: GraphEdge[]): void;
|
|
43
|
+
readonly nodeCount: number;
|
|
44
|
+
readonly edgeCount: number;
|
|
45
|
+
/** Record (or replace) a file's fingerprint. */
|
|
46
|
+
recordFile(meta: FileMeta): void;
|
|
47
|
+
getFile(path: string): FileMeta | undefined;
|
|
48
|
+
allFiles(): FileMeta[];
|
|
49
|
+
/**
|
|
50
|
+
* Remove everything a file owns: its fingerprint, its nodes, and the edges
|
|
51
|
+
* that originate from those nodes. Edges owned by *other* files are left
|
|
52
|
+
* untouched — so an inbound edge may briefly dangle into a removed node until
|
|
53
|
+
* that other file is itself re-indexed. The reconcile primitive behind
|
|
54
|
+
* single-file re-indexing.
|
|
55
|
+
*/
|
|
56
|
+
removeFile(path: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* Apply a file's freshly-analyzed nodes and edges as a *minimal delta*: upsert
|
|
59
|
+
* its nodes, drop only the symbols that disappeared, and reconcile the edges
|
|
60
|
+
* it owns (those leaving its nodes) to exactly `edges`. Unchanged data and
|
|
61
|
+
* everything owned by other files is left in place, so an edit churns only
|
|
62
|
+
* what actually changed. Handles both creating and editing a file;
|
|
63
|
+
* {@link removeFile} handles deletion.
|
|
64
|
+
*/
|
|
65
|
+
reconcileFile(path: string, nodes: GraphNode[], edges: GraphEdge[]): void;
|
|
66
|
+
/** Persist (or replace) an arbitrary string value, e.g. coverage metadata. */
|
|
67
|
+
setMeta(key: string, value: string): void;
|
|
68
|
+
getMeta(key: string): string | undefined;
|
|
69
|
+
/** Drop everything — nodes, edges, files, and metadata — for a clean rebuild
|
|
70
|
+
* of a store that may already hold a previous index (a persistent backend). */
|
|
71
|
+
clear(): void;
|
|
72
|
+
/** Release any underlying resources (a SQLite connection). A no-op for the
|
|
73
|
+
* in-memory store; call before discarding a store you replaced. */
|
|
74
|
+
close(): void;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAExE,iFAAiF;AACjF,MAAM,WAAW,QAAQ;IACvB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,KAAK;IACpB,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAE/B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IAC3C,6DAA6D;IAC7D,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC;IACvC;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC;IAEzD,uDAAuD;IACvD,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,EAAE,CAAC;IACpD,2DAA2D;IAC3D,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,EAAE,CAAC;IAElD,6CAA6C;IAC7C,QAAQ,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACxC,8EAA8E;IAC9E,QAAQ,IAAI,SAAS,EAAE,CAAC;IAExB;;;;;OAKG;IACH,wBAAwB,CAAC,UAAU,EAAE,SAAS,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAExF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,gDAAgD;IAChD,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACjC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC5C,QAAQ,IAAI,QAAQ,EAAE,CAAC;IAEvB;;;;;;OAMG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/B;;;;;;;OAOG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAE1E,8EAA8E;IAC9E,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAEzC;mFAC+E;IAC/E,KAAK,IAAI,IAAI,CAAC;IAEd;uEACmE;IACnE,KAAK,IAAI,IAAI,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mka-rainmaker/ama",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Local-first code-intelligence MCP server with deep, language-specific semantic parsing.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=24"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"ama": "dist/cli/index.js"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/mka-rainmaker/ama.git"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/mka-rainmaker/ama#readme",
|
|
18
|
+
"bugs": "https://github.com/mka-rainmaker/ama/issues",
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"model-context-protocol",
|
|
22
|
+
"code-intelligence",
|
|
23
|
+
"code-graph",
|
|
24
|
+
"static-analysis",
|
|
25
|
+
"typescript",
|
|
26
|
+
"ai-agents",
|
|
27
|
+
"developer-tools"
|
|
28
|
+
],
|
|
29
|
+
"files": ["dist", "README.md", "LICENSE"],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc",
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"test": "vitest run",
|
|
37
|
+
"test:watch": "vitest",
|
|
38
|
+
"serve": "node dist/mcp/server.js",
|
|
39
|
+
"serve:http": "node dist/mcp/http.js",
|
|
40
|
+
"serve:dev": "AMA_LOG_TOOLS=1 AMA_DB=.ama/index.db AMA_ROOT=. tsx watch src/mcp/http.ts",
|
|
41
|
+
"cli": "tsx src/cli/index.ts",
|
|
42
|
+
"format": "biome format --write .",
|
|
43
|
+
"lint": "biome check .",
|
|
44
|
+
"prepublishOnly": "npm run build && npm test"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@modelcontextprotocol/sdk": "^1.13.0",
|
|
48
|
+
"tree-sitter-wasms": "^0.1.13",
|
|
49
|
+
"typescript": "^5.8.0",
|
|
50
|
+
"web-tree-sitter": "^0.20.8",
|
|
51
|
+
"zod": "^3.24.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@biomejs/biome": "^1.9.0",
|
|
55
|
+
"@types/node": "^24.0.0",
|
|
56
|
+
"tsx": "^4.19.0",
|
|
57
|
+
"vitest": "^3.0.0"
|
|
58
|
+
}
|
|
59
|
+
}
|