@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.
Files changed (211) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +149 -0
  3. package/dist/analyzers/baseline/analyzer.d.ts +47 -0
  4. package/dist/analyzers/baseline/analyzer.d.ts.map +1 -0
  5. package/dist/analyzers/baseline/analyzer.js +84 -0
  6. package/dist/analyzers/baseline/analyzer.js.map +1 -0
  7. package/dist/analyzers/baseline/c.d.ts +12 -0
  8. package/dist/analyzers/baseline/c.d.ts.map +1 -0
  9. package/dist/analyzers/baseline/c.js +56 -0
  10. package/dist/analyzers/baseline/c.js.map +1 -0
  11. package/dist/analyzers/baseline/config.d.ts +21 -0
  12. package/dist/analyzers/baseline/config.d.ts.map +1 -0
  13. package/dist/analyzers/baseline/config.js +32 -0
  14. package/dist/analyzers/baseline/config.js.map +1 -0
  15. package/dist/analyzers/baseline/csharp.d.ts +9 -0
  16. package/dist/analyzers/baseline/csharp.d.ts.map +1 -0
  17. package/dist/analyzers/baseline/csharp.js +107 -0
  18. package/dist/analyzers/baseline/csharp.js.map +1 -0
  19. package/dist/analyzers/baseline/go.d.ts +11 -0
  20. package/dist/analyzers/baseline/go.d.ts.map +1 -0
  21. package/dist/analyzers/baseline/go.js +66 -0
  22. package/dist/analyzers/baseline/go.js.map +1 -0
  23. package/dist/analyzers/baseline/java.d.ts +9 -0
  24. package/dist/analyzers/baseline/java.d.ts.map +1 -0
  25. package/dist/analyzers/baseline/java.js +50 -0
  26. package/dist/analyzers/baseline/java.js.map +1 -0
  27. package/dist/analyzers/baseline/javascript.d.ts +10 -0
  28. package/dist/analyzers/baseline/javascript.d.ts.map +1 -0
  29. package/dist/analyzers/baseline/javascript.js +55 -0
  30. package/dist/analyzers/baseline/javascript.js.map +1 -0
  31. package/dist/analyzers/baseline/kotlin.d.ts +11 -0
  32. package/dist/analyzers/baseline/kotlin.d.ts.map +1 -0
  33. package/dist/analyzers/baseline/kotlin.js +67 -0
  34. package/dist/analyzers/baseline/kotlin.js.map +1 -0
  35. package/dist/analyzers/baseline/paths.d.ts +6 -0
  36. package/dist/analyzers/baseline/paths.d.ts.map +1 -0
  37. package/dist/analyzers/baseline/paths.js +17 -0
  38. package/dist/analyzers/baseline/paths.js.map +1 -0
  39. package/dist/analyzers/baseline/php.d.ts +11 -0
  40. package/dist/analyzers/baseline/php.d.ts.map +1 -0
  41. package/dist/analyzers/baseline/php.js +76 -0
  42. package/dist/analyzers/baseline/php.js.map +1 -0
  43. package/dist/analyzers/baseline/python.d.ts +10 -0
  44. package/dist/analyzers/baseline/python.d.ts.map +1 -0
  45. package/dist/analyzers/baseline/python.js +63 -0
  46. package/dist/analyzers/baseline/python.js.map +1 -0
  47. package/dist/analyzers/baseline/rust.d.ts +10 -0
  48. package/dist/analyzers/baseline/rust.d.ts.map +1 -0
  49. package/dist/analyzers/baseline/rust.js +45 -0
  50. package/dist/analyzers/baseline/rust.js.map +1 -0
  51. package/dist/analyzers/baseline/swift.d.ts +11 -0
  52. package/dist/analyzers/baseline/swift.d.ts.map +1 -0
  53. package/dist/analyzers/baseline/swift.js +19 -0
  54. package/dist/analyzers/baseline/swift.js.map +1 -0
  55. package/dist/analyzers/baseline/treesitter.d.ts +11 -0
  56. package/dist/analyzers/baseline/treesitter.d.ts.map +1 -0
  57. package/dist/analyzers/baseline/treesitter.js +87 -0
  58. package/dist/analyzers/baseline/treesitter.js.map +1 -0
  59. package/dist/analyzers/baseline/walk.d.ts +26 -0
  60. package/dist/analyzers/baseline/walk.d.ts.map +1 -0
  61. package/dist/analyzers/baseline/walk.js +76 -0
  62. package/dist/analyzers/baseline/walk.js.map +1 -0
  63. package/dist/analyzers/registry.d.ts +19 -0
  64. package/dist/analyzers/registry.d.ts.map +1 -0
  65. package/dist/analyzers/registry.js +43 -0
  66. package/dist/analyzers/registry.js.map +1 -0
  67. package/dist/analyzers/sfc/analyzer.d.ts +17 -0
  68. package/dist/analyzers/sfc/analyzer.d.ts.map +1 -0
  69. package/dist/analyzers/sfc/analyzer.js +141 -0
  70. package/dist/analyzers/sfc/analyzer.js.map +1 -0
  71. package/dist/analyzers/sidecar/analyzer.d.ts +29 -0
  72. package/dist/analyzers/sidecar/analyzer.d.ts.map +1 -0
  73. package/dist/analyzers/sidecar/analyzer.js +114 -0
  74. package/dist/analyzers/sidecar/analyzer.js.map +1 -0
  75. package/dist/analyzers/sidecar/protocol.d.ts +508 -0
  76. package/dist/analyzers/sidecar/protocol.d.ts.map +1 -0
  77. package/dist/analyzers/sidecar/protocol.js +102 -0
  78. package/dist/analyzers/sidecar/protocol.js.map +1 -0
  79. package/dist/analyzers/types.d.ts +46 -0
  80. package/dist/analyzers/types.d.ts.map +1 -0
  81. package/dist/analyzers/types.js +2 -0
  82. package/dist/analyzers/types.js.map +1 -0
  83. package/dist/analyzers/typescript/analyzer.d.ts +126 -0
  84. package/dist/analyzers/typescript/analyzer.d.ts.map +1 -0
  85. package/dist/analyzers/typescript/analyzer.js +1600 -0
  86. package/dist/analyzers/typescript/analyzer.js.map +1 -0
  87. package/dist/cli/commands/cycles.d.ts +6 -0
  88. package/dist/cli/commands/cycles.d.ts.map +1 -0
  89. package/dist/cli/commands/cycles.js +27 -0
  90. package/dist/cli/commands/cycles.js.map +1 -0
  91. package/dist/cli/commands/files.d.ts +6 -0
  92. package/dist/cli/commands/files.d.ts.map +1 -0
  93. package/dist/cli/commands/files.js +33 -0
  94. package/dist/cli/commands/files.js.map +1 -0
  95. package/dist/cli/commands/impact.d.ts +18 -0
  96. package/dist/cli/commands/impact.d.ts.map +1 -0
  97. package/dist/cli/commands/impact.js +113 -0
  98. package/dist/cli/commands/impact.js.map +1 -0
  99. package/dist/cli/commands/lifecycle.d.ts +5 -0
  100. package/dist/cli/commands/lifecycle.d.ts.map +1 -0
  101. package/dist/cli/commands/lifecycle.js +83 -0
  102. package/dist/cli/commands/lifecycle.js.map +1 -0
  103. package/dist/cli/commands/query.d.ts +31 -0
  104. package/dist/cli/commands/query.d.ts.map +1 -0
  105. package/dist/cli/commands/query.js +187 -0
  106. package/dist/cli/commands/query.js.map +1 -0
  107. package/dist/cli/commands/search.d.ts +21 -0
  108. package/dist/cli/commands/search.d.ts.map +1 -0
  109. package/dist/cli/commands/search.js +160 -0
  110. package/dist/cli/commands/search.js.map +1 -0
  111. package/dist/cli/commands/status.d.ts +6 -0
  112. package/dist/cli/commands/status.d.ts.map +1 -0
  113. package/dist/cli/commands/status.js +63 -0
  114. package/dist/cli/commands/status.js.map +1 -0
  115. package/dist/cli/commands/sync.d.ts +6 -0
  116. package/dist/cli/commands/sync.d.ts.map +1 -0
  117. package/dist/cli/commands/sync.js +57 -0
  118. package/dist/cli/commands/sync.js.map +1 -0
  119. package/dist/cli/emit.d.ts +9 -0
  120. package/dist/cli/emit.d.ts.map +1 -0
  121. package/dist/cli/emit.js +10 -0
  122. package/dist/cli/emit.js.map +1 -0
  123. package/dist/cli/index.d.ts +37 -0
  124. package/dist/cli/index.d.ts.map +1 -0
  125. package/dist/cli/index.js +128 -0
  126. package/dist/cli/index.js.map +1 -0
  127. package/dist/cli/paths.d.ts +7 -0
  128. package/dist/cli/paths.d.ts.map +1 -0
  129. package/dist/cli/paths.js +10 -0
  130. package/dist/cli/paths.js.map +1 -0
  131. package/dist/cli/query-runner.d.ts +13 -0
  132. package/dist/cli/query-runner.d.ts.map +1 -0
  133. package/dist/cli/query-runner.js +33 -0
  134. package/dist/cli/query-runner.js.map +1 -0
  135. package/dist/graph/dispatch.d.ts +17 -0
  136. package/dist/graph/dispatch.d.ts.map +1 -0
  137. package/dist/graph/dispatch.js +82 -0
  138. package/dist/graph/dispatch.js.map +1 -0
  139. package/dist/graph/id.d.ts +19 -0
  140. package/dist/graph/id.d.ts.map +1 -0
  141. package/dist/graph/id.js +17 -0
  142. package/dist/graph/id.js.map +1 -0
  143. package/dist/graph/index.d.ts +6 -0
  144. package/dist/graph/index.d.ts.map +1 -0
  145. package/dist/graph/index.js +4 -0
  146. package/dist/graph/index.js.map +1 -0
  147. package/dist/graph/types.d.ts +71 -0
  148. package/dist/graph/types.d.ts.map +1 -0
  149. package/dist/graph/types.js +52 -0
  150. package/dist/graph/types.js.map +1 -0
  151. package/dist/indexer/debouncer.d.ts +32 -0
  152. package/dist/indexer/debouncer.d.ts.map +1 -0
  153. package/dist/indexer/debouncer.js +81 -0
  154. package/dist/indexer/debouncer.js.map +1 -0
  155. package/dist/indexer/ignore.d.ts +55 -0
  156. package/dist/indexer/ignore.d.ts.map +1 -0
  157. package/dist/indexer/ignore.js +170 -0
  158. package/dist/indexer/ignore.js.map +1 -0
  159. package/dist/indexer/indexer.d.ts +112 -0
  160. package/dist/indexer/indexer.d.ts.map +1 -0
  161. package/dist/indexer/indexer.js +392 -0
  162. package/dist/indexer/indexer.js.map +1 -0
  163. package/dist/indexer/watcher.d.ts +50 -0
  164. package/dist/indexer/watcher.d.ts.map +1 -0
  165. package/dist/indexer/watcher.js +86 -0
  166. package/dist/indexer/watcher.js.map +1 -0
  167. package/dist/mcp/build-info.d.ts +16 -0
  168. package/dist/mcp/build-info.d.ts.map +1 -0
  169. package/dist/mcp/build-info.js +54 -0
  170. package/dist/mcp/build-info.js.map +1 -0
  171. package/dist/mcp/http.d.ts +18 -0
  172. package/dist/mcp/http.d.ts.map +1 -0
  173. package/dist/mcp/http.js +145 -0
  174. package/dist/mcp/http.js.map +1 -0
  175. package/dist/mcp/server.d.ts +22 -0
  176. package/dist/mcp/server.d.ts.map +1 -0
  177. package/dist/mcp/server.js +401 -0
  178. package/dist/mcp/server.js.map +1 -0
  179. package/dist/mcp/session.d.ts +155 -0
  180. package/dist/mcp/session.d.ts.map +1 -0
  181. package/dist/mcp/session.js +319 -0
  182. package/dist/mcp/session.js.map +1 -0
  183. package/dist/query/service.d.ts +329 -0
  184. package/dist/query/service.d.ts.map +1 -0
  185. package/dist/query/service.js +959 -0
  186. package/dist/query/service.js.map +1 -0
  187. package/dist/runtime/entrypoint.d.ts +11 -0
  188. package/dist/runtime/entrypoint.d.ts.map +1 -0
  189. package/dist/runtime/entrypoint.js +22 -0
  190. package/dist/runtime/entrypoint.js.map +1 -0
  191. package/dist/runtime/quiet-sqlite-warning.d.ts +14 -0
  192. package/dist/runtime/quiet-sqlite-warning.d.ts.map +1 -0
  193. package/dist/runtime/quiet-sqlite-warning.js +26 -0
  194. package/dist/runtime/quiet-sqlite-warning.js.map +1 -0
  195. package/dist/runtime/wasm-tier.d.ts +2 -0
  196. package/dist/runtime/wasm-tier.d.ts.map +1 -0
  197. package/dist/runtime/wasm-tier.js +54 -0
  198. package/dist/runtime/wasm-tier.js.map +1 -0
  199. package/dist/store/memory.d.ts +54 -0
  200. package/dist/store/memory.d.ts.map +1 -0
  201. package/dist/store/memory.js +210 -0
  202. package/dist/store/memory.js.map +1 -0
  203. package/dist/store/sqlite.d.ts +38 -0
  204. package/dist/store/sqlite.d.ts.map +1 -0
  205. package/dist/store/sqlite.js +298 -0
  206. package/dist/store/sqlite.js.map +1 -0
  207. package/dist/store/types.d.ts +76 -0
  208. package/dist/store/types.d.ts.map +1 -0
  209. package/dist/store/types.js +2 -0
  210. package/dist/store/types.js.map +1 -0
  211. 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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -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
+ }