vibe-splain 3.4.2 → 4.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.
Files changed (87) hide show
  1. package/README.md +110 -158
  2. package/dist/commands/install.d.ts +0 -5
  3. package/dist/commands/install.js +5 -55
  4. package/dist/commands/serve.js +1 -1
  5. package/dist/export/ArtifactBundleWriter.js +3 -3
  6. package/dist/export/ExportOrchestrator.d.ts +2 -20
  7. package/dist/export/ExportOrchestrator.js +5 -116
  8. package/dist/export/Watcher.js +5 -5
  9. package/dist/export/renderers/AgentMarkdownRenderer.d.ts +1 -1
  10. package/dist/export/renderers/GraphRenderer.d.ts +2 -2
  11. package/dist/export/renderers/HtmlRenderer.d.ts +1 -1
  12. package/dist/export/renderers/HtmlRenderer.js +1 -1
  13. package/dist/export/renderers/JsonRenderer.d.ts +1 -1
  14. package/dist/export/renderers/RawAnalysisRenderer.d.ts +1 -1
  15. package/dist/export/renderers/Renderer.d.ts +1 -1
  16. package/dist/export/renderers/ValidationRenderer.d.ts +1 -1
  17. package/dist/index.js +1425 -6511
  18. package/dist/mcp/server.js +6 -46
  19. package/dist/mcp/tools/get_file_context.js +1 -1
  20. package/dist/mcp/tools/get_project_map.js +1 -1
  21. package/dist/mcp/tools/get_strategic_overview.js +1 -1
  22. package/dist/mcp/tools/get_wild_discoveries.js +1 -1
  23. package/dist/mcp/tools/inspect_pillar.js +1 -1
  24. package/dist/mcp/tools/mark_stale.js +1 -1
  25. package/dist/mcp/tools/scan_project.d.ts +2 -3
  26. package/dist/mcp/tools/scan_project.js +12 -13
  27. package/dist/mcp/tools/set_project_brief.js +1 -1
  28. package/dist/mcp/tools/write_decision_card.d.ts +1 -1
  29. package/dist/mcp/tools/write_decision_card.js +2 -2
  30. package/dist/ui/index.html +1 -1
  31. package/package.json +9 -14
  32. package/dist/commands/bundle.d.ts +0 -4
  33. package/dist/commands/bundle.js +0 -68
  34. package/dist/commands/export.d.ts +0 -1
  35. package/dist/commands/export.js +0 -19
  36. package/dist/commands/gc.d.ts +0 -3
  37. package/dist/commands/gc.js +0 -59
  38. package/dist/commands/hook.d.ts +0 -9
  39. package/dist/commands/hook.js +0 -84
  40. package/dist/commands/importBundle.d.ts +0 -4
  41. package/dist/commands/importBundle.js +0 -80
  42. package/dist/commands/network.d.ts +0 -1
  43. package/dist/commands/network.js +0 -91
  44. package/dist/commands/scan.d.ts +0 -13
  45. package/dist/commands/scan.js +0 -97
  46. package/dist/export/renderers/DeltaRenderer.d.ts +0 -6
  47. package/dist/export/renderers/DeltaRenderer.js +0 -22
  48. package/dist/hook/preToolUse.d.ts +0 -30
  49. package/dist/hook/preToolUse.js +0 -81
  50. package/dist/hook-entry.d.ts +0 -2
  51. package/dist/hook-entry.js +0 -8
  52. package/dist/hook.d.ts +0 -1
  53. package/dist/hook.js +0 -337
  54. package/dist/mcp/BudgetGuard.d.ts +0 -13
  55. package/dist/mcp/BudgetGuard.js +0 -55
  56. package/dist/mcp/SessionScope.d.ts +0 -26
  57. package/dist/mcp/SessionScope.js +0 -56
  58. package/dist/mcp/tools/apply_patch.d.ts +0 -37
  59. package/dist/mcp/tools/apply_patch.js +0 -103
  60. package/dist/mcp/tools/explainSpecialistScope.d.ts +0 -15
  61. package/dist/mcp/tools/explainSpecialistScope.js +0 -30
  62. package/dist/mcp/tools/get_call_chain.d.ts +0 -42
  63. package/dist/mcp/tools/get_call_chain.js +0 -50
  64. package/dist/mcp/tools/get_file_skeleton.d.ts +0 -23
  65. package/dist/mcp/tools/get_file_skeleton.js +0 -124
  66. package/dist/mcp/tools/hydration/get_evidence_slice.d.ts +0 -31
  67. package/dist/mcp/tools/hydration/get_evidence_slice.js +0 -57
  68. package/dist/mcp/tools/hydration/get_project_summary.d.ts +0 -23
  69. package/dist/mcp/tools/hydration/get_project_summary.js +0 -58
  70. package/dist/mcp/tools/hydration/get_start_here.d.ts +0 -23
  71. package/dist/mcp/tools/hydration/get_start_here.js +0 -52
  72. package/dist/mcp/tools/prepareTaskContext.d.ts +0 -38
  73. package/dist/mcp/tools/prepareTaskContext.js +0 -93
  74. package/dist/mcp/tools/read_file.d.ts +0 -31
  75. package/dist/mcp/tools/read_file.js +0 -90
  76. package/dist/mcp/tools/set_session_scope.d.ts +0 -19
  77. package/dist/mcp/tools/set_session_scope.js +0 -40
  78. package/dist/mcp/tools/submit_receipt.d.ts +0 -68
  79. package/dist/mcp/tools/submit_receipt.js +0 -94
  80. package/dist/mcp/tools/work_orders.d.ts +0 -79
  81. package/dist/mcp/tools/work_orders.js +0 -126
  82. package/dist/mcp/tools/yield_for_scope_expansion.d.ts +0 -29
  83. package/dist/mcp/tools/yield_for_scope_expansion.js +0 -59
  84. package/dist/store/BlobStore.d.ts +0 -22
  85. package/dist/store/BlobStore.js +0 -96
  86. package/dist/store/PointerStore.d.ts +0 -52
  87. package/dist/store/PointerStore.js +0 -154
@@ -1,103 +0,0 @@
1
- import { writeFile, rename, mkdir } from 'fs/promises';
2
- import { join, dirname } from 'path';
3
- import { SessionScope, ScopeViolation } from '../SessionScope.js';
4
- import { hashFile, BlobStore } from '../../store/BlobStore.js';
5
- import { PointerStore } from '../../store/PointerStore.js';
6
- import { applyBudgetGuard } from '../BudgetGuard.js';
7
- import { v4 as uuidv4 } from 'uuid';
8
- export class StalePatchError extends Error {
9
- filePath;
10
- expectedHash;
11
- actualHash;
12
- constructor(filePath, expectedHash, actualHash) {
13
- super(`StalePatchError: ${filePath} hash mismatch — expected ${expectedHash}, got ${actualHash}. ` +
14
- 'File was modified since the expectedPrePatchHash was computed. Re-read the file and regenerate the patch.');
15
- this.filePath = filePath;
16
- this.expectedHash = expectedHash;
17
- this.actualHash = actualHash;
18
- this.name = 'StalePatchError';
19
- }
20
- }
21
- export const applyPatchTool = {
22
- name: 'apply_patch',
23
- description: 'Applies a text patch to a file within the active workOrder scope. Requires expectedPrePatchHash to prevent stale-patch corruption. Records pre- and post-patch hashes.',
24
- inputSchema: {
25
- type: 'object',
26
- properties: {
27
- projectRoot: { type: 'string', description: 'Absolute project root' },
28
- filePath: { type: 'string', description: 'Path relative to projectRoot' },
29
- newContent: { type: 'string', description: 'Full new content of the file after the patch' },
30
- expectedPrePatchHash: {
31
- type: 'string',
32
- description: 'sha256:<hex> hash of the file BEFORE patching. Obtain via hashFile or the sourceHash from get_file_skeleton.',
33
- },
34
- scanId: { type: 'string', description: 'Current scan ID for pointer registration' },
35
- },
36
- required: ['projectRoot', 'filePath', 'newContent', 'expectedPrePatchHash', 'scanId'],
37
- },
38
- };
39
- export async function handleApplyPatch(args) {
40
- const projectRoot = args.projectRoot;
41
- const filePath = args.filePath;
42
- const newContent = args.newContent;
43
- const expectedPrePatchHash = args.expectedPrePatchHash;
44
- const scanId = args.scanId;
45
- if (!projectRoot || !filePath || !newContent || !expectedPrePatchHash || !scanId) {
46
- throw new Error('projectRoot, filePath, newContent, expectedPrePatchHash, and scanId are all required');
47
- }
48
- // 1. Scope enforcement
49
- try {
50
- SessionScope.enforce(filePath);
51
- }
52
- catch (e) {
53
- if (e instanceof ScopeViolation)
54
- throw e;
55
- throw e;
56
- }
57
- const absolutePath = filePath.startsWith('/') ? filePath : join(projectRoot, filePath);
58
- // 2. Preimage hash check
59
- let actualPreHash;
60
- try {
61
- actualPreHash = await hashFile(absolutePath);
62
- }
63
- catch {
64
- // File doesn't exist yet — for new files, expectedPrePatchHash must be 'sha256:new'
65
- actualPreHash = 'sha256:new';
66
- }
67
- if (actualPreHash !== expectedPrePatchHash) {
68
- throw new StalePatchError(filePath, expectedPrePatchHash, actualPreHash);
69
- }
70
- // 3. Atomic write
71
- const dir = dirname(absolutePath);
72
- await mkdir(dir, { recursive: true });
73
- const tmpPath = absolutePath + `.tmp_${Date.now()}`;
74
- await writeFile(tmpPath, newContent, 'utf8');
75
- await rename(tmpPath, absolutePath);
76
- // 4. Compute post-patch hash
77
- const postPatchHash = await hashFile(absolutePath);
78
- // 5. Record both hashes in blob store
79
- const blobStore = new BlobStore(projectRoot);
80
- const pointerStore = PointerStore.open(projectRoot);
81
- const { blobPath } = await blobStore.writeAtomic(newContent);
82
- const pointerId = `ptr_patch_${uuidv4().replace(/-/g, '').slice(0, 12)}`;
83
- await pointerStore.insertPointer({
84
- pointerId,
85
- scanId,
86
- artifactName: 'patch_record',
87
- contentHash: postPatchHash,
88
- blobPath,
89
- schemaVersion: '1.0.0',
90
- createdAt: Date.now(),
91
- expiresAt: null,
92
- });
93
- const result = {
94
- ok: true,
95
- filePath,
96
- prePatchHash: actualPreHash,
97
- postPatchHash,
98
- pointerId,
99
- message: `Patch applied to ${filePath}`,
100
- };
101
- return await applyBudgetGuard(projectRoot, scanId, 'patch_record', result);
102
- }
103
- //# sourceMappingURL=apply_patch.js.map
@@ -1,15 +0,0 @@
1
- export declare const explainSpecialistScopeTool: {
2
- name: string;
3
- description: string;
4
- inputSchema: {
5
- type: "object";
6
- properties: {
7
- specialist_id: {
8
- type: string;
9
- description: string;
10
- };
11
- };
12
- required: string[];
13
- };
14
- };
15
- export declare function handleExplainSpecialistScope(args: Record<string, unknown>, options?: any): Promise<unknown>;
@@ -1,30 +0,0 @@
1
- import { getSpecialistProfile, isSpecialistId } from '@vibe-splain/brain';
2
- export const explainSpecialistScopeTool = {
3
- name: 'vibe_explain_specialist_scope',
4
- description: 'Explains the jurisdiction scope card and profile definitions for a given specialist ID.',
5
- inputSchema: {
6
- type: 'object',
7
- properties: {
8
- specialist_id: {
9
- type: 'string',
10
- description: 'Specialist ID to explain (control_flow | data_transform | integration_contracts | generic_repo)',
11
- }
12
- },
13
- required: ['specialist_id'],
14
- },
15
- };
16
- export async function handleExplainSpecialistScope(args, options = {}) {
17
- const specialistId = args.specialist_id;
18
- if (!specialistId)
19
- throw new Error('specialist_id is required');
20
- if (!isSpecialistId(specialistId)) {
21
- throw new Error(`Invalid specialist ID: "${specialistId}". Must be one of: control_flow, data_transform, integration_contracts, generic_repo.`);
22
- }
23
- console.error(`[vibe-splain] Fetching scope profile for specialist: "${specialistId}"`);
24
- const profile = getSpecialistProfile(specialistId);
25
- return {
26
- ok: true,
27
- profile
28
- };
29
- }
30
- //# sourceMappingURL=explainSpecialistScope.js.map
@@ -1,42 +0,0 @@
1
- export declare const getCallChainTool: {
2
- name: string;
3
- description: string;
4
- inputSchema: {
5
- type: "object";
6
- properties: {
7
- projectRoot: {
8
- type: string;
9
- };
10
- entrypointPath: {
11
- type: string;
12
- description: string;
13
- };
14
- maxDepth: {
15
- type: string;
16
- description: string;
17
- };
18
- targetActionKind: {
19
- type: string;
20
- description: string;
21
- };
22
- targetModel: {
23
- type: string;
24
- description: string;
25
- };
26
- targetOperation: {
27
- type: string;
28
- description: string;
29
- };
30
- targetFunctionName: {
31
- type: string;
32
- description: string;
33
- };
34
- includeTests: {
35
- type: string;
36
- description: string;
37
- };
38
- };
39
- required: string[];
40
- };
41
- };
42
- export declare function handleGetCallChain(args: Record<string, unknown>): Promise<unknown>;
@@ -1,50 +0,0 @@
1
- import { traverseCallChain } from '@vibe-splain/brain';
2
- export const getCallChainTool = {
3
- name: 'get_call_chain',
4
- description: `Trace how behavior is reached from an entrypoint by following function call edges through the codebase. Returns a step-by-step chain with exact function names, file paths, line numbers, action kinds, and evidence text. Every edge has a confidence level; unresolved edges are listed explicitly.
5
-
6
- Use structured filters when you know the target:
7
- targetModel + targetOperation: "where does Booking get created?"
8
- targetActionKind: "where is auth enforced?"
9
- targetFunctionName: "how is function X reached?"
10
- No filter returns the full call tree up to maxDepth.
11
-
12
- Run scan_project first — this tool reads from the generated action_bindings.json.`,
13
- inputSchema: {
14
- type: 'object',
15
- properties: {
16
- projectRoot: { type: 'string' },
17
- entrypointPath: { type: 'string', description: 'Relative path to the entrypoint file' },
18
- maxDepth: { type: 'number', description: 'Max traversal depth. Default 6, max 12.' },
19
- targetActionKind: { type: 'string', description: 'Stop at this semantic action kind.' },
20
- targetModel: { type: 'string', description: 'Stop at functions touching this model.' },
21
- targetOperation: { type: 'string', description: 'Narrow targetModel to this operation.' },
22
- targetFunctionName: { type: 'string', description: 'Stop at a specific function name.' },
23
- includeTests: { type: 'boolean', description: 'Include test files in traversal. Default false.' },
24
- },
25
- required: ['projectRoot', 'entrypointPath'],
26
- },
27
- };
28
- export async function handleGetCallChain(args) {
29
- const projectRoot = args.projectRoot;
30
- const entrypointPath = args.entrypointPath;
31
- if (!projectRoot || !entrypointPath)
32
- throw new Error('projectRoot and entrypointPath are required');
33
- const getCallChainArgs = {
34
- entrypointPath,
35
- maxDepth: typeof args.maxDepth === 'number' ? args.maxDepth : undefined,
36
- targetActionKind: typeof args.targetActionKind === 'string' ? args.targetActionKind : undefined,
37
- targetModel: typeof args.targetModel === 'string' ? args.targetModel : undefined,
38
- targetOperation: typeof args.targetOperation === 'string' ? args.targetOperation : undefined,
39
- targetFunctionName: typeof args.targetFunctionName === 'string' ? args.targetFunctionName : undefined,
40
- includeTests: typeof args.includeTests === 'boolean' ? args.includeTests : undefined,
41
- };
42
- try {
43
- const result = await traverseCallChain(projectRoot, getCallChainArgs);
44
- return result;
45
- }
46
- catch (error) {
47
- throw new Error(`get_call_chain failed: ${error instanceof Error ? error.message : String(error)}`);
48
- }
49
- }
50
- //# sourceMappingURL=get_call_chain.js.map
@@ -1,23 +0,0 @@
1
- export declare const getFileSkeletonTool: {
2
- name: string;
3
- description: string;
4
- inputSchema: {
5
- type: "object";
6
- properties: {
7
- projectRoot: {
8
- type: string;
9
- description: string;
10
- };
11
- filePath: {
12
- type: string;
13
- description: string;
14
- };
15
- scanId: {
16
- type: string;
17
- description: string;
18
- };
19
- };
20
- required: string[];
21
- };
22
- };
23
- export declare function handleGetFileSkeleton(args: Record<string, unknown>): Promise<unknown>;
@@ -1,124 +0,0 @@
1
- import { readFile } from 'fs/promises';
2
- import { join } from 'path';
3
- import { SessionScope, ScopeViolation } from '../SessionScope.js';
4
- import { BlobStore, hashFile } from '../../store/BlobStore.js';
5
- import { PointerStore } from '../../store/PointerStore.js';
6
- import { applyBudgetGuard } from '../BudgetGuard.js';
7
- import { v4 as uuidv4 } from 'uuid';
8
- export const getFileSkeletonTool = {
9
- name: 'get_file_skeleton',
10
- description: 'Returns a content-addressed skeleton view of a source file (function signatures, class names, exported symbols). Enforces active workOrder scope. Results are content-addressed — repeated calls on unchanged files return cached pointers.',
11
- inputSchema: {
12
- type: 'object',
13
- properties: {
14
- projectRoot: { type: 'string', description: 'Absolute project root' },
15
- filePath: { type: 'string', description: 'Path relative to projectRoot' },
16
- scanId: { type: 'string', description: 'Current scan ID for pointer registration' },
17
- },
18
- required: ['projectRoot', 'filePath', 'scanId'],
19
- },
20
- };
21
- export async function handleGetFileSkeleton(args) {
22
- const projectRoot = args.projectRoot;
23
- const filePath = args.filePath;
24
- const scanId = args.scanId;
25
- if (!projectRoot || !filePath || !scanId) {
26
- throw new Error('projectRoot, filePath, and scanId are required');
27
- }
28
- // 1. Scope enforcement
29
- try {
30
- SessionScope.enforce(filePath);
31
- }
32
- catch (e) {
33
- if (e instanceof ScopeViolation)
34
- throw e;
35
- throw e;
36
- }
37
- const absolutePath = filePath.startsWith('/') ? filePath : join(projectRoot, filePath);
38
- // 2. Compute preimage hash of source file
39
- let currentHash;
40
- try {
41
- currentHash = await hashFile(absolutePath);
42
- }
43
- catch {
44
- throw new Error(`FileNotFound: cannot read ${filePath}`);
45
- }
46
- // 3. Check cache: same hash + parser version = return existing pointer
47
- const parserVersion = '1.0.0';
48
- const cacheKey = `skeleton:${currentHash}:${parserVersion}`;
49
- const pointerStore = PointerStore.open(projectRoot);
50
- // Look up by contentHash in existing pointers for this scan
51
- const existingPointers = pointerStore.listPointersByScan(scanId);
52
- const cached = existingPointers.find(p => p.artifactName === 'file_skeleton' && p.contentHash === cacheKey);
53
- if (cached) {
54
- return {
55
- pointerId: cached.pointerId,
56
- contentHash: currentHash,
57
- cached: true,
58
- filePath,
59
- };
60
- }
61
- // 4. Build skeleton
62
- const source = await readFile(absolutePath, 'utf8');
63
- const skeleton = extractSkeleton(source, filePath);
64
- // 5. Record content hash
65
- const skeletonPayload = {
66
- filePath,
67
- sourceHash: currentHash,
68
- parserVersion,
69
- skeleton,
70
- };
71
- // 6. Budget enforcement
72
- const blobStore = new BlobStore(projectRoot);
73
- const serialized = JSON.stringify(skeletonPayload, null, 2);
74
- const { contentHash: skeletonHash, blobPath } = await blobStore.writeAtomic(serialized);
75
- const pointerId = `ptr_skel_${uuidv4().replace(/-/g, '').slice(0, 12)}`;
76
- await pointerStore.insertPointer({
77
- pointerId,
78
- scanId,
79
- artifactName: 'file_skeleton',
80
- contentHash: cacheKey, // cache key encodes source hash + parser version
81
- blobPath,
82
- schemaVersion: '1.0.0',
83
- createdAt: Date.now(),
84
- expiresAt: null,
85
- });
86
- const result = {
87
- filePath,
88
- sourceHash: currentHash,
89
- pointerId,
90
- skeleton,
91
- };
92
- return await applyBudgetGuard(projectRoot, scanId, 'file_skeleton', result);
93
- }
94
- function extractSkeleton(source, filePath) {
95
- const lines = source.split('\n');
96
- const skeleton = [];
97
- const ext = filePath.split('.').pop() ?? '';
98
- const isTS = ['ts', 'tsx'].includes(ext);
99
- const isJS = ['js', 'jsx', 'mjs', 'cjs'].includes(ext);
100
- if (isTS || isJS) {
101
- for (let i = 0; i < lines.length; i++) {
102
- const line = lines[i].trim();
103
- // Exported declarations, function/class/interface/type/enum signatures
104
- if (/^(export\s+)?(async\s+)?function\b/.test(line) ||
105
- /^(export\s+)?(abstract\s+)?class\b/.test(line) ||
106
- /^(export\s+)?interface\b/.test(line) ||
107
- /^(export\s+)?type\s+\w+/.test(line) ||
108
- /^(export\s+)?enum\b/.test(line) ||
109
- /^(export\s+)?const\s+\w+\s*[:=(]/.test(line) ||
110
- /^(export\s+)?let\s+\w+\s*[:=(]/.test(line) ||
111
- /^(export\s+)?(default\s+)/.test(line) ||
112
- /^\s*(public|private|protected|static|readonly|abstract)\s+/.test(line) ||
113
- /^import\b/.test(line)) {
114
- skeleton.push(`L${i + 1}: ${lines[i]}`);
115
- }
116
- }
117
- }
118
- else {
119
- // Generic: return first 80 lines as skeleton for unsupported types
120
- return lines.slice(0, 80).map((l, i) => `L${i + 1}: ${l}`);
121
- }
122
- return skeleton;
123
- }
124
- //# sourceMappingURL=get_file_skeleton.js.map
@@ -1,31 +0,0 @@
1
- export declare const getEvidenceSliceTool: {
2
- name: string;
3
- description: string;
4
- inputSchema: {
5
- type: "object";
6
- properties: {
7
- projectRoot: {
8
- type: string;
9
- description: string;
10
- };
11
- pointerId: {
12
- type: string;
13
- description: string;
14
- };
15
- startLine: {
16
- type: string;
17
- description: string;
18
- };
19
- endLine: {
20
- type: string;
21
- description: string;
22
- };
23
- scanId: {
24
- type: string;
25
- description: string;
26
- };
27
- };
28
- required: string[];
29
- };
30
- };
31
- export declare function handleGetEvidenceSlice(args: Record<string, unknown>): Promise<unknown>;
@@ -1,57 +0,0 @@
1
- import { hydratePointer, applyBudgetGuard } from '../../BudgetGuard.js';
2
- import { SessionScope } from '../../SessionScope.js';
3
- export const getEvidenceSliceTool = {
4
- name: 'get_evidence_slice',
5
- description: 'Raw fallback: returns a line-range slice from a blob artifact. Pointer must be valid and unexpired. Output is budgeted.',
6
- inputSchema: {
7
- type: 'object',
8
- properties: {
9
- projectRoot: { type: 'string', description: 'Absolute project root' },
10
- pointerId: { type: 'string', description: 'Pointer ID for the target artifact' },
11
- startLine: { type: 'number', description: 'Inclusive start line (1-based)' },
12
- endLine: { type: 'number', description: 'Inclusive end line (1-based). Capped at startLine+200.' },
13
- scanId: { type: 'string', description: 'Current scan ID for budget pointer registration' },
14
- },
15
- required: ['projectRoot', 'pointerId', 'startLine', 'endLine', 'scanId'],
16
- },
17
- };
18
- export async function handleGetEvidenceSlice(args) {
19
- const projectRoot = args.projectRoot;
20
- const pointerId = args.pointerId;
21
- const startLine = Number(args.startLine);
22
- const endLine = Math.min(Number(args.endLine), startLine + 200);
23
- const scanId = args.scanId;
24
- if (!projectRoot || !pointerId || !scanId) {
25
- throw new Error('projectRoot, pointerId, startLine, endLine, and scanId are required');
26
- }
27
- // 1. Verify pointer, lifetime, hash
28
- const { content, row } = await hydratePointer(projectRoot, pointerId);
29
- const rawText = content.toString('utf8');
30
- // Scope enforcement: if a Worker scope is active, enforce it for file-type artifacts
31
- const scope = SessionScope.get();
32
- if (scope && (row.artifactName === 'file_read' || row.artifactName === 'file_skeleton')) {
33
- try {
34
- const parsed = JSON.parse(rawText);
35
- if (parsed.filePath) {
36
- SessionScope.enforce(parsed.filePath);
37
- }
38
- }
39
- catch (e) {
40
- if (e.name === 'ScopeViolation')
41
- throw e;
42
- }
43
- }
44
- const lines = rawText.split('\n');
45
- const sliced = lines.slice(startLine - 1, endLine);
46
- const result = {
47
- pointerId,
48
- artifactName: row.artifactName,
49
- startLine,
50
- endLine,
51
- totalLines: lines.length,
52
- slice: sliced,
53
- };
54
- // 2. Budget query result
55
- return await applyBudgetGuard(projectRoot, scanId, 'evidence_slice', result);
56
- }
57
- //# sourceMappingURL=get_evidence_slice.js.map
@@ -1,23 +0,0 @@
1
- export declare const getProjectSummaryTool: {
2
- name: string;
3
- description: string;
4
- inputSchema: {
5
- type: "object";
6
- properties: {
7
- projectRoot: {
8
- type: string;
9
- description: string;
10
- };
11
- manifestPointer: {
12
- type: string;
13
- description: string;
14
- };
15
- scanId: {
16
- type: string;
17
- description: string;
18
- };
19
- };
20
- required: string[];
21
- };
22
- };
23
- export declare function handleGetProjectSummary(args: Record<string, unknown>): Promise<unknown>;
@@ -1,58 +0,0 @@
1
- import { hydratePointer, applyBudgetGuard } from '../../BudgetGuard.js';
2
- export const getProjectSummaryTool = {
3
- name: 'get_project_summary',
4
- description: 'Returns high-level project metrics from a scan manifest pointer: file counts, pillar summary, stack. Token-safe. Pointer must be valid and unexpired.',
5
- inputSchema: {
6
- type: 'object',
7
- properties: {
8
- projectRoot: { type: 'string', description: 'Absolute project root' },
9
- manifestPointer: { type: 'string', description: 'Pointer ID for the scan manifest' },
10
- scanId: { type: 'string', description: 'Current scan ID for budget pointer registration' },
11
- },
12
- required: ['projectRoot', 'manifestPointer', 'scanId'],
13
- },
14
- };
15
- export async function handleGetProjectSummary(args) {
16
- const projectRoot = args.projectRoot;
17
- const manifestPointer = args.manifestPointer;
18
- const scanId = args.scanId;
19
- if (!projectRoot || !manifestPointer || !scanId) {
20
- throw new Error('projectRoot, manifestPointer, and scanId are required');
21
- }
22
- const { content, row } = await hydratePointer(projectRoot, manifestPointer);
23
- const payload = JSON.parse(content.toString('utf8'));
24
- if (row.artifactName === 'artifact_manifest') {
25
- const manifest = payload;
26
- const analysisEntry = manifest.artifacts.find(a => a.name === 'analysis' && a.indexes?.startHere);
27
- let indexData = {};
28
- if (analysisEntry?.indexes?.startHere) {
29
- const { content: ic } = await hydratePointer(projectRoot, analysisEntry.indexes.startHere);
30
- indexData = JSON.parse(ic.toString('utf8'));
31
- }
32
- const result = {
33
- scanId: manifest.scanId,
34
- generatedAt: manifest.generatedAt,
35
- artifactCount: manifest.artifacts.length,
36
- totalArtifactBytes: manifest.artifacts.reduce((s, a) => s + (a.sizeBytes ?? 0), 0),
37
- startHere: indexData.startHere,
38
- topHeat: indexData.topHeat,
39
- pillarSummary: indexData.pillarSummary,
40
- totalFiles: indexData.totalFiles,
41
- realSourceFiles: indexData.realSourceFiles,
42
- };
43
- return await applyBudgetGuard(projectRoot, scanId, 'get_project_summary_result', result);
44
- }
45
- if (row.artifactName === 'analysis.index') {
46
- const result = {
47
- scanId: payload.scanId,
48
- startHere: payload.startHere,
49
- topHeat: payload.topHeat,
50
- pillarSummary: payload.pillarSummary,
51
- totalFiles: payload.totalFiles,
52
- realSourceFiles: payload.realSourceFiles,
53
- };
54
- return await applyBudgetGuard(projectRoot, scanId, 'get_project_summary_result', result);
55
- }
56
- throw new Error(`Unsupported artifact type for get_project_summary: ${row.artifactName}`);
57
- }
58
- //# sourceMappingURL=get_project_summary.js.map
@@ -1,23 +0,0 @@
1
- export declare const getStartHereTool: {
2
- name: string;
3
- description: string;
4
- inputSchema: {
5
- type: "object";
6
- properties: {
7
- projectRoot: {
8
- type: string;
9
- description: string;
10
- };
11
- manifestPointer: {
12
- type: string;
13
- description: string;
14
- };
15
- scanId: {
16
- type: string;
17
- description: string;
18
- };
19
- };
20
- required: string[];
21
- };
22
- };
23
- export declare function handleGetStartHere(args: Record<string, unknown>): Promise<unknown>;
@@ -1,52 +0,0 @@
1
- import { hydratePointer, applyBudgetGuard } from '../../BudgetGuard.js';
2
- export const getStartHereTool = {
3
- name: 'get_start_here',
4
- description: 'Hydrates the start-here index for a scan manifest pointer. Returns the top 5 highest-gravity files. Pointer must be valid and unexpired.',
5
- inputSchema: {
6
- type: 'object',
7
- properties: {
8
- projectRoot: { type: 'string', description: 'Absolute project root' },
9
- manifestPointer: { type: 'string', description: 'Pointer ID for the scan manifest or analysis.index artifact' },
10
- scanId: { type: 'string', description: 'Current scan ID for budget pointer registration' },
11
- },
12
- required: ['projectRoot', 'manifestPointer', 'scanId'],
13
- },
14
- };
15
- export async function handleGetStartHere(args) {
16
- const projectRoot = args.projectRoot;
17
- const manifestPointer = args.manifestPointer;
18
- const scanId = args.scanId;
19
- if (!projectRoot || !manifestPointer || !scanId) {
20
- throw new Error('projectRoot, manifestPointer, and scanId are required');
21
- }
22
- // 1. Verify pointer exists, unexpired, hash matches blob
23
- const { content, row } = await hydratePointer(projectRoot, manifestPointer);
24
- const payload = JSON.parse(content.toString('utf8'));
25
- // 2. If it's a manifest pointer, find the analysis.index pointer
26
- if (row.artifactName === 'artifact_manifest') {
27
- const manifest = payload;
28
- const analysisEntry = manifest.artifacts.find(a => a.name === 'analysis' || a.name === 'analysis.index');
29
- if (!analysisEntry?.indexes?.startHere) {
30
- throw new Error('Manifest has no analysis.index entry — rescan to regenerate');
31
- }
32
- const { content: indexContent } = await hydratePointer(projectRoot, analysisEntry.indexes.startHere);
33
- const index = JSON.parse(indexContent.toString('utf8'));
34
- const result = {
35
- startHere: index.startHere.slice(0, 5),
36
- schemaVersion: index.schemaVersion,
37
- scanId: index.scanId,
38
- };
39
- return await applyBudgetGuard(projectRoot, scanId, 'get_start_here_result', result);
40
- }
41
- // 3. If it's an analysis.index pointer directly
42
- if (row.artifactName === 'analysis.index') {
43
- const result = {
44
- startHere: payload.startHere.slice(0, 5),
45
- schemaVersion: payload.schemaVersion,
46
- scanId: payload.scanId,
47
- };
48
- return await applyBudgetGuard(projectRoot, scanId, 'get_start_here_result', result);
49
- }
50
- throw new Error(`Unsupported artifact type for get_start_here: ${row.artifactName}`);
51
- }
52
- //# sourceMappingURL=get_start_here.js.map