ai-mind-map 1.6.0 → 1.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/dist/change-tracker/change-log.js +123 -123
- package/dist/cli.js +83 -83
- package/dist/cli.js.map +1 -1
- package/dist/context/compressor.js +3 -3
- package/dist/context/compressor.js.map +1 -1
- package/dist/context/progressive-disclosure.js +4 -4
- package/dist/context/progressive-disclosure.js.map +1 -1
- package/dist/index.d.ts +0 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1371
- package/dist/index.js.map +1 -1
- package/dist/install.js +114 -114
- package/dist/install.js.map +1 -1
- package/dist/knowledge-graph/changelog.js +62 -62
- package/dist/knowledge-graph/dead-code.js +31 -31
- package/dist/knowledge-graph/graph.js +201 -201
- package/dist/knowledge-graph/indexer.d.ts +20 -0
- package/dist/knowledge-graph/indexer.d.ts.map +1 -1
- package/dist/knowledge-graph/indexer.js +55 -4
- package/dist/knowledge-graph/indexer.js.map +1 -1
- package/dist/knowledge-graph/semantic-search.js +50 -50
- package/dist/memory/decision-log.js +61 -61
- package/dist/memory/persistent-memory.js +70 -70
- package/dist/memory/session-memory.js +54 -54
- package/dist/tools/context-tools.js +2 -2
- package/dist/tools/context-tools.js.map +1 -1
- package/dist/tools/debug-tools.js +9 -9
- package/dist/tools/debug-tools.js.map +1 -1
- package/dist/tools/evolving-tools.js +3 -3
- package/dist/tools/evolving-tools.js.map +1 -1
- package/dist/tools/flow-tools.js +29 -29
- package/dist/tools/flow-tools.js.map +1 -1
- package/dist/tools/session-tools.js +2 -2
- package/dist/tools/session-tools.js.map +1 -1
- package/dist/tools/snapshot-tools.js +24 -24
- package/package.json +1 -1
|
@@ -46,109 +46,109 @@ export class ChangeLog {
|
|
|
46
46
|
}
|
|
47
47
|
// ----------------------------------------------------------- schema ---
|
|
48
48
|
initSchema() {
|
|
49
|
-
this.db.exec(`
|
|
50
|
-
-- Sessions table
|
|
51
|
-
CREATE TABLE IF NOT EXISTS change_sessions (
|
|
52
|
-
session_id TEXT PRIMARY KEY,
|
|
53
|
-
started_at INTEGER NOT NULL,
|
|
54
|
-
ended_at INTEGER,
|
|
55
|
-
total_changes INTEGER NOT NULL DEFAULT 0,
|
|
56
|
-
files_modified TEXT NOT NULL DEFAULT '[]',
|
|
57
|
-
summary TEXT NOT NULL DEFAULT ''
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
-- Change records table
|
|
61
|
-
CREATE TABLE IF NOT EXISTS change_records (
|
|
62
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
63
|
-
file_path TEXT NOT NULL,
|
|
64
|
-
change_type TEXT NOT NULL,
|
|
65
|
-
old_path TEXT,
|
|
66
|
-
summary TEXT NOT NULL DEFAULT '',
|
|
67
|
-
symbols_affected TEXT NOT NULL DEFAULT '[]',
|
|
68
|
-
lines_added INTEGER NOT NULL DEFAULT 0,
|
|
69
|
-
lines_removed INTEGER NOT NULL DEFAULT 0,
|
|
70
|
-
timestamp INTEGER NOT NULL,
|
|
71
|
-
session_id TEXT NOT NULL,
|
|
72
|
-
FOREIGN KEY (session_id) REFERENCES change_sessions(session_id)
|
|
73
|
-
ON DELETE CASCADE
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
-- Indexes for common query patterns
|
|
77
|
-
CREATE INDEX IF NOT EXISTS idx_change_records_session
|
|
78
|
-
ON change_records(session_id);
|
|
79
|
-
CREATE INDEX IF NOT EXISTS idx_change_records_file
|
|
80
|
-
ON change_records(file_path);
|
|
81
|
-
CREATE INDEX IF NOT EXISTS idx_change_records_timestamp
|
|
82
|
-
ON change_records(timestamp);
|
|
83
|
-
CREATE INDEX IF NOT EXISTS idx_change_records_change_type
|
|
84
|
-
ON change_records(change_type);
|
|
85
|
-
|
|
86
|
-
-- FTS5 virtual table for full-text search across summaries and symbols
|
|
87
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS change_records_fts USING fts5(
|
|
88
|
-
file_path,
|
|
89
|
-
summary,
|
|
90
|
-
symbols_affected,
|
|
91
|
-
content = 'change_records',
|
|
92
|
-
content_rowid = 'id',
|
|
93
|
-
tokenize = 'porter unicode61'
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
-- Triggers to keep FTS index in sync
|
|
97
|
-
CREATE TRIGGER IF NOT EXISTS trg_change_records_ai
|
|
98
|
-
AFTER INSERT ON change_records BEGIN
|
|
99
|
-
INSERT INTO change_records_fts(rowid, file_path, summary, symbols_affected)
|
|
100
|
-
VALUES (new.id, new.file_path, new.summary, new.symbols_affected);
|
|
101
|
-
END;
|
|
102
|
-
|
|
103
|
-
CREATE TRIGGER IF NOT EXISTS trg_change_records_ad
|
|
104
|
-
AFTER DELETE ON change_records BEGIN
|
|
105
|
-
INSERT INTO change_records_fts(change_records_fts, rowid, file_path, summary, symbols_affected)
|
|
106
|
-
VALUES ('delete', old.id, old.file_path, old.summary, old.symbols_affected);
|
|
107
|
-
END;
|
|
108
|
-
|
|
109
|
-
CREATE TRIGGER IF NOT EXISTS trg_change_records_au
|
|
110
|
-
AFTER UPDATE ON change_records BEGIN
|
|
111
|
-
INSERT INTO change_records_fts(change_records_fts, rowid, file_path, summary, symbols_affected)
|
|
112
|
-
VALUES ('delete', old.id, old.file_path, old.summary, old.symbols_affected);
|
|
113
|
-
INSERT INTO change_records_fts(rowid, file_path, summary, symbols_affected)
|
|
114
|
-
VALUES (new.id, new.file_path, new.summary, new.symbols_affected);
|
|
115
|
-
END;
|
|
49
|
+
this.db.exec(`
|
|
50
|
+
-- Sessions table
|
|
51
|
+
CREATE TABLE IF NOT EXISTS change_sessions (
|
|
52
|
+
session_id TEXT PRIMARY KEY,
|
|
53
|
+
started_at INTEGER NOT NULL,
|
|
54
|
+
ended_at INTEGER,
|
|
55
|
+
total_changes INTEGER NOT NULL DEFAULT 0,
|
|
56
|
+
files_modified TEXT NOT NULL DEFAULT '[]',
|
|
57
|
+
summary TEXT NOT NULL DEFAULT ''
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
-- Change records table
|
|
61
|
+
CREATE TABLE IF NOT EXISTS change_records (
|
|
62
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
63
|
+
file_path TEXT NOT NULL,
|
|
64
|
+
change_type TEXT NOT NULL,
|
|
65
|
+
old_path TEXT,
|
|
66
|
+
summary TEXT NOT NULL DEFAULT '',
|
|
67
|
+
symbols_affected TEXT NOT NULL DEFAULT '[]',
|
|
68
|
+
lines_added INTEGER NOT NULL DEFAULT 0,
|
|
69
|
+
lines_removed INTEGER NOT NULL DEFAULT 0,
|
|
70
|
+
timestamp INTEGER NOT NULL,
|
|
71
|
+
session_id TEXT NOT NULL,
|
|
72
|
+
FOREIGN KEY (session_id) REFERENCES change_sessions(session_id)
|
|
73
|
+
ON DELETE CASCADE
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
-- Indexes for common query patterns
|
|
77
|
+
CREATE INDEX IF NOT EXISTS idx_change_records_session
|
|
78
|
+
ON change_records(session_id);
|
|
79
|
+
CREATE INDEX IF NOT EXISTS idx_change_records_file
|
|
80
|
+
ON change_records(file_path);
|
|
81
|
+
CREATE INDEX IF NOT EXISTS idx_change_records_timestamp
|
|
82
|
+
ON change_records(timestamp);
|
|
83
|
+
CREATE INDEX IF NOT EXISTS idx_change_records_change_type
|
|
84
|
+
ON change_records(change_type);
|
|
85
|
+
|
|
86
|
+
-- FTS5 virtual table for full-text search across summaries and symbols
|
|
87
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS change_records_fts USING fts5(
|
|
88
|
+
file_path,
|
|
89
|
+
summary,
|
|
90
|
+
symbols_affected,
|
|
91
|
+
content = 'change_records',
|
|
92
|
+
content_rowid = 'id',
|
|
93
|
+
tokenize = 'porter unicode61'
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
-- Triggers to keep FTS index in sync
|
|
97
|
+
CREATE TRIGGER IF NOT EXISTS trg_change_records_ai
|
|
98
|
+
AFTER INSERT ON change_records BEGIN
|
|
99
|
+
INSERT INTO change_records_fts(rowid, file_path, summary, symbols_affected)
|
|
100
|
+
VALUES (new.id, new.file_path, new.summary, new.symbols_affected);
|
|
101
|
+
END;
|
|
102
|
+
|
|
103
|
+
CREATE TRIGGER IF NOT EXISTS trg_change_records_ad
|
|
104
|
+
AFTER DELETE ON change_records BEGIN
|
|
105
|
+
INSERT INTO change_records_fts(change_records_fts, rowid, file_path, summary, symbols_affected)
|
|
106
|
+
VALUES ('delete', old.id, old.file_path, old.summary, old.symbols_affected);
|
|
107
|
+
END;
|
|
108
|
+
|
|
109
|
+
CREATE TRIGGER IF NOT EXISTS trg_change_records_au
|
|
110
|
+
AFTER UPDATE ON change_records BEGIN
|
|
111
|
+
INSERT INTO change_records_fts(change_records_fts, rowid, file_path, summary, symbols_affected)
|
|
112
|
+
VALUES ('delete', old.id, old.file_path, old.summary, old.symbols_affected);
|
|
113
|
+
INSERT INTO change_records_fts(rowid, file_path, summary, symbols_affected)
|
|
114
|
+
VALUES (new.id, new.file_path, new.summary, new.symbols_affected);
|
|
115
|
+
END;
|
|
116
116
|
`);
|
|
117
117
|
}
|
|
118
118
|
prepareStatements() {
|
|
119
|
-
this.stmtInsertChange = this.db.prepare(`
|
|
120
|
-
INSERT INTO change_records
|
|
121
|
-
(file_path, change_type, old_path, summary, symbols_affected,
|
|
122
|
-
lines_added, lines_removed, timestamp, session_id)
|
|
123
|
-
VALUES
|
|
124
|
-
(@filePath, @changeType, @oldPath, @summary, @symbolsAffected,
|
|
125
|
-
@linesAdded, @linesRemoved, @timestamp, @sessionId)
|
|
119
|
+
this.stmtInsertChange = this.db.prepare(`
|
|
120
|
+
INSERT INTO change_records
|
|
121
|
+
(file_path, change_type, old_path, summary, symbols_affected,
|
|
122
|
+
lines_added, lines_removed, timestamp, session_id)
|
|
123
|
+
VALUES
|
|
124
|
+
(@filePath, @changeType, @oldPath, @summary, @symbolsAffected,
|
|
125
|
+
@linesAdded, @linesRemoved, @timestamp, @sessionId)
|
|
126
126
|
`);
|
|
127
|
-
this.stmtInsertSession = this.db.prepare(`
|
|
128
|
-
INSERT INTO change_sessions (session_id, started_at)
|
|
129
|
-
VALUES (@sessionId, @startedAt)
|
|
127
|
+
this.stmtInsertSession = this.db.prepare(`
|
|
128
|
+
INSERT INTO change_sessions (session_id, started_at)
|
|
129
|
+
VALUES (@sessionId, @startedAt)
|
|
130
130
|
`);
|
|
131
|
-
this.stmtEndSession = this.db.prepare(`
|
|
132
|
-
UPDATE change_sessions
|
|
133
|
-
SET ended_at = @endedAt,
|
|
134
|
-
total_changes = (
|
|
135
|
-
SELECT COUNT(*) FROM change_records WHERE session_id = @sessionId
|
|
136
|
-
),
|
|
137
|
-
files_modified = (
|
|
138
|
-
SELECT json_group_array(DISTINCT file_path)
|
|
139
|
-
FROM change_records WHERE session_id = @sessionId
|
|
140
|
-
),
|
|
141
|
-
summary = @summary
|
|
142
|
-
WHERE session_id = @sessionId
|
|
131
|
+
this.stmtEndSession = this.db.prepare(`
|
|
132
|
+
UPDATE change_sessions
|
|
133
|
+
SET ended_at = @endedAt,
|
|
134
|
+
total_changes = (
|
|
135
|
+
SELECT COUNT(*) FROM change_records WHERE session_id = @sessionId
|
|
136
|
+
),
|
|
137
|
+
files_modified = (
|
|
138
|
+
SELECT json_group_array(DISTINCT file_path)
|
|
139
|
+
FROM change_records WHERE session_id = @sessionId
|
|
140
|
+
),
|
|
141
|
+
summary = @summary
|
|
142
|
+
WHERE session_id = @sessionId
|
|
143
143
|
`);
|
|
144
|
-
this.stmtGetSession = this.db.prepare(`
|
|
145
|
-
SELECT * FROM change_sessions WHERE session_id = ?
|
|
144
|
+
this.stmtGetSession = this.db.prepare(`
|
|
145
|
+
SELECT * FROM change_sessions WHERE session_id = ?
|
|
146
146
|
`);
|
|
147
|
-
this.stmtDeleteOldChanges = this.db.prepare(`
|
|
148
|
-
DELETE FROM change_records WHERE timestamp < ?
|
|
147
|
+
this.stmtDeleteOldChanges = this.db.prepare(`
|
|
148
|
+
DELETE FROM change_records WHERE timestamp < ?
|
|
149
149
|
`);
|
|
150
|
-
this.stmtDeleteOldSessions = this.db.prepare(`
|
|
151
|
-
DELETE FROM change_sessions WHERE ended_at IS NOT NULL AND ended_at < ?
|
|
150
|
+
this.stmtDeleteOldSessions = this.db.prepare(`
|
|
151
|
+
DELETE FROM change_sessions WHERE ended_at IS NOT NULL AND ended_at < ?
|
|
152
152
|
`);
|
|
153
153
|
}
|
|
154
154
|
// ----------------------------------------------------- sessions ------
|
|
@@ -271,11 +271,11 @@ export class ChangeLog {
|
|
|
271
271
|
const where = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';
|
|
272
272
|
const limit = options.limit ?? 100;
|
|
273
273
|
const offset = options.offset ?? 0;
|
|
274
|
-
const sql = `
|
|
275
|
-
SELECT * FROM change_records
|
|
276
|
-
${where}
|
|
277
|
-
ORDER BY timestamp DESC
|
|
278
|
-
LIMIT @limit OFFSET @offset
|
|
274
|
+
const sql = `
|
|
275
|
+
SELECT * FROM change_records
|
|
276
|
+
${where}
|
|
277
|
+
ORDER BY timestamp DESC
|
|
278
|
+
LIMIT @limit OFFSET @offset
|
|
279
279
|
`;
|
|
280
280
|
const rows = this.db.prepare(sql).all({ ...params, limit, offset });
|
|
281
281
|
return rows.map(rowToFileChange);
|
|
@@ -307,15 +307,15 @@ export class ChangeLog {
|
|
|
307
307
|
if (!sanitised)
|
|
308
308
|
return [];
|
|
309
309
|
try {
|
|
310
|
-
const sql = `
|
|
311
|
-
SELECT
|
|
312
|
-
cr.*,
|
|
313
|
-
bm25(change_records_fts, 1.0, 2.0, 1.5) AS rank
|
|
314
|
-
FROM change_records_fts fts
|
|
315
|
-
JOIN change_records cr ON cr.id = fts.rowid
|
|
316
|
-
WHERE change_records_fts MATCH @query
|
|
317
|
-
ORDER BY rank
|
|
318
|
-
LIMIT @limit
|
|
310
|
+
const sql = `
|
|
311
|
+
SELECT
|
|
312
|
+
cr.*,
|
|
313
|
+
bm25(change_records_fts, 1.0, 2.0, 1.5) AS rank
|
|
314
|
+
FROM change_records_fts fts
|
|
315
|
+
JOIN change_records cr ON cr.id = fts.rowid
|
|
316
|
+
WHERE change_records_fts MATCH @query
|
|
317
|
+
ORDER BY rank
|
|
318
|
+
LIMIT @limit
|
|
319
319
|
`;
|
|
320
320
|
const rows = this.db.prepare(sql).all({ query: sanitised, limit: maxResults });
|
|
321
321
|
return rows.map((r) => ({
|
|
@@ -408,26 +408,26 @@ export class ChangeLog {
|
|
|
408
408
|
const totalSessions = this.db.prepare('SELECT COUNT(*) AS cnt FROM change_sessions').get().cnt;
|
|
409
409
|
const activeSessions = this.db.prepare('SELECT COUNT(*) AS cnt FROM change_sessions WHERE ended_at IS NULL').get().cnt;
|
|
410
410
|
const mostChangedFiles = this.db
|
|
411
|
-
.prepare(`SELECT file_path AS filePath, COUNT(*) AS changeCount
|
|
412
|
-
FROM change_records
|
|
413
|
-
GROUP BY file_path
|
|
414
|
-
ORDER BY changeCount DESC
|
|
411
|
+
.prepare(`SELECT file_path AS filePath, COUNT(*) AS changeCount
|
|
412
|
+
FROM change_records
|
|
413
|
+
GROUP BY file_path
|
|
414
|
+
ORDER BY changeCount DESC
|
|
415
415
|
LIMIT ?`)
|
|
416
416
|
.all(topN);
|
|
417
417
|
const mostActiveSessions = this.db
|
|
418
|
-
.prepare(`SELECT cs.session_id AS sessionId,
|
|
419
|
-
COUNT(cr.id) AS changeCount,
|
|
420
|
-
cs.started_at AS startedAt
|
|
421
|
-
FROM change_sessions cs
|
|
422
|
-
LEFT JOIN change_records cr ON cr.session_id = cs.session_id
|
|
423
|
-
GROUP BY cs.session_id
|
|
424
|
-
ORDER BY changeCount DESC
|
|
418
|
+
.prepare(`SELECT cs.session_id AS sessionId,
|
|
419
|
+
COUNT(cr.id) AS changeCount,
|
|
420
|
+
cs.started_at AS startedAt
|
|
421
|
+
FROM change_sessions cs
|
|
422
|
+
LEFT JOIN change_records cr ON cr.session_id = cs.session_id
|
|
423
|
+
GROUP BY cs.session_id
|
|
424
|
+
ORDER BY changeCount DESC
|
|
425
425
|
LIMIT ?`)
|
|
426
426
|
.all(topN);
|
|
427
427
|
const lineStats = this.db
|
|
428
|
-
.prepare(`SELECT
|
|
429
|
-
COALESCE(SUM(lines_added), 0) AS linesAdded,
|
|
430
|
-
COALESCE(SUM(lines_removed), 0) AS linesRemoved
|
|
428
|
+
.prepare(`SELECT
|
|
429
|
+
COALESCE(SUM(lines_added), 0) AS linesAdded,
|
|
430
|
+
COALESCE(SUM(lines_removed), 0) AS linesRemoved
|
|
431
431
|
FROM change_records`)
|
|
432
432
|
.get();
|
|
433
433
|
return {
|
package/dist/cli.js
CHANGED
|
@@ -50,10 +50,10 @@ const c = {
|
|
|
50
50
|
gray: supportsColor ? '\x1b[90m' : '',
|
|
51
51
|
};
|
|
52
52
|
function success(msg) {
|
|
53
|
-
console.log(`${c.green}
|
|
53
|
+
console.log(`${c.green}${c.reset} ${msg}`);
|
|
54
54
|
}
|
|
55
55
|
function error(msg) {
|
|
56
|
-
console.log(`${c.red}
|
|
56
|
+
console.log(`${c.red}${c.reset} ${msg}`);
|
|
57
57
|
}
|
|
58
58
|
function info(msg) {
|
|
59
59
|
console.log(`${c.blue}ℹ${c.reset} ${msg}`);
|
|
@@ -193,7 +193,7 @@ async function cmdServe() {
|
|
|
193
193
|
/** ai-mind-map index <project-path> — Index a project */
|
|
194
194
|
async function cmdIndex(args) {
|
|
195
195
|
const projectPath = args.positional[0] || process.cwd();
|
|
196
|
-
heading('
|
|
196
|
+
heading(' Indexing Project');
|
|
197
197
|
info(`Project: ${path.resolve(projectPath)}`);
|
|
198
198
|
divider();
|
|
199
199
|
const config = await resolveConfig(projectPath);
|
|
@@ -221,7 +221,7 @@ async function cmdIndex(args) {
|
|
|
221
221
|
// Clear the progress line
|
|
222
222
|
process.stdout.write('\r' + ' '.repeat(60) + '\r');
|
|
223
223
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
224
|
-
heading('
|
|
224
|
+
heading(' Index Results');
|
|
225
225
|
divider();
|
|
226
226
|
console.log(` ${pad('Files scanned:', 20)} ${c.bold}${formatNum(stats.filesScanned)}${c.reset}`);
|
|
227
227
|
console.log(` ${pad('Files parsed:', 20)} ${c.bold}${formatNum(stats.filesParsed)}${c.reset}`);
|
|
@@ -260,7 +260,7 @@ async function cmdSearch(args) {
|
|
|
260
260
|
results = results.filter((n) => n.type === typeFilter);
|
|
261
261
|
}
|
|
262
262
|
results = results.slice(0, limit);
|
|
263
|
-
heading(
|
|
263
|
+
heading(` Search Results for "${query}"`);
|
|
264
264
|
if (typeFilter)
|
|
265
265
|
info(`Type filter: ${typeFilter}`);
|
|
266
266
|
divider();
|
|
@@ -321,7 +321,7 @@ async function cmdTrace(args) {
|
|
|
321
321
|
info('Try running "ai-mind-map index" first, or search with "ai-mind-map search".');
|
|
322
322
|
return;
|
|
323
323
|
}
|
|
324
|
-
heading(
|
|
324
|
+
heading(` Trace: ${symbolName}`);
|
|
325
325
|
info(`Direction: ${direction} | Depth: ${depth}`);
|
|
326
326
|
divider();
|
|
327
327
|
for (const node of nodes) {
|
|
@@ -362,7 +362,7 @@ async function cmdTrace(args) {
|
|
|
362
362
|
// Blast radius
|
|
363
363
|
const blast = graph.blastRadius(node.id, depth);
|
|
364
364
|
if (blast.length > 0) {
|
|
365
|
-
console.log(`\n ${c.red}
|
|
365
|
+
console.log(`\n ${c.red} Blast Radius${c.reset} (${blast.length} affected nodes):`);
|
|
366
366
|
for (const affected of blast.slice(0, 10)) {
|
|
367
367
|
console.log(` ${c.yellow}⚡${c.reset} ${affected.qualifiedName} ` +
|
|
368
368
|
`${c.dim}(${affected.type})${c.reset}`);
|
|
@@ -385,7 +385,7 @@ async function cmdStructure(args) {
|
|
|
385
385
|
const graph = openGraph(config);
|
|
386
386
|
try {
|
|
387
387
|
const overview = graph.getProjectOverview();
|
|
388
|
-
heading('
|
|
388
|
+
heading(' Project Structure');
|
|
389
389
|
info(`Project: ${config.projectRoot}`);
|
|
390
390
|
divider();
|
|
391
391
|
if (overview.size === 0) {
|
|
@@ -420,7 +420,7 @@ async function cmdStructure(args) {
|
|
|
420
420
|
async function cmdStatus(args) {
|
|
421
421
|
const projectPath = args.positional[0];
|
|
422
422
|
const config = await resolveConfig(projectPath);
|
|
423
|
-
heading('
|
|
423
|
+
heading(' AI Mind Map Status');
|
|
424
424
|
info(`Project: ${config.projectRoot}`);
|
|
425
425
|
info(`Database: ${config.dbPath}`);
|
|
426
426
|
divider();
|
|
@@ -509,7 +509,7 @@ async function cmdRecall(args) {
|
|
|
509
509
|
try {
|
|
510
510
|
const memory = new PersistentMemory(db, config.memory);
|
|
511
511
|
const results = memory.queryMemories({ text: query, limit });
|
|
512
|
-
heading(
|
|
512
|
+
heading(` Memory Recall: "${query}"`);
|
|
513
513
|
divider();
|
|
514
514
|
if (results.length === 0) {
|
|
515
515
|
warn('No memories found matching your query.');
|
|
@@ -582,7 +582,7 @@ async function cmdRemember(args) {
|
|
|
582
582
|
tags,
|
|
583
583
|
source: 'user',
|
|
584
584
|
});
|
|
585
|
-
heading('
|
|
585
|
+
heading(' Memory Stored');
|
|
586
586
|
divider();
|
|
587
587
|
console.log(` ${pad('ID:', 14)} ${c.bold}#${created.id}${c.reset}`);
|
|
588
588
|
console.log(` ${pad('Category:', 14)} ${getCategoryColor(created.category)}${created.category}${c.reset}`);
|
|
@@ -611,7 +611,7 @@ async function cmdDecisions(args) {
|
|
|
611
611
|
status: statusFilter,
|
|
612
612
|
limit: 50,
|
|
613
613
|
});
|
|
614
|
-
heading('
|
|
614
|
+
heading(' Decision Log');
|
|
615
615
|
if (statusFilter)
|
|
616
616
|
info(`Filter: status = ${statusFilter}`);
|
|
617
617
|
divider();
|
|
@@ -646,7 +646,7 @@ async function cmdChanges(args) {
|
|
|
646
646
|
const sinceRaw = typeof args.flags['since'] === 'string' ? args.flags['since'] : undefined;
|
|
647
647
|
const limit = typeof args.flags['limit'] === 'string' ? parseInt(args.flags['limit'], 10) : 30;
|
|
648
648
|
const config = await resolveConfig();
|
|
649
|
-
heading('
|
|
649
|
+
heading(' Change History');
|
|
650
650
|
divider();
|
|
651
651
|
if (!existsSync(config.dbPath)) {
|
|
652
652
|
warn('Database not found. Run "ai-mind-map index" first.');
|
|
@@ -707,7 +707,7 @@ async function cmdConfig(args) {
|
|
|
707
707
|
const subCommand = args.positional[0] || 'list';
|
|
708
708
|
if (subCommand === 'list') {
|
|
709
709
|
const config = await resolveConfig();
|
|
710
|
-
heading('
|
|
710
|
+
heading('⚙ Configuration');
|
|
711
711
|
divider();
|
|
712
712
|
printConfigRecursive(config, '');
|
|
713
713
|
divider();
|
|
@@ -767,7 +767,7 @@ function getNestedValue(obj, path) {
|
|
|
767
767
|
}
|
|
768
768
|
/** ai-mind-map sync — Sync local memories/decisions/rules with team-shared file */
|
|
769
769
|
async function cmdSync(args) {
|
|
770
|
-
heading('
|
|
770
|
+
heading(' Team Shared Context Synchronization');
|
|
771
771
|
divider();
|
|
772
772
|
const config = await loadConfig({
|
|
773
773
|
projectRoot: args.flags['project-root'],
|
|
@@ -814,7 +814,7 @@ async function cmdSync(args) {
|
|
|
814
814
|
}
|
|
815
815
|
/** ai-mind-map update — Check for updates */
|
|
816
816
|
async function cmdUpdate() {
|
|
817
|
-
heading('
|
|
817
|
+
heading(' AI Mind Map — Update');
|
|
818
818
|
divider();
|
|
819
819
|
const currentVersion = getVersion();
|
|
820
820
|
info(`Current version: ${c.bold}v${currentVersion}${c.reset}`);
|
|
@@ -837,7 +837,7 @@ async function cmdUpdate() {
|
|
|
837
837
|
// 2. Compare versions
|
|
838
838
|
if (currentVersion === latestVersion) {
|
|
839
839
|
console.log('');
|
|
840
|
-
console.log(` ${c.green}
|
|
840
|
+
console.log(` ${c.green}${c.reset} You are already on the latest version!`);
|
|
841
841
|
console.log('');
|
|
842
842
|
divider();
|
|
843
843
|
return;
|
|
@@ -861,7 +861,7 @@ async function cmdUpdate() {
|
|
|
861
861
|
const isNpx = process.argv[1]?.includes('_npx') || process.argv[1]?.includes('npm-cache');
|
|
862
862
|
if (isNpx) {
|
|
863
863
|
// npx always uses latest on next run
|
|
864
|
-
console.log(` ${c.green}
|
|
864
|
+
console.log(` ${c.green}${c.reset} You're using npx — next run will automatically use v${latestVersion}`);
|
|
865
865
|
info('To force a cache refresh now:');
|
|
866
866
|
console.log(`\n ${c.bold}npx -y ai-mind-map@latest install${c.reset}\n`);
|
|
867
867
|
}
|
|
@@ -875,7 +875,7 @@ async function cmdUpdate() {
|
|
|
875
875
|
console.log(` ${c.dim}$ ${updateCmd}${c.reset}`);
|
|
876
876
|
execSync(updateCmd, { stdio: 'inherit', timeout: 60_000 });
|
|
877
877
|
console.log('');
|
|
878
|
-
console.log(` ${c.green}
|
|
878
|
+
console.log(` ${c.green}${c.reset} Updated to v${latestVersion}!`);
|
|
879
879
|
}
|
|
880
880
|
catch (err) {
|
|
881
881
|
warn('Auto-update failed. Update manually:');
|
|
@@ -903,75 +903,75 @@ async function cmdUpdate() {
|
|
|
903
903
|
}
|
|
904
904
|
console.log('');
|
|
905
905
|
divider();
|
|
906
|
-
console.log(` ${c.green}
|
|
906
|
+
console.log(` ${c.green}${c.reset} ${c.bold}Update complete!${c.reset} Restart your AI agent to use the new version.`);
|
|
907
907
|
console.log('');
|
|
908
908
|
}
|
|
909
909
|
/** ai-mind-map --help — Show help text */
|
|
910
910
|
function showHelp() {
|
|
911
911
|
const version = getVersion();
|
|
912
|
-
console.log(`
|
|
913
|
-
${c.bold}${c.cyan}AI Mind Map${c.reset} ${c.dim}v${version}${c.reset}
|
|
914
|
-
${c.dim}MCP server that reduces AI coding agent token usage by 80-99%.${c.reset}
|
|
915
|
-
|
|
916
|
-
${c.bold}USAGE${c.reset}
|
|
917
|
-
${c.cyan}ai-mind-map${c.reset} <command> [options]
|
|
918
|
-
|
|
919
|
-
${c.bold}COMMANDS${c.reset}
|
|
920
|
-
${c.cyan}serve${c.reset} Start MCP server (default)
|
|
921
|
-
${c.cyan}index${c.reset} <project-path> Index a project's codebase
|
|
922
|
-
${c.cyan}search${c.reset} <query> Search the knowledge graph
|
|
923
|
-
${c.dim}--type <type> Filter: func, class, method, etc.${c.reset}
|
|
924
|
-
${c.dim}--limit <N> Max results (default: 20)${c.reset}
|
|
925
|
-
${c.cyan}trace${c.reset} <symbol-name> Trace symbol dependencies
|
|
926
|
-
${c.dim}--direction <dir> both, callers, or callees (default: both)${c.reset}
|
|
927
|
-
${c.dim}--depth <N> Traversal depth (default: 3)${c.reset}
|
|
928
|
-
${c.cyan}structure${c.reset} [<project-path>] Show project structure overview
|
|
929
|
-
${c.cyan}status${c.reset} [<project-path>] Show index and memory stats
|
|
930
|
-
${c.cyan}recall${c.reset} <query> Search stored memories
|
|
931
|
-
${c.cyan}remember${c.reset} <content> Store a new memory
|
|
932
|
-
${c.dim}--category <cat> Category (default: convention)${c.reset}
|
|
933
|
-
${c.dim}--tags <tag1,tag2> Comma-separated tags${c.reset}
|
|
934
|
-
${c.cyan}decisions${c.reset} List architectural decisions
|
|
935
|
-
${c.dim}--status <status> Filter: active, superseded, reversed${c.reset}
|
|
936
|
-
${c.cyan}changes${c.reset} Show change history
|
|
937
|
-
${c.dim}--since <last_session|epoch> Filter changes since timestamp${c.reset}
|
|
938
|
-
${c.dim}--limit <N> Max results (default: 30)${c.reset}
|
|
939
|
-
${c.cyan}sync${c.reset} Sync memories, decisions, and rules with shared file
|
|
940
|
-
|
|
941
|
-
${c.bold}AGENT MANAGEMENT${c.reset}
|
|
942
|
-
${c.cyan}install${c.reset} Auto-detect and configure AI agents
|
|
943
|
-
${c.cyan}uninstall${c.reset} Remove agent configurations
|
|
944
|
-
${c.cyan}update${c.reset} Check for updates + auto-update
|
|
945
|
-
${c.cyan}doctor${c.reset} Run diagnostics check
|
|
946
|
-
${c.cyan}doctor --fix${c.reset} Auto-repair broken configurations
|
|
947
|
-
|
|
948
|
-
${c.bold}CONFIGURATION${c.reset}
|
|
949
|
-
${c.cyan}config list${c.reset} Show current configuration
|
|
950
|
-
${c.cyan}config set${c.reset} <key> <value> Set a config value
|
|
951
|
-
${c.cyan}config reset${c.reset} <key> Reset a key to default
|
|
952
|
-
|
|
953
|
-
${c.bold}OTHER${c.reset}
|
|
954
|
-
${c.dim}--help, -h${c.reset} Show this help message
|
|
955
|
-
${c.dim}--version, -v${c.reset} Show version
|
|
956
|
-
|
|
957
|
-
${c.bold}EXAMPLES${c.reset}
|
|
958
|
-
${c.dim}# Index current directory${c.reset}
|
|
959
|
-
${c.cyan}ai-mind-map index .${c.reset}
|
|
960
|
-
|
|
961
|
-
${c.dim}# Search for a function${c.reset}
|
|
962
|
-
${c.cyan}ai-mind-map search "handleAuth" --type function${c.reset}
|
|
963
|
-
|
|
964
|
-
${c.dim}# Trace who calls a function${c.reset}
|
|
965
|
-
${c.cyan}ai-mind-map trace parseConfig --direction callers${c.reset}
|
|
966
|
-
|
|
967
|
-
${c.dim}# Store a convention${c.reset}
|
|
968
|
-
${c.cyan}ai-mind-map remember "Always use snake_case for DB columns" --category convention${c.reset}
|
|
969
|
-
|
|
970
|
-
${c.dim}# Install MCP config for all detected agents${c.reset}
|
|
971
|
-
${c.cyan}ai-mind-map install${c.reset}
|
|
972
|
-
|
|
973
|
-
${c.dim}# Run diagnostics${c.reset}
|
|
974
|
-
${c.cyan}ai-mind-map doctor${c.reset}
|
|
912
|
+
console.log(`
|
|
913
|
+
${c.bold}${c.cyan}AI Mind Map${c.reset} ${c.dim}v${version}${c.reset}
|
|
914
|
+
${c.dim}MCP server that reduces AI coding agent token usage by 80-99%.${c.reset}
|
|
915
|
+
|
|
916
|
+
${c.bold}USAGE${c.reset}
|
|
917
|
+
${c.cyan}ai-mind-map${c.reset} <command> [options]
|
|
918
|
+
|
|
919
|
+
${c.bold}COMMANDS${c.reset}
|
|
920
|
+
${c.cyan}serve${c.reset} Start MCP server (default)
|
|
921
|
+
${c.cyan}index${c.reset} <project-path> Index a project's codebase
|
|
922
|
+
${c.cyan}search${c.reset} <query> Search the knowledge graph
|
|
923
|
+
${c.dim}--type <type> Filter: func, class, method, etc.${c.reset}
|
|
924
|
+
${c.dim}--limit <N> Max results (default: 20)${c.reset}
|
|
925
|
+
${c.cyan}trace${c.reset} <symbol-name> Trace symbol dependencies
|
|
926
|
+
${c.dim}--direction <dir> both, callers, or callees (default: both)${c.reset}
|
|
927
|
+
${c.dim}--depth <N> Traversal depth (default: 3)${c.reset}
|
|
928
|
+
${c.cyan}structure${c.reset} [<project-path>] Show project structure overview
|
|
929
|
+
${c.cyan}status${c.reset} [<project-path>] Show index and memory stats
|
|
930
|
+
${c.cyan}recall${c.reset} <query> Search stored memories
|
|
931
|
+
${c.cyan}remember${c.reset} <content> Store a new memory
|
|
932
|
+
${c.dim}--category <cat> Category (default: convention)${c.reset}
|
|
933
|
+
${c.dim}--tags <tag1,tag2> Comma-separated tags${c.reset}
|
|
934
|
+
${c.cyan}decisions${c.reset} List architectural decisions
|
|
935
|
+
${c.dim}--status <status> Filter: active, superseded, reversed${c.reset}
|
|
936
|
+
${c.cyan}changes${c.reset} Show change history
|
|
937
|
+
${c.dim}--since <last_session|epoch> Filter changes since timestamp${c.reset}
|
|
938
|
+
${c.dim}--limit <N> Max results (default: 30)${c.reset}
|
|
939
|
+
${c.cyan}sync${c.reset} Sync memories, decisions, and rules with shared file
|
|
940
|
+
|
|
941
|
+
${c.bold}AGENT MANAGEMENT${c.reset}
|
|
942
|
+
${c.cyan}install${c.reset} Auto-detect and configure AI agents
|
|
943
|
+
${c.cyan}uninstall${c.reset} Remove agent configurations
|
|
944
|
+
${c.cyan}update${c.reset} Check for updates + auto-update
|
|
945
|
+
${c.cyan}doctor${c.reset} Run diagnostics check
|
|
946
|
+
${c.cyan}doctor --fix${c.reset} Auto-repair broken configurations
|
|
947
|
+
|
|
948
|
+
${c.bold}CONFIGURATION${c.reset}
|
|
949
|
+
${c.cyan}config list${c.reset} Show current configuration
|
|
950
|
+
${c.cyan}config set${c.reset} <key> <value> Set a config value
|
|
951
|
+
${c.cyan}config reset${c.reset} <key> Reset a key to default
|
|
952
|
+
|
|
953
|
+
${c.bold}OTHER${c.reset}
|
|
954
|
+
${c.dim}--help, -h${c.reset} Show this help message
|
|
955
|
+
${c.dim}--version, -v${c.reset} Show version
|
|
956
|
+
|
|
957
|
+
${c.bold}EXAMPLES${c.reset}
|
|
958
|
+
${c.dim}# Index current directory${c.reset}
|
|
959
|
+
${c.cyan}ai-mind-map index .${c.reset}
|
|
960
|
+
|
|
961
|
+
${c.dim}# Search for a function${c.reset}
|
|
962
|
+
${c.cyan}ai-mind-map search "handleAuth" --type function${c.reset}
|
|
963
|
+
|
|
964
|
+
${c.dim}# Trace who calls a function${c.reset}
|
|
965
|
+
${c.cyan}ai-mind-map trace parseConfig --direction callers${c.reset}
|
|
966
|
+
|
|
967
|
+
${c.dim}# Store a convention${c.reset}
|
|
968
|
+
${c.cyan}ai-mind-map remember "Always use snake_case for DB columns" --category convention${c.reset}
|
|
969
|
+
|
|
970
|
+
${c.dim}# Install MCP config for all detected agents${c.reset}
|
|
971
|
+
${c.cyan}ai-mind-map install${c.reset}
|
|
972
|
+
|
|
973
|
+
${c.dim}# Run diagnostics${c.reset}
|
|
974
|
+
${c.cyan}ai-mind-map doctor${c.reset}
|
|
975
975
|
`);
|
|
976
976
|
}
|
|
977
977
|
// ============================================================
|