vibe-splain 3.4.2 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +5 -5
  2. package/dist/hook.js +0 -0
  3. package/dist/index.js +1780 -3520
  4. package/dist/mcp/server.js +1 -24
  5. package/package.json +2 -2
  6. package/dist/commands/bundle.d.ts +0 -4
  7. package/dist/commands/bundle.js +0 -68
  8. package/dist/commands/export.d.ts +0 -1
  9. package/dist/commands/export.js +0 -19
  10. package/dist/commands/gc.d.ts +0 -3
  11. package/dist/commands/gc.js +0 -59
  12. package/dist/commands/importBundle.d.ts +0 -4
  13. package/dist/commands/importBundle.js +0 -80
  14. package/dist/commands/network.d.ts +0 -1
  15. package/dist/commands/network.js +0 -91
  16. package/dist/commands/scan.d.ts +0 -13
  17. package/dist/commands/scan.js +0 -97
  18. package/dist/export/renderers/DeltaRenderer.d.ts +0 -6
  19. package/dist/export/renderers/DeltaRenderer.js +0 -22
  20. package/dist/hook-entry.d.ts +0 -2
  21. package/dist/hook-entry.js +0 -8
  22. package/dist/mcp/tools/apply_patch.d.ts +0 -37
  23. package/dist/mcp/tools/apply_patch.js +0 -103
  24. package/dist/mcp/tools/explainSpecialistScope.d.ts +0 -15
  25. package/dist/mcp/tools/explainSpecialistScope.js +0 -30
  26. package/dist/mcp/tools/get_call_chain.d.ts +0 -42
  27. package/dist/mcp/tools/get_call_chain.js +0 -50
  28. package/dist/mcp/tools/prepareTaskContext.d.ts +0 -38
  29. package/dist/mcp/tools/prepareTaskContext.js +0 -93
  30. package/dist/mcp/tools/set_session_scope.d.ts +0 -19
  31. package/dist/mcp/tools/set_session_scope.js +0 -40
  32. package/dist/mcp/tools/submit_receipt.d.ts +0 -68
  33. package/dist/mcp/tools/submit_receipt.js +0 -94
  34. package/dist/mcp/tools/work_orders.d.ts +0 -79
  35. package/dist/mcp/tools/work_orders.js +0 -126
  36. package/dist/mcp/tools/yield_for_scope_expansion.d.ts +0 -29
  37. package/dist/mcp/tools/yield_for_scope_expansion.js +0 -59
@@ -13,14 +13,9 @@ import { handleGetWildDiscoveries, getWildDiscoveriesTool } from './tools/get_wi
13
13
  import { handleMarkStale, markStaleTool } from './tools/mark_stale.js';
14
14
  import { handleGetFileSkeleton, getFileSkeletonTool } from './tools/get_file_skeleton.js';
15
15
  import { handleReadFile, readFileTool } from './tools/read_file.js';
16
- import { handleCreateWorkOrder, createWorkOrderTool, handleSpawnWorker, spawnWorkerTool } from './tools/work_orders.js';
17
- import { handleSetSessionScope, setSessionScopeTool } from './tools/set_session_scope.js';
18
- import { handleYieldForScopeExpansion, yieldForScopeExpansionTool } from './tools/yield_for_scope_expansion.js';
19
16
  import { handleGetStartHere, getStartHereTool } from './tools/hydration/get_start_here.js';
20
17
  import { handleGetProjectSummary, getProjectSummaryTool } from './tools/hydration/get_project_summary.js';
21
18
  import { handleGetEvidenceSlice, getEvidenceSliceTool } from './tools/hydration/get_evidence_slice.js';
22
- import { handlePrepareTaskContext, prepareTaskContextTool } from './tools/prepareTaskContext.js';
23
- import { handleExplainSpecialistScope, explainSpecialistScopeTool } from './tools/explainSpecialistScope.js';
24
19
  // ⚠️ CRITICAL: Never use console.log() anywhere in this codebase.
25
20
  // stdout is owned by the MCP SDK for protocol messages.
26
21
  // Use console.error() for all diagnostic output.
@@ -40,15 +35,6 @@ const ALL_TOOLS = [
40
35
  getStartHereTool,
41
36
  getProjectSummaryTool,
42
37
  getEvidenceSliceTool,
43
- // Phase 3: Worker Delegation
44
- createWorkOrderTool,
45
- spawnWorkerTool,
46
- // Phase 4: Scope & Escalation
47
- setSessionScopeTool,
48
- yieldForScopeExpansionTool,
49
- // Specialist Network v0
50
- prepareTaskContextTool,
51
- explainSpecialistScopeTool,
52
38
  ];
53
39
  const TOOL_HANDLERS = {
54
40
  scan_project: handleScanProject,
@@ -66,21 +52,12 @@ const TOOL_HANDLERS = {
66
52
  get_start_here: handleGetStartHere,
67
53
  get_project_summary: handleGetProjectSummary,
68
54
  get_evidence_slice: handleGetEvidenceSlice,
69
- // Phase 3
70
- create_work_order: handleCreateWorkOrder,
71
- spawn_worker: handleSpawnWorker,
72
- // Phase 4
73
- set_session_scope: handleSetSessionScope,
74
- yield_for_scope_expansion: handleYieldForScopeExpansion,
75
- // Specialist Network v0
76
- vibe_prepare_task_context: handlePrepareTaskContext,
77
- vibe_explain_specialist_scope: handleExplainSpecialistScope,
78
55
  };
79
56
  export async function startMCPServer(options = {}) {
80
57
  // Initialize Tree-Sitter WASM once at startup
81
58
  await initParser();
82
59
  console.error('[vibe-splain] Tree-Sitter parser initialized');
83
- const server = new Server({ name: 'vibe-splain', version: '3.0.0' }, { capabilities: { tools: {}, prompts: {} } });
60
+ const server = new Server({ name: 'vibe-splain', version: '3.5.0' }, { capabilities: { tools: {}, prompts: {} } });
84
61
  // Register prompts
85
62
  server.setRequestHandler(ListPromptsRequestSchema, async () => ({
86
63
  prompts: [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vibe-splain",
3
- "version": "3.4.2",
4
- "description": "Architectural mapping and behavioral call-chain engine. Built on a language-agnostic foundation with specialized optimization for TypeScript/JavaScript projects.",
3
+ "version": "3.5.0",
4
+ "description": "Static-analysis MRI for codebases: a Tree-Sitter dossier engine and deterministic PreToolUse safety gate for coding agents. Language-agnostic core, optimized for TypeScript/JavaScript.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "abp2204",
@@ -1,4 +0,0 @@
1
- export declare function bundleCommand(scanId: string, opts?: {
2
- output?: string;
3
- projectRoot?: string;
4
- }): Promise<void>;
@@ -1,68 +0,0 @@
1
- import { join } from 'path';
2
- import { writeFile, mkdir, copyFile, rm } from 'fs/promises';
3
- import { existsSync } from 'fs';
4
- import * as tar from 'tar';
5
- import { PointerStore } from '../store/PointerStore.js';
6
- import { BlobStore } from '../store/BlobStore.js';
7
- export async function bundleCommand(scanId, opts = {}) {
8
- const root = opts.projectRoot ?? process.cwd();
9
- const outputPath = opts.output ?? join(root, `vibe-bundle-${scanId}.tar.gz`);
10
- console.error(`[vibe-splain bundle] Bundling scan ${scanId} from ${root}`);
11
- const pointerStore = PointerStore.open(root);
12
- const blobStore = new BlobStore(root);
13
- const pointers = pointerStore.listPointersByScan(scanId);
14
- if (pointers.length === 0) {
15
- throw new Error(`No pointers found for scanId "${scanId}"`);
16
- }
17
- // Stage bundle into a temp directory with predictable layout
18
- const stagingDir = join(root, '.vibe-splainer', 'tmp', `bundle-stage-${scanId}`);
19
- const blobsStageDir = join(stagingDir, 'blobs');
20
- await mkdir(blobsStageDir, { recursive: true });
21
- try {
22
- // Build manifest for the bundle
23
- const bundleManifest = {
24
- schemaVersion: '1.0.0',
25
- scanId,
26
- exportedAt: new Date().toISOString(),
27
- projectRoot: root,
28
- pointers: pointers.map(p => ({
29
- pointerId: p.pointerId,
30
- scanId: p.scanId,
31
- artifactName: p.artifactName,
32
- contentHash: p.contentHash,
33
- blobFile: `blobs/${p.contentHash.replace('sha256:', 'sha256_')}`,
34
- schemaVersion: p.schemaVersion,
35
- createdAt: p.createdAt,
36
- expiresAt: p.expiresAt,
37
- })),
38
- };
39
- await writeFile(join(stagingDir, 'bundle-manifest.json'), JSON.stringify(bundleManifest, null, 2), 'utf8');
40
- // Copy blobs (deduplicated by contentHash)
41
- const seen = new Set();
42
- for (const p of pointers) {
43
- const hex = p.contentHash.replace('sha256:', '');
44
- if (seen.has(hex))
45
- continue;
46
- seen.add(hex);
47
- const srcPath = p.blobPath;
48
- if (!existsSync(srcPath)) {
49
- console.error(`[vibe-splain bundle] Warning: blob missing for ${p.pointerId}: ${srcPath}`);
50
- continue;
51
- }
52
- await copyFile(srcPath, join(blobsStageDir, `sha256_${hex}`));
53
- }
54
- // Create tarball from staging directory
55
- await tar.create({
56
- gzip: true,
57
- file: outputPath,
58
- cwd: stagingDir,
59
- portable: true,
60
- }, ['.']);
61
- console.error(`[vibe-splain bundle] Bundle written: ${outputPath}`);
62
- console.error(`[vibe-splain bundle] ${pointers.length} pointers, ${seen.size} blobs`);
63
- }
64
- finally {
65
- await rm(stagingDir, { recursive: true, force: true });
66
- }
67
- }
68
- //# sourceMappingURL=bundle.js.map
@@ -1 +0,0 @@
1
- export declare function exportCommand(projectRoot: string, options: any): Promise<void>;
@@ -1,19 +0,0 @@
1
- import { readDossier } from '@vibe-splain/brain';
2
- import { ExportOrchestrator } from '../export/ExportOrchestrator.js';
3
- export async function exportCommand(projectRoot, options) {
4
- const root = projectRoot || process.cwd();
5
- console.error(`[vibe-splain] Exporting dossier for ${root}`);
6
- const dossier = await readDossier(root);
7
- if (!dossier) {
8
- console.error('[vibe-splain] Dossier not found. Run scan first.');
9
- process.exit(1);
10
- }
11
- const orchestrator = new ExportOrchestrator(root);
12
- await orchestrator.writeBundle(dossier, {
13
- format: options.format,
14
- budget: options.budget ? parseInt(options.budget, 10) : undefined,
15
- scope: options.scope,
16
- });
17
- console.error('[vibe-splain] Export complete.');
18
- }
19
- //# sourceMappingURL=export.js.map
@@ -1,3 +0,0 @@
1
- export declare function gcCommand(projectRoot?: string, opts?: {
2
- keepScans?: number;
3
- }): Promise<void>;
@@ -1,59 +0,0 @@
1
- import { join } from 'path';
2
- import { rm, readdir } from 'fs/promises';
3
- import { PointerStore } from '../store/PointerStore.js';
4
- import { BlobStore } from '../store/BlobStore.js';
5
- const DEFAULT_KEEP_SCANS = 3;
6
- export async function gcCommand(projectRoot, opts = {}) {
7
- const root = projectRoot ?? process.cwd();
8
- const keepScans = opts.keepScans ?? DEFAULT_KEEP_SCANS;
9
- console.error(`[vibe-splain gc] Running GC on ${root} (keeping last ${keepScans} scans)`);
10
- const pointerStore = PointerStore.open(root);
11
- const blobStore = new BlobStore(root);
12
- // 1. Get all scan IDs ordered by createdAt desc
13
- const allScanIds = pointerStore.listAllScanIds();
14
- console.error(`[vibe-splain gc] Found ${allScanIds.length} scans`);
15
- // Keep the N most recent by taking last N from sorted list
16
- // Scan IDs contain timestamps, sort lexicographically descending
17
- const sorted = [...allScanIds].sort().reverse();
18
- const keepIds = sorted.slice(0, keepScans);
19
- const deleteIds = sorted.slice(keepScans);
20
- if (deleteIds.length === 0) {
21
- console.error('[vibe-splain gc] Nothing to collect');
22
- return;
23
- }
24
- // 2. Collect all blob paths still referenced by kept pointers before deletion
25
- const keptPointers = keepIds.flatMap(id => pointerStore.listPointersByScan(id));
26
- const referencedBlobs = new Set(keptPointers.map(p => p.blobPath));
27
- // 3. Delete old scan pointers
28
- const deleted = await pointerStore.gcScanPointers(keepIds);
29
- console.error(`[vibe-splain gc] Deleted ${deleted} pointer rows`);
30
- // 4. Delete unreferenced blobs (reference count = 0)
31
- const allBlobs = await blobStore.listBlobPaths();
32
- let blobsDeleted = 0;
33
- for (const blobPath of allBlobs) {
34
- if (!referencedBlobs.has(blobPath)) {
35
- try {
36
- await rm(blobPath);
37
- blobsDeleted++;
38
- }
39
- catch {
40
- // ignore — may have already been deleted
41
- }
42
- }
43
- }
44
- console.error(`[vibe-splain gc] Deleted ${blobsDeleted} unreferenced blobs`);
45
- // 5. Clean up tmp dir
46
- const tmpDir = join(root, '.vibe-splainer', 'tmp');
47
- try {
48
- const tmpFiles = await readdir(tmpDir);
49
- for (const f of tmpFiles) {
50
- await rm(join(tmpDir, f), { force: true });
51
- }
52
- console.error(`[vibe-splain gc] Cleaned ${tmpFiles.length} tmp files`);
53
- }
54
- catch {
55
- // tmp dir may not exist
56
- }
57
- console.error('[vibe-splain gc] Done');
58
- }
59
- //# sourceMappingURL=gc.js.map
@@ -1,4 +0,0 @@
1
- export declare function importBundleCommand(tarballPath: string, opts?: {
2
- projectRoot?: string;
3
- namespace?: string;
4
- }): Promise<void>;
@@ -1,80 +0,0 @@
1
- import { join } from 'path';
2
- import { readFile, mkdir, rm } from 'fs/promises';
3
- import { existsSync } from 'fs';
4
- import * as tar from 'tar';
5
- import { createHash } from 'crypto';
6
- import { BlobStore } from '../store/BlobStore.js';
7
- import { PointerStore } from '../store/PointerStore.js';
8
- export async function importBundleCommand(tarballPath, opts = {}) {
9
- const root = opts.projectRoot ?? process.cwd();
10
- const namespace = opts.namespace ?? `imported_${Date.now()}`;
11
- console.error(`[vibe-splain import] Importing ${tarballPath} into ${root} (namespace: ${namespace})`);
12
- if (!existsSync(tarballPath)) {
13
- throw new Error(`Tarball not found: ${tarballPath}`);
14
- }
15
- // Extract to a temp directory
16
- const extractDir = join(root, '.vibe-splainer', 'tmp', `import-${namespace}`);
17
- await mkdir(extractDir, { recursive: true });
18
- try {
19
- await tar.extract({
20
- file: tarballPath,
21
- cwd: extractDir,
22
- });
23
- // Read bundle manifest
24
- const manifestPath = join(extractDir, 'bundle-manifest.json');
25
- if (!existsSync(manifestPath)) {
26
- throw new Error('Invalid bundle: missing bundle-manifest.json');
27
- }
28
- const manifestRaw = await readFile(manifestPath, 'utf8');
29
- const manifest = JSON.parse(manifestRaw);
30
- if (manifest.schemaVersion !== '1.0.0') {
31
- throw new Error(`Unsupported bundle schema version: ${manifest.schemaVersion}`);
32
- }
33
- const blobStore = new BlobStore(root);
34
- const pointerStore = PointerStore.open(root);
35
- await blobStore.ensureDirs();
36
- let imported = 0;
37
- let hashErrors = 0;
38
- for (const entry of manifest.pointers) {
39
- const blobSrcPath = join(extractDir, entry.blobFile);
40
- if (!existsSync(blobSrcPath)) {
41
- console.error(`[vibe-splain import] Missing blob for pointer ${entry.pointerId}: ${entry.blobFile}`);
42
- hashErrors++;
43
- continue;
44
- }
45
- // Verify hash before importing
46
- const content = await readFile(blobSrcPath);
47
- const actualHash = `sha256:${createHash('sha256').update(content).digest('hex')}`;
48
- if (actualHash !== entry.contentHash) {
49
- console.error(`[vibe-splain import] Hash mismatch for ${entry.pointerId}: expected ${entry.contentHash}, got ${actualHash}`);
50
- hashErrors++;
51
- continue;
52
- }
53
- // Write blob to local store (atomic)
54
- const { blobPath } = await blobStore.writeAtomic(content);
55
- // Insert pointer under bundle namespace alias
56
- const namespacedPointerId = `${namespace}::${entry.pointerId}`;
57
- const namespacedScanId = `${namespace}::${entry.scanId}`;
58
- await pointerStore.insertPointer({
59
- pointerId: namespacedPointerId,
60
- scanId: namespacedScanId,
61
- artifactName: entry.artifactName,
62
- contentHash: entry.contentHash,
63
- blobPath,
64
- schemaVersion: entry.schemaVersion,
65
- createdAt: entry.createdAt,
66
- expiresAt: entry.expiresAt,
67
- });
68
- imported++;
69
- }
70
- if (hashErrors > 0) {
71
- console.error(`[vibe-splain import] Warning: ${hashErrors} blobs failed hash verification and were skipped`);
72
- }
73
- console.error(`[vibe-splain import] Imported ${imported}/${manifest.pointers.length} pointers under namespace "${namespace}"`);
74
- console.error(`[vibe-splain import] Original scanId: ${manifest.scanId} → namespaced as: ${namespace}::${manifest.scanId}`);
75
- }
76
- finally {
77
- await rm(extractDir, { recursive: true, force: true });
78
- }
79
- }
80
- //# sourceMappingURL=importBundle.js.map
@@ -1 +0,0 @@
1
- export declare function networkPlanCommand(task: string, options: any): Promise<void>;
@@ -1,91 +0,0 @@
1
- import { join, resolve } from 'path';
2
- import { readFile, writeFile, mkdir } from 'fs/promises';
3
- import { buildExpertNetworkPacket } from '@vibe-splain/brain';
4
- export async function networkPlanCommand(task, options) {
5
- const projectRoot = options.root ? resolve(options.root) : process.cwd();
6
- const maxFiles = options.maxFiles ? parseInt(options.maxFiles, 10) : 8;
7
- // Try to load scan artifact
8
- let scanArtifact = null;
9
- const artifactPath = options.scanArtifact
10
- ? resolve(options.scanArtifact)
11
- : join(projectRoot, '.vibe-splainer', 'analysis.json');
12
- try {
13
- const raw = await readFile(artifactPath, 'utf8');
14
- scanArtifact = JSON.parse(raw);
15
- }
16
- catch (err) {
17
- if (options.scanArtifact) {
18
- console.error(`[vibe-splain] Error reading scan artifact at ${artifactPath}:`, err.message);
19
- }
20
- }
21
- // Build the packet
22
- const packet = buildExpertNetworkPacket({
23
- task,
24
- projectRoot,
25
- scanArtifact,
26
- errorTrace: options.errorTrace,
27
- intendedBehavior: options.intendedBehavior,
28
- maxFiles
29
- });
30
- // Save artifacts
31
- const networkDir = join(projectRoot, '.vibe-splainer', 'network');
32
- const packetsDir = join(networkDir, 'packets');
33
- try {
34
- await mkdir(packetsDir, { recursive: true });
35
- // Save latest
36
- const latestPath = join(networkDir, 'latest_packet.json');
37
- await writeFile(latestPath, JSON.stringify(packet, null, 2), 'utf8');
38
- // Save timestamped
39
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
40
- const timestampedPath = join(packetsDir, `${timestamp}.json`);
41
- await writeFile(timestampedPath, JSON.stringify(packet, null, 2), 'utf8');
42
- if (options.json) {
43
- process.stdout.write(JSON.stringify(packet, null, 2) + '\n');
44
- }
45
- else {
46
- process.stdout.write('────────────────────────────────────────────────────────\n');
47
- process.stdout.write(' Vibe-Splain Specialist Network — Task Plan\n');
48
- process.stdout.write('────────────────────────────────────────────────────────\n');
49
- process.stdout.write(`Task: "${packet.task}"\n`);
50
- process.stdout.write(`Project Root: ${packet.projectRoot}\n`);
51
- process.stdout.write(`Primary Specialist: ${packet.route.primarySpecialist}\n`);
52
- process.stdout.write(`Panel: ${packet.route.panel.join(', ')}\n`);
53
- process.stdout.write(`Confidence: ${packet.route.confidence}\n`);
54
- process.stdout.write(`Reason: ${packet.route.reason}\n`);
55
- process.stdout.write('\nSelected Files:\n');
56
- if (packet.selectedFiles.length > 0) {
57
- packet.selectedFiles.forEach(f => {
58
- process.stdout.write(` • ${f.path} [blastRadius: ${f.blastRadius}]\n`);
59
- process.stdout.write(` Reason: ${f.reason}\n`);
60
- });
61
- }
62
- else {
63
- process.stdout.write(' (No files selected)\n');
64
- }
65
- process.stdout.write('\nRisk Warnings:\n');
66
- if (packet.riskWarnings.length > 0) {
67
- packet.riskWarnings.forEach(w => {
68
- const levelLabel = w.level === 'critical' ? '🔴 CRITICAL' : (w.level === 'warning' ? '🟡 WARNING' : 'ℹ️ INFO');
69
- process.stdout.write(` • [${levelLabel}] ${w.message}\n`);
70
- process.stdout.write(` Reason: ${w.reason}\n`);
71
- });
72
- }
73
- else {
74
- process.stdout.write(' (No risks identified)\n');
75
- }
76
- process.stdout.write('\nSmallest Safe Change Policy:\n');
77
- process.stdout.write(` ${packet.smallestSafeChangePolicy.summary}\n`);
78
- process.stdout.write('\nSaved Artifacts:\n');
79
- process.stdout.write(` • Latest: ${latestPath}\n`);
80
- process.stdout.write(` • Packet: ${timestampedPath}\n`);
81
- process.stdout.write('────────────────────────────────────────────────────────\n');
82
- }
83
- }
84
- catch (err) {
85
- console.error('[vibe-splain] Error saving network artifacts:', err.message);
86
- if (options.json) {
87
- process.stdout.write(JSON.stringify(packet, null, 2) + '\n');
88
- }
89
- }
90
- }
91
- //# sourceMappingURL=network.js.map
@@ -1,13 +0,0 @@
1
- interface ScanOptions {
2
- root?: string;
3
- out?: string;
4
- json?: boolean;
5
- }
6
- /**
7
- * Headless one-shot scan. Reuses the exact MCP scan pipeline (performScan),
8
- * relocates the artifact bundle to --out, and prints a summary. The gravity
9
- * formula is selected by the ROZE_GRAVITY_V2 env var, never a CLI flag — v2 is
10
- * still an experimental candidate (see CONTEXT.md / Phase 0).
11
- */
12
- export declare function scanCommand(options?: ScanOptions): Promise<void>;
13
- export {};
@@ -1,97 +0,0 @@
1
- import { resolve, join, dirname } from 'path';
2
- import { rm, rename, mkdir, writeFile } from 'fs/promises';
3
- import { performScan } from '../mcp/tools/scan_project.js';
4
- /**
5
- * Headless one-shot scan. Reuses the exact MCP scan pipeline (performScan),
6
- * relocates the artifact bundle to --out, and prints a summary. The gravity
7
- * formula is selected by the ROZE_GRAVITY_V2 env var, never a CLI flag — v2 is
8
- * still an experimental candidate (see CONTEXT.md / Phase 0).
9
- */
10
- export async function scanCommand(options = {}) {
11
- const root = resolve(options.root || '.');
12
- const gravityMode = process.env.ROZE_GRAVITY_V2 === '1' ? 'v2_candidate' : 'v1_default';
13
- console.error(`[roze] Scanning ${root} (gravity mode: ${gravityMode})...`);
14
- const { result, scanId } = await performScan(root);
15
- // The pipeline always writes to <root>/.roze. Relocate to --out if different
16
- // so v1 and v2 runs can coexist for comparison.
17
- const defaultDir = join(root, '.roze');
18
- const outDir = resolve(options.out || defaultDir);
19
- if (outDir !== defaultDir) {
20
- await rm(outDir, { recursive: true, force: true });
21
- await mkdir(dirname(outDir), { recursive: true });
22
- await rename(defaultDir, outDir);
23
- }
24
- // Persist the gravity mode so v1/v2 scans are self-identifying.
25
- const meta = {
26
- gravityMode,
27
- scannedAt: new Date().toISOString(),
28
- root,
29
- scanId,
30
- totalFilesScanned: result.totalFilesScanned,
31
- realSourceCount: result.realSourceCount,
32
- wildCandidateCount: result.wildCandidates.length,
33
- };
34
- await writeFile(join(outDir, 'scan_meta.json'), JSON.stringify(meta, null, 2));
35
- // Build gravity/heat lookups from the scored files for display.
36
- const gravityByPath = new Map(result.files.map(f => [f.relativePath, f.gravity]));
37
- const heatByPath = new Map(result.files.map(f => [f.relativePath, f.heat]));
38
- const topGravity = result.map.topGravity.slice(0, 12).map(p => ({
39
- path: p,
40
- gravity: Math.round(gravityByPath.get(p) ?? 0),
41
- }));
42
- const topHeat = result.map.topHeat.slice(0, 12).map(p => ({
43
- path: p,
44
- heat: Math.round(heatByPath.get(p) ?? 0),
45
- }));
46
- const wildDiscovery = result.wildCandidates.slice(0, 12).map(f => ({
47
- path: f.relativePath,
48
- heat: Math.round(f.heat),
49
- gravity: Math.round(f.gravity),
50
- topSmells: f.smells.filter(s => s.severity >= 3).slice(0, 3).map(s => s.note),
51
- }));
52
- const specialistMap = result.map.pillars.map(p => ({
53
- name: p.name,
54
- fileCount: p.memberFiles.length,
55
- }));
56
- const summary = {
57
- gravityMode,
58
- root,
59
- outDir,
60
- dossier: join(outDir, 'dossier.json'),
61
- analysis: join(outDir, 'analysis.json'),
62
- stack: result.map.stack,
63
- totalFilesScanned: result.totalFilesScanned,
64
- realSourceCount: result.realSourceCount,
65
- topGravity,
66
- topHeat,
67
- wildDiscovery,
68
- specialistMap,
69
- };
70
- if (options.json) {
71
- process.stdout.write(JSON.stringify(summary, null, 2) + '\n');
72
- return;
73
- }
74
- const lines = [];
75
- lines.push('');
76
- lines.push(`roze scan — gravity mode: ${gravityMode}`);
77
- lines.push(` root: ${root}`);
78
- lines.push(` stack: ${result.map.stack.join(', ') || '(none detected)'}`);
79
- lines.push(` files: ${result.totalFilesScanned} scanned, ${result.realSourceCount} real-source`);
80
- lines.push('');
81
- lines.push('Top Gravity (Start Here):');
82
- topGravity.forEach((f, i) => lines.push(` ${String(i + 1).padStart(2)}. [${String(f.gravity).padStart(3)}] ${f.path}`));
83
- lines.push('');
84
- lines.push('Top Heat (Wild Discovery):');
85
- topHeat.forEach((f, i) => lines.push(` ${String(i + 1).padStart(2)}. [${String(f.heat).padStart(3)}] ${f.path}`));
86
- lines.push('');
87
- lines.push('Specialist Map (pillars):');
88
- specialistMap.forEach(p => lines.push(` - ${p.name} (${p.fileCount} files)`));
89
- lines.push('');
90
- lines.push(`Artifacts written to: ${outDir}`);
91
- lines.push(` dossier: ${join(outDir, 'dossier.json')}`);
92
- lines.push(` analysis: ${join(outDir, 'analysis.json')}`);
93
- lines.push(` meta: ${join(outDir, 'scan_meta.json')} (gravityMode: ${gravityMode})`);
94
- lines.push('');
95
- process.stdout.write(lines.join('\n'));
96
- }
97
- //# sourceMappingURL=scan.js.map
@@ -1,6 +0,0 @@
1
- import type { DossierViewModel, AnalysisStore } from '@vibe-splain/brain';
2
- import type { Renderer } from './Renderer.js';
3
- import type { Artifact } from '../ArtifactBundleWriter.js';
4
- export declare class DeltaRenderer implements Renderer {
5
- render(_viewModel: DossierViewModel, store: AnalysisStore): Artifact[];
6
- }
@@ -1,22 +0,0 @@
1
- export class DeltaRenderer {
2
- render(_viewModel, store) {
3
- const deltaTargets = Object.values(store.files)
4
- .filter(pf => pf.isRealSource)
5
- .sort((a, b) => b.gravity - a.gravity)
6
- .map(pf => ({
7
- path: pf.relativePath,
8
- gravity: Math.round(pf.gravity),
9
- isLoadBearing: pf.canonicalLoadBearing,
10
- blastRadius: pf.importedBy,
11
- pillarHint: pf.pillarHint,
12
- }));
13
- return [
14
- {
15
- type: 'delta',
16
- path: 'delta_targets.json',
17
- content: JSON.stringify(deltaTargets, null, 2),
18
- }
19
- ];
20
- }
21
- }
22
- //# sourceMappingURL=DeltaRenderer.js.map
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env node
2
- // Lean entrypoint for the PreToolUse hook. Bundled separately from the main CLI
3
- // so it pulls in ONLY the gate-index reader + decision logic — no Tree-Sitter
4
- // WASM, no MCP SDK, no chokidar. Keeps per-edit startup near the bare-Node floor
5
- // (~40–60ms) instead of loading the full scanner bundle (~260ms+).
6
- import { hookPreToolUseCommand } from './commands/hook.js';
7
- hookPreToolUseCommand();
8
- //# sourceMappingURL=hook-entry.js.map
@@ -1,37 +0,0 @@
1
- export declare class StalePatchError extends Error {
2
- readonly filePath: string;
3
- readonly expectedHash: string;
4
- readonly actualHash: string;
5
- constructor(filePath: string, expectedHash: string, actualHash: string);
6
- }
7
- export declare const applyPatchTool: {
8
- name: string;
9
- description: string;
10
- inputSchema: {
11
- type: "object";
12
- properties: {
13
- projectRoot: {
14
- type: string;
15
- description: string;
16
- };
17
- filePath: {
18
- type: string;
19
- description: string;
20
- };
21
- newContent: {
22
- type: string;
23
- description: string;
24
- };
25
- expectedPrePatchHash: {
26
- type: string;
27
- description: string;
28
- };
29
- scanId: {
30
- type: string;
31
- description: string;
32
- };
33
- };
34
- required: string[];
35
- };
36
- };
37
- export declare function handleApplyPatch(args: Record<string, unknown>): Promise<unknown>;