@colbymchenry/codegraph 0.5.7 → 0.6.2
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 -21
- package/README.md +682 -681
- package/dist/bin/codegraph.js +14 -14
- package/dist/bin/codegraph.js.map +1 -1
- package/dist/bin/uninstall.d.ts +15 -0
- package/dist/bin/uninstall.d.ts.map +1 -0
- package/dist/bin/uninstall.js +174 -0
- package/dist/bin/uninstall.js.map +1 -0
- package/dist/db/migrations.js +11 -11
- package/dist/db/queries.js +86 -86
- package/dist/db/schema.sql +163 -163
- package/dist/directory.js +16 -16
- package/dist/extraction/grammars.d.ts.map +1 -1
- package/dist/extraction/grammars.js +50 -4
- package/dist/extraction/grammars.js.map +1 -1
- package/dist/extraction/tree-sitter.d.ts +64 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +586 -1
- package/dist/extraction/tree-sitter.js.map +1 -1
- package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/dist/installer/banner.d.ts +1 -1
- package/dist/installer/banner.d.ts.map +1 -1
- package/dist/installer/banner.js +12 -10
- package/dist/installer/banner.js.map +1 -1
- package/dist/installer/claude-md-template.js +32 -32
- package/dist/installer/config-writer.d.ts +0 -1
- package/dist/installer/config-writer.d.ts.map +1 -1
- package/dist/installer/config-writer.js +8 -26
- package/dist/installer/config-writer.js.map +1 -1
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +11 -26
- package/dist/installer/index.js.map +1 -1
- package/dist/resolution/import-resolver.d.ts +4 -0
- package/dist/resolution/import-resolver.d.ts.map +1 -1
- package/dist/resolution/import-resolver.js +9 -0
- package/dist/resolution/import-resolver.js.map +1 -1
- package/dist/resolution/index.d.ts +1 -1
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +39 -4
- package/dist/resolution/index.js.map +1 -1
- package/dist/sync/git-hooks.d.ts +66 -0
- package/dist/sync/git-hooks.d.ts.map +1 -0
- package/dist/sync/git-hooks.js +281 -0
- package/dist/sync/git-hooks.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -1
- package/dist/vectors/search.js +33 -33
- package/package.json +60 -59
- package/scripts/patch-tree-sitter-dart.js +112 -112
- package/scripts/postinstall.js +68 -68
package/dist/db/queries.js
CHANGED
|
@@ -85,20 +85,20 @@ class QueryBuilder {
|
|
|
85
85
|
*/
|
|
86
86
|
insertNode(node) {
|
|
87
87
|
if (!this.stmts.insertNode) {
|
|
88
|
-
this.stmts.insertNode = this.db.prepare(`
|
|
89
|
-
INSERT OR REPLACE INTO nodes (
|
|
90
|
-
id, kind, name, qualified_name, file_path, language,
|
|
91
|
-
start_line, end_line, start_column, end_column,
|
|
92
|
-
docstring, signature, visibility,
|
|
93
|
-
is_exported, is_async, is_static, is_abstract,
|
|
94
|
-
decorators, type_parameters, updated_at
|
|
95
|
-
) VALUES (
|
|
96
|
-
@id, @kind, @name, @qualifiedName, @filePath, @language,
|
|
97
|
-
@startLine, @endLine, @startColumn, @endColumn,
|
|
98
|
-
@docstring, @signature, @visibility,
|
|
99
|
-
@isExported, @isAsync, @isStatic, @isAbstract,
|
|
100
|
-
@decorators, @typeParameters, @updatedAt
|
|
101
|
-
)
|
|
88
|
+
this.stmts.insertNode = this.db.prepare(`
|
|
89
|
+
INSERT OR REPLACE INTO nodes (
|
|
90
|
+
id, kind, name, qualified_name, file_path, language,
|
|
91
|
+
start_line, end_line, start_column, end_column,
|
|
92
|
+
docstring, signature, visibility,
|
|
93
|
+
is_exported, is_async, is_static, is_abstract,
|
|
94
|
+
decorators, type_parameters, updated_at
|
|
95
|
+
) VALUES (
|
|
96
|
+
@id, @kind, @name, @qualifiedName, @filePath, @language,
|
|
97
|
+
@startLine, @endLine, @startColumn, @endColumn,
|
|
98
|
+
@docstring, @signature, @visibility,
|
|
99
|
+
@isExported, @isAsync, @isStatic, @isAbstract,
|
|
100
|
+
@decorators, @typeParameters, @updatedAt
|
|
101
|
+
)
|
|
102
102
|
`);
|
|
103
103
|
}
|
|
104
104
|
// Validate required fields to prevent SQLite bind errors
|
|
@@ -165,28 +165,28 @@ class QueryBuilder {
|
|
|
165
165
|
*/
|
|
166
166
|
updateNode(node) {
|
|
167
167
|
if (!this.stmts.updateNode) {
|
|
168
|
-
this.stmts.updateNode = this.db.prepare(`
|
|
169
|
-
UPDATE nodes SET
|
|
170
|
-
kind = @kind,
|
|
171
|
-
name = @name,
|
|
172
|
-
qualified_name = @qualifiedName,
|
|
173
|
-
file_path = @filePath,
|
|
174
|
-
language = @language,
|
|
175
|
-
start_line = @startLine,
|
|
176
|
-
end_line = @endLine,
|
|
177
|
-
start_column = @startColumn,
|
|
178
|
-
end_column = @endColumn,
|
|
179
|
-
docstring = @docstring,
|
|
180
|
-
signature = @signature,
|
|
181
|
-
visibility = @visibility,
|
|
182
|
-
is_exported = @isExported,
|
|
183
|
-
is_async = @isAsync,
|
|
184
|
-
is_static = @isStatic,
|
|
185
|
-
is_abstract = @isAbstract,
|
|
186
|
-
decorators = @decorators,
|
|
187
|
-
type_parameters = @typeParameters,
|
|
188
|
-
updated_at = @updatedAt
|
|
189
|
-
WHERE id = @id
|
|
168
|
+
this.stmts.updateNode = this.db.prepare(`
|
|
169
|
+
UPDATE nodes SET
|
|
170
|
+
kind = @kind,
|
|
171
|
+
name = @name,
|
|
172
|
+
qualified_name = @qualifiedName,
|
|
173
|
+
file_path = @filePath,
|
|
174
|
+
language = @language,
|
|
175
|
+
start_line = @startLine,
|
|
176
|
+
end_line = @endLine,
|
|
177
|
+
start_column = @startColumn,
|
|
178
|
+
end_column = @endColumn,
|
|
179
|
+
docstring = @docstring,
|
|
180
|
+
signature = @signature,
|
|
181
|
+
visibility = @visibility,
|
|
182
|
+
is_exported = @isExported,
|
|
183
|
+
is_async = @isAsync,
|
|
184
|
+
is_static = @isStatic,
|
|
185
|
+
is_abstract = @isAbstract,
|
|
186
|
+
decorators = @decorators,
|
|
187
|
+
type_parameters = @typeParameters,
|
|
188
|
+
updated_at = @updatedAt
|
|
189
|
+
WHERE id = @id
|
|
190
190
|
`);
|
|
191
191
|
}
|
|
192
192
|
// Invalidate cache before update
|
|
@@ -358,11 +358,11 @@ class QueryBuilder {
|
|
|
358
358
|
if (!ftsQuery) {
|
|
359
359
|
return [];
|
|
360
360
|
}
|
|
361
|
-
let sql = `
|
|
362
|
-
SELECT nodes.*, bm25(nodes_fts) as score
|
|
363
|
-
FROM nodes_fts
|
|
364
|
-
JOIN nodes ON nodes_fts.id = nodes.id
|
|
365
|
-
WHERE nodes_fts MATCH ?
|
|
361
|
+
let sql = `
|
|
362
|
+
SELECT nodes.*, bm25(nodes_fts) as score
|
|
363
|
+
FROM nodes_fts
|
|
364
|
+
JOIN nodes ON nodes_fts.id = nodes.id
|
|
365
|
+
WHERE nodes_fts MATCH ?
|
|
366
366
|
`;
|
|
367
367
|
const params = [ftsQuery];
|
|
368
368
|
if (kinds && kinds.length > 0) {
|
|
@@ -393,21 +393,21 @@ class QueryBuilder {
|
|
|
393
393
|
*/
|
|
394
394
|
searchNodesLike(query, options) {
|
|
395
395
|
const { kinds, languages, limit = 100, offset = 0 } = options;
|
|
396
|
-
let sql = `
|
|
397
|
-
SELECT nodes.*,
|
|
398
|
-
CASE
|
|
399
|
-
WHEN name = ? THEN 1.0
|
|
400
|
-
WHEN name LIKE ? THEN 0.9
|
|
401
|
-
WHEN name LIKE ? THEN 0.8
|
|
402
|
-
WHEN qualified_name LIKE ? THEN 0.7
|
|
403
|
-
ELSE 0.5
|
|
404
|
-
END as score
|
|
405
|
-
FROM nodes
|
|
406
|
-
WHERE (
|
|
407
|
-
name LIKE ? OR
|
|
408
|
-
qualified_name LIKE ? OR
|
|
409
|
-
name LIKE ?
|
|
410
|
-
)
|
|
396
|
+
let sql = `
|
|
397
|
+
SELECT nodes.*,
|
|
398
|
+
CASE
|
|
399
|
+
WHEN name = ? THEN 1.0
|
|
400
|
+
WHEN name LIKE ? THEN 0.9
|
|
401
|
+
WHEN name LIKE ? THEN 0.8
|
|
402
|
+
WHEN qualified_name LIKE ? THEN 0.7
|
|
403
|
+
ELSE 0.5
|
|
404
|
+
END as score
|
|
405
|
+
FROM nodes
|
|
406
|
+
WHERE (
|
|
407
|
+
name LIKE ? OR
|
|
408
|
+
qualified_name LIKE ? OR
|
|
409
|
+
name LIKE ?
|
|
410
|
+
)
|
|
411
411
|
`;
|
|
412
412
|
// Pattern variants for better matching
|
|
413
413
|
const exactMatch = query;
|
|
@@ -453,14 +453,14 @@ class QueryBuilder {
|
|
|
453
453
|
return [];
|
|
454
454
|
const { kinds, languages, limit = 50 } = options;
|
|
455
455
|
// Build query with exact matches (case-insensitive)
|
|
456
|
-
let sql = `
|
|
457
|
-
SELECT nodes.*,
|
|
458
|
-
CASE
|
|
459
|
-
WHEN name COLLATE NOCASE IN (${names.map(() => '?').join(',')}) THEN 1.0
|
|
460
|
-
ELSE 0.9
|
|
461
|
-
END as score
|
|
462
|
-
FROM nodes
|
|
463
|
-
WHERE name COLLATE NOCASE IN (${names.map(() => '?').join(',')})
|
|
456
|
+
let sql = `
|
|
457
|
+
SELECT nodes.*,
|
|
458
|
+
CASE
|
|
459
|
+
WHEN name COLLATE NOCASE IN (${names.map(() => '?').join(',')}) THEN 1.0
|
|
460
|
+
ELSE 0.9
|
|
461
|
+
END as score
|
|
462
|
+
FROM nodes
|
|
463
|
+
WHERE name COLLATE NOCASE IN (${names.map(() => '?').join(',')})
|
|
464
464
|
`;
|
|
465
465
|
// Duplicate names for both SELECT and WHERE clauses
|
|
466
466
|
const params = [...names, ...names];
|
|
@@ -488,9 +488,9 @@ class QueryBuilder {
|
|
|
488
488
|
*/
|
|
489
489
|
insertEdge(edge) {
|
|
490
490
|
if (!this.stmts.insertEdge) {
|
|
491
|
-
this.stmts.insertEdge = this.db.prepare(`
|
|
492
|
-
INSERT OR IGNORE INTO edges (source, target, kind, metadata, line, col, provenance)
|
|
493
|
-
VALUES (@source, @target, @kind, @metadata, @line, @col, @provenance)
|
|
491
|
+
this.stmts.insertEdge = this.db.prepare(`
|
|
492
|
+
INSERT OR IGNORE INTO edges (source, target, kind, metadata, line, col, provenance)
|
|
493
|
+
VALUES (@source, @target, @kind, @metadata, @line, @col, @provenance)
|
|
494
494
|
`);
|
|
495
495
|
}
|
|
496
496
|
this.stmts.insertEdge.run({
|
|
@@ -569,17 +569,17 @@ class QueryBuilder {
|
|
|
569
569
|
*/
|
|
570
570
|
upsertFile(file) {
|
|
571
571
|
if (!this.stmts.upsertFile) {
|
|
572
|
-
this.stmts.upsertFile = this.db.prepare(`
|
|
573
|
-
INSERT INTO files (path, content_hash, language, size, modified_at, indexed_at, node_count, errors)
|
|
574
|
-
VALUES (@path, @contentHash, @language, @size, @modifiedAt, @indexedAt, @nodeCount, @errors)
|
|
575
|
-
ON CONFLICT(path) DO UPDATE SET
|
|
576
|
-
content_hash = @contentHash,
|
|
577
|
-
language = @language,
|
|
578
|
-
size = @size,
|
|
579
|
-
modified_at = @modifiedAt,
|
|
580
|
-
indexed_at = @indexedAt,
|
|
581
|
-
node_count = @nodeCount,
|
|
582
|
-
errors = @errors
|
|
572
|
+
this.stmts.upsertFile = this.db.prepare(`
|
|
573
|
+
INSERT INTO files (path, content_hash, language, size, modified_at, indexed_at, node_count, errors)
|
|
574
|
+
VALUES (@path, @contentHash, @language, @size, @modifiedAt, @indexedAt, @nodeCount, @errors)
|
|
575
|
+
ON CONFLICT(path) DO UPDATE SET
|
|
576
|
+
content_hash = @contentHash,
|
|
577
|
+
language = @language,
|
|
578
|
+
size = @size,
|
|
579
|
+
modified_at = @modifiedAt,
|
|
580
|
+
indexed_at = @indexedAt,
|
|
581
|
+
node_count = @nodeCount,
|
|
582
|
+
errors = @errors
|
|
583
583
|
`);
|
|
584
584
|
}
|
|
585
585
|
this.stmts.upsertFile.run({
|
|
@@ -643,9 +643,9 @@ class QueryBuilder {
|
|
|
643
643
|
*/
|
|
644
644
|
insertUnresolvedRef(ref) {
|
|
645
645
|
if (!this.stmts.insertUnresolved) {
|
|
646
|
-
this.stmts.insertUnresolved = this.db.prepare(`
|
|
647
|
-
INSERT INTO unresolved_refs (from_node_id, reference_name, reference_kind, line, col, candidates, file_path, language)
|
|
648
|
-
VALUES (@fromNodeId, @referenceName, @referenceKind, @line, @col, @candidates, @filePath, @language)
|
|
646
|
+
this.stmts.insertUnresolved = this.db.prepare(`
|
|
647
|
+
INSERT INTO unresolved_refs (from_node_id, reference_name, reference_kind, line, col, candidates, file_path, language)
|
|
648
|
+
VALUES (@fromNodeId, @referenceName, @referenceKind, @line, @col, @candidates, @filePath, @language)
|
|
649
649
|
`);
|
|
650
650
|
}
|
|
651
651
|
this.stmts.insertUnresolved.run({
|
|
@@ -761,11 +761,11 @@ class QueryBuilder {
|
|
|
761
761
|
*/
|
|
762
762
|
getStats() {
|
|
763
763
|
// Single query for all three aggregate counts
|
|
764
|
-
const counts = this.db.prepare(`
|
|
765
|
-
SELECT
|
|
766
|
-
(SELECT COUNT(*) FROM nodes) AS node_count,
|
|
767
|
-
(SELECT COUNT(*) FROM edges) AS edge_count,
|
|
768
|
-
(SELECT COUNT(*) FROM files) AS file_count
|
|
764
|
+
const counts = this.db.prepare(`
|
|
765
|
+
SELECT
|
|
766
|
+
(SELECT COUNT(*) FROM nodes) AS node_count,
|
|
767
|
+
(SELECT COUNT(*) FROM edges) AS edge_count,
|
|
768
|
+
(SELECT COUNT(*) FROM files) AS file_count
|
|
769
769
|
`).get();
|
|
770
770
|
const nodesByKind = {};
|
|
771
771
|
const nodeKindRows = this.db
|
package/dist/db/schema.sql
CHANGED
|
@@ -1,163 +1,163 @@
|
|
|
1
|
-
-- CodeGraph SQLite Schema
|
|
2
|
-
-- Version 1
|
|
3
|
-
|
|
4
|
-
-- Schema version tracking
|
|
5
|
-
CREATE TABLE IF NOT EXISTS schema_versions (
|
|
6
|
-
version INTEGER PRIMARY KEY,
|
|
7
|
-
applied_at INTEGER NOT NULL,
|
|
8
|
-
description TEXT
|
|
9
|
-
);
|
|
10
|
-
|
|
11
|
-
-- Insert initial version
|
|
12
|
-
INSERT INTO schema_versions (version, applied_at, description)
|
|
13
|
-
VALUES (1, strftime('%s', 'now') * 1000, 'Initial schema');
|
|
14
|
-
|
|
15
|
-
-- =============================================================================
|
|
16
|
-
-- Core Tables
|
|
17
|
-
-- =============================================================================
|
|
18
|
-
|
|
19
|
-
-- Nodes: Code symbols (functions, classes, variables, etc.)
|
|
20
|
-
CREATE TABLE IF NOT EXISTS nodes (
|
|
21
|
-
id TEXT PRIMARY KEY,
|
|
22
|
-
kind TEXT NOT NULL,
|
|
23
|
-
name TEXT NOT NULL,
|
|
24
|
-
qualified_name TEXT NOT NULL,
|
|
25
|
-
file_path TEXT NOT NULL,
|
|
26
|
-
language TEXT NOT NULL,
|
|
27
|
-
start_line INTEGER NOT NULL,
|
|
28
|
-
end_line INTEGER NOT NULL,
|
|
29
|
-
start_column INTEGER NOT NULL,
|
|
30
|
-
end_column INTEGER NOT NULL,
|
|
31
|
-
docstring TEXT,
|
|
32
|
-
signature TEXT,
|
|
33
|
-
visibility TEXT,
|
|
34
|
-
is_exported INTEGER DEFAULT 0,
|
|
35
|
-
is_async INTEGER DEFAULT 0,
|
|
36
|
-
is_static INTEGER DEFAULT 0,
|
|
37
|
-
is_abstract INTEGER DEFAULT 0,
|
|
38
|
-
decorators TEXT, -- JSON array
|
|
39
|
-
type_parameters TEXT, -- JSON array
|
|
40
|
-
updated_at INTEGER NOT NULL
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
-- Edges: Relationships between nodes
|
|
44
|
-
CREATE TABLE IF NOT EXISTS edges (
|
|
45
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
46
|
-
source TEXT NOT NULL,
|
|
47
|
-
target TEXT NOT NULL,
|
|
48
|
-
kind TEXT NOT NULL,
|
|
49
|
-
metadata TEXT, -- JSON object
|
|
50
|
-
line INTEGER,
|
|
51
|
-
col INTEGER,
|
|
52
|
-
provenance TEXT DEFAULT NULL,
|
|
53
|
-
FOREIGN KEY (source) REFERENCES nodes(id) ON DELETE CASCADE,
|
|
54
|
-
FOREIGN KEY (target) REFERENCES nodes(id) ON DELETE CASCADE
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
-- Files: Tracked source files
|
|
58
|
-
CREATE TABLE IF NOT EXISTS files (
|
|
59
|
-
path TEXT PRIMARY KEY,
|
|
60
|
-
content_hash TEXT NOT NULL,
|
|
61
|
-
language TEXT NOT NULL,
|
|
62
|
-
size INTEGER NOT NULL,
|
|
63
|
-
modified_at INTEGER NOT NULL,
|
|
64
|
-
indexed_at INTEGER NOT NULL,
|
|
65
|
-
node_count INTEGER DEFAULT 0,
|
|
66
|
-
errors TEXT -- JSON array
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
-- Unresolved References: References that need resolution after full indexing
|
|
70
|
-
CREATE TABLE IF NOT EXISTS unresolved_refs (
|
|
71
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
72
|
-
from_node_id TEXT NOT NULL,
|
|
73
|
-
reference_name TEXT NOT NULL,
|
|
74
|
-
reference_kind TEXT NOT NULL,
|
|
75
|
-
line INTEGER NOT NULL,
|
|
76
|
-
col INTEGER NOT NULL,
|
|
77
|
-
candidates TEXT, -- JSON array
|
|
78
|
-
file_path TEXT NOT NULL DEFAULT '',
|
|
79
|
-
language TEXT NOT NULL DEFAULT 'unknown',
|
|
80
|
-
FOREIGN KEY (from_node_id) REFERENCES nodes(id) ON DELETE CASCADE
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
-- =============================================================================
|
|
84
|
-
-- Indexes for Query Performance
|
|
85
|
-
-- =============================================================================
|
|
86
|
-
|
|
87
|
-
-- Node indexes
|
|
88
|
-
CREATE INDEX IF NOT EXISTS idx_nodes_kind ON nodes(kind);
|
|
89
|
-
CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes(name);
|
|
90
|
-
CREATE INDEX IF NOT EXISTS idx_nodes_qualified_name ON nodes(qualified_name);
|
|
91
|
-
CREATE INDEX IF NOT EXISTS idx_nodes_file_path ON nodes(file_path);
|
|
92
|
-
CREATE INDEX IF NOT EXISTS idx_nodes_language ON nodes(language);
|
|
93
|
-
CREATE INDEX IF NOT EXISTS idx_nodes_file_line ON nodes(file_path, start_line);
|
|
94
|
-
|
|
95
|
-
-- Full-text search index on node names, docstrings, and signatures
|
|
96
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(
|
|
97
|
-
id,
|
|
98
|
-
name,
|
|
99
|
-
qualified_name,
|
|
100
|
-
docstring,
|
|
101
|
-
signature,
|
|
102
|
-
content='nodes',
|
|
103
|
-
content_rowid='rowid'
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
-- Triggers to keep FTS index in sync
|
|
107
|
-
CREATE TRIGGER IF NOT EXISTS nodes_ai AFTER INSERT ON nodes BEGIN
|
|
108
|
-
INSERT INTO nodes_fts(rowid, id, name, qualified_name, docstring, signature)
|
|
109
|
-
VALUES (NEW.rowid, NEW.id, NEW.name, NEW.qualified_name, NEW.docstring, NEW.signature);
|
|
110
|
-
END;
|
|
111
|
-
|
|
112
|
-
CREATE TRIGGER IF NOT EXISTS nodes_ad AFTER DELETE ON nodes BEGIN
|
|
113
|
-
INSERT INTO nodes_fts(nodes_fts, rowid, id, name, qualified_name, docstring, signature)
|
|
114
|
-
VALUES ('delete', OLD.rowid, OLD.id, OLD.name, OLD.qualified_name, OLD.docstring, OLD.signature);
|
|
115
|
-
END;
|
|
116
|
-
|
|
117
|
-
CREATE TRIGGER IF NOT EXISTS nodes_au AFTER UPDATE ON nodes BEGIN
|
|
118
|
-
INSERT INTO nodes_fts(nodes_fts, rowid, id, name, qualified_name, docstring, signature)
|
|
119
|
-
VALUES ('delete', OLD.rowid, OLD.id, OLD.name, OLD.qualified_name, OLD.docstring, OLD.signature);
|
|
120
|
-
INSERT INTO nodes_fts(rowid, id, name, qualified_name, docstring, signature)
|
|
121
|
-
VALUES (NEW.rowid, NEW.id, NEW.name, NEW.qualified_name, NEW.docstring, NEW.signature);
|
|
122
|
-
END;
|
|
123
|
-
|
|
124
|
-
-- Edge indexes
|
|
125
|
-
CREATE INDEX IF NOT EXISTS idx_edges_source ON edges(source);
|
|
126
|
-
CREATE INDEX IF NOT EXISTS idx_edges_target ON edges(target);
|
|
127
|
-
CREATE INDEX IF NOT EXISTS idx_edges_kind ON edges(kind);
|
|
128
|
-
CREATE INDEX IF NOT EXISTS idx_edges_source_kind ON edges(source, kind);
|
|
129
|
-
CREATE INDEX IF NOT EXISTS idx_edges_target_kind ON edges(target, kind);
|
|
130
|
-
|
|
131
|
-
-- File indexes
|
|
132
|
-
CREATE INDEX IF NOT EXISTS idx_files_language ON files(language);
|
|
133
|
-
CREATE INDEX IF NOT EXISTS idx_files_modified_at ON files(modified_at);
|
|
134
|
-
|
|
135
|
-
-- Unresolved refs indexes
|
|
136
|
-
CREATE INDEX IF NOT EXISTS idx_unresolved_from_node ON unresolved_refs(from_node_id);
|
|
137
|
-
CREATE INDEX IF NOT EXISTS idx_unresolved_name ON unresolved_refs(reference_name);
|
|
138
|
-
CREATE INDEX IF NOT EXISTS idx_unresolved_file_path ON unresolved_refs(file_path);
|
|
139
|
-
CREATE INDEX IF NOT EXISTS idx_unresolved_from_name ON unresolved_refs(from_node_id, reference_name);
|
|
140
|
-
CREATE INDEX IF NOT EXISTS idx_edges_provenance ON edges(provenance);
|
|
141
|
-
|
|
142
|
-
-- =============================================================================
|
|
143
|
-
-- Vector Storage (for future semantic search)
|
|
144
|
-
-- =============================================================================
|
|
145
|
-
|
|
146
|
-
-- Vector embeddings for semantic search
|
|
147
|
-
-- Note: No foreign key constraint to allow standalone vector testing
|
|
148
|
-
-- The VectorManager handles node-vector relationship at the application level
|
|
149
|
-
CREATE TABLE IF NOT EXISTS vectors (
|
|
150
|
-
node_id TEXT PRIMARY KEY,
|
|
151
|
-
embedding BLOB NOT NULL, -- Float32 array stored as blob
|
|
152
|
-
model TEXT NOT NULL, -- Model used to generate embedding
|
|
153
|
-
created_at INTEGER NOT NULL
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
CREATE INDEX IF NOT EXISTS idx_vectors_model ON vectors(model);
|
|
157
|
-
|
|
158
|
-
-- Project metadata for version/provenance tracking
|
|
159
|
-
CREATE TABLE IF NOT EXISTS project_metadata (
|
|
160
|
-
key TEXT PRIMARY KEY,
|
|
161
|
-
value TEXT NOT NULL,
|
|
162
|
-
updated_at INTEGER NOT NULL
|
|
163
|
-
);
|
|
1
|
+
-- CodeGraph SQLite Schema
|
|
2
|
+
-- Version 1
|
|
3
|
+
|
|
4
|
+
-- Schema version tracking
|
|
5
|
+
CREATE TABLE IF NOT EXISTS schema_versions (
|
|
6
|
+
version INTEGER PRIMARY KEY,
|
|
7
|
+
applied_at INTEGER NOT NULL,
|
|
8
|
+
description TEXT
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
-- Insert initial version
|
|
12
|
+
INSERT INTO schema_versions (version, applied_at, description)
|
|
13
|
+
VALUES (1, strftime('%s', 'now') * 1000, 'Initial schema');
|
|
14
|
+
|
|
15
|
+
-- =============================================================================
|
|
16
|
+
-- Core Tables
|
|
17
|
+
-- =============================================================================
|
|
18
|
+
|
|
19
|
+
-- Nodes: Code symbols (functions, classes, variables, etc.)
|
|
20
|
+
CREATE TABLE IF NOT EXISTS nodes (
|
|
21
|
+
id TEXT PRIMARY KEY,
|
|
22
|
+
kind TEXT NOT NULL,
|
|
23
|
+
name TEXT NOT NULL,
|
|
24
|
+
qualified_name TEXT NOT NULL,
|
|
25
|
+
file_path TEXT NOT NULL,
|
|
26
|
+
language TEXT NOT NULL,
|
|
27
|
+
start_line INTEGER NOT NULL,
|
|
28
|
+
end_line INTEGER NOT NULL,
|
|
29
|
+
start_column INTEGER NOT NULL,
|
|
30
|
+
end_column INTEGER NOT NULL,
|
|
31
|
+
docstring TEXT,
|
|
32
|
+
signature TEXT,
|
|
33
|
+
visibility TEXT,
|
|
34
|
+
is_exported INTEGER DEFAULT 0,
|
|
35
|
+
is_async INTEGER DEFAULT 0,
|
|
36
|
+
is_static INTEGER DEFAULT 0,
|
|
37
|
+
is_abstract INTEGER DEFAULT 0,
|
|
38
|
+
decorators TEXT, -- JSON array
|
|
39
|
+
type_parameters TEXT, -- JSON array
|
|
40
|
+
updated_at INTEGER NOT NULL
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
-- Edges: Relationships between nodes
|
|
44
|
+
CREATE TABLE IF NOT EXISTS edges (
|
|
45
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
46
|
+
source TEXT NOT NULL,
|
|
47
|
+
target TEXT NOT NULL,
|
|
48
|
+
kind TEXT NOT NULL,
|
|
49
|
+
metadata TEXT, -- JSON object
|
|
50
|
+
line INTEGER,
|
|
51
|
+
col INTEGER,
|
|
52
|
+
provenance TEXT DEFAULT NULL,
|
|
53
|
+
FOREIGN KEY (source) REFERENCES nodes(id) ON DELETE CASCADE,
|
|
54
|
+
FOREIGN KEY (target) REFERENCES nodes(id) ON DELETE CASCADE
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
-- Files: Tracked source files
|
|
58
|
+
CREATE TABLE IF NOT EXISTS files (
|
|
59
|
+
path TEXT PRIMARY KEY,
|
|
60
|
+
content_hash TEXT NOT NULL,
|
|
61
|
+
language TEXT NOT NULL,
|
|
62
|
+
size INTEGER NOT NULL,
|
|
63
|
+
modified_at INTEGER NOT NULL,
|
|
64
|
+
indexed_at INTEGER NOT NULL,
|
|
65
|
+
node_count INTEGER DEFAULT 0,
|
|
66
|
+
errors TEXT -- JSON array
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
-- Unresolved References: References that need resolution after full indexing
|
|
70
|
+
CREATE TABLE IF NOT EXISTS unresolved_refs (
|
|
71
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
72
|
+
from_node_id TEXT NOT NULL,
|
|
73
|
+
reference_name TEXT NOT NULL,
|
|
74
|
+
reference_kind TEXT NOT NULL,
|
|
75
|
+
line INTEGER NOT NULL,
|
|
76
|
+
col INTEGER NOT NULL,
|
|
77
|
+
candidates TEXT, -- JSON array
|
|
78
|
+
file_path TEXT NOT NULL DEFAULT '',
|
|
79
|
+
language TEXT NOT NULL DEFAULT 'unknown',
|
|
80
|
+
FOREIGN KEY (from_node_id) REFERENCES nodes(id) ON DELETE CASCADE
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
-- =============================================================================
|
|
84
|
+
-- Indexes for Query Performance
|
|
85
|
+
-- =============================================================================
|
|
86
|
+
|
|
87
|
+
-- Node indexes
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_kind ON nodes(kind);
|
|
89
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes(name);
|
|
90
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_qualified_name ON nodes(qualified_name);
|
|
91
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_file_path ON nodes(file_path);
|
|
92
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_language ON nodes(language);
|
|
93
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_file_line ON nodes(file_path, start_line);
|
|
94
|
+
|
|
95
|
+
-- Full-text search index on node names, docstrings, and signatures
|
|
96
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(
|
|
97
|
+
id,
|
|
98
|
+
name,
|
|
99
|
+
qualified_name,
|
|
100
|
+
docstring,
|
|
101
|
+
signature,
|
|
102
|
+
content='nodes',
|
|
103
|
+
content_rowid='rowid'
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
-- Triggers to keep FTS index in sync
|
|
107
|
+
CREATE TRIGGER IF NOT EXISTS nodes_ai AFTER INSERT ON nodes BEGIN
|
|
108
|
+
INSERT INTO nodes_fts(rowid, id, name, qualified_name, docstring, signature)
|
|
109
|
+
VALUES (NEW.rowid, NEW.id, NEW.name, NEW.qualified_name, NEW.docstring, NEW.signature);
|
|
110
|
+
END;
|
|
111
|
+
|
|
112
|
+
CREATE TRIGGER IF NOT EXISTS nodes_ad AFTER DELETE ON nodes BEGIN
|
|
113
|
+
INSERT INTO nodes_fts(nodes_fts, rowid, id, name, qualified_name, docstring, signature)
|
|
114
|
+
VALUES ('delete', OLD.rowid, OLD.id, OLD.name, OLD.qualified_name, OLD.docstring, OLD.signature);
|
|
115
|
+
END;
|
|
116
|
+
|
|
117
|
+
CREATE TRIGGER IF NOT EXISTS nodes_au AFTER UPDATE ON nodes BEGIN
|
|
118
|
+
INSERT INTO nodes_fts(nodes_fts, rowid, id, name, qualified_name, docstring, signature)
|
|
119
|
+
VALUES ('delete', OLD.rowid, OLD.id, OLD.name, OLD.qualified_name, OLD.docstring, OLD.signature);
|
|
120
|
+
INSERT INTO nodes_fts(rowid, id, name, qualified_name, docstring, signature)
|
|
121
|
+
VALUES (NEW.rowid, NEW.id, NEW.name, NEW.qualified_name, NEW.docstring, NEW.signature);
|
|
122
|
+
END;
|
|
123
|
+
|
|
124
|
+
-- Edge indexes
|
|
125
|
+
CREATE INDEX IF NOT EXISTS idx_edges_source ON edges(source);
|
|
126
|
+
CREATE INDEX IF NOT EXISTS idx_edges_target ON edges(target);
|
|
127
|
+
CREATE INDEX IF NOT EXISTS idx_edges_kind ON edges(kind);
|
|
128
|
+
CREATE INDEX IF NOT EXISTS idx_edges_source_kind ON edges(source, kind);
|
|
129
|
+
CREATE INDEX IF NOT EXISTS idx_edges_target_kind ON edges(target, kind);
|
|
130
|
+
|
|
131
|
+
-- File indexes
|
|
132
|
+
CREATE INDEX IF NOT EXISTS idx_files_language ON files(language);
|
|
133
|
+
CREATE INDEX IF NOT EXISTS idx_files_modified_at ON files(modified_at);
|
|
134
|
+
|
|
135
|
+
-- Unresolved refs indexes
|
|
136
|
+
CREATE INDEX IF NOT EXISTS idx_unresolved_from_node ON unresolved_refs(from_node_id);
|
|
137
|
+
CREATE INDEX IF NOT EXISTS idx_unresolved_name ON unresolved_refs(reference_name);
|
|
138
|
+
CREATE INDEX IF NOT EXISTS idx_unresolved_file_path ON unresolved_refs(file_path);
|
|
139
|
+
CREATE INDEX IF NOT EXISTS idx_unresolved_from_name ON unresolved_refs(from_node_id, reference_name);
|
|
140
|
+
CREATE INDEX IF NOT EXISTS idx_edges_provenance ON edges(provenance);
|
|
141
|
+
|
|
142
|
+
-- =============================================================================
|
|
143
|
+
-- Vector Storage (for future semantic search)
|
|
144
|
+
-- =============================================================================
|
|
145
|
+
|
|
146
|
+
-- Vector embeddings for semantic search
|
|
147
|
+
-- Note: No foreign key constraint to allow standalone vector testing
|
|
148
|
+
-- The VectorManager handles node-vector relationship at the application level
|
|
149
|
+
CREATE TABLE IF NOT EXISTS vectors (
|
|
150
|
+
node_id TEXT PRIMARY KEY,
|
|
151
|
+
embedding BLOB NOT NULL, -- Float32 array stored as blob
|
|
152
|
+
model TEXT NOT NULL, -- Model used to generate embedding
|
|
153
|
+
created_at INTEGER NOT NULL
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
CREATE INDEX IF NOT EXISTS idx_vectors_model ON vectors(model);
|
|
157
|
+
|
|
158
|
+
-- Project metadata for version/provenance tracking
|
|
159
|
+
CREATE TABLE IF NOT EXISTS project_metadata (
|
|
160
|
+
key TEXT PRIMARY KEY,
|
|
161
|
+
value TEXT NOT NULL,
|
|
162
|
+
updated_at INTEGER NOT NULL
|
|
163
|
+
);
|
package/dist/directory.js
CHANGED
|
@@ -117,22 +117,22 @@ function createDirectory(projectRoot) {
|
|
|
117
117
|
// Create .gitignore inside .codegraph (if it doesn't exist)
|
|
118
118
|
const gitignorePath = path.join(codegraphDir, '.gitignore');
|
|
119
119
|
if (!fs.existsSync(gitignorePath)) {
|
|
120
|
-
const gitignoreContent = `# CodeGraph data files
|
|
121
|
-
# These are local to each machine and should not be committed
|
|
122
|
-
|
|
123
|
-
# Database
|
|
124
|
-
*.db
|
|
125
|
-
*.db-wal
|
|
126
|
-
*.db-shm
|
|
127
|
-
|
|
128
|
-
# Cache
|
|
129
|
-
cache/
|
|
130
|
-
|
|
131
|
-
# Logs
|
|
132
|
-
*.log
|
|
133
|
-
|
|
134
|
-
# Hook markers
|
|
135
|
-
.dirty
|
|
120
|
+
const gitignoreContent = `# CodeGraph data files
|
|
121
|
+
# These are local to each machine and should not be committed
|
|
122
|
+
|
|
123
|
+
# Database
|
|
124
|
+
*.db
|
|
125
|
+
*.db-wal
|
|
126
|
+
*.db-shm
|
|
127
|
+
|
|
128
|
+
# Cache
|
|
129
|
+
cache/
|
|
130
|
+
|
|
131
|
+
# Logs
|
|
132
|
+
*.log
|
|
133
|
+
|
|
134
|
+
# Hook markers
|
|
135
|
+
.dirty
|
|
136
136
|
`;
|
|
137
137
|
fs.writeFileSync(gitignorePath, gitignoreContent, 'utf-8');
|
|
138
138
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grammars.d.ts","sourceRoot":"","sources":["../../src/extraction/grammars.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"grammars.d.ts","sourceRoot":"","sources":["../../src/extraction/grammars.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,MAAM,EAA4B,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AA4BpC;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAmClD,CAAC;AAWF;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAwBlD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAc3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAGzD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAK/D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,QAAQ,EAAE,CAIlD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAM/E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAwBjE"}
|