milens 0.2.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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +213 -0
  3. package/dist/analyzer/engine.d.ts +11 -0
  4. package/dist/analyzer/engine.d.ts.map +1 -0
  5. package/dist/analyzer/engine.js +163 -0
  6. package/dist/analyzer/engine.js.map +1 -0
  7. package/dist/analyzer/resolver.d.ts +12 -0
  8. package/dist/analyzer/resolver.d.ts.map +1 -0
  9. package/dist/analyzer/resolver.js +119 -0
  10. package/dist/analyzer/resolver.js.map +1 -0
  11. package/dist/analyzer/scanner.d.ts +6 -0
  12. package/dist/analyzer/scanner.d.ts.map +1 -0
  13. package/dist/analyzer/scanner.js +73 -0
  14. package/dist/analyzer/scanner.js.map +1 -0
  15. package/dist/cli.d.ts +3 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +269 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/parser/extract.d.ts +24 -0
  20. package/dist/parser/extract.d.ts.map +1 -0
  21. package/dist/parser/extract.js +239 -0
  22. package/dist/parser/extract.js.map +1 -0
  23. package/dist/parser/lang-go.d.ts +4 -0
  24. package/dist/parser/lang-go.d.ts.map +1 -0
  25. package/dist/parser/lang-go.js +45 -0
  26. package/dist/parser/lang-go.js.map +1 -0
  27. package/dist/parser/lang-java.d.ts +4 -0
  28. package/dist/parser/lang-java.d.ts.map +1 -0
  29. package/dist/parser/lang-java.js +46 -0
  30. package/dist/parser/lang-java.js.map +1 -0
  31. package/dist/parser/lang-js.d.ts +4 -0
  32. package/dist/parser/lang-js.d.ts.map +1 -0
  33. package/dist/parser/lang-js.js +64 -0
  34. package/dist/parser/lang-js.js.map +1 -0
  35. package/dist/parser/lang-php.d.ts +4 -0
  36. package/dist/parser/lang-php.d.ts.map +1 -0
  37. package/dist/parser/lang-php.js +54 -0
  38. package/dist/parser/lang-php.js.map +1 -0
  39. package/dist/parser/lang-py.d.ts +4 -0
  40. package/dist/parser/lang-py.d.ts.map +1 -0
  41. package/dist/parser/lang-py.js +46 -0
  42. package/dist/parser/lang-py.js.map +1 -0
  43. package/dist/parser/lang-rust.d.ts +4 -0
  44. package/dist/parser/lang-rust.d.ts.map +1 -0
  45. package/dist/parser/lang-rust.js +54 -0
  46. package/dist/parser/lang-rust.js.map +1 -0
  47. package/dist/parser/lang-ts.d.ts +4 -0
  48. package/dist/parser/lang-ts.d.ts.map +1 -0
  49. package/dist/parser/lang-ts.js +88 -0
  50. package/dist/parser/lang-ts.js.map +1 -0
  51. package/dist/parser/lang-vue.d.ts +12 -0
  52. package/dist/parser/lang-vue.d.ts.map +1 -0
  53. package/dist/parser/lang-vue.js +28 -0
  54. package/dist/parser/lang-vue.js.map +1 -0
  55. package/dist/parser/languages.d.ts +6 -0
  56. package/dist/parser/languages.d.ts.map +1 -0
  57. package/dist/parser/languages.js +24 -0
  58. package/dist/parser/languages.js.map +1 -0
  59. package/dist/parser/loader.d.ts +5 -0
  60. package/dist/parser/loader.d.ts.map +1 -0
  61. package/dist/parser/loader.js +37 -0
  62. package/dist/parser/loader.js.map +1 -0
  63. package/dist/server/mcp.d.ts +5 -0
  64. package/dist/server/mcp.d.ts.map +1 -0
  65. package/dist/server/mcp.js +355 -0
  66. package/dist/server/mcp.js.map +1 -0
  67. package/dist/skills.d.ts +8 -0
  68. package/dist/skills.d.ts.map +1 -0
  69. package/dist/skills.js +178 -0
  70. package/dist/skills.js.map +1 -0
  71. package/dist/store/db.d.ts +59 -0
  72. package/dist/store/db.d.ts.map +1 -0
  73. package/dist/store/db.js +260 -0
  74. package/dist/store/db.js.map +1 -0
  75. package/dist/store/registry.d.ts +13 -0
  76. package/dist/store/registry.d.ts.map +1 -0
  77. package/dist/store/registry.js +69 -0
  78. package/dist/store/registry.js.map +1 -0
  79. package/dist/store/schema.sql +60 -0
  80. package/dist/types.d.ts +67 -0
  81. package/dist/types.d.ts.map +1 -0
  82. package/dist/types.js +3 -0
  83. package/dist/types.js.map +1 -0
  84. package/package.json +60 -0
@@ -0,0 +1,260 @@
1
+ import BetterSqlite3 from 'better-sqlite3';
2
+ import { readFileSync } from 'node:fs';
3
+ import { join, dirname } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { createHash } from 'node:crypto';
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ export class Database {
8
+ db;
9
+ stmts;
10
+ constructor(dbPath) {
11
+ this.db = new BetterSqlite3(dbPath);
12
+ this.db.pragma('journal_mode = WAL');
13
+ this.db.pragma('synchronous = NORMAL');
14
+ this.db.pragma('foreign_keys = ON');
15
+ this.db.pragma('cache_size = -8000'); // 8MB page cache
16
+ this.applySchema();
17
+ this.stmts = this.prepareStatements();
18
+ }
19
+ prepareStatements() {
20
+ return {
21
+ checkHash: this.db.prepare('SELECT hash FROM file_hashes WHERE path = ?'),
22
+ upsertHash: this.db.prepare(`INSERT INTO file_hashes (path, hash) VALUES (?, ?)
23
+ ON CONFLICT(path) DO UPDATE SET hash = excluded.hash, analyzed_at = datetime('now')`),
24
+ insertSym: this.db.prepare(`INSERT OR REPLACE INTO symbols (id, name, kind, file_path, start_line, end_line, exported, parent_id, signature)
25
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`),
26
+ insertLink: this.db.prepare(`INSERT OR REPLACE INTO links (id, from_id, to_id, type, confidence, line_number)
27
+ VALUES (?, ?, ?, ?, ?, ?)`),
28
+ searchFts: this.db.prepare(`SELECT s.* FROM symbol_fts f
29
+ JOIN symbols s ON s.rowid = f.rowid
30
+ WHERE symbol_fts MATCH ?
31
+ ORDER BY rank LIMIT ?`),
32
+ byName: this.db.prepare('SELECT * FROM symbols WHERE name = ?'),
33
+ byId: this.db.prepare('SELECT * FROM symbols WHERE id = ?'),
34
+ byFile: this.db.prepare('SELECT * FROM symbols WHERE file_path = ?'),
35
+ linksIn: this.db.prepare('SELECT * FROM links WHERE to_id = ?'),
36
+ linksOut: this.db.prepare('SELECT * FROM links WHERE from_id = ?'),
37
+ upstream: this.db.prepare(`
38
+ WITH RECURSIVE upstream(id, depth, via) AS (
39
+ SELECT from_id, 1, type FROM links WHERE to_id = ? AND type IN ('calls', 'imports', 'extends', 'implements')
40
+ UNION
41
+ SELECT l.from_id, u.depth + 1, l.type
42
+ FROM links l JOIN upstream u ON l.to_id = u.id
43
+ WHERE u.depth < ? AND l.type IN ('calls', 'imports', 'extends', 'implements')
44
+ )
45
+ SELECT DISTINCT s.*, u.depth, u.via FROM upstream u JOIN symbols s ON s.id = u.id ORDER BY u.depth
46
+ `),
47
+ downstream: this.db.prepare(`
48
+ WITH RECURSIVE downstream(id, depth, via) AS (
49
+ SELECT to_id, 1, type FROM links WHERE from_id = ? AND type IN ('calls', 'imports', 'extends', 'implements')
50
+ UNION
51
+ SELECT l.to_id, d.depth + 1, l.type
52
+ FROM links l JOIN downstream d ON l.from_id = d.id
53
+ WHERE d.depth < ? AND l.type IN ('calls', 'imports', 'extends', 'implements')
54
+ )
55
+ SELECT DISTINCT s.*, d.depth, d.via FROM downstream d JOIN symbols s ON s.id = d.id ORDER BY d.depth
56
+ `),
57
+ countSymbols: this.db.prepare('SELECT COUNT(*) as c FROM symbols'),
58
+ countLinks: this.db.prepare('SELECT COUNT(*) as c FROM links'),
59
+ countFiles: this.db.prepare('SELECT COUNT(*) as c FROM file_hashes'),
60
+ deleteFileLinks: this.db.prepare('DELETE FROM links WHERE from_id IN (SELECT id FROM symbols WHERE file_path = ?)'),
61
+ deleteFileSymbols: this.db.prepare('DELETE FROM symbols WHERE file_path = ?'),
62
+ };
63
+ }
64
+ applySchema() {
65
+ let sql;
66
+ try {
67
+ sql = readFileSync(join(__dirname, 'schema.sql'), 'utf-8');
68
+ }
69
+ catch {
70
+ sql = readFileSync(join(__dirname, '..', '..', 'src', 'store', 'schema.sql'), 'utf-8');
71
+ }
72
+ this.db.exec(sql);
73
+ }
74
+ // ── File hash tracking ──
75
+ isFileUpToDate(filePath, content) {
76
+ const hash = createHash('sha256').update(content).digest('hex').slice(0, 16);
77
+ const row = this.stmts.checkHash.get(filePath);
78
+ return row?.hash === hash;
79
+ }
80
+ upsertFileHash(filePath, content) {
81
+ const hash = createHash('sha256').update(content).digest('hex').slice(0, 16);
82
+ this.stmts.upsertHash.run(filePath, hash);
83
+ }
84
+ // ── Symbol CRUD ──
85
+ insertSymbol(sym) {
86
+ this.stmts.insertSym.run(sym.id, sym.name, sym.kind, sym.filePath, sym.startLine, sym.endLine, sym.exported ? 1 : 0, sym.parentId ?? null, sym.signature ?? null);
87
+ }
88
+ insertLink(link) {
89
+ this.stmts.insertLink.run(link.id, link.fromId, link.toId, link.type, link.confidence, link.line ?? null);
90
+ }
91
+ // ── Queries ──
92
+ searchSymbols(query, limit = 20) {
93
+ const rows = this.stmts.searchFts.all(query, limit);
94
+ return rows.map(rowToSymbol);
95
+ }
96
+ findSymbolByName(name) {
97
+ const rows = this.stmts.byName.all(name);
98
+ return rows.map(rowToSymbol);
99
+ }
100
+ findSymbolById(id) {
101
+ const row = this.stmts.byId.get(id);
102
+ return row ? rowToSymbol(row) : null;
103
+ }
104
+ getSymbolsByFile(filePath) {
105
+ const rows = this.stmts.byFile.all(filePath);
106
+ return rows.map(rowToSymbol);
107
+ }
108
+ getIncomingLinks(symbolId) {
109
+ const rows = this.stmts.linksIn.all(symbolId);
110
+ return rows.map(rowToLink);
111
+ }
112
+ getOutgoingLinks(symbolId) {
113
+ const rows = this.stmts.linksOut.all(symbolId);
114
+ return rows.map(rowToLink);
115
+ }
116
+ findUpstream(symbolId, maxDepth = 3) {
117
+ const rows = this.stmts.upstream.all(symbolId, maxDepth);
118
+ return rows.map(r => ({ symbol: rowToSymbol(r), depth: r.depth, via: r.via }));
119
+ }
120
+ findDownstream(symbolId, maxDepth = 3) {
121
+ const rows = this.stmts.downstream.all(symbolId, maxDepth);
122
+ return rows.map(r => ({ symbol: rowToSymbol(r), depth: r.depth, via: r.via }));
123
+ }
124
+ getStats() {
125
+ const symbols = this.stmts.countSymbols.get().c;
126
+ const links = this.stmts.countLinks.get().c;
127
+ const files = this.stmts.countFiles.get().c;
128
+ return { symbols, links, files };
129
+ }
130
+ getAllSymbols() {
131
+ const rows = this.db.prepare('SELECT * FROM symbols').all();
132
+ return rows.map(rowToSymbol);
133
+ }
134
+ getAllLinks() {
135
+ const rows = this.db.prepare('SELECT * FROM links').all();
136
+ return rows.map(rowToLink);
137
+ }
138
+ findDeadCode(kind, limit = 50) {
139
+ const sql = kind
140
+ ? `SELECT s.* FROM symbols s
141
+ LEFT JOIN links l ON l.to_id = s.id AND l.type != 'contains'
142
+ WHERE s.exported = 1 AND s.kind = ? AND l.id IS NULL
143
+ LIMIT ?`
144
+ : `SELECT s.* FROM symbols s
145
+ LEFT JOIN links l ON l.to_id = s.id AND l.type != 'contains'
146
+ WHERE s.exported = 1 AND l.id IS NULL
147
+ LIMIT ?`;
148
+ const rows = kind
149
+ ? this.db.prepare(sql).all(kind, limit)
150
+ : this.db.prepare(sql).all(limit);
151
+ return rows.map(rowToSymbol);
152
+ }
153
+ getTypeHierarchy(symbolId) {
154
+ const ancestors = this.db.prepare(`
155
+ WITH RECURSIVE up(id, depth) AS (
156
+ SELECT to_id, 1 FROM links WHERE from_id = ? AND type IN ('extends', 'implements')
157
+ UNION
158
+ SELECT l.to_id, u.depth + 1
159
+ FROM links l JOIN up u ON l.from_id = u.id
160
+ WHERE l.type IN ('extends', 'implements') AND u.depth < 10
161
+ )
162
+ SELECT DISTINCT s.*, u.depth FROM up u JOIN symbols s ON s.id = u.id ORDER BY u.depth
163
+ `).all(symbolId);
164
+ const descendants = this.db.prepare(`
165
+ WITH RECURSIVE down(id, depth) AS (
166
+ SELECT from_id, 1 FROM links WHERE to_id = ? AND type IN ('extends', 'implements')
167
+ UNION
168
+ SELECT l.from_id, d.depth + 1
169
+ FROM links l JOIN down d ON l.to_id = d.id
170
+ WHERE l.type IN ('extends', 'implements') AND d.depth < 10
171
+ )
172
+ SELECT DISTINCT s.*, d.depth FROM down d JOIN symbols s ON s.id = d.id ORDER BY d.depth
173
+ `).all(symbolId);
174
+ return {
175
+ ancestors: ancestors.map(r => ({ symbol: rowToSymbol(r), depth: r.depth })),
176
+ descendants: descendants.map(r => ({ symbol: rowToSymbol(r), depth: r.depth })),
177
+ };
178
+ }
179
+ findPath(fromName, toName, maxDepth = 5) {
180
+ const fromSyms = this.findSymbolByName(fromName);
181
+ const toSyms = this.findSymbolByName(toName);
182
+ if (fromSyms.length === 0 || toSyms.length === 0)
183
+ return null;
184
+ const fromId = fromSyms[0].id;
185
+ const toIds = new Set(toSyms.map(s => s.id));
186
+ // BFS outgoing from source
187
+ const rows = this.db.prepare(`
188
+ WITH RECURSIVE path(id, depth, via) AS (
189
+ SELECT to_id, 1, type FROM links WHERE from_id = ? AND type != 'contains'
190
+ UNION
191
+ SELECT l.to_id, p.depth + 1, l.type
192
+ FROM links l JOIN path p ON l.from_id = p.id
193
+ WHERE l.type != 'contains' AND p.depth < ?
194
+ )
195
+ SELECT DISTINCT s.*, p.depth, p.via FROM path p JOIN symbols s ON s.id = p.id ORDER BY p.depth
196
+ `).all(fromId, maxDepth);
197
+ const result = [];
198
+ for (const r of rows) {
199
+ result.push({ symbol: rowToSymbol(r), depth: r.depth, via: r.via });
200
+ if (toIds.has(r.id))
201
+ break;
202
+ }
203
+ const found = result.find(r => toIds.has(r.symbol.id));
204
+ if (!found)
205
+ return null;
206
+ return result.filter(r => r.depth <= found.depth);
207
+ }
208
+ getChangedFiles() {
209
+ const rows = this.db.prepare('SELECT DISTINCT file_path FROM symbols').all();
210
+ return rows.map((r) => r.file_path);
211
+ }
212
+ // ── Maintenance ──
213
+ deleteFileData(filePath) {
214
+ this.stmts.deleteFileLinks.run(filePath);
215
+ this.stmts.deleteFileSymbols.run(filePath);
216
+ }
217
+ rebuildSearch() {
218
+ this.db.exec(`INSERT INTO symbol_fts(symbol_fts) VALUES('rebuild')`);
219
+ }
220
+ clearSymbolsAndLinks() {
221
+ this.db.exec('DELETE FROM symbols');
222
+ this.db.exec('DELETE FROM links');
223
+ }
224
+ clear() {
225
+ this.db.exec('DELETE FROM symbols');
226
+ this.db.exec('DELETE FROM links');
227
+ this.db.exec('DELETE FROM file_hashes');
228
+ }
229
+ transaction(fn) {
230
+ return this.db.transaction(fn)();
231
+ }
232
+ close() {
233
+ this.db.close();
234
+ }
235
+ }
236
+ // ── Row mappers ──
237
+ function rowToSymbol(row) {
238
+ return {
239
+ id: row.id,
240
+ name: row.name,
241
+ kind: row.kind,
242
+ filePath: row.file_path,
243
+ startLine: row.start_line,
244
+ endLine: row.end_line,
245
+ exported: row.exported === 1,
246
+ parentId: row.parent_id ?? undefined,
247
+ signature: row.signature ?? undefined,
248
+ };
249
+ }
250
+ function rowToLink(row) {
251
+ return {
252
+ id: row.id,
253
+ fromId: row.from_id,
254
+ toId: row.to_id,
255
+ type: row.type,
256
+ confidence: row.confidence,
257
+ line: row.line_number ?? undefined,
258
+ };
259
+ }
260
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/store/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { RepoEntry } from '../types.js';
2
+ export declare class RepoRegistry {
3
+ private entries;
4
+ constructor();
5
+ private load;
6
+ private save;
7
+ register(rootPath: string, dbPath: string, hash: string): void;
8
+ findByRoot(rootPath: string): RepoEntry | undefined;
9
+ findDbPath(rootPath: string): string | null;
10
+ listAll(): RepoEntry[];
11
+ remove(rootPath: string): boolean;
12
+ }
13
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/store/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK7C,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAmB;;IAMlC,OAAO,CAAC,IAAI;IAWZ,OAAO,CAAC,IAAI;IAKZ,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAiB9D,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAKnD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAO3C,OAAO,IAAI,SAAS,EAAE;IAItB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAUlC"}
@@ -0,0 +1,69 @@
1
+ import { join, resolve } from 'node:path';
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ const MILENS_HOME = join(homedir(), '.milens');
5
+ const REGISTRY_FILE = join(MILENS_HOME, 'registry.json');
6
+ export class RepoRegistry {
7
+ entries = [];
8
+ constructor() {
9
+ this.load();
10
+ }
11
+ load() {
12
+ try {
13
+ if (existsSync(REGISTRY_FILE)) {
14
+ const data = JSON.parse(readFileSync(REGISTRY_FILE, 'utf-8'));
15
+ this.entries = Array.isArray(data) ? data : [];
16
+ }
17
+ }
18
+ catch {
19
+ this.entries = [];
20
+ }
21
+ }
22
+ save() {
23
+ mkdirSync(MILENS_HOME, { recursive: true });
24
+ writeFileSync(REGISTRY_FILE, JSON.stringify(this.entries, null, 2));
25
+ }
26
+ register(rootPath, dbPath, hash) {
27
+ const absolute = resolve(rootPath);
28
+ const idx = this.entries.findIndex(e => e.rootPath === absolute);
29
+ const entry = {
30
+ rootPath: absolute,
31
+ dbPath: resolve(dbPath),
32
+ analyzedAt: new Date().toISOString(),
33
+ hash,
34
+ };
35
+ if (idx >= 0) {
36
+ this.entries[idx] = entry;
37
+ }
38
+ else {
39
+ this.entries.push(entry);
40
+ }
41
+ this.save();
42
+ }
43
+ findByRoot(rootPath) {
44
+ const absolute = resolve(rootPath);
45
+ return this.entries.find(e => e.rootPath === absolute);
46
+ }
47
+ findDbPath(rootPath) {
48
+ const entry = this.findByRoot(rootPath);
49
+ if (!entry)
50
+ return null;
51
+ if (!existsSync(entry.dbPath))
52
+ return null;
53
+ return entry.dbPath;
54
+ }
55
+ listAll() {
56
+ return [...this.entries];
57
+ }
58
+ remove(rootPath) {
59
+ const absolute = resolve(rootPath);
60
+ const before = this.entries.length;
61
+ this.entries = this.entries.filter(e => e.rootPath !== absolute);
62
+ if (this.entries.length < before) {
63
+ this.save();
64
+ return true;
65
+ }
66
+ return false;
67
+ }
68
+ }
69
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/store/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ -- milens code intelligence database schema
2
+
3
+ CREATE TABLE IF NOT EXISTS symbols (
4
+ id TEXT PRIMARY KEY,
5
+ name TEXT NOT NULL,
6
+ kind TEXT NOT NULL,
7
+ file_path TEXT NOT NULL,
8
+ start_line INTEGER,
9
+ end_line INTEGER,
10
+ exported INTEGER DEFAULT 0,
11
+ parent_id TEXT,
12
+ signature TEXT
13
+ );
14
+
15
+ CREATE TABLE IF NOT EXISTS links (
16
+ id TEXT PRIMARY KEY,
17
+ from_id TEXT NOT NULL,
18
+ to_id TEXT NOT NULL,
19
+ type TEXT NOT NULL,
20
+ confidence REAL DEFAULT 1.0,
21
+ line_number INTEGER
22
+ );
23
+
24
+ CREATE TABLE IF NOT EXISTS file_hashes (
25
+ path TEXT PRIMARY KEY,
26
+ hash TEXT NOT NULL,
27
+ analyzed_at TEXT NOT NULL DEFAULT (datetime('now'))
28
+ );
29
+
30
+ CREATE TABLE IF NOT EXISTS meta (
31
+ key TEXT PRIMARY KEY,
32
+ value TEXT
33
+ );
34
+
35
+ CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
36
+ CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_path);
37
+ CREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);
38
+ CREATE INDEX IF NOT EXISTS idx_links_from ON links(from_id);
39
+ CREATE INDEX IF NOT EXISTS idx_links_to ON links(to_id);
40
+ CREATE INDEX IF NOT EXISTS idx_links_type ON links(type);
41
+
42
+ -- FTS5 full-text search on symbol names and paths
43
+ CREATE VIRTUAL TABLE IF NOT EXISTS symbol_fts USING fts5(
44
+ name,
45
+ file_path,
46
+ kind,
47
+ content='symbols',
48
+ content_rowid='rowid'
49
+ );
50
+
51
+ -- Triggers to keep FTS in sync
52
+ CREATE TRIGGER IF NOT EXISTS symbols_ai AFTER INSERT ON symbols BEGIN
53
+ INSERT INTO symbol_fts(rowid, name, file_path, kind)
54
+ VALUES (new.rowid, new.name, new.file_path, new.kind);
55
+ END;
56
+
57
+ CREATE TRIGGER IF NOT EXISTS symbols_ad AFTER DELETE ON symbols BEGIN
58
+ INSERT INTO symbol_fts(symbol_fts, rowid, name, file_path, kind)
59
+ VALUES ('delete', old.rowid, old.name, old.file_path, old.kind);
60
+ END;
@@ -0,0 +1,67 @@
1
+ export type SymbolKind = 'function' | 'class' | 'method' | 'interface' | 'variable' | 'type' | 'enum' | 'struct' | 'trait' | 'module';
2
+ export interface CodeSymbol {
3
+ id: string;
4
+ name: string;
5
+ kind: SymbolKind;
6
+ filePath: string;
7
+ startLine: number;
8
+ endLine: number;
9
+ exported: boolean;
10
+ parentId?: string;
11
+ signature?: string;
12
+ }
13
+ export type LinkType = 'imports' | 'calls' | 'extends' | 'implements' | 'contains';
14
+ export interface SymbolLink {
15
+ id: string;
16
+ fromId: string;
17
+ toId: string;
18
+ type: LinkType;
19
+ confidence: number;
20
+ line?: number;
21
+ }
22
+ export interface RawImport {
23
+ filePath: string;
24
+ modulePath: string;
25
+ names: Array<{
26
+ name: string;
27
+ alias?: string;
28
+ }>;
29
+ isDefault: boolean;
30
+ isWildcard: boolean;
31
+ line: number;
32
+ }
33
+ export interface RawCall {
34
+ filePath: string;
35
+ enclosingSymbolId: string;
36
+ calleeName: string;
37
+ receiver?: string;
38
+ line: number;
39
+ }
40
+ export interface RawHeritage {
41
+ filePath: string;
42
+ childName: string;
43
+ parentName: string;
44
+ type: 'extends' | 'implements';
45
+ line: number;
46
+ }
47
+ export interface ExtractionResult {
48
+ symbols: CodeSymbol[];
49
+ imports: RawImport[];
50
+ calls: RawCall[];
51
+ heritage: RawHeritage[];
52
+ exportedNames: Set<string>;
53
+ }
54
+ export interface AnalysisStats {
55
+ filesScanned: number;
56
+ filesParsed: number;
57
+ symbolCount: number;
58
+ linkCount: number;
59
+ durationMs: number;
60
+ }
61
+ export interface RepoEntry {
62
+ rootPath: string;
63
+ dbPath: string;
64
+ analyzedAt: string;
65
+ hash: string;
66
+ }
67
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAClB,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAC7C,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,CAAC;AAEnF,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,GAAG,YAAY,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ // ── Core domain types for milens code intelligence ──
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,uDAAuD"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "milens",
3
+ "version": "0.2.0",
4
+ "description": "Lightweight Code Intelligence Platform — analyze codebases and build knowledge graphs",
5
+ "type": "module",
6
+ "bin": {
7
+ "milens": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist/",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc && node -e \"require('fs').copyFileSync('src/store/schema.sql','dist/store/schema.sql')\"",
16
+ "dev": "tsx src/cli.ts",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest",
19
+ "lint": "tsc --noEmit",
20
+ "prepublishOnly": "npm run build && npm test",
21
+ "self-analyze": "tsx src/cli.ts analyze -p . --force --verbose",
22
+ "self-serve": "tsx src/cli.ts serve -p . --http --port 3100"
23
+ },
24
+ "keywords": [
25
+ "code-intelligence",
26
+ "knowledge-graph",
27
+ "mcp",
28
+ "tree-sitter",
29
+ "static-analysis",
30
+ "codebase-indexer",
31
+ "ai-agent"
32
+ ],
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/fuze210699/milens.git"
36
+ },
37
+ "homepage": "https://github.com/fuze210699/milens#readme",
38
+ "bugs": {
39
+ "url": "https://github.com/fuze210699/milens/issues"
40
+ },
41
+ "engines": {
42
+ "node": ">=20.0.0"
43
+ },
44
+ "dependencies": {
45
+ "@modelcontextprotocol/sdk": "^1.29.0",
46
+ "better-sqlite3": "^11.0.0",
47
+ "commander": "^12.0.0",
48
+ "ignore": "^7.0.0",
49
+ "tree-sitter-wasms": "^0.1.12",
50
+ "web-tree-sitter": "^0.24.7"
51
+ },
52
+ "license": "MIT",
53
+ "devDependencies": {
54
+ "@types/better-sqlite3": "^7.0.0",
55
+ "@types/node": "^20.0.0",
56
+ "tsx": "^4.0.0",
57
+ "typescript": "^5.4.0",
58
+ "vitest": "^4.0.0"
59
+ }
60
+ }