ariadne-mcp 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 +113 -0
- package/dist/graph/db.d.ts +26 -0
- package/dist/graph/db.d.ts.map +1 -0
- package/dist/graph/db.js +84 -0
- package/dist/graph/db.js.map +1 -0
- package/dist/graph/queries.d.ts +41 -0
- package/dist/graph/queries.d.ts.map +1 -0
- package/dist/graph/queries.js +219 -0
- package/dist/graph/queries.js.map +1 -0
- package/dist/graph/schema.d.ts +6 -0
- package/dist/graph/schema.d.ts.map +1 -0
- package/dist/graph/schema.js +48 -0
- package/dist/graph/schema.js.map +1 -0
- package/dist/graph/writer.d.ts +24 -0
- package/dist/graph/writer.d.ts.map +1 -0
- package/dist/graph/writer.js +66 -0
- package/dist/graph/writer.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/detector.d.ts +16 -0
- package/dist/indexer/detector.d.ts.map +1 -0
- package/dist/indexer/detector.js +69 -0
- package/dist/indexer/detector.js.map +1 -0
- package/dist/indexer/index.d.ts +11 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +168 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/languages/base.d.ts +15 -0
- package/dist/indexer/languages/base.d.ts.map +1 -0
- package/dist/indexer/languages/base.js +3 -0
- package/dist/indexer/languages/base.js.map +1 -0
- package/dist/indexer/languages/javascript.d.ts +15 -0
- package/dist/indexer/languages/javascript.d.ts.map +1 -0
- package/dist/indexer/languages/javascript.js +252 -0
- package/dist/indexer/languages/javascript.js.map +1 -0
- package/dist/indexer/languages/python.d.ts +6 -0
- package/dist/indexer/languages/python.d.ts.map +1 -0
- package/dist/indexer/languages/python.js +257 -0
- package/dist/indexer/languages/python.js.map +1 -0
- package/dist/indexer/languages/typescript.d.ts +22 -0
- package/dist/indexer/languages/typescript.d.ts.map +1 -0
- package/dist/indexer/languages/typescript.js +371 -0
- package/dist/indexer/languages/typescript.js.map +1 -0
- package/dist/indexer/parser.d.ts +4 -0
- package/dist/indexer/parser.d.ts.map +1 -0
- package/dist/indexer/parser.js +29 -0
- package/dist/indexer/parser.js.map +1 -0
- package/dist/indexer/scanner.d.ts +3 -0
- package/dist/indexer/scanner.d.ts.map +1 -0
- package/dist/indexer/scanner.js +11 -0
- package/dist/indexer/scanner.js.map +1 -0
- package/dist/indexer/scip-reader.d.ts +34 -0
- package/dist/indexer/scip-reader.d.ts.map +1 -0
- package/dist/indexer/scip-reader.js +261 -0
- package/dist/indexer/scip-reader.js.map +1 -0
- package/dist/indexer/scip-runner.d.ts +27 -0
- package/dist/indexer/scip-runner.d.ts.map +1 -0
- package/dist/indexer/scip-runner.js +130 -0
- package/dist/indexer/scip-runner.js.map +1 -0
- package/dist/indexer/scip.d.ts +695 -0
- package/dist/indexer/scip.d.ts.map +1 -0
- package/dist/indexer/scip.js +1755 -0
- package/dist/indexer/scip.js.map +1 -0
- package/dist/indexer/status.d.ts +25 -0
- package/dist/indexer/status.d.ts.map +1 -0
- package/dist/indexer/status.js +30 -0
- package/dist/indexer/status.js.map +1 -0
- package/dist/indexer/watcher.d.ts +20 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +126 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +74 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/format.d.ts +28 -0
- package/dist/tools/format.d.ts.map +1 -0
- package/dist/tools/format.js +69 -0
- package/dist/tools/format.js.map +1 -0
- package/dist/tools/get-call-path.d.ts +24 -0
- package/dist/tools/get-call-path.d.ts.map +1 -0
- package/dist/tools/get-call-path.js +29 -0
- package/dist/tools/get-call-path.js.map +1 -0
- package/dist/tools/get-callees.d.ts +19 -0
- package/dist/tools/get-callees.d.ts.map +1 -0
- package/dist/tools/get-callees.js +26 -0
- package/dist/tools/get-callees.js.map +1 -0
- package/dist/tools/get-callers.d.ts +19 -0
- package/dist/tools/get-callers.d.ts.map +1 -0
- package/dist/tools/get-callers.js +26 -0
- package/dist/tools/get-callers.js.map +1 -0
- package/dist/tools/get-definition.d.ts +24 -0
- package/dist/tools/get-definition.d.ts.map +1 -0
- package/dist/tools/get-definition.js +38 -0
- package/dist/tools/get-definition.js.map +1 -0
- package/dist/tools/get-file-symbols.d.ts +19 -0
- package/dist/tools/get-file-symbols.d.ts.map +1 -0
- package/dist/tools/get-file-symbols.js +31 -0
- package/dist/tools/get-file-symbols.js.map +1 -0
- package/dist/tools/get-implementations.d.ts +19 -0
- package/dist/tools/get-implementations.d.ts.map +1 -0
- package/dist/tools/get-implementations.js +26 -0
- package/dist/tools/get-implementations.js.map +1 -0
- package/dist/tools/get-index-status.d.ts +11 -0
- package/dist/tools/get-index-status.d.ts.map +1 -0
- package/dist/tools/get-index-status.js +59 -0
- package/dist/tools/get-index-status.js.map +1 -0
- package/dist/tools/get-references.d.ts +19 -0
- package/dist/tools/get-references.d.ts.map +1 -0
- package/dist/tools/get-references.js +26 -0
- package/dist/tools/get-references.js.map +1 -0
- package/dist/tools/get-source-definition.d.ts +24 -0
- package/dist/tools/get-source-definition.d.ts.map +1 -0
- package/dist/tools/get-source-definition.js +42 -0
- package/dist/tools/get-source-definition.js.map +1 -0
- package/dist/tools/get-type-definition.d.ts +19 -0
- package/dist/tools/get-type-definition.d.ts.map +1 -0
- package/dist/tools/get-type-definition.js +27 -0
- package/dist/tools/get-type-definition.js.map +1 -0
- package/dist/tools/index.d.ts +149 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +57 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types/index.d.ts +35 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Madan Gopal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Ariadne
|
|
2
|
+
|
|
3
|
+
**IDE-grade code navigation for AI agents — as an MCP server.**
|
|
4
|
+
|
|
5
|
+
Ariadne indexes your codebase into a local graph and exposes it as [MCP](https://modelcontextprotocol.io) tools, so coding agents like Claude can navigate your code structurally instead of grepping raw text.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
get_definition("processPayment") → payments/service.ts:142
|
|
9
|
+
get_callers("processPayment") → [checkout.controller.ts:88, retry.worker.ts:34]
|
|
10
|
+
get_call_path("checkout", "save") → checkout → processPayment → repository.save
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Why
|
|
14
|
+
|
|
15
|
+
When Claude (or any coding agent) needs to understand a codebase, it typically:
|
|
16
|
+
- Greps for symbol names across thousands of files
|
|
17
|
+
- Reads entire files to find one function
|
|
18
|
+
- Loses the thread across long call chains
|
|
19
|
+
|
|
20
|
+
This burns tokens fast and produces shallow answers. Ariadne gives agents the same navigation primitives an IDE has — go-to-definition, find-references, call hierarchy — but queryable over MCP.
|
|
21
|
+
|
|
22
|
+
**Same question, different approach:**
|
|
23
|
+
|
|
24
|
+
| Without Ariadne | With Ariadne |
|
|
25
|
+
|---|---|
|
|
26
|
+
| Grep 8 files, read 4 in full | 3 tool calls |
|
|
27
|
+
| ~8,000 tokens | ~400 tokens |
|
|
28
|
+
| Guesses at call chains | Exact paths from SCIP index |
|
|
29
|
+
|
|
30
|
+
## Setup
|
|
31
|
+
|
|
32
|
+
Add this to your MCP config (Claude Desktop, Cursor, or any MCP-compatible editor) — once, and never touch it again:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"mcpServers": {
|
|
37
|
+
"ariadne": {
|
|
38
|
+
"command": "npx",
|
|
39
|
+
"args": ["-y", "ariadne"]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
That's it. Ariadne is spawned as a subprocess and inherits the editor's working directory (your project root). No flags, no paths, no configuration.
|
|
46
|
+
|
|
47
|
+
## What happens on first run
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
→ Detecting languages... found TypeScript
|
|
51
|
+
→ Reusing existing TypeScript SCIP index (< 24 h old).
|
|
52
|
+
→ Loading TypeScript/JavaScript index...
|
|
53
|
+
→ Graph ready: 148,363 symbols, 364,387 edges
|
|
54
|
+
→ Ariadne ready.
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- **First startup**: runs `scip-typescript` or `scip-python` to build a full semantic index (5–10 min for large repos, auto-installed via npx/pip)
|
|
58
|
+
- **Subsequent startups**: reuses the cached `.scip` file if < 24h old — loads in ~10s
|
|
59
|
+
- **File saves**: tree-sitter patches the graph incrementally within ~150ms
|
|
60
|
+
|
|
61
|
+
## MCP Tools
|
|
62
|
+
|
|
63
|
+
| Tool | Description |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `get_definition` | Where is this symbol defined? File, line, signature |
|
|
66
|
+
| `get_source_definition` | Same, but skips barrel/re-export files |
|
|
67
|
+
| `get_callers` | Every call site that invokes this symbol |
|
|
68
|
+
| `get_callees` | Every symbol this function calls |
|
|
69
|
+
| `get_call_path` | Shortest call chain between two symbols |
|
|
70
|
+
| `get_references` | Every usage across the repo |
|
|
71
|
+
| `get_implementations` | All classes implementing this interface |
|
|
72
|
+
| `get_type_definition` | Where the type of this symbol is defined |
|
|
73
|
+
| `get_file_symbols` | Full symbol map of a file |
|
|
74
|
+
| `get_index_status` | Current indexing state — check this if tools return empty results |
|
|
75
|
+
|
|
76
|
+
## Supported Languages
|
|
77
|
+
|
|
78
|
+
| Language | Full index (SCIP) | Incremental (tree-sitter) |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| TypeScript / TSX | ✅ | ✅ |
|
|
81
|
+
| JavaScript / JSX | ✅ | ✅ |
|
|
82
|
+
| Python | ✅ | ✅ |
|
|
83
|
+
|
|
84
|
+
## How it works
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
npx ariadne
|
|
88
|
+
→ process.cwd() repo root (inherited from editor)
|
|
89
|
+
→ scip-typescript / scip-python full semantic index → .ariadne/index.scip
|
|
90
|
+
→ loadScipIndex() symbols + edges → .ariadne/graph.db (SQLite)
|
|
91
|
+
→ chokidar watcher incremental tree-sitter patches on file save
|
|
92
|
+
→ MCP stdio transport ready for tool calls
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- **SCIP** ([Semantic Code Intelligence Protocol](https://github.com/sourcegraph/scip)) produces cross-file symbol resolution — something tree-sitter alone can't do
|
|
96
|
+
- **SQLite** (via `better-sqlite3`) stores the graph — fast point lookups, no server required
|
|
97
|
+
- **tree-sitter** patches individual files on save between SCIP runs
|
|
98
|
+
|
|
99
|
+
Graph lives at `<repo>/.ariadne/graph.db` — add `.ariadne/` to your `.gitignore`.
|
|
100
|
+
|
|
101
|
+
## Requirements
|
|
102
|
+
|
|
103
|
+
- Node.js 20+
|
|
104
|
+
- For TypeScript/JavaScript indexing: nothing extra (scip-typescript installed via npx)
|
|
105
|
+
- For Python indexing: Python 3.8+ with pip (scip-python installed via pip)
|
|
106
|
+
|
|
107
|
+
## Contributing
|
|
108
|
+
|
|
109
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
110
|
+
|
|
111
|
+
## License
|
|
112
|
+
|
|
113
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
export type { Database };
|
|
3
|
+
/**
|
|
4
|
+
* Open (or create) the graph database at <repoRoot>/.ariadne/graph.db.
|
|
5
|
+
* Applies WAL mode, safety PRAGMAs, and runs all schema statements.
|
|
6
|
+
* Safe to call multiple times — subsequent calls are no-ops.
|
|
7
|
+
*/
|
|
8
|
+
export declare function init(repoRoot: string): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Returns the active SQLite database.
|
|
11
|
+
* Throws if init() has not been called yet.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getDb(): Database.Database;
|
|
14
|
+
/**
|
|
15
|
+
* Close the database synchronously.
|
|
16
|
+
*/
|
|
17
|
+
export declare function close(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Close the DB, delete all related files (graph.db, WAL, SHM), then reopen
|
|
20
|
+
* a fresh empty database. Used before a full re-index so stale data from a
|
|
21
|
+
* prior partial load doesn't persist.
|
|
22
|
+
*
|
|
23
|
+
* SQLite WAL files are named graph.db-wal and graph.db-shm (unlike DuckDB).
|
|
24
|
+
*/
|
|
25
|
+
export declare function wipAndReinit(repoRoot: string): Promise<void>;
|
|
26
|
+
//# sourceMappingURL=db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/graph/db.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAKtC,YAAY,EAAE,QAAQ,EAAE,CAAC;AAIzB;;;;GAIG;AACH,wBAAsB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8B1D;AAED;;;GAGG;AACH,wBAAgB,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAGzC;AAED;;GAEG;AACH,wBAAgB,KAAK,IAAI,IAAI,CAI5B;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAalE"}
|
package/dist/graph/db.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.init = init;
|
|
7
|
+
exports.getDb = getDb;
|
|
8
|
+
exports.close = close;
|
|
9
|
+
exports.wipAndReinit = wipAndReinit;
|
|
10
|
+
// Singleton better-sqlite3 connection for the lifetime of the process.
|
|
11
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
12
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
13
|
+
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
14
|
+
const schema_js_1 = require("./schema.js");
|
|
15
|
+
let _db = null;
|
|
16
|
+
/**
|
|
17
|
+
* Open (or create) the graph database at <repoRoot>/.ariadne/graph.db.
|
|
18
|
+
* Applies WAL mode, safety PRAGMAs, and runs all schema statements.
|
|
19
|
+
* Safe to call multiple times — subsequent calls are no-ops.
|
|
20
|
+
*/
|
|
21
|
+
async function init(repoRoot) {
|
|
22
|
+
if (_db)
|
|
23
|
+
return;
|
|
24
|
+
const ariadneDir = node_path_1.default.join(repoRoot, ".ariadne");
|
|
25
|
+
await promises_1.default.mkdir(ariadneDir, { recursive: true });
|
|
26
|
+
const dbPath = node_path_1.default.join(ariadneDir, "graph.db");
|
|
27
|
+
const db = new better_sqlite3_1.default(dbPath);
|
|
28
|
+
// WAL mode: multiple concurrent readers never block each other, and readers
|
|
29
|
+
// don't block the writer. Auto-recovers the WAL on open after a crash —
|
|
30
|
+
// no manual CHECKPOINT required unlike DuckDB.
|
|
31
|
+
db.pragma("journal_mode = WAL");
|
|
32
|
+
// NORMAL: safe on crash (no corruption), only risks losing the last partial
|
|
33
|
+
// uncommitted transaction — acceptable for an index that can be rebuilt.
|
|
34
|
+
db.pragma("synchronous = NORMAL");
|
|
35
|
+
// Wait up to 5 s before throwing SQLITE_BUSY instead of failing immediately.
|
|
36
|
+
db.pragma("busy_timeout = 5000");
|
|
37
|
+
// 64 MB page cache in memory.
|
|
38
|
+
db.pragma("cache_size = -64000");
|
|
39
|
+
// Keep temp tables in memory.
|
|
40
|
+
db.pragma("temp_store = MEMORY");
|
|
41
|
+
// 256 MB memory-mapped I/O for faster reads on large DBs.
|
|
42
|
+
db.pragma("mmap_size = 268435456");
|
|
43
|
+
for (const sql of schema_js_1.ALL_SCHEMA_STATEMENTS) {
|
|
44
|
+
db.exec(sql);
|
|
45
|
+
}
|
|
46
|
+
_db = db;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Returns the active SQLite database.
|
|
50
|
+
* Throws if init() has not been called yet.
|
|
51
|
+
*/
|
|
52
|
+
function getDb() {
|
|
53
|
+
if (!_db)
|
|
54
|
+
throw new Error("DB not initialised — call init() first");
|
|
55
|
+
return _db;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Close the database synchronously.
|
|
59
|
+
*/
|
|
60
|
+
function close() {
|
|
61
|
+
if (!_db)
|
|
62
|
+
return;
|
|
63
|
+
_db.close();
|
|
64
|
+
_db = null;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Close the DB, delete all related files (graph.db, WAL, SHM), then reopen
|
|
68
|
+
* a fresh empty database. Used before a full re-index so stale data from a
|
|
69
|
+
* prior partial load doesn't persist.
|
|
70
|
+
*
|
|
71
|
+
* SQLite WAL files are named graph.db-wal and graph.db-shm (unlike DuckDB).
|
|
72
|
+
*/
|
|
73
|
+
async function wipAndReinit(repoRoot) {
|
|
74
|
+
const ariadneDir = node_path_1.default.join(repoRoot, ".ariadne");
|
|
75
|
+
const dbPath = node_path_1.default.join(ariadneDir, "graph.db");
|
|
76
|
+
close();
|
|
77
|
+
await Promise.all([
|
|
78
|
+
promises_1.default.rm(dbPath, { force: true }),
|
|
79
|
+
promises_1.default.rm(dbPath + "-wal", { force: true }),
|
|
80
|
+
promises_1.default.rm(dbPath + "-shm", { force: true }),
|
|
81
|
+
]);
|
|
82
|
+
await init(repoRoot);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/graph/db.ts"],"names":[],"mappings":";;;;;AAiBA,oBA8BC;AAMD,sBAGC;AAKD,sBAIC;AASD,oCAaC;AAvFD,uEAAuE;AACvE,gEAAkC;AAClC,0DAA6B;AAC7B,oEAAsC;AACtC,2CAAoD;AAMpD,IAAI,GAAG,GAA6B,IAAI,CAAC;AAEzC;;;;GAIG;AACI,KAAK,UAAU,IAAI,CAAC,QAAgB;IACzC,IAAI,GAAG;QAAE,OAAO;IAEhB,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACnD,MAAM,kBAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhD,MAAM,MAAM,GAAG,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACjD,MAAM,EAAE,GAAG,IAAI,wBAAQ,CAAC,MAAM,CAAC,CAAC;IAEhC,4EAA4E;IAC5E,yEAAyE;IACzE,+CAA+C;IAC/C,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,4EAA4E;IAC5E,yEAAyE;IACzE,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAClC,6EAA6E;IAC7E,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACjC,8BAA8B;IAC9B,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACjC,8BAA8B;IAC9B,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACjC,0DAA0D;IAC1D,EAAE,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAEnC,KAAK,MAAM,GAAG,IAAI,iCAAqB,EAAE,CAAC;QACxC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IAED,GAAG,GAAG,EAAE,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,SAAgB,KAAK;IACnB,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IACpE,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,SAAgB,KAAK;IACnB,IAAI,CAAC,GAAG;QAAE,OAAO;IACjB,GAAG,CAAC,KAAK,EAAE,CAAC;IACZ,GAAG,GAAG,IAAI,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAEjD,KAAK,EAAE,CAAC;IAER,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,kBAAE,CAAC,EAAE,CAAC,MAAM,EAAa,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzC,kBAAE,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,EAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzC,kBAAE,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,EAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;KAC1C,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Database } from "./db.js";
|
|
2
|
+
import type { Symbol, DefinitionResult, CallSite, CallPath } from "../types/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Find where a symbol is defined.
|
|
5
|
+
* If `file` is provided, restricts the search to that file.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getDefinition(db: Database.Database, name: string, file?: string): Promise<DefinitionResult | null>;
|
|
8
|
+
/**
|
|
9
|
+
* Find all call sites that invoke symbols matching `symbolName`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getCallers(db: Database.Database, symbolName: string): Promise<CallSite[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Find all symbols called by symbols matching `symbolName`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getCallees(db: Database.Database, symbolName: string): Promise<Symbol[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Find all edges pointing at symbols matching `symbolName`, any edge kind.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getReferences(db: Database.Database, symbolName: string): Promise<CallSite[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Find all symbols that implement the given interface/base class.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getImplementations(db: Database.Database, symbolName: string): Promise<DefinitionResult[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Return all symbols defined in a given file, ordered by line number.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getFileSymbols(db: Database.Database, filePath: string): Promise<Symbol[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Best-effort: find the type/interface a symbol references.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getTypeDefinition(db: Database.Database, symbolName: string): Promise<DefinitionResult[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Like getDefinition but skips barrel/index files.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getSourceDefinition(db: Database.Database, name: string, file?: string): Promise<DefinitionResult | null>;
|
|
36
|
+
/**
|
|
37
|
+
* BFS over 'calls' edges to find the shortest call chain between two symbols.
|
|
38
|
+
* Loads all calls edges into an in-process Map once, then runs BFS.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getCallPath(db: Database.Database, fromName: string, toName: string): Promise<CallPath | null>;
|
|
41
|
+
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/graph/queries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,EAAQ,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAsB5F;;;GAGG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CASlC;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAgBrB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC,CAcnB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAerB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAW7B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,EAAE,CAAC,CAMnB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAiB7B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAgBlC;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CA8E1B"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefinition = getDefinition;
|
|
4
|
+
exports.getCallers = getCallers;
|
|
5
|
+
exports.getCallees = getCallees;
|
|
6
|
+
exports.getReferences = getReferences;
|
|
7
|
+
exports.getImplementations = getImplementations;
|
|
8
|
+
exports.getFileSymbols = getFileSymbols;
|
|
9
|
+
exports.getTypeDefinition = getTypeDefinition;
|
|
10
|
+
exports.getSourceDefinition = getSourceDefinition;
|
|
11
|
+
exports.getCallPath = getCallPath;
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Internal helpers
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
function rowToSymbol(row) {
|
|
16
|
+
return {
|
|
17
|
+
id: row["id"],
|
|
18
|
+
name: row["name"],
|
|
19
|
+
kind: row["kind"],
|
|
20
|
+
file: row["file"],
|
|
21
|
+
line: row["line"],
|
|
22
|
+
signature: row["signature"] ?? undefined,
|
|
23
|
+
docstring: row["docstring"] ?? undefined,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Queries
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Find where a symbol is defined.
|
|
31
|
+
* If `file` is provided, restricts the search to that file.
|
|
32
|
+
*/
|
|
33
|
+
async function getDefinition(db, name, file) {
|
|
34
|
+
const row = file
|
|
35
|
+
? db.prepare(`SELECT * FROM symbols WHERE name = $name AND file = $file LIMIT 1`)
|
|
36
|
+
.get({ name, file })
|
|
37
|
+
: db.prepare(`SELECT * FROM symbols WHERE name = $name LIMIT 1`)
|
|
38
|
+
.get({ name });
|
|
39
|
+
if (!row)
|
|
40
|
+
return null;
|
|
41
|
+
return { symbol: rowToSymbol(row) };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Find all call sites that invoke symbols matching `symbolName`.
|
|
45
|
+
*/
|
|
46
|
+
async function getCallers(db, symbolName) {
|
|
47
|
+
const rows = db.prepare(`
|
|
48
|
+
SELECT
|
|
49
|
+
s.id, s.name, s.kind, s.file, s.line, s.signature, s.docstring,
|
|
50
|
+
e.line AS call_line
|
|
51
|
+
FROM edges e
|
|
52
|
+
JOIN symbols s ON s.id = e.from_symbol
|
|
53
|
+
WHERE e.to_symbol IN (SELECT id FROM symbols WHERE name = $name)
|
|
54
|
+
AND e.kind = 'calls'
|
|
55
|
+
ORDER BY s.file, e.line
|
|
56
|
+
`).all({ name: symbolName });
|
|
57
|
+
return rows.map((row) => ({
|
|
58
|
+
caller: rowToSymbol(row),
|
|
59
|
+
line: row["call_line"] ?? row["line"],
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Find all symbols called by symbols matching `symbolName`.
|
|
64
|
+
*/
|
|
65
|
+
async function getCallees(db, symbolName) {
|
|
66
|
+
const rows = db.prepare(`
|
|
67
|
+
SELECT DISTINCT s.id, s.name, s.kind, s.file, s.line, s.signature, s.docstring
|
|
68
|
+
FROM edges e
|
|
69
|
+
JOIN symbols s ON s.id = e.to_symbol
|
|
70
|
+
WHERE e.from_symbol IN (SELECT id FROM symbols WHERE name = $name)
|
|
71
|
+
AND e.kind = 'calls'
|
|
72
|
+
AND s.name NOT LIKE '%<get>%'
|
|
73
|
+
AND s.name NOT LIKE '%<set>%'
|
|
74
|
+
AND NOT (s.name LIKE '<%' AND s.name LIKE '%>')
|
|
75
|
+
ORDER BY s.name
|
|
76
|
+
`).all({ name: symbolName });
|
|
77
|
+
return rows.map(rowToSymbol);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Find all edges pointing at symbols matching `symbolName`, any edge kind.
|
|
81
|
+
*/
|
|
82
|
+
async function getReferences(db, symbolName) {
|
|
83
|
+
const rows = db.prepare(`
|
|
84
|
+
SELECT
|
|
85
|
+
s.id, s.name, s.kind, s.file, s.line, s.signature, s.docstring,
|
|
86
|
+
e.line AS ref_line
|
|
87
|
+
FROM edges e
|
|
88
|
+
JOIN symbols s ON s.id = e.from_symbol
|
|
89
|
+
WHERE e.to_symbol IN (SELECT id FROM symbols WHERE name = $name)
|
|
90
|
+
ORDER BY s.file, e.line
|
|
91
|
+
`).all({ name: symbolName });
|
|
92
|
+
return rows.map((row) => ({
|
|
93
|
+
caller: rowToSymbol(row),
|
|
94
|
+
line: row["ref_line"] ?? row["line"],
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Find all symbols that implement the given interface/base class.
|
|
99
|
+
*/
|
|
100
|
+
async function getImplementations(db, symbolName) {
|
|
101
|
+
const rows = db.prepare(`
|
|
102
|
+
SELECT DISTINCT s.id, s.name, s.kind, s.file, s.line, s.signature, s.docstring
|
|
103
|
+
FROM edges e
|
|
104
|
+
JOIN symbols s ON s.id = e.from_symbol
|
|
105
|
+
WHERE e.to_symbol IN (SELECT id FROM symbols WHERE name = $name)
|
|
106
|
+
AND e.kind = 'implements'
|
|
107
|
+
ORDER BY s.file, s.line
|
|
108
|
+
`).all({ name: symbolName });
|
|
109
|
+
return rows.map((row) => ({ symbol: rowToSymbol(row) }));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Return all symbols defined in a given file, ordered by line number.
|
|
113
|
+
*/
|
|
114
|
+
async function getFileSymbols(db, filePath) {
|
|
115
|
+
const rows = db.prepare(`SELECT * FROM symbols WHERE file = $file ORDER BY line`).all({ file: filePath });
|
|
116
|
+
return rows.map(rowToSymbol);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Best-effort: find the type/interface a symbol references.
|
|
120
|
+
*/
|
|
121
|
+
async function getTypeDefinition(db, symbolName) {
|
|
122
|
+
const rows = db.prepare(`
|
|
123
|
+
SELECT DISTINCT s.id, s.name, s.kind, s.file, s.line, s.signature, s.docstring
|
|
124
|
+
FROM edges e
|
|
125
|
+
JOIN symbols s ON s.id = e.to_symbol
|
|
126
|
+
WHERE e.from_symbol IN (SELECT id FROM symbols WHERE name = $name)
|
|
127
|
+
AND e.kind = 'references'
|
|
128
|
+
AND (
|
|
129
|
+
s.signature LIKE '%interface %'
|
|
130
|
+
OR s.signature LIKE '%type %'
|
|
131
|
+
OR s.kind = 'class'
|
|
132
|
+
)
|
|
133
|
+
ORDER BY s.file, s.line
|
|
134
|
+
LIMIT 20
|
|
135
|
+
`).all({ name: symbolName });
|
|
136
|
+
return rows.map((row) => ({ symbol: rowToSymbol(row) }));
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Like getDefinition but skips barrel/index files.
|
|
140
|
+
*/
|
|
141
|
+
async function getSourceDefinition(db, name, file) {
|
|
142
|
+
const base = `
|
|
143
|
+
SELECT * FROM symbols
|
|
144
|
+
WHERE name = $name
|
|
145
|
+
AND file NOT LIKE '%/index.ts'
|
|
146
|
+
AND file NOT LIKE '%/index.js'
|
|
147
|
+
AND file NOT LIKE '%/index.mts'
|
|
148
|
+
AND file NOT LIKE '%/index.mjs'
|
|
149
|
+
`;
|
|
150
|
+
const row = file
|
|
151
|
+
? db.prepare(base + ` AND file = $file LIMIT 1`).get({ name, file })
|
|
152
|
+
: db.prepare(base + ` LIMIT 1`).get({ name });
|
|
153
|
+
if (!row)
|
|
154
|
+
return null;
|
|
155
|
+
return { symbol: rowToSymbol(row) };
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* BFS over 'calls' edges to find the shortest call chain between two symbols.
|
|
159
|
+
* Loads all calls edges into an in-process Map once, then runs BFS.
|
|
160
|
+
*/
|
|
161
|
+
async function getCallPath(db, fromName, toName) {
|
|
162
|
+
const MAX_DEPTH = 12;
|
|
163
|
+
// ── Load all calls edges into adjacency list ──────────────────────────────
|
|
164
|
+
const edgeRows = db.prepare(`SELECT from_symbol, to_symbol, line FROM edges WHERE kind = 'calls'`).all();
|
|
165
|
+
const adj = new Map();
|
|
166
|
+
for (const row of edgeRows) {
|
|
167
|
+
let bucket = adj.get(row.from_symbol);
|
|
168
|
+
if (!bucket) {
|
|
169
|
+
bucket = [];
|
|
170
|
+
adj.set(row.from_symbol, bucket);
|
|
171
|
+
}
|
|
172
|
+
bucket.push({ to: row.to_symbol, line: row.line ?? undefined });
|
|
173
|
+
}
|
|
174
|
+
// ── Resolve start/end symbol IDs ─────────────────────────────────────────
|
|
175
|
+
const startIds = db.prepare(`SELECT id FROM symbols WHERE name = $name`).all({ name: fromName }).map((r) => r.id);
|
|
176
|
+
if (startIds.length === 0)
|
|
177
|
+
return null;
|
|
178
|
+
const endIds = new Set(db.prepare(`SELECT id FROM symbols WHERE name = $name`).all({ name: toName })
|
|
179
|
+
.map((r) => r.id));
|
|
180
|
+
if (endIds.size === 0)
|
|
181
|
+
return null;
|
|
182
|
+
const visited = new Set(startIds);
|
|
183
|
+
const queue = startIds.map((id) => ({ id, symbolPath: [id], edgePath: [] }));
|
|
184
|
+
let foundPath = null;
|
|
185
|
+
bfs: while (queue.length > 0) {
|
|
186
|
+
const item = queue.shift();
|
|
187
|
+
if (endIds.has(item.id)) {
|
|
188
|
+
foundPath = { symbolIds: item.symbolPath, edges: item.edgePath };
|
|
189
|
+
break bfs;
|
|
190
|
+
}
|
|
191
|
+
if (item.symbolPath.length >= MAX_DEPTH)
|
|
192
|
+
continue;
|
|
193
|
+
for (const next of adj.get(item.id) ?? []) {
|
|
194
|
+
if (!visited.has(next.to)) {
|
|
195
|
+
visited.add(next.to);
|
|
196
|
+
queue.push({
|
|
197
|
+
id: next.to,
|
|
198
|
+
symbolPath: [...item.symbolPath, next.to],
|
|
199
|
+
edgePath: [
|
|
200
|
+
...item.edgePath,
|
|
201
|
+
{ from: item.id, to: next.to, kind: "calls", line: next.line },
|
|
202
|
+
],
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (!foundPath)
|
|
208
|
+
return null;
|
|
209
|
+
// ── Resolve symbol IDs → Symbol objects ──────────────────────────────────
|
|
210
|
+
const ids = foundPath.symbolIds;
|
|
211
|
+
const placeholders = ids.map((_, i) => `$id${i}`).join(", ");
|
|
212
|
+
const idParams = {};
|
|
213
|
+
ids.forEach((id, i) => { idParams[`id${i}`] = id; });
|
|
214
|
+
const symRows = db.prepare(`SELECT * FROM symbols WHERE id IN (${placeholders})`).all(idParams);
|
|
215
|
+
const symMap = new Map(symRows.map((row) => [row["id"], rowToSymbol(row)]));
|
|
216
|
+
const symbols = ids.map((id) => symMap.get(id)).filter((s) => s !== undefined);
|
|
217
|
+
return { symbols, edges: foundPath.edges };
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/graph/queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const CREATE_SYMBOLS_TABLE = "\nCREATE TABLE IF NOT EXISTS symbols (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n file TEXT NOT NULL,\n line INTEGER NOT NULL,\n signature TEXT,\n docstring TEXT\n) WITHOUT ROWID";
|
|
2
|
+
export declare const CREATE_EDGES_TABLE = "\nCREATE TABLE IF NOT EXISTS edges (\n from_symbol TEXT NOT NULL,\n to_symbol TEXT NOT NULL,\n kind TEXT NOT NULL,\n line INTEGER,\n PRIMARY KEY (from_symbol, to_symbol, kind)\n)";
|
|
3
|
+
export declare const CREATE_META_TABLE = "\nCREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n) WITHOUT ROWID";
|
|
4
|
+
export declare const INDEX_STATEMENTS: string[];
|
|
5
|
+
export declare const ALL_SCHEMA_STATEMENTS: string[];
|
|
6
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/graph/schema.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,oBAAoB,mPASjB,CAAC;AAIjB,eAAO,MAAM,kBAAkB,4MAO7B,CAAC;AAEH,eAAO,MAAM,iBAAiB,2GAId,CAAC;AAIjB,eAAO,MAAM,gBAAgB,UAK5B,CAAC;AAEF,eAAO,MAAM,qBAAqB,UAKjC,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// SQLite DDL for the ariadne graph store.
|
|
3
|
+
// All table creation is idempotent (CREATE TABLE IF NOT EXISTS).
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.ALL_SCHEMA_STATEMENTS = exports.INDEX_STATEMENTS = exports.CREATE_META_TABLE = exports.CREATE_EDGES_TABLE = exports.CREATE_SYMBOLS_TABLE = void 0;
|
|
6
|
+
// WITHOUT ROWID: stores rows in a B-tree keyed directly by the TEXT primary
|
|
7
|
+
// key, eliminating the secondary index lookup rowid→row. ~2× faster on PK
|
|
8
|
+
// lookups and ~50% smaller on disk for TEXT-heavy rows like SCIP symbol IDs.
|
|
9
|
+
exports.CREATE_SYMBOLS_TABLE = `
|
|
10
|
+
CREATE TABLE IF NOT EXISTS symbols (
|
|
11
|
+
id TEXT PRIMARY KEY,
|
|
12
|
+
name TEXT NOT NULL,
|
|
13
|
+
kind TEXT NOT NULL,
|
|
14
|
+
file TEXT NOT NULL,
|
|
15
|
+
line INTEGER NOT NULL,
|
|
16
|
+
signature TEXT,
|
|
17
|
+
docstring TEXT
|
|
18
|
+
) WITHOUT ROWID`;
|
|
19
|
+
// Edges use a composite PRIMARY KEY for deduplication.
|
|
20
|
+
// No separate id column — the (from, to, kind) triple is the natural key.
|
|
21
|
+
exports.CREATE_EDGES_TABLE = `
|
|
22
|
+
CREATE TABLE IF NOT EXISTS edges (
|
|
23
|
+
from_symbol TEXT NOT NULL,
|
|
24
|
+
to_symbol TEXT NOT NULL,
|
|
25
|
+
kind TEXT NOT NULL,
|
|
26
|
+
line INTEGER,
|
|
27
|
+
PRIMARY KEY (from_symbol, to_symbol, kind)
|
|
28
|
+
)`;
|
|
29
|
+
exports.CREATE_META_TABLE = `
|
|
30
|
+
CREATE TABLE IF NOT EXISTS meta (
|
|
31
|
+
key TEXT PRIMARY KEY,
|
|
32
|
+
value TEXT NOT NULL
|
|
33
|
+
) WITHOUT ROWID`;
|
|
34
|
+
// Extra indexes — PRIMARY KEY already covers from_symbol on edges;
|
|
35
|
+
// add to_symbol and kind for reverse lookups and kind filters.
|
|
36
|
+
exports.INDEX_STATEMENTS = [
|
|
37
|
+
`CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name)`,
|
|
38
|
+
`CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file)`,
|
|
39
|
+
`CREATE INDEX IF NOT EXISTS idx_edges_to ON edges(to_symbol)`,
|
|
40
|
+
`CREATE INDEX IF NOT EXISTS idx_edges_kind ON edges(kind)`,
|
|
41
|
+
];
|
|
42
|
+
exports.ALL_SCHEMA_STATEMENTS = [
|
|
43
|
+
exports.CREATE_SYMBOLS_TABLE,
|
|
44
|
+
exports.CREATE_EDGES_TABLE,
|
|
45
|
+
exports.CREATE_META_TABLE,
|
|
46
|
+
...exports.INDEX_STATEMENTS,
|
|
47
|
+
];
|
|
48
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/graph/schema.ts"],"names":[],"mappings":";AAAA,0CAA0C;AAC1C,iEAAiE;;;AAEjE,4EAA4E;AAC5E,2EAA2E;AAC3E,6EAA6E;AAChE,QAAA,oBAAoB,GAAG;;;;;;;;;gBASpB,CAAC;AAEjB,uDAAuD;AACvD,0EAA0E;AAC7D,QAAA,kBAAkB,GAAG;;;;;;;EAOhC,CAAC;AAEU,QAAA,iBAAiB,GAAG;;;;gBAIjB,CAAC;AAEjB,mEAAmE;AACnE,+DAA+D;AAClD,QAAA,gBAAgB,GAAG;IAC9B,8DAA8D;IAC9D,8DAA8D;IAC9D,iEAAiE;IACjE,4DAA4D;CAC7D,CAAC;AAEW,QAAA,qBAAqB,GAAG;IACnC,4BAAoB;IACpB,0BAAkB;IAClB,yBAAiB;IACjB,GAAG,wBAAgB;CACpB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Database } from "./db.js";
|
|
2
|
+
import type { Symbol, Edge } from "../types/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Insert or replace a symbol. Uses the SCIP symbol string as the primary key
|
|
5
|
+
* so re-indexing the same file is idempotent.
|
|
6
|
+
*/
|
|
7
|
+
export declare function upsertSymbol(db: Database.Database, symbol: Symbol): void;
|
|
8
|
+
/**
|
|
9
|
+
* Insert an edge if it doesn't already exist.
|
|
10
|
+
* The composite PK (from_symbol, to_symbol, kind) enforces uniqueness.
|
|
11
|
+
*/
|
|
12
|
+
export declare function upsertEdge(db: Database.Database, edge: Edge): void;
|
|
13
|
+
/**
|
|
14
|
+
* Remove all symbols (and their edges) for a given file.
|
|
15
|
+
* Called before re-parsing a changed file so stale data doesn't accumulate.
|
|
16
|
+
*/
|
|
17
|
+
export declare function deleteSymbolsByFile(db: Database.Database, file: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Wipe the entire graph. Prefer wipAndReinit() from db.ts for full re-index
|
|
20
|
+
* (file deletion is faster and avoids any MVCC overhead).
|
|
21
|
+
* This function is kept for use in tests and small-scale resets.
|
|
22
|
+
*/
|
|
23
|
+
export declare function clearAll(db: Database.Database): void;
|
|
24
|
+
//# sourceMappingURL=writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/graph/writer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAaxE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAUlE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAS7E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAMpD"}
|