devsmind-mcp 2.2.2 → 2.3.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/README.md +234 -606
- package/dist/cli/analyze.d.ts +13 -0
- package/dist/cli/analyze.js +143 -0
- package/dist/cli/analyze.js.map +1 -0
- package/dist/cli/index.js +62 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/integrations/memory.js +7 -2
- package/dist/cli/integrations/memory.js.map +1 -1
- package/dist/cli/integrations/prompt.d.ts +2 -0
- package/dist/cli/integrations/prompt.js +21 -7
- package/dist/cli/integrations/prompt.js.map +1 -1
- package/dist/cli/rule.js +35 -54
- package/dist/cli/rule.js.map +1 -1
- package/dist/cli/sync.d.ts +7 -0
- package/dist/cli/sync.js +40 -7
- package/dist/cli/sync.js.map +1 -1
- package/dist/cli/workflow.d.ts +8 -0
- package/dist/cli/workflow.js +156 -0
- package/dist/cli/workflow.js.map +1 -0
- package/dist/db/analyze.d.ts +67 -0
- package/dist/db/analyze.js +163 -0
- package/dist/db/analyze.js.map +1 -0
- package/dist/db/database.d.ts +151 -2
- package/dist/db/database.js +682 -62
- package/dist/db/database.js.map +1 -1
- package/dist/db/schema.d.ts +28 -1
- package/dist/db/schema.js +34 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/db/staging.d.ts +4 -0
- package/dist/db/staging.js +16 -2
- package/dist/db/staging.js.map +1 -1
- package/dist/db/workflow-import.d.ts +22 -0
- package/dist/db/workflow-import.js +116 -0
- package/dist/db/workflow-import.js.map +1 -0
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +369 -11
- package/dist/mcp/server.js.map +1 -1
- package/dist/utils/config.d.ts +2 -0
- package/dist/utils/config.js +11 -0
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/git.d.ts +14 -0
- package/dist/utils/git.js +43 -0
- package/dist/utils/git.js.map +1 -0
- package/package.json +1 -1
package/dist/cli/rule.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule.js","sourceRoot":"","sources":["../../src/cli/rule.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,
|
|
1
|
+
{"version":3,"file":"rule.js","sourceRoot":"","sources":["../../src/cli/rule.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/sync.d.ts
CHANGED
|
@@ -7,7 +7,14 @@
|
|
|
7
7
|
* trigger a sync, and the DB's constructor-time `syncFromDisk()` only runs once
|
|
8
8
|
* per process. So after a `git pull` the committed graph changes never reach the
|
|
9
9
|
* local DB without a restart. This command applies them on demand.
|
|
10
|
+
*
|
|
11
|
+
* `--analyze` (optionally with `--fix`) runs `devsmind analyze` immediately after,
|
|
12
|
+
* on the same connection — the natural place to catch drift a teammate's changes
|
|
13
|
+
* introduced, right when you pull them in.
|
|
10
14
|
*/
|
|
11
15
|
export declare function handleSync(opts: {
|
|
12
16
|
path?: string;
|
|
17
|
+
analyze?: boolean;
|
|
18
|
+
fix?: boolean;
|
|
19
|
+
godEntityThreshold?: string;
|
|
13
20
|
}): Promise<void>;
|
package/dist/cli/sync.js
CHANGED
|
@@ -42,6 +42,8 @@ const path = __importStar(require("path"));
|
|
|
42
42
|
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
43
43
|
const config_1 = require("../utils/config");
|
|
44
44
|
const database_1 = require("../db/database");
|
|
45
|
+
const analyze_1 = require("../db/analyze");
|
|
46
|
+
const analyze_2 = require("./analyze");
|
|
45
47
|
/**
|
|
46
48
|
* `devsmind sync` — force the on-disk graph (`graph/**`) and history
|
|
47
49
|
* (`history/*.json`) into the local `brain.db`.
|
|
@@ -51,6 +53,10 @@ const database_1 = require("../db/database");
|
|
|
51
53
|
* trigger a sync, and the DB's constructor-time `syncFromDisk()` only runs once
|
|
52
54
|
* per process. So after a `git pull` the committed graph changes never reach the
|
|
53
55
|
* local DB without a restart. This command applies them on demand.
|
|
56
|
+
*
|
|
57
|
+
* `--analyze` (optionally with `--fix`) runs `devsmind analyze` immediately after,
|
|
58
|
+
* on the same connection — the natural place to catch drift a teammate's changes
|
|
59
|
+
* introduced, right when you pull them in.
|
|
54
60
|
*/
|
|
55
61
|
async function handleSync(opts) {
|
|
56
62
|
const devmindDir = (0, config_1.resolveDevmindDir)(opts.path);
|
|
@@ -65,12 +71,20 @@ async function handleSync(opts) {
|
|
|
65
71
|
// Read the pre-sync counts straight from the existing brain.db file (if any),
|
|
66
72
|
// BEFORE DevMindDatabase's constructor runs syncFromDisk(). This lets us show
|
|
67
73
|
// an honest delta of what the sync actually pulled in.
|
|
68
|
-
|
|
74
|
+
let before;
|
|
75
|
+
try {
|
|
76
|
+
before = readRawCounts(dbPath);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
console.error(`\n❌ ${err.message}`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
69
82
|
// Constructing the DB runs syncFromDisk() once; we call it again explicitly so
|
|
70
83
|
// the behaviour is obvious and robust even if the constructor changes later.
|
|
71
84
|
const db = new database_1.DevMindDatabase(dbPath);
|
|
72
85
|
try {
|
|
73
86
|
db.syncFromDisk();
|
|
87
|
+
db.syncToDisk();
|
|
74
88
|
const after = db.getCounts();
|
|
75
89
|
const delta = (a, b) => {
|
|
76
90
|
const d = b - a;
|
|
@@ -80,12 +94,24 @@ async function handleSync(opts) {
|
|
|
80
94
|
console.log(` Nodes : ${after.nodes}${delta(before.nodes, after.nodes)}`);
|
|
81
95
|
console.log(` Connections : ${after.connections}${delta(before.connections, after.connections)}`);
|
|
82
96
|
console.log(` History : ${after.history}${delta(before.history, after.history)}\n`);
|
|
97
|
+
if (opts.analyze) {
|
|
98
|
+
const godEntityThreshold = opts.godEntityThreshold ? parseInt(opts.godEntityThreshold, 10) : undefined;
|
|
99
|
+
console.log(`🩺 Running analyze${opts.fix ? ' (--fix)' : ''}...`);
|
|
100
|
+
const report = (0, analyze_1.runAnalysis)(db, path.dirname(devmindDir), { fix: opts.fix === true, godEntityThreshold });
|
|
101
|
+
(0, analyze_2.printReport)(report);
|
|
102
|
+
}
|
|
83
103
|
}
|
|
84
104
|
finally {
|
|
85
105
|
db.close();
|
|
86
106
|
}
|
|
87
107
|
}
|
|
88
|
-
/**
|
|
108
|
+
/**
|
|
109
|
+
* Count rows in an existing brain.db without triggering a sync. A missing file is a
|
|
110
|
+
* legitimate zero (first-ever sync). A file that exists but fails to OPEN (corrupt/
|
|
111
|
+
* truncated SQLite) is NOT a legitimate zero — that would print a misleading "+500"
|
|
112
|
+
* delta as if the DB were simply empty, masking real corruption. Per-table read
|
|
113
|
+
* failures (e.g. a table missing on an older schema) still fall back to 0.
|
|
114
|
+
*/
|
|
89
115
|
function readRawCounts(dbPath) {
|
|
90
116
|
const zero = { nodes: 0, connections: 0, history: 0 };
|
|
91
117
|
if (!fs.existsSync(dbPath))
|
|
@@ -93,6 +119,17 @@ function readRawCounts(dbPath) {
|
|
|
93
119
|
let raw = null;
|
|
94
120
|
try {
|
|
95
121
|
raw = new better_sqlite3_1.default(dbPath, { readonly: true });
|
|
122
|
+
// better-sqlite3 opens lazily — a garbage/truncated file doesn't throw until the
|
|
123
|
+
// first real read, so force one here to detect corruption up front rather than
|
|
124
|
+
// letting per-table reads below silently swallow it into a misleading zero.
|
|
125
|
+
raw.prepare('SELECT 1').get();
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
if (raw)
|
|
129
|
+
raw.close();
|
|
130
|
+
throw new Error(`brain.db exists but could not be read (${err.message}) — it may be corrupted. Investigate before syncing, or remove it to start fresh.`);
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
96
133
|
const one = (sql) => {
|
|
97
134
|
try {
|
|
98
135
|
const row = raw.prepare(sql).get();
|
|
@@ -108,12 +145,8 @@ function readRawCounts(dbPath) {
|
|
|
108
145
|
history: one('SELECT COUNT(*) AS c FROM history'),
|
|
109
146
|
};
|
|
110
147
|
}
|
|
111
|
-
catch {
|
|
112
|
-
return zero;
|
|
113
|
-
}
|
|
114
148
|
finally {
|
|
115
|
-
|
|
116
|
-
raw.close();
|
|
149
|
+
raw.close();
|
|
117
150
|
}
|
|
118
151
|
}
|
|
119
152
|
//# sourceMappingURL=sync.js.map
|
package/dist/cli/sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/cli/sync.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/cli/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** `devsmind workflow` — interactive list/view/pause/resume. Day-to-day creation and step-recording happens through the MCP tools the agent calls, not this command. */
|
|
2
|
+
export declare function handleWorkflow(opts: {
|
|
3
|
+
path?: string;
|
|
4
|
+
}): Promise<void>;
|
|
5
|
+
/** `devsmind workflow import <path>` — imports a folder of .md flow docs, or a single file, as paused workflows. */
|
|
6
|
+
export declare function handleWorkflowImport(pathArg: string, opts: {
|
|
7
|
+
path?: string;
|
|
8
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.handleWorkflow = handleWorkflow;
|
|
40
|
+
exports.handleWorkflowImport = handleWorkflowImport;
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
44
|
+
const config_1 = require("../utils/config");
|
|
45
|
+
const database_1 = require("../db/database");
|
|
46
|
+
const workflow_import_1 = require("../db/workflow-import");
|
|
47
|
+
function openDb(pathOpt) {
|
|
48
|
+
const devmindDir = (0, config_1.resolveDevmindDir)(pathOpt);
|
|
49
|
+
if (!devmindDir) {
|
|
50
|
+
console.error(`❌ No .devmind directory found.\n` +
|
|
51
|
+
` Run from inside a DevsMind brain folder, or pass --path <devmind_path>.`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
return { db: new database_1.DevMindDatabase(path.join(devmindDir, 'brain.db')), devmindDir };
|
|
55
|
+
}
|
|
56
|
+
/** `devsmind workflow` — interactive list/view/pause/resume. Day-to-day creation and step-recording happens through the MCP tools the agent calls, not this command. */
|
|
57
|
+
async function handleWorkflow(opts) {
|
|
58
|
+
const { db } = openDb(opts.path);
|
|
59
|
+
try {
|
|
60
|
+
await runWorkflowLoop(db);
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
db.close();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function runWorkflowLoop(db) {
|
|
67
|
+
while (true) {
|
|
68
|
+
const workflows = db.listWorkflows();
|
|
69
|
+
if (workflows.length === 0) {
|
|
70
|
+
console.log('📝 No workflows yet. Create one via the workflow_create MCP tool, or import existing docs with `devsmind workflow import <path>`.');
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const statusEmoji = { active: '🟢', paused: '⏸️', completed: '✅' };
|
|
74
|
+
const choices = workflows.map(w => ({
|
|
75
|
+
title: `${statusEmoji[w.status] || ''} [${w.status}] ${w.name}`,
|
|
76
|
+
value: w.id
|
|
77
|
+
}));
|
|
78
|
+
choices.push({ title: '🚪 Exit', value: 'exit' });
|
|
79
|
+
const response = await (0, prompts_1.default)({
|
|
80
|
+
type: 'select',
|
|
81
|
+
name: 'id',
|
|
82
|
+
message: `Workflows (${workflows.length}):`,
|
|
83
|
+
choices
|
|
84
|
+
});
|
|
85
|
+
if (!response.id || response.id === 'exit') {
|
|
86
|
+
console.log('🚪 Goodbye!');
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
await showWorkflowMenu(db, response.id);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function showWorkflowMenu(db, id) {
|
|
93
|
+
while (true) {
|
|
94
|
+
let workflow;
|
|
95
|
+
let steps, artifacts;
|
|
96
|
+
try {
|
|
97
|
+
({ workflow, steps, artifacts } = db.getWorkflowContext(id));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
console.log(`\n==================================================`);
|
|
103
|
+
console.log(`📋 ${workflow.name} [${workflow.status}]`);
|
|
104
|
+
console.log(`==================================================`);
|
|
105
|
+
console.log(workflow.description);
|
|
106
|
+
console.log(`\nSteps (${steps.length}):`);
|
|
107
|
+
for (const s of steps) {
|
|
108
|
+
console.log(` ${s.step_index}. ${s.summary}${s.pending_tasks ? ` (pending: ${s.pending_tasks})` : ''}`);
|
|
109
|
+
}
|
|
110
|
+
console.log(`\nArtifacts (${artifacts.length}):`);
|
|
111
|
+
for (const a of artifacts) {
|
|
112
|
+
console.log(` - [${a.type}] ${a.source_name} → ${a.file_path.replace(/\\/g, '/')}`);
|
|
113
|
+
}
|
|
114
|
+
const choices = [];
|
|
115
|
+
if (workflow.status !== 'active')
|
|
116
|
+
choices.push({ title: '▶️ Resume (make active)', value: 'resume' });
|
|
117
|
+
if (workflow.status === 'active')
|
|
118
|
+
choices.push({ title: '⏸️ Pause', value: 'pause' });
|
|
119
|
+
if (workflow.status !== 'completed')
|
|
120
|
+
choices.push({ title: '✅ Mark completed', value: 'complete' });
|
|
121
|
+
choices.push({ title: '⬅️ Back to list', value: 'back' });
|
|
122
|
+
const response = await (0, prompts_1.default)({ type: 'select', name: 'action', message: 'Action:', choices });
|
|
123
|
+
if (!response.action || response.action === 'back')
|
|
124
|
+
return;
|
|
125
|
+
if (response.action === 'resume')
|
|
126
|
+
db.resumeWorkflow(id);
|
|
127
|
+
if (response.action === 'pause')
|
|
128
|
+
db.pauseWorkflow();
|
|
129
|
+
if (response.action === 'complete')
|
|
130
|
+
db.completeWorkflow(id);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** `devsmind workflow import <path>` — imports a folder of .md flow docs, or a single file, as paused workflows. */
|
|
134
|
+
async function handleWorkflowImport(pathArg, opts) {
|
|
135
|
+
const { db } = openDb(opts.path);
|
|
136
|
+
try {
|
|
137
|
+
const resolved = path.resolve(pathArg);
|
|
138
|
+
const isDir = fs.existsSync(resolved) && fs.statSync(resolved).isDirectory();
|
|
139
|
+
const result = (0, workflow_import_1.importWorkflowDocs)(db, isDir ? resolved : undefined, isDir ? undefined : resolved);
|
|
140
|
+
console.log(`\n📥 Import complete.`);
|
|
141
|
+
if (result.created.length)
|
|
142
|
+
console.log(` Created (${result.created.length}): ${result.created.join(', ')}`);
|
|
143
|
+
if (result.updated.length)
|
|
144
|
+
console.log(` Updated (${result.updated.length}): ${result.updated.join(', ')}`);
|
|
145
|
+
if (result.skipped.length)
|
|
146
|
+
console.log(` Skipped (${result.skipped.length}): ${result.skipped.join(', ')}`);
|
|
147
|
+
if (!result.created.length && !result.updated.length && !result.skipped.length) {
|
|
148
|
+
console.log(' Nothing to import.');
|
|
149
|
+
}
|
|
150
|
+
console.log();
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
db.close();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/cli/workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { DevMindDatabase } from './database';
|
|
2
|
+
export interface AnalysisOptions {
|
|
3
|
+
fix?: boolean;
|
|
4
|
+
godEntityThreshold?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface AnalysisReport {
|
|
7
|
+
fixed: boolean;
|
|
8
|
+
summary: Record<string, number>;
|
|
9
|
+
god_entities: {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
file_path: string;
|
|
13
|
+
degree: number;
|
|
14
|
+
}[];
|
|
15
|
+
circular_dependencies: string[][];
|
|
16
|
+
orphaned_nodes: {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
file_path: string;
|
|
20
|
+
}[];
|
|
21
|
+
dangling_edges: {
|
|
22
|
+
source_node_id: string;
|
|
23
|
+
target_node_id: string;
|
|
24
|
+
}[];
|
|
25
|
+
duplicate_ids: {
|
|
26
|
+
lower_id: string;
|
|
27
|
+
ids: string[];
|
|
28
|
+
}[];
|
|
29
|
+
missing_developer_attribution: {
|
|
30
|
+
id: string;
|
|
31
|
+
node_id: string;
|
|
32
|
+
updated_at: string;
|
|
33
|
+
}[];
|
|
34
|
+
empty_code_snapshots: {
|
|
35
|
+
id: string;
|
|
36
|
+
node_id: string;
|
|
37
|
+
updated_at: string;
|
|
38
|
+
}[];
|
|
39
|
+
spurious_nodes: {
|
|
40
|
+
id: string;
|
|
41
|
+
name: string;
|
|
42
|
+
file_path: string;
|
|
43
|
+
}[];
|
|
44
|
+
missing_files: {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
file_path: string;
|
|
48
|
+
}[];
|
|
49
|
+
renamed_files: {
|
|
50
|
+
repo: string;
|
|
51
|
+
from: string;
|
|
52
|
+
to: string;
|
|
53
|
+
migrated: boolean;
|
|
54
|
+
}[];
|
|
55
|
+
untracked_files: {
|
|
56
|
+
repo: string;
|
|
57
|
+
file: string;
|
|
58
|
+
}[];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Runs every local, zero-AI health check against the graph and — when `fix` is true —
|
|
62
|
+
* applies only the safe/reversible fixes (soft-deprecate dead nodes, delete dangling
|
|
63
|
+
* edges, migrate renames). Everything else is report-only: god entities, cycles,
|
|
64
|
+
* duplicate ids, missing developer attribution, empty snapshots, and untracked files
|
|
65
|
+
* all need human/AI judgement a mechanical fixer shouldn't make on its own.
|
|
66
|
+
*/
|
|
67
|
+
export declare function runAnalysis(db: DevMindDatabase, workspaceRoot: string, opts?: AnalysisOptions): AnalysisReport;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runAnalysis = runAnalysis;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const config_1 = require("../utils/config");
|
|
40
|
+
const git_1 = require("../utils/git");
|
|
41
|
+
const scanner_1 = require("../utils/scanner");
|
|
42
|
+
const LAST_ANALYSIS_KEY = 'last_analysis_at';
|
|
43
|
+
const DEFAULT_LOOKBACK_DAYS = 30;
|
|
44
|
+
/**
|
|
45
|
+
* Runs every local, zero-AI health check against the graph and — when `fix` is true —
|
|
46
|
+
* applies only the safe/reversible fixes (soft-deprecate dead nodes, delete dangling
|
|
47
|
+
* edges, migrate renames). Everything else is report-only: god entities, cycles,
|
|
48
|
+
* duplicate ids, missing developer attribution, empty snapshots, and untracked files
|
|
49
|
+
* all need human/AI judgement a mechanical fixer shouldn't make on its own.
|
|
50
|
+
*/
|
|
51
|
+
function runAnalysis(db, workspaceRoot, opts = {}) {
|
|
52
|
+
const fix = opts.fix === true;
|
|
53
|
+
const godEntityThreshold = opts.godEntityThreshold ?? 15;
|
|
54
|
+
const god_entities = db.getGodEntities(godEntityThreshold);
|
|
55
|
+
const circular_dependencies = db.getCircularDependencies();
|
|
56
|
+
const orphaned_nodes = db.getOrphanedNodes().map(n => ({ id: n.id, name: n.name, file_path: n.file_path }));
|
|
57
|
+
const dangling_edges = db.getDanglingEdges().map(c => ({ source_node_id: c.source_node_id, target_node_id: c.target_node_id }));
|
|
58
|
+
const duplicate_ids = db.getDuplicateNodeIds().map(d => ({ lower_id: d.lowerId, ids: d.ids }));
|
|
59
|
+
const missing_developer_attribution = db.getHistoryMissingDeveloper();
|
|
60
|
+
const empty_code_snapshots = db.getEmptyCodeSnapshots();
|
|
61
|
+
const { spurious: spurious_nodes, missingFile: missing_files } = db.findSpuriousAndMissingFileNodes(workspaceRoot);
|
|
62
|
+
const lastAnalysisAt = db.getSystemMeta(LAST_ANALYSIS_KEY);
|
|
63
|
+
const lookbackIso = lastAnalysisAt || new Date(Date.now() - DEFAULT_LOOKBACK_DAYS * 24 * 60 * 60 * 1000).toISOString();
|
|
64
|
+
const renamed_files = [];
|
|
65
|
+
const untracked_files = [];
|
|
66
|
+
const context = db.getContext();
|
|
67
|
+
if (context) {
|
|
68
|
+
for (const repo of context.config.repos) {
|
|
69
|
+
const repoPath = (0, config_1.resolveRepoPath)(context, repo.name);
|
|
70
|
+
if (!repoPath || !fs.existsSync(repoPath))
|
|
71
|
+
continue;
|
|
72
|
+
for (const r of (0, git_1.getRenamedFilesSince)(repoPath, lookbackIso)) {
|
|
73
|
+
renamed_files.push({ repo: repo.name, from: r.from, to: r.to, migrated: false });
|
|
74
|
+
}
|
|
75
|
+
const changed = (0, git_1.getChangedFilesSince)(repoPath, lookbackIso);
|
|
76
|
+
const knownFiles = new Set(db.listNodes({ include_deprecated: true }).flatMap(n => (n.file_path || '').split(',').map(p => p.trim()).filter(Boolean)));
|
|
77
|
+
for (const relFile of changed) {
|
|
78
|
+
const ext = path.extname(relFile).toLowerCase();
|
|
79
|
+
if (!scanner_1.INDEXABLE_EXTENSIONS.has(ext))
|
|
80
|
+
continue;
|
|
81
|
+
const absFile = path.resolve(repoPath, relFile);
|
|
82
|
+
if (!fs.existsSync(absFile))
|
|
83
|
+
continue; // deleted since — not a blind spot
|
|
84
|
+
const hasNode = Array.from(knownFiles).some(f => path.resolve(f) === absFile);
|
|
85
|
+
if (!hasNode)
|
|
86
|
+
untracked_files.push({ repo: repo.name, file: relFile });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (fix) {
|
|
91
|
+
for (const n of [...orphaned_nodes, ...spurious_nodes, ...missing_files]) {
|
|
92
|
+
db.deprecateNode(n.id);
|
|
93
|
+
}
|
|
94
|
+
for (const e of dangling_edges) {
|
|
95
|
+
db.deleteDanglingEdge(e.source_node_id, e.target_node_id);
|
|
96
|
+
}
|
|
97
|
+
if (context) {
|
|
98
|
+
for (const r of renamed_files) {
|
|
99
|
+
const migrated = migrateRename(db, context, r.repo, r.from, r.to);
|
|
100
|
+
r.migrated = migrated;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
db.setSystemMeta(LAST_ANALYSIS_KEY, new Date().toISOString());
|
|
104
|
+
}
|
|
105
|
+
const summary = {
|
|
106
|
+
god_entities: god_entities.length,
|
|
107
|
+
circular_dependencies: circular_dependencies.length,
|
|
108
|
+
orphaned_nodes: orphaned_nodes.length,
|
|
109
|
+
dangling_edges: dangling_edges.length,
|
|
110
|
+
duplicate_ids: duplicate_ids.length,
|
|
111
|
+
missing_developer_attribution: missing_developer_attribution.length,
|
|
112
|
+
empty_code_snapshots: empty_code_snapshots.length,
|
|
113
|
+
spurious_nodes: spurious_nodes.length,
|
|
114
|
+
missing_files: missing_files.length,
|
|
115
|
+
renamed_files: renamed_files.length,
|
|
116
|
+
untracked_files: untracked_files.length,
|
|
117
|
+
};
|
|
118
|
+
return {
|
|
119
|
+
fixed: fix,
|
|
120
|
+
summary,
|
|
121
|
+
god_entities,
|
|
122
|
+
circular_dependencies,
|
|
123
|
+
orphaned_nodes,
|
|
124
|
+
dangling_edges,
|
|
125
|
+
duplicate_ids,
|
|
126
|
+
missing_developer_attribution,
|
|
127
|
+
empty_code_snapshots,
|
|
128
|
+
spurious_nodes,
|
|
129
|
+
missing_files,
|
|
130
|
+
renamed_files,
|
|
131
|
+
untracked_files,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/** Migrates every node whose file_path resolves to `from` onto `to`, cascading the id/connections/history via `renameNode`. Returns true if anything was migrated. */
|
|
135
|
+
function migrateRename(db, context, repoName, from, to) {
|
|
136
|
+
if (!context)
|
|
137
|
+
return false;
|
|
138
|
+
const repoPath = (0, config_1.resolveRepoPath)(context, repoName);
|
|
139
|
+
if (!repoPath)
|
|
140
|
+
return false;
|
|
141
|
+
const oldAbs = path.resolve(repoPath, from);
|
|
142
|
+
const newAbs = path.resolve(repoPath, to);
|
|
143
|
+
// Deliberately excludes deprecated nodes — renameNode's insert doesn't preserve the
|
|
144
|
+
// deprecated flag, so migrating a dead node would silently resurrect it as active.
|
|
145
|
+
// A deprecated node's file_path accuracy doesn't matter once it's already excluded
|
|
146
|
+
// from use.
|
|
147
|
+
const affected = db.listNodes().filter(n => (n.file_path || '').split(',').map(p => p.trim()).some(p => path.resolve(p) === oldAbs));
|
|
148
|
+
let migrated = false;
|
|
149
|
+
for (const node of affected) {
|
|
150
|
+
const newId = node.id.replace(from, to);
|
|
151
|
+
if (newId === node.id)
|
|
152
|
+
continue;
|
|
153
|
+
try {
|
|
154
|
+
db.renameNode(node.id, newId, undefined, newAbs);
|
|
155
|
+
migrated = true;
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// Leave this node untouched — analyze reports it again next run rather than failing the whole batch.
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return migrated;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=analyze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/db/analyze.ts"],"names":[],"mappings":"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"}
|