devsmind-mcp 2.4.0 → 3.0.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 +326 -234
- package/dist/cli/activity.d.ts +9 -0
- package/dist/cli/activity.js +69 -0
- package/dist/cli/activity.js.map +1 -0
- package/dist/cli/describe.d.ts +31 -0
- package/dist/cli/describe.js +201 -0
- package/dist/cli/describe.js.map +1 -0
- package/dist/cli/diff.d.ts +14 -0
- package/dist/cli/diff.js +161 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/embed.d.ts +6 -0
- package/dist/cli/embed.js +109 -0
- package/dist/cli/embed.js.map +1 -0
- package/dist/cli/extract-agent.d.ts +66 -0
- package/dist/cli/extract-agent.js +192 -0
- package/dist/cli/extract-agent.js.map +1 -0
- package/dist/cli/feedback.d.ts +11 -0
- package/dist/cli/feedback.js +90 -0
- package/dist/cli/feedback.js.map +1 -0
- package/dist/cli/index.js +128 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts +30 -0
- package/dist/cli/init.js +89 -18
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/integrations/memory-topics.d.ts +44 -0
- package/dist/cli/integrations/memory-topics.js +295 -0
- package/dist/cli/integrations/memory-topics.js.map +1 -0
- package/dist/cli/integrations/memory.d.ts +11 -5
- package/dist/cli/integrations/memory.js +132 -37
- package/dist/cli/integrations/memory.js.map +1 -1
- package/dist/cli/integrations/prompt.d.ts +8 -0
- package/dist/cli/integrations/prompt.js +24 -3
- package/dist/cli/integrations/prompt.js.map +1 -1
- package/dist/cli/integrations/registry.d.ts +19 -5
- package/dist/cli/integrations/registry.js +23 -13
- package/dist/cli/integrations/registry.js.map +1 -1
- package/dist/cli/llm-client.d.ts +116 -0
- package/dist/cli/llm-client.js +322 -0
- package/dist/cli/llm-client.js.map +1 -0
- package/dist/cli/rule.d.ts +22 -2
- package/dist/cli/rule.js +113 -32
- package/dist/cli/rule.js.map +1 -1
- package/dist/cli/runner.d.ts +21 -0
- package/dist/cli/runner.js +94 -276
- package/dist/cli/runner.js.map +1 -1
- package/dist/cli/sync-progress.d.ts +9 -0
- package/dist/cli/sync-progress.js +41 -0
- package/dist/cli/sync-progress.js.map +1 -0
- package/dist/cli/sync.js +5 -2
- package/dist/cli/sync.js.map +1 -1
- package/dist/cli/view.js +3 -2
- package/dist/cli/view.js.map +1 -1
- package/dist/cli/workflow.js +26 -20
- package/dist/cli/workflow.js.map +1 -1
- package/dist/db/activity.d.ts +200 -0
- package/dist/db/activity.js +347 -0
- package/dist/db/activity.js.map +1 -0
- package/dist/db/analyze.js +18 -6
- package/dist/db/analyze.js.map +1 -1
- package/dist/db/database.d.ts +583 -99
- package/dist/db/database.js +1825 -553
- package/dist/db/database.js.map +1 -1
- package/dist/db/edges.d.ts +24 -0
- package/dist/db/edges.js +84 -0
- package/dist/db/edges.js.map +1 -1
- package/dist/db/embedder.d.ts +39 -0
- package/dist/db/embedder.js +0 -0
- package/dist/db/embedder.js.map +1 -0
- package/dist/db/feedback.d.ts +128 -0
- package/dist/db/feedback.js +182 -0
- package/dist/db/feedback.js.map +1 -0
- package/dist/db/file-diff.d.ts +32 -0
- package/dist/db/file-diff.js +110 -0
- package/dist/db/file-diff.js.map +1 -0
- package/dist/db/grep.d.ts +78 -0
- package/dist/db/grep.js +475 -0
- package/dist/db/grep.js.map +1 -0
- package/dist/db/message-revert.d.ts +63 -0
- package/dist/db/message-revert.js +258 -0
- package/dist/db/message-revert.js.map +1 -0
- package/dist/db/revert.d.ts +31 -0
- package/dist/db/revert.js +108 -0
- package/dist/db/revert.js.map +1 -0
- package/dist/db/schema.d.ts +49 -4
- package/dist/db/schema.js +125 -73
- package/dist/db/schema.js.map +1 -1
- package/dist/db/search-index.d.ts +65 -0
- package/dist/db/search-index.js +74 -0
- package/dist/db/search-index.js.map +1 -0
- package/dist/db/staging.d.ts +90 -5
- package/dist/db/staging.js +148 -22
- package/dist/db/staging.js.map +1 -1
- package/dist/mcp/server.d.ts +29 -7
- package/dist/mcp/server.js +2584 -809
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/vendor/3d-force-graph.min.js +5 -0
- package/dist/mcp/vendor/force-graph.min.js +5 -0
- package/dist/mcp/vendor/model/model_int8.onnx +0 -0
- package/dist/mcp/vendor/model/vocab.txt +30522 -0
- package/dist/mcp/vendor/three.min.js +7 -0
- package/dist/mcp/view.css +419 -0
- package/dist/mcp/view.html +161 -0
- package/dist/mcp/view.js +245 -0
- package/dist/mcp/view_chat.js +382 -0
- package/dist/mcp/view_graph.js +576 -0
- package/dist/mcp/visualizer.d.ts +25 -2
- package/dist/mcp/visualizer.js +31 -4
- package/dist/mcp/visualizer.js.map +1 -1
- package/dist/utils/ast.d.ts +89 -0
- package/dist/utils/ast.js +378 -10
- package/dist/utils/ast.js.map +1 -1
- package/dist/utils/diff.d.ts +44 -0
- package/dist/utils/diff.js +78 -0
- package/dist/utils/diff.js.map +1 -0
- package/dist/utils/edit.d.ts +6 -0
- package/dist/utils/edit.js +47 -14
- package/dist/utils/edit.js.map +1 -1
- package/dist/utils/scanner.js +12 -4
- package/dist/utils/scanner.js.map +1 -1
- package/dist/utils/tokenize.d.ts +45 -0
- package/dist/utils/tokenize.js +129 -0
- package/dist/utils/tokenize.js.map +1 -0
- package/dist/utils/version.d.ts +14 -0
- package/dist/utils/version.js +61 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +18 -5
- package/dist/mcp/visualizer_2d.html +0 -635
- package/dist/mcp/visualizer_3d.html +0 -613
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleActivity = handleActivity;
|
|
4
|
+
const config_1 = require("../utils/config");
|
|
5
|
+
const activity_1 = require("../db/activity");
|
|
6
|
+
const DIM = '\x1b[2m';
|
|
7
|
+
const BOLD = '\x1b[1m';
|
|
8
|
+
const RED = '\x1b[31m';
|
|
9
|
+
const RESET = '\x1b[0m';
|
|
10
|
+
function dayLabel(dateStr) {
|
|
11
|
+
const d = new Date(dateStr);
|
|
12
|
+
const today = new Date();
|
|
13
|
+
const yesterday = new Date(today);
|
|
14
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
15
|
+
const sameDay = (a, b) => a.toDateString() === b.toDateString();
|
|
16
|
+
if (sameDay(d, today))
|
|
17
|
+
return 'Today';
|
|
18
|
+
if (sameDay(d, yesterday))
|
|
19
|
+
return 'Yesterday';
|
|
20
|
+
return d.toLocaleDateString(undefined, { weekday: 'long', month: 'short', day: 'numeric' });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* `devsmind activity` — the local, gitignored timeline in the terminal: read-only, same store
|
|
24
|
+
* `devsmind view` → Activity reads. Revert/un-revert stays on the page, where the diff and the
|
|
25
|
+
* confirmation live together; this is for a quick "what did I do" check without a browser.
|
|
26
|
+
*/
|
|
27
|
+
async function handleActivity(opts) {
|
|
28
|
+
const devmindDir = (0, config_1.resolveDevmindDir)(opts.path);
|
|
29
|
+
if (!devmindDir) {
|
|
30
|
+
console.error(`❌ No .devmind directory found.\n` +
|
|
31
|
+
` Run from inside a DevsMind brain folder, or pass --path <devmind_path>.`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
const sinceDays = opts.since ? parseInt(opts.since, 10) : undefined;
|
|
35
|
+
const cutoff = sinceDays !== undefined && !Number.isNaN(sinceDays)
|
|
36
|
+
? Date.now() - sinceDays * 24 * 60 * 60 * 1000
|
|
37
|
+
: null;
|
|
38
|
+
let messages = (0, activity_1.listMessages)(devmindDir); // newest-created-first
|
|
39
|
+
if (cutoff !== null) {
|
|
40
|
+
messages = messages.filter(m => new Date(m.created_at).getTime() >= cutoff);
|
|
41
|
+
}
|
|
42
|
+
if (!messages.length) {
|
|
43
|
+
console.log(`\n🗓️ No activity recorded${cutoff !== null ? ` in the last ${sinceDays} day(s)` : ''}.\n` +
|
|
44
|
+
` This fills in as edit_node + commit_changes run. Pass ${BOLD}message${RESET} on commit_changes\n` +
|
|
45
|
+
` so requests get titled here instead of just summarized.\n`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const byDay = new Map();
|
|
49
|
+
for (const m of messages) {
|
|
50
|
+
const key = new Date(m.created_at).toDateString();
|
|
51
|
+
if (!byDay.has(key))
|
|
52
|
+
byDay.set(key, []);
|
|
53
|
+
byDay.get(key).push(m);
|
|
54
|
+
}
|
|
55
|
+
console.log('');
|
|
56
|
+
for (const [, dayMessages] of byDay) {
|
|
57
|
+
console.log(`${BOLD}${dayLabel(dayMessages[0].created_at)}${RESET} ${DIM}${dayMessages.length} message(s)${RESET}`);
|
|
58
|
+
for (const m of dayMessages) {
|
|
59
|
+
const time = new Date(m.created_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
60
|
+
const title = m.request || m.summary || '(untitled change)';
|
|
61
|
+
const revertedTag = m.status === 'reverted' ? ` ${RED}[reverted]${RESET}` : '';
|
|
62
|
+
console.log(` ${DIM}${time}${RESET} ${title}${revertedTag}`);
|
|
63
|
+
console.log(` ${DIM}${' '.repeat(time.length)} ${m.edits.length} change(s) · ${m.id}${RESET}`);
|
|
64
|
+
}
|
|
65
|
+
console.log('');
|
|
66
|
+
}
|
|
67
|
+
console.log(`${DIM}Full diffs + revert: devsmind view → Activity${RESET}\n`);
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/cli/activity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { DevMindDatabase } from '../db/database';
|
|
2
|
+
import { LlmCredentials } from './llm-client';
|
|
3
|
+
export interface DescribeRunResult {
|
|
4
|
+
/** Nodes with no description at the moment `describePendingNodes` was called. */
|
|
5
|
+
pending: number;
|
|
6
|
+
described: number;
|
|
7
|
+
failed: number;
|
|
8
|
+
skipped: number;
|
|
9
|
+
embedded: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Describes every currently-undescribed, non-deprecated node using already-resolved `creds`.
|
|
13
|
+
* Shared by `handleDescribe` (which resolves creds from its own --provider/--key CLI flags) and
|
|
14
|
+
* `runBackgroundIndexing`'s optional Phase 3 (which reuses the creds it already resolved for
|
|
15
|
+
* extraction — same provider, same call, no separate credential setup).
|
|
16
|
+
*/
|
|
17
|
+
export declare function describePendingNodes(db: DevMindDatabase, creds: LlmCredentials, opts?: {
|
|
18
|
+
batchSize?: number;
|
|
19
|
+
rpm?: number;
|
|
20
|
+
log?: (msg: string) => void;
|
|
21
|
+
}): Promise<DescribeRunResult>;
|
|
22
|
+
export declare function handleDescribe(opts: {
|
|
23
|
+
path?: string;
|
|
24
|
+
provider: 'gemini' | 'vertex' | 'ollama';
|
|
25
|
+
model?: string;
|
|
26
|
+
key?: string;
|
|
27
|
+
url?: string;
|
|
28
|
+
rpm?: number;
|
|
29
|
+
batchSize?: number;
|
|
30
|
+
dryRun?: boolean;
|
|
31
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,201 @@
|
|
|
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.describePendingNodes = describePendingNodes;
|
|
37
|
+
exports.handleDescribe = handleDescribe;
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const database_1 = require("../db/database");
|
|
40
|
+
const config_1 = require("../utils/config");
|
|
41
|
+
const llm_client_1 = require("./llm-client");
|
|
42
|
+
const runner_1 = require("./runner");
|
|
43
|
+
const tokenize_1 = require("../utils/tokenize");
|
|
44
|
+
const json_1 = require("../utils/json");
|
|
45
|
+
const embedder_1 = require("../db/embedder");
|
|
46
|
+
const sync_progress_1 = require("./sync-progress");
|
|
47
|
+
/**
|
|
48
|
+
* The one-off backfill for nodes that already exist but predate the description requirement
|
|
49
|
+
* (or were created by a teammate on an older devsmind version). The GROW-AS-YOU-GO path — the
|
|
50
|
+
* commit_changes gate + add_description — is what keeps new nodes described going forward;
|
|
51
|
+
* this command is only for clearing an existing backlog, and is always safe to re-run: the
|
|
52
|
+
* work queue is simply `WHERE description IS NULL`, so nothing here can double-describe a node
|
|
53
|
+
* or lose track of progress on interruption.
|
|
54
|
+
*
|
|
55
|
+
* The core loop (`describePendingNodes`) is also reused as an optional Phase 3 of
|
|
56
|
+
* `devsmind index --run` (see runner.ts's `--describe` flag) — `devsmind index --run`'s own
|
|
57
|
+
* Phase 1 extraction never writes a description (it's LLM-extracted structure only), so its
|
|
58
|
+
* nodes start out exactly as undescribed as a pre-description-requirement backlog would be, and
|
|
59
|
+
* the SAME credentials already resolved for indexing can describe them immediately afterward
|
|
60
|
+
* instead of requiring a separate `devsmind describe` invocation with its own --key/--provider.
|
|
61
|
+
*/
|
|
62
|
+
const BATCH_SIZE = 25;
|
|
63
|
+
const SYSTEM_PROMPT = 'You are documenting an existing codebase for a semantic search index. For each code entity given, write a 1-3 sentence natural-language DESCRIPTION of what it actually DOES and the domain concepts involved — using words a developer would search by later (e.g. mention "login"/"sign-in"/"authentication" together, not just whichever single term the code happens to use). NEVER restate the identifier\'s own name back as the description ("verifyCredentials" -> "verifies credentials" is rejected — it adds no new searchable vocabulary). Return ONLY a JSON object matching {"descriptions": [{"node_id": "...", "description": "..."}]} — exactly one entry per entity given, node_id copied verbatim, in the same order. No markdown fences, no extra commentary.';
|
|
64
|
+
function buildUserPrompt(nodes) {
|
|
65
|
+
return nodes.map(n => `node_id: ${n.node_id}\nname: ${n.name}\ntype: ${n.type}\nsignature: ${n.signature || '(none)'}\nfile: ${n.file_path}\ncode:\n${n.code.slice(0, 2000)}`).join('\n---\n');
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Describes every currently-undescribed, non-deprecated node using already-resolved `creds`.
|
|
69
|
+
* Shared by `handleDescribe` (which resolves creds from its own --provider/--key CLI flags) and
|
|
70
|
+
* `runBackgroundIndexing`'s optional Phase 3 (which reuses the creds it already resolved for
|
|
71
|
+
* extraction — same provider, same call, no separate credential setup).
|
|
72
|
+
*/
|
|
73
|
+
async function describePendingNodes(db, creds, opts = {}) {
|
|
74
|
+
const log = opts.log ?? console.log;
|
|
75
|
+
const pending = db.getAllNodes().filter(n => !n.deprecated && !n.description);
|
|
76
|
+
const result = { pending: pending.length, described: 0, failed: 0, skipped: 0, embedded: 0 };
|
|
77
|
+
if (pending.length === 0) {
|
|
78
|
+
log('✅ Nothing to describe — every node already has one.');
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
log(` Pending : ${pending.length} node(s) with no description`);
|
|
82
|
+
// Checked once, not per-batch — if the optional ONNX dependency is absent this stays false for
|
|
83
|
+
// the whole run and every batch just skips the embed step. Description-writing still succeeds
|
|
84
|
+
// either way; an unembedded description is picked up later by `devsmind embed`.
|
|
85
|
+
const embedderAvailable = await (0, embedder_1.isEmbedderAvailable)();
|
|
86
|
+
if (!embedderAvailable) {
|
|
87
|
+
log(' (semantic embedder unavailable — descriptions will be written without vectors; run "devsmind embed" later once it is)');
|
|
88
|
+
}
|
|
89
|
+
const batchSize = Math.max(1, opts.batchSize || BATCH_SIZE);
|
|
90
|
+
for (let i = 0; i < pending.length; i += batchSize) {
|
|
91
|
+
const batch = pending.slice(i, i + batchSize);
|
|
92
|
+
const candidates = [];
|
|
93
|
+
for (const n of batch) {
|
|
94
|
+
const latest = db.getLatestCode(n.id);
|
|
95
|
+
if (!latest?.code_snapshot) {
|
|
96
|
+
result.skipped++;
|
|
97
|
+
continue;
|
|
98
|
+
} // nothing to describe FROM
|
|
99
|
+
candidates.push({ node_id: n.id, name: n.name, type: n.type, signature: n.signature, file_path: n.file_path, code: latest.code_snapshot });
|
|
100
|
+
}
|
|
101
|
+
if (candidates.length === 0)
|
|
102
|
+
continue;
|
|
103
|
+
log(`\n[${Math.min(i + batchSize, pending.length)}/${pending.length}] describing a batch of ${candidates.length}...`);
|
|
104
|
+
let raw;
|
|
105
|
+
try {
|
|
106
|
+
await (0, runner_1.throttleRpm)(opts.rpm);
|
|
107
|
+
raw = await (0, llm_client_1.sendPromptWithRetry)(creds, SYSTEM_PROMPT, buildUserPrompt(candidates), {
|
|
108
|
+
onRetry: (msg) => log(` ⚠ ${msg}`)
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
// Per-batch failures are non-fatal — this batch's nodes stay undescribed (still NULL) and
|
|
113
|
+
// get picked up again automatically on the next `devsmind describe` run. Nothing to clean
|
|
114
|
+
// up, nothing lost.
|
|
115
|
+
log(` ❌ batch failed after retries (${err.message}) — skipping, safe to re-run this command later`);
|
|
116
|
+
result.failed += candidates.length;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const parsed = (0, json_1.safeJsonParse)(raw, {});
|
|
120
|
+
const byId = new Map((parsed.descriptions || []).map(it => [it.node_id, it.description]));
|
|
121
|
+
// Accumulated across this batch and flushed as ONE embedding call below, after the
|
|
122
|
+
// description-write loop — batching matters far more for ONNX inference than it did for
|
|
123
|
+
// describe's own HTTP calls, so embedding one-at-a-time inside the loop would be wasteful.
|
|
124
|
+
const toEmbed = [];
|
|
125
|
+
for (const n of candidates) {
|
|
126
|
+
const description = byId.get(n.node_id);
|
|
127
|
+
if (!description) {
|
|
128
|
+
result.failed++;
|
|
129
|
+
log(` ⚠ no description returned for ${n.node_id}`);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const check = (0, tokenize_1.validateDescription)(description, n.node_id);
|
|
133
|
+
if (!check.ok) {
|
|
134
|
+
result.failed++;
|
|
135
|
+
log(` ⚠ rejected for ${n.node_id}: ${check.error}`);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
db.upsertNode({ id: n.node_id, type: n.type, name: n.name, file_path: n.file_path, description });
|
|
139
|
+
result.described++;
|
|
140
|
+
if (embedderAvailable)
|
|
141
|
+
toEmbed.push({ node_id: n.node_id, description });
|
|
142
|
+
}
|
|
143
|
+
if (toEmbed.length > 0) {
|
|
144
|
+
const vectors = await (0, embedder_1.embedTextsInt8)(toEmbed.map(t => t.description));
|
|
145
|
+
if (vectors) {
|
|
146
|
+
for (let j = 0; j < toEmbed.length; j++) {
|
|
147
|
+
db.upsertNodeVector(toEmbed[j].node_id, vectors[j], (0, embedder_1.hashDescription)(toEmbed[j].description));
|
|
148
|
+
result.embedded++;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
// Embedder was available a moment ago but failed mid-run — descriptions are already
|
|
153
|
+
// written and safe; these nodes just fall into `devsmind embed`'s queue for later.
|
|
154
|
+
log(` ⚠ embedding failed for this batch — descriptions saved, vectors pending (run "devsmind embed" later)`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
log(`\n✅ Described ${result.described} node(s).` +
|
|
159
|
+
(embedderAvailable ? ` Embedded ${result.embedded}.` : '') +
|
|
160
|
+
(result.failed ? ` ${result.failed} failed or were rejected (still undescribed — re-run to retry just those).` : '') +
|
|
161
|
+
(result.skipped ? ` ${result.skipped} skipped (no code snapshot on record to describe from).` : ''));
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
async function handleDescribe(opts) {
|
|
165
|
+
const devmindDir = (0, config_1.resolveDevmindDir)(opts.path);
|
|
166
|
+
if (!devmindDir) {
|
|
167
|
+
console.error('❌ No .devmind directory found.\n Run from inside a DevsMind brain folder, or pass --path <devmind_path>.');
|
|
168
|
+
process.exit(1);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
console.log(`🧠 DevsMind Describe — backfilling node descriptions`);
|
|
172
|
+
console.log(` Brain : ${devmindDir}`);
|
|
173
|
+
const db = new database_1.DevMindDatabase(path.join(devmindDir, 'brain.db'), { onSyncProgress: sync_progress_1.renderSyncProgress });
|
|
174
|
+
(0, sync_progress_1.clearSyncProgressLine)();
|
|
175
|
+
if (opts.dryRun) {
|
|
176
|
+
const pending = db.getAllNodes().filter(n => !n.deprecated && !n.description);
|
|
177
|
+
console.log(` Pending : ${pending.length} node(s) with no description`);
|
|
178
|
+
console.log(' (--dry-run: listing only, no credentials needed, no LLM calls made, nothing written)');
|
|
179
|
+
for (const n of pending.slice(0, 50))
|
|
180
|
+
console.log(` - ${n.id}`);
|
|
181
|
+
if (pending.length > 50)
|
|
182
|
+
console.log(` ... and ${pending.length - 50} more`);
|
|
183
|
+
db.close();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// Credentials are only resolved past this point — --dry-run above never needs them at all.
|
|
187
|
+
let creds;
|
|
188
|
+
try {
|
|
189
|
+
creds = (0, llm_client_1.resolveLlmCredentials)({ provider: opts.provider, model: opts.model, key: opts.key, url: opts.url });
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
console.error(`❌ ${err.message}`);
|
|
193
|
+
db.close();
|
|
194
|
+
process.exit(1);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
console.log(` Provider : ${opts.provider} Model: ${creds.model}`);
|
|
198
|
+
await describePendingNodes(db, creds, { batchSize: opts.batchSize, rpm: opts.rpm });
|
|
199
|
+
db.close();
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=describe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe.js","sourceRoot":"","sources":["../../src/cli/describe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** `devsmind diff <node_id>` — what the agent changed about one entity, newest last. */
|
|
2
|
+
export declare function handleDiff(nodeId: string, opts: {
|
|
3
|
+
path?: string;
|
|
4
|
+
}): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* `devsmind revert <node_id>` — restore an entity to before its newest recorded edit.
|
|
7
|
+
*
|
|
8
|
+
* Confirms first, and shows the diff being undone: this erases the change and its recorded
|
|
9
|
+
* reasoning, and nothing here can bring either back.
|
|
10
|
+
*/
|
|
11
|
+
export declare function handleRevert(nodeId: string, opts: {
|
|
12
|
+
path?: string;
|
|
13
|
+
yes?: boolean;
|
|
14
|
+
}): Promise<void>;
|
package/dist/cli/diff.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
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.handleDiff = handleDiff;
|
|
40
|
+
exports.handleRevert = handleRevert;
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
43
|
+
const config_1 = require("../utils/config");
|
|
44
|
+
const database_1 = require("../db/database");
|
|
45
|
+
const diff_1 = require("../utils/diff");
|
|
46
|
+
const revert_1 = require("../db/revert");
|
|
47
|
+
const RED = '\x1b[31m';
|
|
48
|
+
const GREEN = '\x1b[32m';
|
|
49
|
+
const DIM = '\x1b[2m';
|
|
50
|
+
const BOLD = '\x1b[1m';
|
|
51
|
+
const RESET = '\x1b[0m';
|
|
52
|
+
function openBrain(optPath) {
|
|
53
|
+
const devmindDir = (0, config_1.resolveDevmindDir)(optPath);
|
|
54
|
+
if (!devmindDir) {
|
|
55
|
+
console.error(`❌ No .devmind directory found.\n` +
|
|
56
|
+
` Run from inside a DevsMind brain folder, or pass --path <devmind_path>.`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
return { db: new database_1.DevMindDatabase(path.join(devmindDir, 'brain.db')), devmindDir };
|
|
60
|
+
}
|
|
61
|
+
function printLines(lines) {
|
|
62
|
+
for (const l of lines) {
|
|
63
|
+
if (l.type === 'add')
|
|
64
|
+
console.log(`${GREEN}+ ${l.text}${RESET}`);
|
|
65
|
+
else if (l.type === 'del')
|
|
66
|
+
console.log(`${RED}- ${l.text}${RESET}`);
|
|
67
|
+
else
|
|
68
|
+
console.log(`${DIM} ${l.text}${RESET}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** `devsmind diff <node_id>` — what the agent changed about one entity, newest last. */
|
|
72
|
+
async function handleDiff(nodeId, opts) {
|
|
73
|
+
const { db } = openBrain(opts.path);
|
|
74
|
+
try {
|
|
75
|
+
const node = db.getNode(nodeId);
|
|
76
|
+
const resolvedId = node ? node.id : nodeId;
|
|
77
|
+
const entry = db.getLatestHistory(resolvedId);
|
|
78
|
+
if (!entry) {
|
|
79
|
+
console.log(`\n${BOLD}${resolvedId}${RESET}\n No history recorded.`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (!entry.edits.length) {
|
|
83
|
+
console.log(`\n${BOLD}${resolvedId}${RESET}\n` +
|
|
84
|
+
` ${DIM}No diff available — this change was recorded without a before-state.${RESET}\n` +
|
|
85
|
+
` ${DIM}Entries predating diff tracking, and stage_change entries (non-TS/JS), have none.${RESET}`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
console.log(`\n${BOLD}${resolvedId}${RESET} ${DIM}${entry.edits.length} edit(s) this session${RESET}`);
|
|
89
|
+
entry.edits.forEach((e, i) => {
|
|
90
|
+
const lines = (0, diff_1.diffSnapshots)(e.before, e.after);
|
|
91
|
+
const added = lines.filter(l => l.type === 'add').length;
|
|
92
|
+
const removed = lines.filter(l => l.type === 'del').length;
|
|
93
|
+
console.log(`\n${DIM}── ${new Date(e.at).toLocaleString()} ${RESET}${GREEN}+${added}${RESET} ${RED}-${removed}${RESET}`);
|
|
94
|
+
const what = e.reasoning.split('\n').find(l => /^What changed:/i.test(l));
|
|
95
|
+
if (what)
|
|
96
|
+
console.log(`${DIM} ${what.replace(/^What changed:\s*/i, '')}${RESET}`);
|
|
97
|
+
console.log('');
|
|
98
|
+
printLines(lines);
|
|
99
|
+
if (i === entry.edits.length - 1) {
|
|
100
|
+
console.log(`\n${DIM} devsmind revert ${resolvedId} ${RESET}${DIM}undoes this one${RESET}`);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
console.log('');
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
db.close();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* `devsmind revert <node_id>` — restore an entity to before its newest recorded edit.
|
|
111
|
+
*
|
|
112
|
+
* Confirms first, and shows the diff being undone: this erases the change and its recorded
|
|
113
|
+
* reasoning, and nothing here can bring either back.
|
|
114
|
+
*/
|
|
115
|
+
async function handleRevert(nodeId, opts) {
|
|
116
|
+
const { db, devmindDir } = openBrain(opts.path);
|
|
117
|
+
try {
|
|
118
|
+
const node = db.getNode(nodeId);
|
|
119
|
+
const resolvedId = node ? node.id : nodeId;
|
|
120
|
+
if (!opts.yes) {
|
|
121
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
122
|
+
console.error(`❌ devsmind revert needs an interactive terminal to confirm. Pass --yes to skip the prompt.`);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
const entry = db.getLatestHistory(resolvedId);
|
|
126
|
+
if (entry?.edits.length) {
|
|
127
|
+
const last = entry.edits[entry.edits.length - 1];
|
|
128
|
+
console.log(`\n${BOLD}${resolvedId}${RESET} — about to undo:\n`);
|
|
129
|
+
printLines((0, diff_1.diffSnapshots)(last.before, last.after));
|
|
130
|
+
}
|
|
131
|
+
const { go } = await (0, prompts_1.default)({
|
|
132
|
+
type: 'confirm',
|
|
133
|
+
name: 'go',
|
|
134
|
+
message: 'Restore the code and erase this change from history?',
|
|
135
|
+
initial: false
|
|
136
|
+
});
|
|
137
|
+
if (!go) {
|
|
138
|
+
console.log(' Cancelled — nothing changed.');
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const result = (0, revert_1.revertLastEdit)(db, devmindDir, resolvedId);
|
|
143
|
+
if (!result.ok) {
|
|
144
|
+
console.error(`\n❌ ${result.error}`);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
console.log(`\n✅ Reverted ${resolvedId}`);
|
|
148
|
+
console.log(` File : ${String(result.file_path).replace(/\\/g, '/')}`);
|
|
149
|
+
if (result.was_staged)
|
|
150
|
+
console.log(` ${DIM}The change was still staged, so there was no history to erase.${RESET}`);
|
|
151
|
+
else if (result.entry_deleted)
|
|
152
|
+
console.log(` ${DIM}History entry deleted.${RESET}`);
|
|
153
|
+
if (result.note)
|
|
154
|
+
console.log(` ${DIM}${result.note}${RESET}`);
|
|
155
|
+
console.log('');
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
db.close();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/cli/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
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.handleEmbed = handleEmbed;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const database_1 = require("../db/database");
|
|
39
|
+
const config_1 = require("../utils/config");
|
|
40
|
+
const embedder_1 = require("../db/embedder");
|
|
41
|
+
const sync_progress_1 = require("./sync-progress");
|
|
42
|
+
/**
|
|
43
|
+
* The one-off (and re-runnable) backfill that computes vectors for every described node that
|
|
44
|
+
* doesn't have one yet, or whose vector is stale. Fully local and offline — no `--provider`,
|
|
45
|
+
* `--key`, or `--rpm` like `describe` has, because inference is on-device: no credentials, no
|
|
46
|
+
* rate limit. Safe to re-run any time; the work queue (`getNodesNeedingEmbedding`) is naturally
|
|
47
|
+
* idempotent — a node already carrying a fresh vector for the current model just isn't selected.
|
|
48
|
+
*/
|
|
49
|
+
const BATCH_SIZE = 32;
|
|
50
|
+
async function handleEmbed(opts) {
|
|
51
|
+
const devmindDir = (0, config_1.resolveDevmindDir)(opts.path);
|
|
52
|
+
if (!devmindDir) {
|
|
53
|
+
console.error('❌ No .devmind directory found.\n Run from inside a DevsMind brain folder, or pass --path <devmind_path>.');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
console.log(`🧠 DevsMind Embed — computing semantic vectors`);
|
|
58
|
+
console.log(` Brain : ${devmindDir}`);
|
|
59
|
+
const db = new database_1.DevMindDatabase(path.join(devmindDir, 'brain.db'), { onSyncProgress: sync_progress_1.renderSyncProgress });
|
|
60
|
+
(0, sync_progress_1.clearSyncProgressLine)();
|
|
61
|
+
const pending = db.getNodesNeedingEmbedding(!!opts.force);
|
|
62
|
+
console.log(` Pending : ${pending.length} node(s) need${opts.force ? ' (--force: re-embedding all described nodes)' : ' a vector'}`);
|
|
63
|
+
if (pending.length === 0) {
|
|
64
|
+
console.log('✅ Nothing to embed — every described node already has a current vector.');
|
|
65
|
+
db.close();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (opts.dryRun) {
|
|
69
|
+
console.log(' (--dry-run: listing only, no inference run, nothing written)');
|
|
70
|
+
for (const n of pending.slice(0, 50))
|
|
71
|
+
console.log(` - ${n.id}`);
|
|
72
|
+
if (pending.length > 50)
|
|
73
|
+
console.log(` ... and ${pending.length - 50} more`);
|
|
74
|
+
db.close();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const available = await (0, embedder_1.isEmbedderAvailable)();
|
|
78
|
+
if (!available) {
|
|
79
|
+
console.error('❌ The local embedding model is unavailable — either the optional "onnxruntime-node"\n' +
|
|
80
|
+
' dependency failed to install for this platform, or the vendored model files are\n' +
|
|
81
|
+
' missing. Semantic search will still fall back to keyword (BM25) search without it.');
|
|
82
|
+
db.close();
|
|
83
|
+
process.exit(1);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const batchSize = Math.max(1, opts.batchSize || BATCH_SIZE);
|
|
87
|
+
let embedded = 0, failed = 0;
|
|
88
|
+
for (let i = 0; i < pending.length; i += batchSize) {
|
|
89
|
+
const batch = pending.slice(i, i + batchSize);
|
|
90
|
+
console.log(`\n[${Math.min(i + batchSize, pending.length)}/${pending.length}] embedding a batch of ${batch.length}...`);
|
|
91
|
+
const vectors = await (0, embedder_1.embedTextsInt8)(batch.map(n => n.description));
|
|
92
|
+
if (!vectors) {
|
|
93
|
+
// The embedder was available a moment ago but failed mid-run (rare) — this batch's nodes
|
|
94
|
+
// stay in the queue (no vector was written) and get retried on the next `devsmind embed`.
|
|
95
|
+
console.log(` ❌ batch failed — skipping, safe to re-run this command later`);
|
|
96
|
+
failed += batch.length;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
for (let j = 0; j < batch.length; j++) {
|
|
100
|
+
const node = batch[j];
|
|
101
|
+
db.upsertNodeVector(node.id, vectors[j], (0, embedder_1.hashDescription)(node.description));
|
|
102
|
+
embedded++;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
console.log(`\n✅ Embedded ${embedded} node(s).` +
|
|
106
|
+
(failed ? ` ${failed} failed (still pending — re-run this command to retry just those).` : ''));
|
|
107
|
+
db.close();
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=embed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed.js","sourceRoot":"","sources":["../../src/cli/embed.ts"],"names":[],"mappings":"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"}
|