@grafema/mcp 0.2.1-beta → 0.2.6-beta
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 +49 -25
- package/dist/analysis-worker.js +16 -8
- package/dist/analysis-worker.js.map +1 -0
- package/dist/analysis.d.ts.map +1 -1
- package/dist/analysis.js +1 -0
- package/dist/analysis.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +27 -7
- package/dist/config.js.map +1 -0
- package/dist/definitions.d.ts +4 -4
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +158 -3
- package/dist/definitions.js.map +1 -0
- package/dist/handlers/analysis-handlers.d.ts +9 -0
- package/dist/handlers/analysis-handlers.d.ts.map +1 -0
- package/dist/handlers/analysis-handlers.js +73 -0
- package/dist/handlers/analysis-handlers.js.map +1 -0
- package/dist/handlers/context-handlers.d.ts +21 -0
- package/dist/handlers/context-handlers.d.ts.map +1 -0
- package/dist/handlers/context-handlers.js +330 -0
- package/dist/handlers/context-handlers.js.map +1 -0
- package/dist/handlers/coverage-handlers.d.ts +6 -0
- package/dist/handlers/coverage-handlers.d.ts.map +1 -0
- package/dist/handlers/coverage-handlers.js +42 -0
- package/dist/handlers/coverage-handlers.js.map +1 -0
- package/dist/handlers/dataflow-handlers.d.ts +8 -0
- package/dist/handlers/dataflow-handlers.d.ts.map +1 -0
- package/dist/handlers/dataflow-handlers.js +140 -0
- package/dist/handlers/dataflow-handlers.js.map +1 -0
- package/dist/handlers/documentation-handlers.d.ts +6 -0
- package/dist/handlers/documentation-handlers.d.ts.map +1 -0
- package/dist/handlers/documentation-handlers.js +79 -0
- package/dist/handlers/documentation-handlers.js.map +1 -0
- package/dist/handlers/guarantee-handlers.d.ts +21 -0
- package/dist/handlers/guarantee-handlers.d.ts.map +1 -0
- package/dist/handlers/guarantee-handlers.js +251 -0
- package/dist/handlers/guarantee-handlers.js.map +1 -0
- package/dist/handlers/guard-handlers.d.ts +14 -0
- package/dist/handlers/guard-handlers.d.ts.map +1 -0
- package/dist/handlers/guard-handlers.js +77 -0
- package/dist/handlers/guard-handlers.js.map +1 -0
- package/dist/handlers/index.d.ts +14 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +14 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/issue-handlers.d.ts +6 -0
- package/dist/handlers/issue-handlers.d.ts.map +1 -0
- package/dist/handlers/issue-handlers.js +66 -0
- package/dist/handlers/issue-handlers.js.map +1 -0
- package/dist/handlers/project-handlers.d.ts +7 -0
- package/dist/handlers/project-handlers.d.ts.map +1 -0
- package/dist/handlers/project-handlers.js +153 -0
- package/dist/handlers/project-handlers.js.map +1 -0
- package/dist/handlers/query-handlers.d.ts +8 -0
- package/dist/handlers/query-handlers.d.ts.map +1 -0
- package/dist/handlers/query-handlers.js +171 -0
- package/dist/handlers/query-handlers.js.map +1 -0
- package/dist/handlers.d.ts +6 -2
- package/dist/handlers.d.ts.map +1 -1
- package/dist/handlers.js +367 -20
- package/dist/handlers.js.map +1 -0
- package/dist/prompts.d.ts +25 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +33 -0
- package/dist/prompts.js.map +1 -0
- package/dist/server.js +52 -20
- package/dist/server.js.map +1 -0
- package/dist/state.js +1 -0
- package/dist/state.js.map +1 -0
- package/dist/types.d.ts +59 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.js +2 -1
- package/dist/utils.js.map +1 -0
- package/package.json +4 -3
- package/src/analysis-worker.ts +20 -9
- package/src/analysis.ts +2 -1
- package/src/config.ts +36 -4
- package/src/definitions.ts +162 -5
- package/src/handlers/analysis-handlers.ts +105 -0
- package/src/handlers/context-handlers.ts +410 -0
- package/src/handlers/coverage-handlers.ts +56 -0
- package/src/handlers/dataflow-handlers.ts +193 -0
- package/src/handlers/documentation-handlers.ts +89 -0
- package/src/handlers/guarantee-handlers.ts +278 -0
- package/src/handlers/guard-handlers.ts +100 -0
- package/src/handlers/index.ts +14 -0
- package/src/handlers/issue-handlers.ts +81 -0
- package/src/handlers/project-handlers.ts +200 -0
- package/src/handlers/query-handlers.ts +232 -0
- package/src/prompts.ts +56 -0
- package/src/server.ts +87 -21
- package/src/types.ts +68 -1
- package/src/utils.ts +2 -2
- package/src/handlers.ts +0 -1180
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Analysis Handlers
|
|
3
|
+
*/
|
|
4
|
+
import { ensureAnalyzed } from '../analysis.js';
|
|
5
|
+
import { getAnalysisStatus, getOrCreateBackend, isAnalysisRunning } from '../state.js';
|
|
6
|
+
import { textResult, errorResult, } from '../utils.js';
|
|
7
|
+
// === ANALYSIS HANDLERS ===
|
|
8
|
+
export async function handleAnalyzeProject(args) {
|
|
9
|
+
const { service, force } = args;
|
|
10
|
+
// Early check: return error for force=true if analysis is already running
|
|
11
|
+
// This provides immediate feedback instead of waiting or causing corruption
|
|
12
|
+
if (force && isAnalysisRunning()) {
|
|
13
|
+
return errorResult('Cannot force re-analysis: analysis is already in progress. ' +
|
|
14
|
+
'Use get_analysis_status to check current status, or wait for completion.');
|
|
15
|
+
}
|
|
16
|
+
// Note: setIsAnalyzed(false) is now handled inside ensureAnalyzed() within the lock
|
|
17
|
+
// to prevent race conditions where multiple calls could both clear the database
|
|
18
|
+
try {
|
|
19
|
+
await ensureAnalyzed(service || null, force || false);
|
|
20
|
+
const status = getAnalysisStatus();
|
|
21
|
+
return textResult(`Analysis complete!\n` +
|
|
22
|
+
`- Services discovered: ${status.servicesDiscovered}\n` +
|
|
23
|
+
`- Services analyzed: ${status.servicesAnalyzed}\n` +
|
|
24
|
+
`- Total time: ${status.timings.total || 'N/A'}s`);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
28
|
+
return errorResult(message);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export async function handleGetAnalysisStatus() {
|
|
32
|
+
const status = getAnalysisStatus();
|
|
33
|
+
return textResult(`Analysis Status:\n` +
|
|
34
|
+
`- Running: ${status.running}\n` +
|
|
35
|
+
`- Phase: ${status.phase || 'N/A'}\n` +
|
|
36
|
+
`- Message: ${status.message || 'N/A'}\n` +
|
|
37
|
+
`- Services discovered: ${status.servicesDiscovered}\n` +
|
|
38
|
+
`- Services analyzed: ${status.servicesAnalyzed}\n` +
|
|
39
|
+
(status.error ? `- Error: ${status.error}\n` : ''));
|
|
40
|
+
}
|
|
41
|
+
export async function handleGetStats() {
|
|
42
|
+
const db = await getOrCreateBackend();
|
|
43
|
+
const nodeCount = await db.nodeCount();
|
|
44
|
+
const edgeCount = await db.edgeCount();
|
|
45
|
+
const nodesByType = await db.countNodesByType();
|
|
46
|
+
const edgesByType = await db.countEdgesByType();
|
|
47
|
+
return textResult(`Graph Statistics:\n\n` +
|
|
48
|
+
`Total nodes: ${nodeCount.toLocaleString()}\n` +
|
|
49
|
+
`Total edges: ${edgeCount.toLocaleString()}\n\n` +
|
|
50
|
+
`Nodes by type:\n${JSON.stringify(nodesByType, null, 2)}\n\n` +
|
|
51
|
+
`Edges by type:\n${JSON.stringify(edgesByType, null, 2)}`);
|
|
52
|
+
}
|
|
53
|
+
export async function handleGetSchema(args) {
|
|
54
|
+
const db = await getOrCreateBackend();
|
|
55
|
+
const { type = 'all' } = args;
|
|
56
|
+
const nodesByType = await db.countNodesByType();
|
|
57
|
+
const edgesByType = await db.countEdgesByType();
|
|
58
|
+
let output = '';
|
|
59
|
+
if (type === 'nodes' || type === 'all') {
|
|
60
|
+
output += `Node Types (${Object.keys(nodesByType).length}):\n`;
|
|
61
|
+
for (const [t, count] of Object.entries(nodesByType)) {
|
|
62
|
+
output += ` - ${t}: ${count}\n`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (type === 'edges' || type === 'all') {
|
|
66
|
+
output += `\nEdge Types (${Object.keys(edgesByType).length}):\n`;
|
|
67
|
+
for (const [t, count] of Object.entries(edgesByType)) {
|
|
68
|
+
output += ` - ${t}: ${count}\n`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return textResult(output);
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=analysis-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis-handlers.js","sourceRoot":"","sources":["../../src/handlers/analysis-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Context Handlers
|
|
3
|
+
*/
|
|
4
|
+
import type { ToolResult, GetFunctionDetailsArgs, GetContextArgs, GetFileOverviewArgs } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Get comprehensive function details including calls made and callers.
|
|
7
|
+
*
|
|
8
|
+
* Graph structure:
|
|
9
|
+
* ```
|
|
10
|
+
* FUNCTION -[HAS_SCOPE]-> SCOPE -[CONTAINS]-> CALL/METHOD_CALL
|
|
11
|
+
* SCOPE -[CONTAINS]-> SCOPE (nested blocks)
|
|
12
|
+
* CALL -[CALLS]-> FUNCTION (target)
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* This is the core tool for understanding function behavior.
|
|
16
|
+
* Use transitive=true to follow call chains (A -> B -> C).
|
|
17
|
+
*/
|
|
18
|
+
export declare function handleGetFunctionDetails(args: GetFunctionDetailsArgs): Promise<ToolResult>;
|
|
19
|
+
export declare function handleGetContext(args: GetContextArgs): Promise<ToolResult>;
|
|
20
|
+
export declare function handleGetFileOverview(args: GetFileOverviewArgs): Promise<ToolResult>;
|
|
21
|
+
//# sourceMappingURL=context-handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-handlers.d.ts","sourceRoot":"","sources":["../../src/handlers/context-handlers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH,OAAO,KAAK,EACV,UAAU,EACV,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EAEpB,MAAM,aAAa,CAAC;AAIrB;;;;;;;;;;;;GAYG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,UAAU,CAAC,CA6ErB;AA+CD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,UAAU,CAAC,CAkIrB;AAID,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,UAAU,CAAC,CA2GrB"}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Context Handlers
|
|
3
|
+
*/
|
|
4
|
+
import { ensureAnalyzed } from '../analysis.js';
|
|
5
|
+
import { getProjectPath } from '../state.js';
|
|
6
|
+
import { findCallsInFunction, findContainingFunction, FileOverview, buildNodeContext, getNodeDisplayName, formatEdgeMetadata, STRUCTURAL_EDGE_TYPES } from '@grafema/core';
|
|
7
|
+
import { existsSync, readFileSync, realpathSync } from 'fs';
|
|
8
|
+
import { isAbsolute, join, relative } from 'path';
|
|
9
|
+
import { serializeBigInt, textResult, errorResult, } from '../utils.js';
|
|
10
|
+
// === GET FUNCTION DETAILS (REG-254) ===
|
|
11
|
+
/**
|
|
12
|
+
* Get comprehensive function details including calls made and callers.
|
|
13
|
+
*
|
|
14
|
+
* Graph structure:
|
|
15
|
+
* ```
|
|
16
|
+
* FUNCTION -[HAS_SCOPE]-> SCOPE -[CONTAINS]-> CALL/METHOD_CALL
|
|
17
|
+
* SCOPE -[CONTAINS]-> SCOPE (nested blocks)
|
|
18
|
+
* CALL -[CALLS]-> FUNCTION (target)
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* This is the core tool for understanding function behavior.
|
|
22
|
+
* Use transitive=true to follow call chains (A -> B -> C).
|
|
23
|
+
*/
|
|
24
|
+
export async function handleGetFunctionDetails(args) {
|
|
25
|
+
const db = await ensureAnalyzed();
|
|
26
|
+
const { name, file, transitive = false } = args;
|
|
27
|
+
// Step 1: Find the function
|
|
28
|
+
const candidates = [];
|
|
29
|
+
for await (const node of db.queryNodes({ type: 'FUNCTION' })) {
|
|
30
|
+
if (node.name !== name)
|
|
31
|
+
continue;
|
|
32
|
+
if (file && !node.file?.includes(file))
|
|
33
|
+
continue;
|
|
34
|
+
candidates.push(node);
|
|
35
|
+
}
|
|
36
|
+
if (candidates.length === 0) {
|
|
37
|
+
return errorResult(`Function "${name}" not found.` +
|
|
38
|
+
(file ? ` (searched in files matching "${file}")` : ''));
|
|
39
|
+
}
|
|
40
|
+
if (candidates.length > 1 && !file) {
|
|
41
|
+
const locations = candidates.map(f => `${f.file}:${f.line}`).join(', ');
|
|
42
|
+
return errorResult(`Multiple functions named "${name}" found: ${locations}. ` +
|
|
43
|
+
`Use the "file" parameter to disambiguate.`);
|
|
44
|
+
}
|
|
45
|
+
const targetFunction = candidates[0];
|
|
46
|
+
// Step 2: Find calls using shared utility
|
|
47
|
+
const calls = await findCallsInFunction(db, targetFunction.id, {
|
|
48
|
+
transitive,
|
|
49
|
+
transitiveDepth: 5,
|
|
50
|
+
});
|
|
51
|
+
// Step 3: Find callers
|
|
52
|
+
const calledBy = [];
|
|
53
|
+
const incomingCalls = await db.getIncomingEdges(targetFunction.id, ['CALLS']);
|
|
54
|
+
const seenCallers = new Set();
|
|
55
|
+
for (const edge of incomingCalls) {
|
|
56
|
+
const caller = await findContainingFunction(db, edge.src);
|
|
57
|
+
if (caller && !seenCallers.has(caller.id)) {
|
|
58
|
+
seenCallers.add(caller.id);
|
|
59
|
+
calledBy.push(caller);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Step 4: Build result
|
|
63
|
+
const result = {
|
|
64
|
+
id: targetFunction.id,
|
|
65
|
+
name: targetFunction.name,
|
|
66
|
+
file: targetFunction.file,
|
|
67
|
+
line: targetFunction.line,
|
|
68
|
+
async: targetFunction.async,
|
|
69
|
+
calls,
|
|
70
|
+
calledBy,
|
|
71
|
+
};
|
|
72
|
+
// Format output
|
|
73
|
+
const summary = [
|
|
74
|
+
`Function: ${result.name}`,
|
|
75
|
+
`File: ${result.file || 'unknown'}:${result.line || '?'}`,
|
|
76
|
+
`Async: ${result.async || false}`,
|
|
77
|
+
`Transitive: ${transitive}`,
|
|
78
|
+
'',
|
|
79
|
+
`Calls (${calls.length}):`,
|
|
80
|
+
...formatCallsForDisplay(calls),
|
|
81
|
+
'',
|
|
82
|
+
`Called by (${calledBy.length}):`,
|
|
83
|
+
...calledBy.map(c => ` - ${c.name} (${c.file}:${c.line})`),
|
|
84
|
+
].join('\n');
|
|
85
|
+
return textResult(summary + '\n\n' +
|
|
86
|
+
JSON.stringify(serializeBigInt(result), null, 2));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Format calls for display, grouped by depth if transitive
|
|
90
|
+
*/
|
|
91
|
+
function formatCallsForDisplay(calls) {
|
|
92
|
+
const directCalls = calls.filter(c => (c.depth || 0) === 0);
|
|
93
|
+
const transitiveCalls = calls.filter(c => (c.depth || 0) > 0);
|
|
94
|
+
const lines = [];
|
|
95
|
+
// Direct calls
|
|
96
|
+
for (const c of directCalls) {
|
|
97
|
+
const target = c.resolved
|
|
98
|
+
? ` -> ${c.target?.name} (${c.target?.file}:${c.target?.line})`
|
|
99
|
+
: ' (unresolved)';
|
|
100
|
+
const prefix = c.type === 'METHOD_CALL' ? `${c.object}.` : '';
|
|
101
|
+
lines.push(` - ${prefix}${c.name}()${target}`);
|
|
102
|
+
}
|
|
103
|
+
// Transitive calls (grouped by depth)
|
|
104
|
+
if (transitiveCalls.length > 0) {
|
|
105
|
+
lines.push('');
|
|
106
|
+
lines.push(' Transitive calls:');
|
|
107
|
+
const byDepth = new Map();
|
|
108
|
+
for (const c of transitiveCalls) {
|
|
109
|
+
const depth = c.depth || 1;
|
|
110
|
+
if (!byDepth.has(depth))
|
|
111
|
+
byDepth.set(depth, []);
|
|
112
|
+
byDepth.get(depth).push(c);
|
|
113
|
+
}
|
|
114
|
+
for (const [depth, depthCalls] of Array.from(byDepth.entries()).sort((a, b) => a[0] - b[0])) {
|
|
115
|
+
for (const c of depthCalls) {
|
|
116
|
+
const indent = ' '.repeat(depth + 1);
|
|
117
|
+
const prefix = c.type === 'METHOD_CALL' ? `${c.object}.` : '';
|
|
118
|
+
const target = c.resolved ? ` -> ${c.target?.name}` : '';
|
|
119
|
+
lines.push(`${indent}[depth=${depth}] ${prefix}${c.name}()${target}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return lines;
|
|
124
|
+
}
|
|
125
|
+
// === NODE CONTEXT (REG-406) ===
|
|
126
|
+
export async function handleGetContext(args) {
|
|
127
|
+
const db = await ensureAnalyzed();
|
|
128
|
+
const { semanticId, contextLines: ctxLines = 3, edgeType } = args;
|
|
129
|
+
// 1. Look up node
|
|
130
|
+
const node = await db.getNode(semanticId);
|
|
131
|
+
if (!node) {
|
|
132
|
+
return errorResult(`Node not found: "${semanticId}"\n` +
|
|
133
|
+
`Use find_nodes or query_graph to find the correct semantic ID.`);
|
|
134
|
+
}
|
|
135
|
+
const edgeTypeFilter = edgeType
|
|
136
|
+
? new Set(edgeType.split(',').map(t => t.trim().toUpperCase()))
|
|
137
|
+
: null;
|
|
138
|
+
// 2. Build context using shared logic
|
|
139
|
+
const projectPath = getProjectPath();
|
|
140
|
+
const ctx = await buildNodeContext(db, node, {
|
|
141
|
+
contextLines: ctxLines,
|
|
142
|
+
edgeTypeFilter,
|
|
143
|
+
readFileContent: (filePath) => {
|
|
144
|
+
const absPath = isAbsolute(filePath) ? filePath : join(projectPath, filePath);
|
|
145
|
+
if (!existsSync(absPath))
|
|
146
|
+
return null;
|
|
147
|
+
try {
|
|
148
|
+
return readFileSync(absPath, 'utf-8');
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
// 3. Format text output
|
|
156
|
+
const relFile = node.file ? (isAbsolute(node.file) ? relative(projectPath, node.file) : node.file) : undefined;
|
|
157
|
+
const lines = [];
|
|
158
|
+
lines.push(`[${node.type}] ${getNodeDisplayName(node)}`);
|
|
159
|
+
lines.push(` ID: ${node.id}`);
|
|
160
|
+
if (relFile) {
|
|
161
|
+
lines.push(` Location: ${relFile}${node.line ? `:${node.line}` : ''}`);
|
|
162
|
+
}
|
|
163
|
+
// Source
|
|
164
|
+
if (ctx.source) {
|
|
165
|
+
lines.push('');
|
|
166
|
+
lines.push(` Source (lines ${ctx.source.startLine}-${ctx.source.endLine}):`);
|
|
167
|
+
const maxLineNum = ctx.source.endLine;
|
|
168
|
+
const lineNumWidth = String(maxLineNum).length;
|
|
169
|
+
for (let i = 0; i < ctx.source.lines.length; i++) {
|
|
170
|
+
const lineNum = ctx.source.startLine + i;
|
|
171
|
+
const paddedNum = String(lineNum).padStart(lineNumWidth, ' ');
|
|
172
|
+
const prefix = lineNum === node.line ? '>' : ' ';
|
|
173
|
+
const displayLine = ctx.source.lines[i].length > 120
|
|
174
|
+
? ctx.source.lines[i].slice(0, 117) + '...'
|
|
175
|
+
: ctx.source.lines[i];
|
|
176
|
+
lines.push(` ${prefix}${paddedNum} | ${displayLine}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const formatEdgeSection = (groups, dir) => {
|
|
180
|
+
for (const group of groups) {
|
|
181
|
+
const isStructural = STRUCTURAL_EDGE_TYPES.has(group.edgeType);
|
|
182
|
+
lines.push(` ${group.edgeType} (${group.edges.length}):`);
|
|
183
|
+
for (const { edge, node: connNode } of group.edges) {
|
|
184
|
+
if (!connNode) {
|
|
185
|
+
const danglingId = dir === '->' ? edge.dst : edge.src;
|
|
186
|
+
lines.push(` ${dir} [dangling] ${danglingId}`);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const nFile = connNode.file ? (isAbsolute(connNode.file) ? relative(projectPath, connNode.file) : connNode.file) : '';
|
|
190
|
+
const nLoc = nFile ? (connNode.line ? `${nFile}:${connNode.line}` : nFile) : '';
|
|
191
|
+
const locStr = nLoc ? ` (${nLoc})` : '';
|
|
192
|
+
const metaStr = formatEdgeMetadata(edge);
|
|
193
|
+
lines.push(` ${dir} [${connNode.type}] ${getNodeDisplayName(connNode)}${locStr}${metaStr}`);
|
|
194
|
+
// Code context for non-structural edges
|
|
195
|
+
if (!isStructural && connNode.file && connNode.line && ctxLines > 0) {
|
|
196
|
+
const absoluteConnFile = !isAbsolute(connNode.file) ? join(projectPath, connNode.file) : connNode.file;
|
|
197
|
+
if (existsSync(absoluteConnFile)) {
|
|
198
|
+
try {
|
|
199
|
+
const content = readFileSync(absoluteConnFile, 'utf-8');
|
|
200
|
+
const allFileLines = content.split('\n');
|
|
201
|
+
const nLine = connNode.line;
|
|
202
|
+
const sLine = Math.max(1, nLine - Math.min(ctxLines, 2));
|
|
203
|
+
const eLine = Math.min(allFileLines.length, nLine + Math.min(ctxLines, 2));
|
|
204
|
+
const w = String(eLine).length;
|
|
205
|
+
for (let i = sLine; i <= eLine; i++) {
|
|
206
|
+
const p = i === nLine ? '>' : ' ';
|
|
207
|
+
const ln = String(i).padStart(w, ' ');
|
|
208
|
+
const displayLn = allFileLines[i - 1].length > 120
|
|
209
|
+
? allFileLines[i - 1].slice(0, 117) + '...'
|
|
210
|
+
: allFileLines[i - 1];
|
|
211
|
+
lines.push(` ${p}${ln} | ${displayLn}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch { /* ignore */ }
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
if (ctx.outgoing.length > 0) {
|
|
221
|
+
lines.push('');
|
|
222
|
+
lines.push(' Outgoing edges:');
|
|
223
|
+
formatEdgeSection(ctx.outgoing, '->');
|
|
224
|
+
}
|
|
225
|
+
if (ctx.incoming.length > 0) {
|
|
226
|
+
lines.push('');
|
|
227
|
+
lines.push(' Incoming edges:');
|
|
228
|
+
formatEdgeSection(ctx.incoming, '<-');
|
|
229
|
+
}
|
|
230
|
+
if (ctx.outgoing.length === 0 && ctx.incoming.length === 0) {
|
|
231
|
+
lines.push('');
|
|
232
|
+
lines.push(' No edges found.');
|
|
233
|
+
}
|
|
234
|
+
// Build JSON result alongside text
|
|
235
|
+
const jsonResult = {
|
|
236
|
+
node: { id: node.id, type: node.type, name: node.name, file: relFile, line: node.line },
|
|
237
|
+
source: ctx.source ? {
|
|
238
|
+
startLine: ctx.source.startLine,
|
|
239
|
+
endLine: ctx.source.endLine,
|
|
240
|
+
lines: ctx.source.lines,
|
|
241
|
+
} : null,
|
|
242
|
+
outgoing: Object.fromEntries(ctx.outgoing.map(g => [g.edgeType, g.edges])),
|
|
243
|
+
incoming: Object.fromEntries(ctx.incoming.map(g => [g.edgeType, g.edges])),
|
|
244
|
+
};
|
|
245
|
+
return textResult(lines.join('\n') + '\n\n' + JSON.stringify(serializeBigInt(jsonResult), null, 2));
|
|
246
|
+
}
|
|
247
|
+
// === FILE OVERVIEW (REG-412) ===
|
|
248
|
+
export async function handleGetFileOverview(args) {
|
|
249
|
+
const db = await ensureAnalyzed();
|
|
250
|
+
const projectPath = getProjectPath();
|
|
251
|
+
const { file, include_edges: includeEdges = true } = args;
|
|
252
|
+
let filePath = file;
|
|
253
|
+
if (!filePath.startsWith('/')) {
|
|
254
|
+
filePath = join(projectPath, filePath);
|
|
255
|
+
}
|
|
256
|
+
if (!existsSync(filePath)) {
|
|
257
|
+
return errorResult(`File not found: ${file}\n` +
|
|
258
|
+
`Resolved to: ${filePath}\n` +
|
|
259
|
+
`Project root: ${projectPath}`);
|
|
260
|
+
}
|
|
261
|
+
const absolutePath = realpathSync(filePath);
|
|
262
|
+
const relativePath = relative(projectPath, absolutePath);
|
|
263
|
+
try {
|
|
264
|
+
const overview = new FileOverview(db);
|
|
265
|
+
const result = await overview.getOverview(absolutePath, {
|
|
266
|
+
includeEdges,
|
|
267
|
+
});
|
|
268
|
+
result.file = relativePath;
|
|
269
|
+
if (result.status === 'NOT_ANALYZED') {
|
|
270
|
+
return textResult(`File not analyzed: ${relativePath}\n` +
|
|
271
|
+
`Run analyze_project to build the graph.`);
|
|
272
|
+
}
|
|
273
|
+
const lines = [];
|
|
274
|
+
lines.push(`Module: ${result.file}`);
|
|
275
|
+
if (result.imports.length > 0) {
|
|
276
|
+
const sources = result.imports.map(i => i.source);
|
|
277
|
+
lines.push(`Imports: ${sources.join(', ')}`);
|
|
278
|
+
}
|
|
279
|
+
if (result.exports.length > 0) {
|
|
280
|
+
const names = result.exports.map(e => e.isDefault ? `${e.name} (default)` : e.name);
|
|
281
|
+
lines.push(`Exports: ${names.join(', ')}`);
|
|
282
|
+
}
|
|
283
|
+
if (result.classes.length > 0) {
|
|
284
|
+
lines.push('');
|
|
285
|
+
lines.push('Classes:');
|
|
286
|
+
for (const cls of result.classes) {
|
|
287
|
+
const ext = cls.extends ? ` extends ${cls.extends}` : '';
|
|
288
|
+
lines.push(` ${cls.name}${ext} (line ${cls.line ?? '?'})`);
|
|
289
|
+
for (const m of cls.methods) {
|
|
290
|
+
const calls = m.calls.length > 0
|
|
291
|
+
? ` -> ${m.calls.join(', ')}`
|
|
292
|
+
: '';
|
|
293
|
+
const params = m.params
|
|
294
|
+
? `(${m.params.join(', ')})`
|
|
295
|
+
: '()';
|
|
296
|
+
lines.push(` ${m.name}${params}${calls}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (result.functions.length > 0) {
|
|
301
|
+
lines.push('');
|
|
302
|
+
lines.push('Functions:');
|
|
303
|
+
for (const fn of result.functions) {
|
|
304
|
+
const calls = fn.calls.length > 0
|
|
305
|
+
? ` -> ${fn.calls.join(', ')}`
|
|
306
|
+
: '';
|
|
307
|
+
const params = fn.params
|
|
308
|
+
? `(${fn.params.join(', ')})`
|
|
309
|
+
: '()';
|
|
310
|
+
const asyncStr = fn.async ? 'async ' : '';
|
|
311
|
+
lines.push(` ${asyncStr}${fn.name}${params}${calls} (line ${fn.line ?? '?'})`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (result.variables.length > 0) {
|
|
315
|
+
lines.push('');
|
|
316
|
+
lines.push('Variables:');
|
|
317
|
+
for (const v of result.variables) {
|
|
318
|
+
const assign = v.assignedFrom ? ` = ${v.assignedFrom}` : '';
|
|
319
|
+
lines.push(` ${v.kind} ${v.name}${assign} (line ${v.line ?? '?'})`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return textResult(lines.join('\n') + '\n\n' +
|
|
323
|
+
JSON.stringify(serializeBigInt(result), null, 2));
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
327
|
+
return errorResult(`Failed to get file overview: ${message}`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=context-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-handlers.js","sourceRoot":"","sources":["../../src/handlers/context-handlers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3K,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAClD,OAAO,EACL,eAAe,EACf,UAAU,EACV,WAAW,GACZ,MAAM,aAAa,CAAC;AASrB,yCAAyC;AAEzC;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,IAA4B;IAE5B,MAAM,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC;IAClC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;IAEhD,4BAA4B;IAC5B,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;QAC7D,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,SAAS;QACjC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAS;QACjD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,WAAW,CAChB,aAAa,IAAI,cAAc;YAC/B,CAAC,IAAI,CAAC,CAAC,CAAC,iCAAiC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CACxD,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxE,OAAO,WAAW,CAChB,6BAA6B,IAAI,YAAY,SAAS,IAAI;YAC1D,2CAA2C,CAC5C,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAErC,0CAA0C;IAC1C,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE,EAAE;QAC7D,UAAU;QACV,eAAe,EAAE,CAAC;KACnB,CAAC,CAAC;IAEH,uBAAuB;IACvB,MAAM,QAAQ,GAAiB,EAAE,CAAC;IAClC,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,gBAAgB,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IAEtC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1D,IAAI,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YAC1C,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,MAAM,MAAM,GAAG;QACb,EAAE,EAAE,cAAc,CAAC,EAAE;QACrB,IAAI,EAAE,cAAc,CAAC,IAAI;QACzB,IAAI,EAAE,cAAc,CAAC,IAAI;QACzB,IAAI,EAAE,cAAc,CAAC,IAA0B;QAC/C,KAAK,EAAE,cAAc,CAAC,KAA4B;QAClD,KAAK;QACL,QAAQ;KACT,CAAC;IAEF,gBAAgB;IAChB,MAAM,OAAO,GAAG;QACd,aAAa,MAAM,CAAC,IAAI,EAAE;QAC1B,SAAS,MAAM,CAAC,IAAI,IAAI,SAAS,IAAI,MAAM,CAAC,IAAI,IAAI,GAAG,EAAE;QACzD,UAAU,MAAM,CAAC,KAAK,IAAI,KAAK,EAAE;QACjC,eAAe,UAAU,EAAE;QAC3B,EAAE;QACF,UAAU,KAAK,CAAC,MAAM,IAAI;QAC1B,GAAG,qBAAqB,CAAC,KAAK,CAAC;QAC/B,EAAE;QACF,cAAc,QAAQ,CAAC,MAAM,IAAI;QACjC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC;KAC5D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,UAAU,CACf,OAAO,GAAG,MAAM;QAChB,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CACjD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,KAAiB;IAC9C,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5D,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAE9D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,eAAe;IACf,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ;YACvB,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,GAAG;YAC/D,CAAC,CAAC,eAAe,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,OAAO,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,sCAAsC;IACtC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAElC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;QAED,KAAK,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5F,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;gBACtC,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9D,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzD,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,UAAU,KAAK,KAAK,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iCAAiC;AAEjC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAoB;IAEpB,MAAM,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC;IAClC,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,GAAG,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAElE,kBAAkB;IAClB,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,WAAW,CAChB,oBAAoB,UAAU,KAAK;YACnC,gEAAgE,CACjE,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,QAAQ;QAC7B,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;QAC/D,CAAC,CAAC,IAAI,CAAC;IAET,sCAAsC;IACtC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,GAAG,GAAgB,MAAM,gBAAgB,CAAC,EAAE,EAAE,IAAI,EAAE;QACxD,YAAY,EAAE,QAAQ;QACtB,cAAc;QACd,eAAe,EAAE,CAAC,QAAgB,EAAE,EAAE;YACpC,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC9E,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC;YACtC,IAAI,CAAC;gBAAC,OAAO,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO,IAAI,CAAC;YAAC,CAAC;QACvE,CAAC;KACF,CAAC,CAAC;IAEH,wBAAwB;IACxB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/G,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/B,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC,eAAe,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,SAAS;IACT,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;QAC9E,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;QACtC,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC;QAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACjD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC;YACzC,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,OAAO,KAAM,IAAI,CAAC,IAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC7D,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG;gBAClD,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK;gBAC3C,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,OAAO,MAAM,GAAG,SAAS,MAAM,WAAW,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,MAAM,iBAAiB,GAAG,CAAC,MAA+B,EAAE,GAAgB,EAAE,EAAE;QAC9E,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC/D,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;YAC7D,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,MAAM,UAAU,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;oBACtD,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,eAAe,UAAU,EAAE,CAAC,CAAC;oBACpD,SAAS;gBACX,CAAC;gBACD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtH,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChF,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBACzC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,QAAQ,CAAC,IAAI,KAAK,kBAAkB,CAAC,QAAQ,CAAC,GAAG,MAAM,GAAG,OAAO,EAAE,CAAC,CAAC;gBAEjG,wCAAwC;gBACxC,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;oBACpE,MAAM,gBAAgB,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACvG,IAAI,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;wBACjC,IAAI,CAAC;4BACH,MAAM,OAAO,GAAG,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;4BACxD,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAc,CAAC;4BACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;4BACzD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;4BAC3E,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;4BAC/B,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gCACpC,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;gCAClC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gCACtC,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG;oCAChD,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK;oCAC3C,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gCACxB,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,SAAS,EAAE,CAAC,CAAC;4BACpD,CAAC;wBACH,CAAC;wBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;oBAC1B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAChC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAChC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAClC,CAAC;IAED,mCAAmC;IACnC,MAAM,UAAU,GAAG;QACjB,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;QACvF,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;YACnB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS;YAC/B,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO;YAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK;SACxB,CAAC,CAAC,CAAC,IAAI;QACR,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1E,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;KAC3E,CAAC;IAEF,OAAO,UAAU,CACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CACjF,CAAC;AACJ,CAAC;AAED,kCAAkC;AAElC,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAAyB;IAEzB,MAAM,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC;IAClC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IAE1D,IAAI,QAAQ,GAAG,IAAI,CAAC;IAEpB,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,WAAW,CAChB,mBAAmB,IAAI,IAAI;YAC3B,gBAAgB,QAAQ,IAAI;YAC5B,iBAAiB,WAAW,EAAE,CAC/B,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAEzD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,YAAY,EAAE;YACtD,YAAY;SACb,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC;QAE3B,IAAI,MAAM,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;YACrC,OAAO,UAAU,CACf,sBAAsB,YAAY,IAAI;gBACtC,yCAAyC,CAC1C,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAErC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CACnC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAC7C,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACvB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACjC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzD,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,GAAG,UAAU,GAAG,CAAC,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC;gBAC5D,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;oBAC5B,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;wBAC9B,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;wBAC9B,CAAC,CAAC,EAAE,CAAC;oBACP,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM;wBACrB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;wBAC5B,CAAC,CAAC,IAAI,CAAC;oBACT,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACzB,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBAClC,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;oBAC/B,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;oBAC/B,CAAC,CAAC,EAAE,CAAC;gBACP,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM;oBACtB,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;oBAC7B,CAAC,CAAC,IAAI,CAAC;gBACT,MAAM,QAAQ,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1C,KAAK,CAAC,IAAI,CACR,KAAK,QAAQ,GAAG,EAAE,CAAC,IAAI,GAAG,MAAM,GAAG,KAAK,WAAW,EAAE,CAAC,IAAI,IAAI,GAAG,GAAG,CACrE,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACzB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACjC,MAAM,MAAM,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,GAAG,MAAM,WAAW,CAAC,CAAC,IAAI,IAAI,GAAG,GAAG,CAC1D,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM;YACzB,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CACjD,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,WAAW,CAAC,gCAAgC,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-handlers.d.ts","sourceRoot":"","sources":["../../src/handlers/coverage-handlers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EAChB,MAAM,aAAa,CAAC;AAIrB,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAsClF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Coverage Handlers
|
|
3
|
+
*/
|
|
4
|
+
import { getOrCreateBackend, getProjectPath } from '../state.js';
|
|
5
|
+
import { CoverageAnalyzer } from '@grafema/core';
|
|
6
|
+
import { textResult, errorResult, } from '../utils.js';
|
|
7
|
+
// === COVERAGE ===
|
|
8
|
+
export async function handleGetCoverage(args) {
|
|
9
|
+
const db = await getOrCreateBackend();
|
|
10
|
+
const projectPath = getProjectPath();
|
|
11
|
+
const { path: targetPath = projectPath } = args;
|
|
12
|
+
try {
|
|
13
|
+
const analyzer = new CoverageAnalyzer(db, targetPath);
|
|
14
|
+
const result = await analyzer.analyze();
|
|
15
|
+
// Format output for AI agents
|
|
16
|
+
let output = `Analysis Coverage for ${targetPath}\n`;
|
|
17
|
+
output += `==============================\n\n`;
|
|
18
|
+
output += `File breakdown:\n`;
|
|
19
|
+
output += ` Total files: ${result.total}\n`;
|
|
20
|
+
output += ` Analyzed: ${result.analyzed.count} (${result.percentages.analyzed}%) - in graph\n`;
|
|
21
|
+
output += ` Unsupported: ${result.unsupported.count} (${result.percentages.unsupported}%) - no indexer available\n`;
|
|
22
|
+
output += ` Unreachable: ${result.unreachable.count} (${result.percentages.unreachable}%) - not imported from entrypoints\n`;
|
|
23
|
+
if (result.unsupported.count > 0) {
|
|
24
|
+
output += `\nUnsupported files by extension:\n`;
|
|
25
|
+
for (const [ext, files] of Object.entries(result.unsupported.byExtension)) {
|
|
26
|
+
output += ` ${ext}: ${files.length} files\n`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (result.unreachable.count > 0) {
|
|
30
|
+
output += `\nUnreachable source files:\n`;
|
|
31
|
+
for (const [ext, files] of Object.entries(result.unreachable.byExtension)) {
|
|
32
|
+
output += ` ${ext}: ${files.length} files\n`;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return textResult(output);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
39
|
+
return errorResult(`Failed to calculate coverage: ${message}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=coverage-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-handlers.js","sourceRoot":"","sources":["../../src/handlers/coverage-handlers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EACL,UAAU,EACV,WAAW,GACZ,MAAM,aAAa,CAAC;AAMrB,mBAAmB;AAEnB,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAqB;IAC3D,MAAM,EAAE,GAAG,MAAM,kBAAkB,EAAE,CAAC;IACtC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,WAAW,EAAE,GAAG,IAAI,CAAC;IAEhD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;QAExC,8BAA8B;QAC9B,IAAI,MAAM,GAAG,yBAAyB,UAAU,IAAI,CAAC;QACrD,MAAM,IAAI,oCAAoC,CAAC;QAE/C,MAAM,IAAI,mBAAmB,CAAC;QAC9B,MAAM,IAAI,sBAAsB,MAAM,CAAC,KAAK,IAAI,CAAC;QACjD,MAAM,IAAI,sBAAsB,MAAM,CAAC,QAAQ,CAAC,KAAK,KAAK,MAAM,CAAC,WAAW,CAAC,QAAQ,iBAAiB,CAAC;QACvG,MAAM,IAAI,sBAAsB,MAAM,CAAC,WAAW,CAAC,KAAK,KAAK,MAAM,CAAC,WAAW,CAAC,WAAW,6BAA6B,CAAC;QACzH,MAAM,IAAI,sBAAsB,MAAM,CAAC,WAAW,CAAC,KAAK,KAAK,MAAM,CAAC,WAAW,CAAC,WAAW,sCAAsC,CAAC;QAElI,IAAI,MAAM,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,qCAAqC,CAAC;YAChD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC1E,MAAM,IAAI,KAAK,GAAG,KAAK,KAAK,CAAC,MAAM,UAAU,CAAC;YAChD,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,+BAA+B,CAAC;YAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC1E,MAAM,IAAI,KAAK,GAAG,KAAK,KAAK,CAAC,MAAM,UAAU,CAAC;YAChD,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,WAAW,CAAC,iCAAiC,OAAO,EAAE,CAAC,CAAC;IACjE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Dataflow Handlers
|
|
3
|
+
*/
|
|
4
|
+
import type { ToolResult, TraceAliasArgs, TraceDataFlowArgs, CheckInvariantArgs } from '../types.js';
|
|
5
|
+
export declare function handleTraceAlias(args: TraceAliasArgs): Promise<ToolResult>;
|
|
6
|
+
export declare function handleTraceDataFlow(args: TraceDataFlowArgs): Promise<ToolResult>;
|
|
7
|
+
export declare function handleCheckInvariant(args: CheckInvariantArgs): Promise<ToolResult>;
|
|
8
|
+
//# sourceMappingURL=dataflow-handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataflow-handlers.d.ts","sourceRoot":"","sources":["../../src/handlers/dataflow-handlers.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAEnB,MAAM,aAAa,CAAC;AAIrB,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CA2DhF;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CA+DtF;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC,CA6CxF"}
|