vibe-splain 2.7.3 → 3.1.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/dist/commands/export.d.ts +1 -0
- package/dist/commands/export.js +19 -0
- package/dist/commands/serve.d.ts +1 -1
- package/dist/commands/serve.js +2 -2
- package/dist/export/ArtifactBundleWriter.d.ts +22 -0
- package/dist/export/ArtifactBundleWriter.js +74 -0
- package/dist/export/ExportOrchestrator.d.ts +12 -0
- package/dist/export/ExportOrchestrator.js +73 -0
- package/dist/export/Watcher.d.ts +1 -0
- package/dist/export/Watcher.js +55 -0
- package/dist/export/renderers/AgentMarkdownRenderer.d.ts +9 -0
- package/dist/export/renderers/AgentMarkdownRenderer.js +106 -0
- package/dist/export/renderers/DeltaRenderer.d.ts +6 -0
- package/dist/export/renderers/DeltaRenderer.js +22 -0
- package/dist/export/renderers/GraphRenderer.d.ts +9 -0
- package/dist/export/renderers/GraphRenderer.js +18 -0
- package/dist/export/renderers/HtmlRenderer.d.ts +6 -0
- package/dist/export/renderers/HtmlRenderer.js +77 -0
- package/dist/export/renderers/JsonRenderer.d.ts +6 -0
- package/dist/export/renderers/JsonRenderer.js +12 -0
- package/dist/export/renderers/RawAnalysisRenderer.d.ts +6 -0
- package/dist/export/renderers/RawAnalysisRenderer.js +12 -0
- package/dist/export/renderers/Renderer.d.ts +5 -0
- package/dist/export/renderers/Renderer.js +2 -0
- package/dist/export/renderers/ValidationRenderer.d.ts +6 -0
- package/dist/export/renderers/ValidationRenderer.js +14 -0
- package/dist/index.js +888 -660
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +3 -3
- package/dist/mcp/tools/mark_stale.d.ts +1 -1
- package/dist/mcp/tools/mark_stale.js +9 -3
- package/dist/mcp/tools/scan_project.d.ts +1 -1
- package/dist/mcp/tools/scan_project.js +25 -5
- package/dist/mcp/tools/set_project_brief.d.ts +1 -1
- package/dist/mcp/tools/set_project_brief.js +9 -3
- package/dist/mcp/tools/write_decision_card.d.ts +1 -1
- package/dist/mcp/tools/write_decision_card.js +15 -4
- package/dist/ui/index.html +2 -2
- package/package.json +1 -1
package/dist/mcp/server.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function startMCPServer(): Promise<void>;
|
|
1
|
+
export declare function startMCPServer(options?: any): Promise<void>;
|
package/dist/mcp/server.js
CHANGED
|
@@ -39,11 +39,11 @@ const TOOL_HANDLERS = {
|
|
|
39
39
|
get_wild_discoveries: handleGetWildDiscoveries,
|
|
40
40
|
mark_stale: handleMarkStale,
|
|
41
41
|
};
|
|
42
|
-
export async function startMCPServer() {
|
|
42
|
+
export async function startMCPServer(options = {}) {
|
|
43
43
|
// Initialize Tree-Sitter WASM once at startup
|
|
44
44
|
await initParser();
|
|
45
45
|
console.error('[vibe-splain] Tree-Sitter parser initialized');
|
|
46
|
-
const server = new Server({ name: 'vibe-splain', version: '
|
|
46
|
+
const server = new Server({ name: 'vibe-splain', version: '3.0.0' }, { capabilities: { tools: {}, prompts: {} } });
|
|
47
47
|
// Register prompts
|
|
48
48
|
server.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
|
49
49
|
prompts: [
|
|
@@ -143,7 +143,7 @@ When done, share the exact file:// UI link returned by scan_project. Never inven
|
|
|
143
143
|
};
|
|
144
144
|
}
|
|
145
145
|
try {
|
|
146
|
-
const result = await handler(
|
|
146
|
+
const result = await handler(args, options);
|
|
147
147
|
return {
|
|
148
148
|
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
149
149
|
};
|
|
@@ -19,4 +19,4 @@ export declare const markStaleTool: {
|
|
|
19
19
|
required: string[];
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
|
-
export declare function handleMarkStale(args: Record<string, unknown
|
|
22
|
+
export declare function handleMarkStale(args: Record<string, unknown>, options?: any): Promise<unknown>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { readDossier
|
|
1
|
+
import { readDossier } from '@vibe-splain/brain';
|
|
2
|
+
import { ExportOrchestrator } from '../../export/ExportOrchestrator.js';
|
|
2
3
|
export const markStaleTool = {
|
|
3
4
|
name: 'mark_stale',
|
|
4
5
|
description: 'Manually marks Decision Cards as stale when you detect a file has changed. The file watcher does this automatically, but call this if you modify a file yourself during a session.',
|
|
@@ -18,7 +19,7 @@ export const markStaleTool = {
|
|
|
18
19
|
required: ['projectRoot', 'filePaths'],
|
|
19
20
|
},
|
|
20
21
|
};
|
|
21
|
-
export async function handleMarkStale(args) {
|
|
22
|
+
export async function handleMarkStale(args, options = {}) {
|
|
22
23
|
const projectRoot = args.projectRoot;
|
|
23
24
|
const filePaths = args.filePaths;
|
|
24
25
|
if (!projectRoot || !filePaths)
|
|
@@ -48,7 +49,12 @@ export async function handleMarkStale(args) {
|
|
|
48
49
|
dossier.stalePaths.push(filePath);
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
|
-
|
|
52
|
+
const orchestrator = new ExportOrchestrator(projectRoot);
|
|
53
|
+
await orchestrator.writeBundle(dossier, {
|
|
54
|
+
format: options.format,
|
|
55
|
+
budget: options.budget ? parseInt(options.budget, 10) : undefined,
|
|
56
|
+
scope: options.scope,
|
|
57
|
+
});
|
|
52
58
|
return {
|
|
53
59
|
success: true,
|
|
54
60
|
staleCardsMarked: staleCount,
|
|
@@ -12,4 +12,4 @@ export declare const scanProjectTool: {
|
|
|
12
12
|
required: string[];
|
|
13
13
|
};
|
|
14
14
|
};
|
|
15
|
-
export declare function handleScanProject(args: Record<string, unknown
|
|
15
|
+
export declare function handleScanProject(args: Record<string, unknown>, options?: any): Promise<unknown>;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { scanProject,
|
|
1
|
+
import { scanProject, readDossier } from '@vibe-splain/brain';
|
|
2
|
+
import { ExportOrchestrator } from '../../export/ExportOrchestrator.js';
|
|
3
|
+
import { startWatcher } from '../../export/Watcher.js';
|
|
2
4
|
export const scanProjectTool = {
|
|
3
5
|
name: 'scan_project',
|
|
4
6
|
description: 'Scans a codebase (TS/JS/Python/Go/Rust/Java) and returns a structural analysis. CALL THIS FIRST, then call get_project_map. Files are scored on two axes: GRAVITY (importance — fan-in + PageRank centrality) and HEAT (smell/tech-debt). Mockups, vendored code, and orphan files are demoted (isRealSource:false) so cards target the real application. After scanning, call get_project_map to get the fixed pillar set, Start-Here (top gravity) and Wild-Discovery (top heat) lists. The uiUrl is a file:// link — share it with the user.',
|
|
@@ -13,7 +15,7 @@ export const scanProjectTool = {
|
|
|
13
15
|
required: ['projectRoot'],
|
|
14
16
|
},
|
|
15
17
|
};
|
|
16
|
-
export async function handleScanProject(args) {
|
|
18
|
+
export async function handleScanProject(args, options = {}) {
|
|
17
19
|
const projectRoot = args.projectRoot;
|
|
18
20
|
if (!projectRoot)
|
|
19
21
|
throw new Error('projectRoot is required');
|
|
@@ -26,7 +28,15 @@ export async function handleScanProject(args) {
|
|
|
26
28
|
version: '2.0.0',
|
|
27
29
|
scannedAt: new Date().toISOString(),
|
|
28
30
|
projectRoot,
|
|
29
|
-
map: {
|
|
31
|
+
map: {
|
|
32
|
+
...result.map,
|
|
33
|
+
brief,
|
|
34
|
+
validation: result.validation ? {
|
|
35
|
+
passed: result.validation.passed,
|
|
36
|
+
errors: result.validation.errors,
|
|
37
|
+
warnings: result.validation.warnings,
|
|
38
|
+
} : undefined
|
|
39
|
+
},
|
|
30
40
|
pillars: existing?.pillars ?? [],
|
|
31
41
|
wildDiscoveries: existing?.wildDiscoveries ?? [],
|
|
32
42
|
stalePaths: existing?.stalePaths ?? [],
|
|
@@ -37,13 +47,23 @@ export async function handleScanProject(args) {
|
|
|
37
47
|
dossier.pillars.push({ name: def.name, cardCount: 0, decisions: [] });
|
|
38
48
|
}
|
|
39
49
|
}
|
|
40
|
-
|
|
50
|
+
const orchestrator = new ExportOrchestrator(projectRoot);
|
|
51
|
+
await orchestrator.writeBundle(dossier, {
|
|
52
|
+
format: options.format,
|
|
53
|
+
budget: options.budget ? parseInt(options.budget, 10) : undefined,
|
|
54
|
+
scope: options.scope,
|
|
55
|
+
}, result.store, result.graph);
|
|
41
56
|
// Watch the real-source files for staleness.
|
|
42
|
-
startWatcher(projectRoot, result.files.map(f => f.path));
|
|
57
|
+
await startWatcher(projectRoot, result.files.map(f => f.path));
|
|
43
58
|
console.error(`[vibe-splain] Scan complete. ${result.totalFilesScanned} files, ${result.realSourceCount} real-source, ${result.wildCandidates.length} wild candidates.`);
|
|
44
59
|
const validation = result.validation ?? { passed: true, errors: 0, warnings: 0, reportPath: '.vibe-splainer/validation_report.json' };
|
|
60
|
+
let statusMsg = 'Scan complete.';
|
|
61
|
+
if (!validation.passed) {
|
|
62
|
+
statusMsg = `SCAN QUALITY WARNING: ${validation.errors} errors and ${validation.warnings} warnings found in validation report. Delta Engine automation may be blocked.`;
|
|
63
|
+
}
|
|
45
64
|
return {
|
|
46
65
|
ok: true,
|
|
66
|
+
message: statusMsg,
|
|
47
67
|
validation: {
|
|
48
68
|
passed: validation.passed,
|
|
49
69
|
errors: validation.errors,
|
|
@@ -16,4 +16,4 @@ export declare const setProjectBriefTool: {
|
|
|
16
16
|
required: string[];
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
|
-
export declare function handleSetProjectBrief(args: Record<string, unknown
|
|
19
|
+
export declare function handleSetProjectBrief(args: Record<string, unknown>, options?: any): Promise<unknown>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { readDossier
|
|
1
|
+
import { readDossier } from '@vibe-splain/brain';
|
|
2
|
+
import { ExportOrchestrator } from '../../export/ExportOrchestrator.js';
|
|
2
3
|
export const setProjectBriefTool = {
|
|
3
4
|
name: 'set_project_brief',
|
|
4
5
|
description: 'Persists your 3-5 sentence project brief into the dossier (and regenerates the UI). Call this AFTER get_project_map and BEFORE writing any decision card. The brief must say: what this project IS, the real stack, and — critically — which files are the actual application vs. mockups/generated/vendored noise.',
|
|
@@ -11,7 +12,7 @@ export const setProjectBriefTool = {
|
|
|
11
12
|
required: ['projectRoot', 'brief'],
|
|
12
13
|
},
|
|
13
14
|
};
|
|
14
|
-
export async function handleSetProjectBrief(args) {
|
|
15
|
+
export async function handleSetProjectBrief(args, options = {}) {
|
|
15
16
|
const projectRoot = args.projectRoot;
|
|
16
17
|
const brief = args.brief;
|
|
17
18
|
if (!projectRoot || !brief)
|
|
@@ -21,7 +22,12 @@ export async function handleSetProjectBrief(args) {
|
|
|
21
22
|
return { error: 'No project map found. Run scan_project first.' };
|
|
22
23
|
}
|
|
23
24
|
dossier.map.brief = brief;
|
|
24
|
-
|
|
25
|
+
const orchestrator = new ExportOrchestrator(projectRoot);
|
|
26
|
+
await orchestrator.writeBundle(dossier, {
|
|
27
|
+
format: options.format,
|
|
28
|
+
budget: options.budget ? parseInt(options.budget, 10) : undefined,
|
|
29
|
+
scope: options.scope,
|
|
30
|
+
});
|
|
25
31
|
// Drive the loop: hand back the exact remaining worklist so the agent does
|
|
26
32
|
// not stop and ask the user. Weak models treat "brief saved" as done otherwise.
|
|
27
33
|
const documented = new Set([...dossier.pillars.flatMap(p => p.decisions), ...dossier.wildDiscoveries]
|
|
@@ -79,4 +79,4 @@ export declare const writeDecisionCardTool: {
|
|
|
79
79
|
required: string[];
|
|
80
80
|
};
|
|
81
81
|
};
|
|
82
|
-
export declare function handleWriteDecisionCard(args: Record<string, unknown
|
|
82
|
+
export declare function handleWriteDecisionCard(args: Record<string, unknown>, options?: any): Promise<unknown>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { readDossier,
|
|
1
|
+
import { readDossier, validateMermaidNodeCount, readAnalysis } from '@vibe-splain/brain';
|
|
2
|
+
import { ExportOrchestrator } from '../../export/ExportOrchestrator.js';
|
|
2
3
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
4
|
import { createHash } from 'crypto';
|
|
4
5
|
import { readFile } from 'fs/promises';
|
|
@@ -49,7 +50,7 @@ export const writeDecisionCardTool = {
|
|
|
49
50
|
required: ['projectRoot', 'pillar', 'primaryFile', 'title', 'thesis', 'category', 'severity', 'narrative', 'confidence', 'evidence'],
|
|
50
51
|
},
|
|
51
52
|
};
|
|
52
|
-
export async function handleWriteDecisionCard(args) {
|
|
53
|
+
export async function handleWriteDecisionCard(args, options = {}) {
|
|
53
54
|
const projectRoot = args.projectRoot;
|
|
54
55
|
const pillar = args.pillar;
|
|
55
56
|
const primaryFile = args.primaryFile;
|
|
@@ -94,9 +95,14 @@ export async function handleWriteDecisionCard(args) {
|
|
|
94
95
|
p.decisions = p.decisions.filter(c => c.id !== existing.id);
|
|
95
96
|
dossier.wildDiscoveries = dossier.wildDiscoveries.filter(c => c.id !== existing.id);
|
|
96
97
|
}
|
|
97
|
-
//
|
|
98
|
+
// ADR-019: machine-derived confidence cap
|
|
98
99
|
const store = await readAnalysis(projectRoot);
|
|
99
100
|
const persisted = store?.files[primaryFile];
|
|
101
|
+
const machineConfidence = persisted?.confidence || 'low';
|
|
102
|
+
const confidenceOrder = { low: 0, medium: 1, high: 2 };
|
|
103
|
+
if (confidenceOrder[confidence] > confidenceOrder[machineConfidence]) {
|
|
104
|
+
throw new Error(`Requested confidence "${confidence}" exceeds machine-derived confidence "${machineConfidence}" for this file. Ground your narrative in the MRI evidence.`);
|
|
105
|
+
}
|
|
100
106
|
const gravity = persisted ? Math.round(persisted.gravity) : undefined;
|
|
101
107
|
const heat = persisted ? Math.round(persisted.heat) : undefined;
|
|
102
108
|
// Hash the primaryFile so the watcher can detect staleness per-file.
|
|
@@ -126,7 +132,12 @@ export async function handleWriteDecisionCard(args) {
|
|
|
126
132
|
}
|
|
127
133
|
bucket.decisions.push(card);
|
|
128
134
|
bucket.cardCount = bucket.decisions.length;
|
|
129
|
-
|
|
135
|
+
const orchestrator = new ExportOrchestrator(projectRoot);
|
|
136
|
+
await orchestrator.writeBundle(dossier, {
|
|
137
|
+
format: options.format,
|
|
138
|
+
budget: options.budget ? parseInt(options.budget, 10) : undefined,
|
|
139
|
+
scope: options.scope,
|
|
140
|
+
});
|
|
130
141
|
console.error(`[vibe-splain] Card written: "${title}" [${category} sev${severity}] in "${pillar}"${isWild ? ' (Wild Discovery)' : ''}`);
|
|
131
142
|
// Keep the loop going: compute what is still undocumented.
|
|
132
143
|
const documented = new Set([...dossier.pillars.flatMap(p => p.decisions), ...dossier.wildDiscoveries]
|