purecontext-mcp 1.1.7 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT_INSTRUCTIONS.md +393 -0
- package/AGENT_INSTRUCTIONS_SHORT.md +53 -0
- package/AST-SEARCH.md +274 -0
- package/CHANGELOG.md +62 -0
- package/CODE-INTELLIGENCE.md +369 -0
- package/HEALTH-DASHBOARDS.md +241 -0
- package/README.md +7 -0
- package/REFACTORING-SAFELY.md +279 -0
- package/UNDERSTANDING-RELATIONSHIPS.md +240 -0
- package/USER-GUIDE.md +14 -0
- package/VISUALIZING-CODE.md +199 -0
- package/WORKFLOW-TECH-DEBT.md +286 -0
- package/dist/core/db/dep-store.d.ts +75 -0
- package/dist/core/db/dep-store.d.ts.map +1 -1
- package/dist/core/db/dep-store.js +277 -0
- package/dist/core/db/dep-store.js.map +1 -1
- package/dist/core/db/schema.d.ts.map +1 -1
- package/dist/core/db/schema.js +12 -0
- package/dist/core/db/schema.js.map +1 -1
- package/dist/core/index-manager.js +1 -1
- package/dist/core/index-manager.js.map +1 -1
- package/dist/core/token-tracker.d.ts +0 -9
- package/dist/core/token-tracker.d.ts.map +1 -1
- package/dist/core/token-tracker.js +0 -21
- package/dist/core/token-tracker.js.map +1 -1
- package/dist/core/types.d.ts +5 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/graph/diagram-renderer.d.ts +83 -0
- package/dist/graph/diagram-renderer.d.ts.map +1 -0
- package/dist/graph/diagram-renderer.js +294 -0
- package/dist/graph/diagram-renderer.js.map +1 -0
- package/dist/graph/graph-traversal.d.ts +92 -0
- package/dist/graph/graph-traversal.d.ts.map +1 -1
- package/dist/graph/graph-traversal.js +440 -2
- package/dist/graph/graph-traversal.js.map +1 -1
- package/dist/server/http-server.d.ts.map +1 -1
- package/dist/server/http-server.js +30 -1
- package/dist/server/http-server.js.map +1 -1
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/mcp-server.js +145 -0
- package/dist/server/mcp-server.js.map +1 -1
- package/dist/server/tools/_meta.d.ts +0 -2
- package/dist/server/tools/_meta.d.ts.map +1 -1
- package/dist/server/tools/_meta.js +1 -4
- package/dist/server/tools/_meta.js.map +1 -1
- package/dist/server/tools/check-delete-safe.d.ts +50 -0
- package/dist/server/tools/check-delete-safe.d.ts.map +1 -0
- package/dist/server/tools/check-delete-safe.js +308 -0
- package/dist/server/tools/check-delete-safe.js.map +1 -0
- package/dist/server/tools/check-move-safe.d.ts +44 -0
- package/dist/server/tools/check-move-safe.d.ts.map +1 -0
- package/dist/server/tools/check-move-safe.js +266 -0
- package/dist/server/tools/check-move-safe.js.map +1 -0
- package/dist/server/tools/check-rename-safe.d.ts +48 -0
- package/dist/server/tools/check-rename-safe.d.ts.map +1 -0
- package/dist/server/tools/check-rename-safe.js +218 -0
- package/dist/server/tools/check-rename-safe.js.map +1 -0
- package/dist/server/tools/diff-health-radar.d.ts +44 -0
- package/dist/server/tools/diff-health-radar.d.ts.map +1 -0
- package/dist/server/tools/diff-health-radar.js +192 -0
- package/dist/server/tools/diff-health-radar.js.map +1 -0
- package/dist/server/tools/find-cycles.d.ts +31 -0
- package/dist/server/tools/find-cycles.d.ts.map +1 -0
- package/dist/server/tools/find-cycles.js +85 -0
- package/dist/server/tools/find-cycles.js.map +1 -0
- package/dist/server/tools/find-implementations.d.ts +47 -0
- package/dist/server/tools/find-implementations.d.ts.map +1 -0
- package/dist/server/tools/find-implementations.js +167 -0
- package/dist/server/tools/find-implementations.js.map +1 -0
- package/dist/server/tools/find-untested-symbols.d.ts +52 -0
- package/dist/server/tools/find-untested-symbols.d.ts.map +1 -0
- package/dist/server/tools/find-untested-symbols.js +308 -0
- package/dist/server/tools/find-untested-symbols.js.map +1 -0
- package/dist/server/tools/get-architecture-snapshot.d.ts +43 -0
- package/dist/server/tools/get-architecture-snapshot.d.ts.map +1 -0
- package/dist/server/tools/get-architecture-snapshot.js +292 -0
- package/dist/server/tools/get-architecture-snapshot.js.map +1 -0
- package/dist/server/tools/get-call-hierarchy.d.ts +43 -0
- package/dist/server/tools/get-call-hierarchy.d.ts.map +1 -0
- package/dist/server/tools/get-call-hierarchy.js +119 -0
- package/dist/server/tools/get-call-hierarchy.js.map +1 -0
- package/dist/server/tools/get-class-hierarchy.d.ts +36 -0
- package/dist/server/tools/get-class-hierarchy.d.ts.map +1 -0
- package/dist/server/tools/get-class-hierarchy.js +125 -0
- package/dist/server/tools/get-class-hierarchy.js.map +1 -0
- package/dist/server/tools/get-complexity-hotspots.d.ts +50 -0
- package/dist/server/tools/get-complexity-hotspots.d.ts.map +1 -0
- package/dist/server/tools/get-complexity-hotspots.js +282 -0
- package/dist/server/tools/get-complexity-hotspots.js.map +1 -0
- package/dist/server/tools/get-coupling-map.d.ts +39 -0
- package/dist/server/tools/get-coupling-map.d.ts.map +1 -0
- package/dist/server/tools/get-coupling-map.js +107 -0
- package/dist/server/tools/get-coupling-map.js.map +1 -0
- package/dist/server/tools/get-debt-report.d.ts +44 -0
- package/dist/server/tools/get-debt-report.d.ts.map +1 -0
- package/dist/server/tools/get-debt-report.js +606 -0
- package/dist/server/tools/get-debt-report.js.map +1 -0
- package/dist/server/tools/get-entry-points.d.ts +79 -0
- package/dist/server/tools/get-entry-points.d.ts.map +1 -0
- package/dist/server/tools/get-entry-points.js +362 -0
- package/dist/server/tools/get-entry-points.js.map +1 -0
- package/dist/server/tools/get-public-api.d.ts +53 -0
- package/dist/server/tools/get-public-api.d.ts.map +1 -0
- package/dist/server/tools/get-public-api.js +218 -0
- package/dist/server/tools/get-public-api.js.map +1 -0
- package/dist/server/tools/get-savings-stats.d.ts.map +1 -1
- package/dist/server/tools/get-savings-stats.js +1 -3
- package/dist/server/tools/get-savings-stats.js.map +1 -1
- package/dist/server/tools/get-test-coverage-map.d.ts +66 -0
- package/dist/server/tools/get-test-coverage-map.d.ts.map +1 -0
- package/dist/server/tools/get-test-coverage-map.js +588 -0
- package/dist/server/tools/get-test-coverage-map.js.map +1 -0
- package/dist/server/tools/get-todos.d.ts +51 -0
- package/dist/server/tools/get-todos.d.ts.map +1 -0
- package/dist/server/tools/get-todos.js +180 -0
- package/dist/server/tools/get-todos.js.map +1 -0
- package/dist/server/tools/get-type-graph.d.ts +73 -0
- package/dist/server/tools/get-type-graph.d.ts.map +1 -0
- package/dist/server/tools/get-type-graph.js +437 -0
- package/dist/server/tools/get-type-graph.js.map +1 -0
- package/dist/server/tools/health-radar.d.ts +50 -0
- package/dist/server/tools/health-radar.d.ts.map +1 -0
- package/dist/server/tools/health-radar.js +426 -0
- package/dist/server/tools/health-radar.js.map +1 -0
- package/dist/server/tools/plan-refactoring.d.ts +74 -0
- package/dist/server/tools/plan-refactoring.d.ts.map +1 -0
- package/dist/server/tools/plan-refactoring.js +644 -0
- package/dist/server/tools/plan-refactoring.js.map +1 -0
- package/dist/server/tools/render-call-graph.d.ts +40 -0
- package/dist/server/tools/render-call-graph.d.ts.map +1 -0
- package/dist/server/tools/render-call-graph.js +215 -0
- package/dist/server/tools/render-call-graph.js.map +1 -0
- package/dist/server/tools/render-class-hierarchy.d.ts +42 -0
- package/dist/server/tools/render-class-hierarchy.d.ts.map +1 -0
- package/dist/server/tools/render-class-hierarchy.js +265 -0
- package/dist/server/tools/render-class-hierarchy.js.map +1 -0
- package/dist/server/tools/render-dep-matrix.d.ts +38 -0
- package/dist/server/tools/render-dep-matrix.d.ts.map +1 -0
- package/dist/server/tools/render-dep-matrix.js +186 -0
- package/dist/server/tools/render-dep-matrix.js.map +1 -0
- package/dist/server/tools/render-diagram.d.ts +47 -0
- package/dist/server/tools/render-diagram.d.ts.map +1 -0
- package/dist/server/tools/render-diagram.js +266 -0
- package/dist/server/tools/render-diagram.js.map +1 -0
- package/dist/server/tools/render-import-graph.d.ts +41 -0
- package/dist/server/tools/render-import-graph.d.ts.map +1 -0
- package/dist/server/tools/render-import-graph.js +158 -0
- package/dist/server/tools/render-import-graph.js.map +1 -0
- package/dist/server/tools/search-ast.d.ts +55 -0
- package/dist/server/tools/search-ast.d.ts.map +1 -0
- package/dist/server/tools/search-ast.js +279 -0
- package/dist/server/tools/search-ast.js.map +1 -0
- package/dist/server/tools/search-by-complexity.d.ts +92 -0
- package/dist/server/tools/search-by-complexity.d.ts.map +1 -0
- package/dist/server/tools/search-by-complexity.js +268 -0
- package/dist/server/tools/search-by-complexity.js.map +1 -0
- package/dist/server/tools/search-by-decorator.d.ts +48 -0
- package/dist/server/tools/search-by-decorator.d.ts.map +1 -0
- package/dist/server/tools/search-by-decorator.js +518 -0
- package/dist/server/tools/search-by-decorator.js.map +1 -0
- package/dist/server/tools/search-by-signature.d.ts +56 -0
- package/dist/server/tools/search-by-signature.d.ts.map +1 -0
- package/dist/server/tools/search-by-signature.js +200 -0
- package/dist/server/tools/search-by-signature.js.map +1 -0
- package/dist/ui/assets/BlastRadius-QdgESOL8.js +1 -0
- package/dist/ui/assets/{DependencyGraph-CDtBHM0U.js → DependencyGraph-BSMhzwWV.js} +6 -6
- package/dist/ui/assets/{NotFound-Cdt6X8pl.js → NotFound-CipFP_s1.js} +1 -1
- package/dist/ui/assets/RepoDetail-Dfp5z5Kq.js +1 -0
- package/dist/ui/assets/{RepoList-B9LaZvob.js → RepoList-BKtST3hB.js} +1 -1
- package/dist/ui/assets/{Search-CLqv2KGV.js → Search-DzhGDViy.js} +1 -1
- package/dist/ui/assets/{SymbolView-BlbDR1DU.js → SymbolView-ryVEwAHG.js} +1 -1
- package/dist/ui/assets/{index-DADf5y_L.css → index-Ny8gn9F0.css} +1 -1
- package/dist/ui/assets/{index-i3Q1XbEh.js → index-nX2chMqi.js} +6 -6
- package/dist/ui/assets/{useSearch-mbMk6-M1.js → useSearch-BnBCRKui.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/dev/jcodemunch-gap-analysis.md +198 -0
- package/package.json +9 -1
- package/user-manual.md +2466 -0
- package/dist/ui/assets/BlastRadius-BDZWhEk-.js +0 -1
- package/dist/ui/assets/RepoDetail-M6WaYbZ3.js +0 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* render-dep-matrix.ts
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: render_dep_matrix
|
|
5
|
+
*
|
|
6
|
+
* Render a dependency matrix (coupling heatmap) for the top-N most coupled
|
|
7
|
+
* files in the repo. Matrix cell [row][col] is 1 when row imports col, 0
|
|
8
|
+
* otherwise; the diagonal is always "—".
|
|
9
|
+
*
|
|
10
|
+
* Two formats:
|
|
11
|
+
* 'ascii' — text table (default). Token-efficient, renders in any markdown.
|
|
12
|
+
* 'mermaid' — `graph TD` showing direct import edges between the top-N files.
|
|
13
|
+
* More useful than xychart-beta which cannot represent a matrix.
|
|
14
|
+
*
|
|
15
|
+
* File selection: the N files with the highest total coupling
|
|
16
|
+
* (efferentCoupling + afferentCoupling) are chosen. Use `filePath` to scope
|
|
17
|
+
* selection to a directory.
|
|
18
|
+
*/
|
|
19
|
+
import { z } from 'zod';
|
|
20
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
21
|
+
export declare const name = "render_dep_matrix";
|
|
22
|
+
export declare const description: string;
|
|
23
|
+
export declare const inputSchema: {
|
|
24
|
+
repoId: z.ZodString;
|
|
25
|
+
topN: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
filePath: z.ZodOptional<z.ZodString>;
|
|
27
|
+
format: z.ZodOptional<z.ZodEnum<{
|
|
28
|
+
ascii: "ascii";
|
|
29
|
+
mermaid: "mermaid";
|
|
30
|
+
}>>;
|
|
31
|
+
};
|
|
32
|
+
export declare function handler(args: {
|
|
33
|
+
repoId: string;
|
|
34
|
+
topN?: number;
|
|
35
|
+
filePath?: string;
|
|
36
|
+
format?: 'ascii' | 'mermaid';
|
|
37
|
+
}): Promise<CallToolResult>;
|
|
38
|
+
//# sourceMappingURL=render-dep-matrix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-dep-matrix.d.ts","sourceRoot":"","sources":["../../../src/server/tools/render-dep-matrix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,eAAO,MAAM,IAAI,sBAAsB,CAAC;AAExC,eAAO,MAAM,WAAW,QAO2B,CAAC;AAEpD,eAAO,MAAM,WAAW;;;;;;;;CAuBvB,CAAC;AA6GF,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B,GAAG,OAAO,CAAC,cAAc,CAAC,CAkE1B"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* render-dep-matrix.ts
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: render_dep_matrix
|
|
5
|
+
*
|
|
6
|
+
* Render a dependency matrix (coupling heatmap) for the top-N most coupled
|
|
7
|
+
* files in the repo. Matrix cell [row][col] is 1 when row imports col, 0
|
|
8
|
+
* otherwise; the diagonal is always "—".
|
|
9
|
+
*
|
|
10
|
+
* Two formats:
|
|
11
|
+
* 'ascii' — text table (default). Token-efficient, renders in any markdown.
|
|
12
|
+
* 'mermaid' — `graph TD` showing direct import edges between the top-N files.
|
|
13
|
+
* More useful than xychart-beta which cannot represent a matrix.
|
|
14
|
+
*
|
|
15
|
+
* File selection: the N files with the highest total coupling
|
|
16
|
+
* (efferentCoupling + afferentCoupling) are chosen. Use `filePath` to scope
|
|
17
|
+
* selection to a directory.
|
|
18
|
+
*/
|
|
19
|
+
import { z } from 'zod';
|
|
20
|
+
import { openDatabase, getRepo } from '../../core/db/schema.js';
|
|
21
|
+
import { getCouplingMap } from '../../core/db/dep-store.js';
|
|
22
|
+
import { sanitizeId, shortLabel, parentDir, renderMermaidModule, } from '../../graph/diagram-renderer.js';
|
|
23
|
+
import { buildMeta } from './_meta.js';
|
|
24
|
+
export const name = 'render_dep_matrix';
|
|
25
|
+
export const description = 'Render a dependency matrix for the top-N most coupled files. ' +
|
|
26
|
+
'Each cell shows 1 if the row file imports the column file, 0 otherwise; ' +
|
|
27
|
+
'the diagonal shows "—". ' +
|
|
28
|
+
'ASCII format (default) is token-efficient and renders in any markdown context. ' +
|
|
29
|
+
'Mermaid format produces a graph TD showing import edges between the top-N files. ' +
|
|
30
|
+
'Use topN (default 10) to control how many files appear. ' +
|
|
31
|
+
'Use filePath to scope selection to a directory.';
|
|
32
|
+
export const inputSchema = {
|
|
33
|
+
repoId: z.string().describe('Repo ID from index_folder or resolve_repo'),
|
|
34
|
+
topN: z
|
|
35
|
+
.number()
|
|
36
|
+
.int()
|
|
37
|
+
.min(1)
|
|
38
|
+
.max(50)
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('Number of most-coupled files to include (default 10)'),
|
|
41
|
+
filePath: z
|
|
42
|
+
.string()
|
|
43
|
+
.optional()
|
|
44
|
+
.describe('Scope file selection to files under this directory path (relative to repo root). ' +
|
|
45
|
+
'When omitted, selects from the whole repo.'),
|
|
46
|
+
format: z
|
|
47
|
+
.enum(['ascii', 'mermaid'])
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('"ascii" (default) — text table readable in any markdown. ' +
|
|
50
|
+
'"mermaid" — graph TD diagram of import edges between the selected files.'),
|
|
51
|
+
};
|
|
52
|
+
// ─── Rendering helpers ────────────────────────────────────────────────────────
|
|
53
|
+
/**
|
|
54
|
+
* Return the last `segments` path components of a file path.
|
|
55
|
+
* e.g. `src/core/index-manager.ts` → `core/index-manager.ts` (segments=2)
|
|
56
|
+
*/
|
|
57
|
+
function truncatePath(filePath, segments = 2) {
|
|
58
|
+
const parts = filePath.replace(/\\/g, '/').split('/');
|
|
59
|
+
return parts.slice(-segments).join('/');
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Render a text dependency matrix.
|
|
63
|
+
*
|
|
64
|
+
* Rows = files (labelled with last-2-segment names).
|
|
65
|
+
* Columns = same files (headers use last-2-segment names, potentially padded).
|
|
66
|
+
* Cell: '1' if row imports col, '0' otherwise, '—' on diagonal.
|
|
67
|
+
*/
|
|
68
|
+
function renderAsciiMatrix(filePaths, importMap) {
|
|
69
|
+
if (filePaths.length === 0)
|
|
70
|
+
return '(no files)';
|
|
71
|
+
const rowLabels = filePaths.map((fp) => truncatePath(fp));
|
|
72
|
+
const colHeaders = filePaths.map((fp) => truncatePath(fp));
|
|
73
|
+
// Measure column widths (at least 1 char for the cell value)
|
|
74
|
+
const colWidths = colHeaders.map((h) => h.length);
|
|
75
|
+
const rowLabelWidth = Math.max(...rowLabels.map((l) => l.length));
|
|
76
|
+
const lines = [];
|
|
77
|
+
const GAP = 2; // spaces between columns
|
|
78
|
+
// Build header line
|
|
79
|
+
const headerParts = [' '.repeat(rowLabelWidth)];
|
|
80
|
+
for (let c = 0; c < colHeaders.length; c++) {
|
|
81
|
+
headerParts.push(colHeaders[c].padStart(colWidths[c] + GAP));
|
|
82
|
+
}
|
|
83
|
+
lines.push(headerParts.join(''));
|
|
84
|
+
// Build data rows
|
|
85
|
+
for (let r = 0; r < filePaths.length; r++) {
|
|
86
|
+
const rowImports = importMap.get(filePaths[r]) ?? new Set();
|
|
87
|
+
const parts = [rowLabels[r].padEnd(rowLabelWidth)];
|
|
88
|
+
for (let c = 0; c < filePaths.length; c++) {
|
|
89
|
+
let cell;
|
|
90
|
+
if (r === c) {
|
|
91
|
+
cell = '—';
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
cell = rowImports.has(filePaths[c]) ? '1' : '0';
|
|
95
|
+
}
|
|
96
|
+
parts.push(cell.padStart(colWidths[c] + GAP));
|
|
97
|
+
}
|
|
98
|
+
lines.push(parts.join(''));
|
|
99
|
+
}
|
|
100
|
+
return lines.join('\n');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Render a `graph TD` Mermaid diagram showing import edges between the
|
|
104
|
+
* top-N files. Only edges where both endpoints are in the selected set are
|
|
105
|
+
* drawn (same semantics as matrix cells with value 1).
|
|
106
|
+
*/
|
|
107
|
+
function renderMermaidMatrix(filePaths, importMap) {
|
|
108
|
+
const fileSet = new Set(filePaths);
|
|
109
|
+
const nodes = filePaths.map((fp) => ({
|
|
110
|
+
id: sanitizeId(fp),
|
|
111
|
+
label: shortLabel(fp),
|
|
112
|
+
fullPath: fp,
|
|
113
|
+
group: parentDir(fp),
|
|
114
|
+
}));
|
|
115
|
+
const seenEdges = new Set();
|
|
116
|
+
const edges = [];
|
|
117
|
+
for (const fp of filePaths) {
|
|
118
|
+
for (const dep of importMap.get(fp) ?? new Set()) {
|
|
119
|
+
if (!fileSet.has(dep))
|
|
120
|
+
continue;
|
|
121
|
+
const key = `${fp}→${dep}`;
|
|
122
|
+
if (!seenEdges.has(key)) {
|
|
123
|
+
seenEdges.add(key);
|
|
124
|
+
edges.push({ source: sanitizeId(fp), target: sanitizeId(dep) });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return renderMermaidModule(nodes, edges);
|
|
129
|
+
}
|
|
130
|
+
// ─── Handler ──────────────────────────────────────────────────────────────────
|
|
131
|
+
export async function handler(args) {
|
|
132
|
+
const t0 = Date.now();
|
|
133
|
+
const { repoId, topN = 10, filePath, format = 'ascii' } = args;
|
|
134
|
+
const db = openDatabase(repoId);
|
|
135
|
+
try {
|
|
136
|
+
const repo = getRepo(db, repoId);
|
|
137
|
+
if (!repo) {
|
|
138
|
+
return {
|
|
139
|
+
content: [
|
|
140
|
+
{ type: 'text', text: JSON.stringify({ error: `Repo "${repoId}" not found. Run index_folder first.` }) },
|
|
141
|
+
],
|
|
142
|
+
isError: true,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// Fetch coupling rows for the whole repo (or scoped path).
|
|
146
|
+
let rows = getCouplingMap(db, repoId, filePath);
|
|
147
|
+
// When scoping to a directory, filter to files under that path.
|
|
148
|
+
if (filePath) {
|
|
149
|
+
const prefix = filePath.endsWith('/') ? filePath : filePath + '/';
|
|
150
|
+
rows = rows.filter((r) => r.filePath.startsWith(prefix) || r.filePath === filePath);
|
|
151
|
+
}
|
|
152
|
+
// Sort by total coupling descending, stable by filePath.
|
|
153
|
+
rows.sort((a, b) => b.efferentCoupling + b.afferentCoupling - (a.efferentCoupling + a.afferentCoupling) ||
|
|
154
|
+
a.filePath.localeCompare(b.filePath));
|
|
155
|
+
// Take top-N.
|
|
156
|
+
rows = rows.slice(0, topN);
|
|
157
|
+
const filePaths = rows.map((r) => r.filePath);
|
|
158
|
+
// Build a set-of-targets per file for O(1) lookup during matrix construction.
|
|
159
|
+
const importMap = new Map();
|
|
160
|
+
for (const r of rows) {
|
|
161
|
+
importMap.set(r.filePath, new Set(r.efferentDeps));
|
|
162
|
+
}
|
|
163
|
+
// Render the matrix in the requested format.
|
|
164
|
+
let matrix;
|
|
165
|
+
if (format === 'mermaid') {
|
|
166
|
+
matrix = renderMermaidMatrix(filePaths, importMap);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
matrix = renderAsciiMatrix(filePaths, importMap);
|
|
170
|
+
}
|
|
171
|
+
const output = {
|
|
172
|
+
matrix,
|
|
173
|
+
files: filePaths,
|
|
174
|
+
format,
|
|
175
|
+
_tokenEstimate: Math.ceil(matrix.length / 4),
|
|
176
|
+
_meta: buildMeta({ timingMs: Date.now() - t0 }),
|
|
177
|
+
};
|
|
178
|
+
return {
|
|
179
|
+
content: [{ type: 'text', text: JSON.stringify(output, null, 2) }],
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
db.close();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=render-dep-matrix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-dep-matrix.js","sourceRoot":"","sources":["../../../src/server/tools/render-dep-matrix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* render-diagram.ts
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: render_diagram
|
|
5
|
+
*
|
|
6
|
+
* Generate a Mermaid or DOT diagram from the dependency graph for a file,
|
|
7
|
+
* directory, or the whole repo. The primary general-purpose visualization tool —
|
|
8
|
+
* specialized variants (render_call_graph, render_class_hierarchy, etc.) build
|
|
9
|
+
* on this foundation.
|
|
10
|
+
*
|
|
11
|
+
* Diagram types:
|
|
12
|
+
* 'module' — file-level import graph, nodes = files, clustered by directory
|
|
13
|
+
* 'call' — call graph rooted at rootSymbolId (requires Task 174 data)
|
|
14
|
+
* 'class' — class inheritance rooted at rootSymbolId (requires Task 175 data)
|
|
15
|
+
* 'import' — alias for 'module' at the symbol level (same DB, different label)
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
19
|
+
export declare const name = "render_diagram";
|
|
20
|
+
export declare const description: string;
|
|
21
|
+
export declare const inputSchema: {
|
|
22
|
+
repoId: z.ZodString;
|
|
23
|
+
type: z.ZodEnum<{
|
|
24
|
+
class: "class";
|
|
25
|
+
import: "import";
|
|
26
|
+
module: "module";
|
|
27
|
+
call: "call";
|
|
28
|
+
}>;
|
|
29
|
+
rootSymbolId: z.ZodOptional<z.ZodString>;
|
|
30
|
+
filePath: z.ZodOptional<z.ZodString>;
|
|
31
|
+
maxNodes: z.ZodOptional<z.ZodNumber>;
|
|
32
|
+
maxDepth: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
format: z.ZodOptional<z.ZodEnum<{
|
|
34
|
+
dot: "dot";
|
|
35
|
+
mermaid: "mermaid";
|
|
36
|
+
}>>;
|
|
37
|
+
};
|
|
38
|
+
export declare function handler(args: {
|
|
39
|
+
repoId: string;
|
|
40
|
+
type: 'module' | 'call' | 'class' | 'import';
|
|
41
|
+
rootSymbolId?: string;
|
|
42
|
+
filePath?: string;
|
|
43
|
+
maxNodes?: number;
|
|
44
|
+
maxDepth?: number;
|
|
45
|
+
format?: 'mermaid' | 'dot';
|
|
46
|
+
}): Promise<CallToolResult>;
|
|
47
|
+
//# sourceMappingURL=render-diagram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-diagram.d.ts","sourceRoot":"","sources":["../../../src/server/tools/render-diagram.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzE,eAAO,MAAM,IAAI,mBAAmB,CAAC;AAErC,eAAO,MAAM,WAAW,QAOsD,CAAC;AAE/E,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;CAsCvB,CAAC;AAgBF,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;CAC5B,GAAG,OAAO,CAAC,cAAc,CAAC,CAgG1B"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* render-diagram.ts
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: render_diagram
|
|
5
|
+
*
|
|
6
|
+
* Generate a Mermaid or DOT diagram from the dependency graph for a file,
|
|
7
|
+
* directory, or the whole repo. The primary general-purpose visualization tool —
|
|
8
|
+
* specialized variants (render_call_graph, render_class_hierarchy, etc.) build
|
|
9
|
+
* on this foundation.
|
|
10
|
+
*
|
|
11
|
+
* Diagram types:
|
|
12
|
+
* 'module' — file-level import graph, nodes = files, clustered by directory
|
|
13
|
+
* 'call' — call graph rooted at rootSymbolId (requires Task 174 data)
|
|
14
|
+
* 'class' — class inheritance rooted at rootSymbolId (requires Task 175 data)
|
|
15
|
+
* 'import' — alias for 'module' at the symbol level (same DB, different label)
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
import { openDatabase, getRepo } from '../../core/db/schema.js';
|
|
19
|
+
import { getAllDepEdges } from '../../core/db/dep-store.js';
|
|
20
|
+
import { buildCallHierarchy, buildClassHierarchy } from '../../graph/graph-traversal.js';
|
|
21
|
+
import { sanitizeId, shortLabel, parentDir, pruneGraph, renderMermaidModule, renderMermaidCallGraph, renderMermaidClassDiagram, renderDot, } from '../../graph/diagram-renderer.js';
|
|
22
|
+
import { buildMeta } from './_meta.js';
|
|
23
|
+
export const name = 'render_diagram';
|
|
24
|
+
export const description = 'Generate a Mermaid or DOT diagram from the indexed dependency graph. ' +
|
|
25
|
+
'Use type "module" for a file-level import graph of the whole repo or a directory. ' +
|
|
26
|
+
'Use type "call" with rootSymbolId for a call hierarchy flowchart. ' +
|
|
27
|
+
'Use type "class" with rootSymbolId for a class inheritance classDiagram. ' +
|
|
28
|
+
'Use type "import" for the same as "module" (alias). ' +
|
|
29
|
+
'Mermaid output renders natively in GitHub, VS Code, and Claude. ' +
|
|
30
|
+
'maxNodes (default 30) and maxDepth (default 3) prevent oversized diagrams.';
|
|
31
|
+
export const inputSchema = {
|
|
32
|
+
repoId: z.string().describe('Repo ID from index_folder or resolve_repo'),
|
|
33
|
+
type: z
|
|
34
|
+
.enum(['module', 'call', 'class', 'import'])
|
|
35
|
+
.describe('"module"/"import" — file-level import graph; ' +
|
|
36
|
+
'"call" — call graph (requires rootSymbolId); ' +
|
|
37
|
+
'"class" — class hierarchy (requires rootSymbolId)'),
|
|
38
|
+
rootSymbolId: z
|
|
39
|
+
.string()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe('Anchor symbol ID for call/class diagrams. Required for type "call" and "class".'),
|
|
42
|
+
filePath: z
|
|
43
|
+
.string()
|
|
44
|
+
.optional()
|
|
45
|
+
.describe('Scope the diagram to a directory or file prefix (relative to repo root). ' +
|
|
46
|
+
'E.g. "src/core/" restricts the module diagram to that directory.'),
|
|
47
|
+
maxNodes: z
|
|
48
|
+
.number()
|
|
49
|
+
.int()
|
|
50
|
+
.min(1)
|
|
51
|
+
.max(200)
|
|
52
|
+
.optional()
|
|
53
|
+
.describe('Maximum number of nodes to include. Least-connected nodes are dropped first. Default 30.'),
|
|
54
|
+
maxDepth: z
|
|
55
|
+
.number()
|
|
56
|
+
.int()
|
|
57
|
+
.min(1)
|
|
58
|
+
.max(10)
|
|
59
|
+
.optional()
|
|
60
|
+
.describe('Maximum traversal depth for call/class diagrams. Default 3.'),
|
|
61
|
+
format: z
|
|
62
|
+
.enum(['mermaid', 'dot'])
|
|
63
|
+
.optional()
|
|
64
|
+
.describe('Output format. Default "mermaid".'),
|
|
65
|
+
};
|
|
66
|
+
// ─── Handler ──────────────────────────────────────────────────────────────────
|
|
67
|
+
export async function handler(args) {
|
|
68
|
+
const t0 = Date.now();
|
|
69
|
+
const { repoId, type, rootSymbolId, filePath, maxNodes = 30, maxDepth = 3, format = 'mermaid', } = args;
|
|
70
|
+
const db = openDatabase(repoId);
|
|
71
|
+
try {
|
|
72
|
+
const repo = getRepo(db, repoId);
|
|
73
|
+
if (!repo) {
|
|
74
|
+
return {
|
|
75
|
+
content: [
|
|
76
|
+
{ type: 'text', text: JSON.stringify({ error: `Repo "${repoId}" not found. Run index_folder first.` }) },
|
|
77
|
+
],
|
|
78
|
+
isError: true,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
let nodes;
|
|
82
|
+
let edges;
|
|
83
|
+
if (type === 'module' || type === 'import') {
|
|
84
|
+
({ nodes, edges } = buildModuleGraph(repoId, db, filePath));
|
|
85
|
+
}
|
|
86
|
+
else if (type === 'call') {
|
|
87
|
+
if (!rootSymbolId) {
|
|
88
|
+
return {
|
|
89
|
+
content: [{ type: 'text', text: JSON.stringify({ error: 'rootSymbolId is required for type "call".' }) }],
|
|
90
|
+
isError: true,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const result = buildCallHierarchy(rootSymbolId, repoId, db, 'both', maxDepth, maxNodes * 2);
|
|
94
|
+
if (!result) {
|
|
95
|
+
return {
|
|
96
|
+
content: [{ type: 'text', text: JSON.stringify({ error: `Symbol "${rootSymbolId}" not found.` }) }],
|
|
97
|
+
isError: true,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
({ nodes, edges } = flattenCallTree(result.root, result.root.symbolId));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// type === 'class'
|
|
104
|
+
if (!rootSymbolId) {
|
|
105
|
+
return {
|
|
106
|
+
content: [{ type: 'text', text: JSON.stringify({ error: 'rootSymbolId is required for type "class".' }) }],
|
|
107
|
+
isError: true,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const result = buildClassHierarchy(rootSymbolId, repoId, db, 'both', maxDepth, true);
|
|
111
|
+
if (!result) {
|
|
112
|
+
return {
|
|
113
|
+
content: [{ type: 'text', text: JSON.stringify({ error: `Symbol "${rootSymbolId}" not found.` }) }],
|
|
114
|
+
isError: true,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
({ nodes, edges } = flattenClassTree(result.root));
|
|
118
|
+
}
|
|
119
|
+
// Apply maxNodes pruning
|
|
120
|
+
const { nodes: prunedNodes, edges: prunedEdges, truncated } = pruneGraph(nodes, edges, maxNodes);
|
|
121
|
+
// Render
|
|
122
|
+
let diagram;
|
|
123
|
+
if (format === 'dot') {
|
|
124
|
+
diagram = renderDot(prunedNodes, prunedEdges);
|
|
125
|
+
}
|
|
126
|
+
else if (type === 'call') {
|
|
127
|
+
const rootNode = prunedNodes.find((n) => n.styleClass === 'root');
|
|
128
|
+
const rootId = rootNode?.id ?? (prunedNodes[0]?.id ?? '');
|
|
129
|
+
diagram = renderMermaidCallGraph(prunedNodes, prunedEdges, rootId);
|
|
130
|
+
}
|
|
131
|
+
else if (type === 'class') {
|
|
132
|
+
diagram = renderMermaidClassDiagram(prunedNodes, prunedEdges);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
diagram = renderMermaidModule(prunedNodes, prunedEdges);
|
|
136
|
+
}
|
|
137
|
+
const output = {
|
|
138
|
+
diagram,
|
|
139
|
+
format,
|
|
140
|
+
nodeCount: prunedNodes.length,
|
|
141
|
+
edgeCount: prunedEdges.length,
|
|
142
|
+
truncated,
|
|
143
|
+
_tokenEstimate: Math.ceil(diagram.length / 4),
|
|
144
|
+
_meta: buildMeta({ timingMs: Date.now() - t0 }),
|
|
145
|
+
};
|
|
146
|
+
return {
|
|
147
|
+
content: [{ type: 'text', text: JSON.stringify(output, null, 2) }],
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
db.close();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// ─── Module graph builder ─────────────────────────────────────────────────────
|
|
155
|
+
function buildModuleGraph(repoId, db, filePathScope) {
|
|
156
|
+
const allEdges = getAllDepEdges(db, repoId);
|
|
157
|
+
// Filter by scope prefix if provided
|
|
158
|
+
const scopePrefix = filePathScope
|
|
159
|
+
? filePathScope.endsWith('/') ? filePathScope : filePathScope + '/'
|
|
160
|
+
: null;
|
|
161
|
+
const scopedEdges = scopePrefix
|
|
162
|
+
? allEdges.filter((e) => e.sourceFile.startsWith(scopePrefix) && e.targetFile.startsWith(scopePrefix))
|
|
163
|
+
: allEdges;
|
|
164
|
+
// Collect unique file paths
|
|
165
|
+
const fileSet = new Set();
|
|
166
|
+
for (const e of scopedEdges) {
|
|
167
|
+
fileSet.add(e.sourceFile);
|
|
168
|
+
fileSet.add(e.targetFile);
|
|
169
|
+
}
|
|
170
|
+
const nodes = Array.from(fileSet).map((fp) => ({
|
|
171
|
+
id: sanitizeId(fp),
|
|
172
|
+
label: shortLabel(fp),
|
|
173
|
+
fullPath: fp,
|
|
174
|
+
group: parentDir(fp),
|
|
175
|
+
}));
|
|
176
|
+
// Deduplicate edges (same source→target pair may appear multiple times)
|
|
177
|
+
const seenEdges = new Set();
|
|
178
|
+
const edges = [];
|
|
179
|
+
for (const e of scopedEdges) {
|
|
180
|
+
const key = `${e.sourceFile}→${e.targetFile}`;
|
|
181
|
+
if (!seenEdges.has(key)) {
|
|
182
|
+
seenEdges.add(key);
|
|
183
|
+
edges.push({
|
|
184
|
+
source: sanitizeId(e.sourceFile),
|
|
185
|
+
target: sanitizeId(e.targetFile),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return { nodes, edges };
|
|
190
|
+
}
|
|
191
|
+
// ─── Call tree flattener ──────────────────────────────────────────────────────
|
|
192
|
+
function flattenCallTree(root, rootSymbolId) {
|
|
193
|
+
const nodeMap = new Map();
|
|
194
|
+
const edges = [];
|
|
195
|
+
const visited = new Set();
|
|
196
|
+
function walk(node, parentId) {
|
|
197
|
+
const nodeId = sanitizeId(node.symbolId);
|
|
198
|
+
const isRoot = node.symbolId === rootSymbolId;
|
|
199
|
+
if (!nodeMap.has(nodeId)) {
|
|
200
|
+
nodeMap.set(nodeId, {
|
|
201
|
+
id: nodeId,
|
|
202
|
+
label: `${node.name}\n${shortLabel(node.filePath)}`,
|
|
203
|
+
fullPath: node.filePath,
|
|
204
|
+
group: parentDir(node.filePath),
|
|
205
|
+
styleClass: isRoot ? 'root' : undefined,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (parentId !== null && !visited.has(`${parentId}→${nodeId}`)) {
|
|
209
|
+
visited.add(`${parentId}→${nodeId}`);
|
|
210
|
+
edges.push({
|
|
211
|
+
source: parentId,
|
|
212
|
+
target: nodeId,
|
|
213
|
+
dashed: node.cyclic,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
if (!node.cyclic) {
|
|
217
|
+
for (const child of node.children) {
|
|
218
|
+
walk(child, nodeId);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
walk(root, null);
|
|
223
|
+
return { nodes: Array.from(nodeMap.values()), edges };
|
|
224
|
+
}
|
|
225
|
+
// ─── Class hierarchy flattener ────────────────────────────────────────────────
|
|
226
|
+
function flattenClassTree(root) {
|
|
227
|
+
const nodeMap = new Map();
|
|
228
|
+
const edges = [];
|
|
229
|
+
const visited = new Set();
|
|
230
|
+
function nodeKey(node) {
|
|
231
|
+
return node.symbolId ?? `ext_${sanitizeId(node.name)}`;
|
|
232
|
+
}
|
|
233
|
+
function walk(node, parentNode) {
|
|
234
|
+
const key = sanitizeId(nodeKey(node));
|
|
235
|
+
if (!nodeMap.has(key)) {
|
|
236
|
+
nodeMap.set(key, {
|
|
237
|
+
id: key,
|
|
238
|
+
label: node.name,
|
|
239
|
+
fullPath: node.filePath ?? '',
|
|
240
|
+
group: node.filePath ? parentDir(node.filePath) : 'external',
|
|
241
|
+
styleClass: node.filePath === null ? 'external' : undefined,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
if (parentNode !== null) {
|
|
245
|
+
const parentKey = sanitizeId(nodeKey(parentNode));
|
|
246
|
+
const edgeKey = `${key}→${parentKey}`;
|
|
247
|
+
if (!visited.has(edgeKey)) {
|
|
248
|
+
visited.add(edgeKey);
|
|
249
|
+
// parent is an ancestor (depth < 0) or interface → dashed for implements
|
|
250
|
+
const isInterface = parentNode.isInterface;
|
|
251
|
+
edges.push({
|
|
252
|
+
source: key,
|
|
253
|
+
target: parentKey,
|
|
254
|
+
dashed: isInterface,
|
|
255
|
+
label: isInterface ? 'implements' : 'extends',
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
for (const child of node.children) {
|
|
260
|
+
walk(child, node);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
walk(root, null);
|
|
264
|
+
return { nodes: Array.from(nodeMap.values()), edges };
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=render-diagram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-diagram.js","sourceRoot":"","sources":["../../../src/server/tools/render-diagram.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* render-import-graph.ts
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: render_import_graph
|
|
5
|
+
*
|
|
6
|
+
* Render a file-level import graph for a directory as a Mermaid or DOT diagram.
|
|
7
|
+
*
|
|
8
|
+
* Node categories:
|
|
9
|
+
* - In-scope nodes — files whose path starts with `filePath` (no special style)
|
|
10
|
+
* - Boundary nodes — files OUTSIDE `filePath` that are imported by in-scope files
|
|
11
|
+
* (shown with a grey fill so the import boundary is visible)
|
|
12
|
+
* - External nodes — npm package specifiers (only when includeExternal: true;
|
|
13
|
+
* these are not stored in dep_edges so they are a no-op at
|
|
14
|
+
* the moment — the parameter is accepted for API stability)
|
|
15
|
+
*
|
|
16
|
+
* All dep_edges are internal file-to-file edges (external npm imports are dropped
|
|
17
|
+
* at graph-build time in graph-builder.ts). Boundary nodes are detected by
|
|
18
|
+
* comparing `targetFile` against the `filePath` scope prefix.
|
|
19
|
+
*/
|
|
20
|
+
import { z } from 'zod';
|
|
21
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
22
|
+
export declare const name = "render_import_graph";
|
|
23
|
+
export declare const description: string;
|
|
24
|
+
export declare const inputSchema: {
|
|
25
|
+
repoId: z.ZodString;
|
|
26
|
+
filePath: z.ZodString;
|
|
27
|
+
includeExternal: z.ZodOptional<z.ZodBoolean>;
|
|
28
|
+
maxNodes: z.ZodOptional<z.ZodNumber>;
|
|
29
|
+
format: z.ZodOptional<z.ZodEnum<{
|
|
30
|
+
dot: "dot";
|
|
31
|
+
mermaid: "mermaid";
|
|
32
|
+
}>>;
|
|
33
|
+
};
|
|
34
|
+
export declare function handler(args: {
|
|
35
|
+
repoId: string;
|
|
36
|
+
filePath: string;
|
|
37
|
+
includeExternal?: boolean;
|
|
38
|
+
maxNodes?: number;
|
|
39
|
+
format?: 'mermaid' | 'dot';
|
|
40
|
+
}): Promise<CallToolResult>;
|
|
41
|
+
//# sourceMappingURL=render-import-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-import-graph.d.ts","sourceRoot":"","sources":["../../../src/server/tools/render-import-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,eAAO,MAAM,IAAI,wBAAwB,CAAC;AAE1C,eAAO,MAAM,WAAW,QAM2C,CAAC;AAEpE,eAAO,MAAM,WAAW;;;;;;;;;CA4BvB,CAAC;AAeF,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;CAC5B,GAAG,OAAO,CAAC,cAAc,CAAC,CAyH1B"}
|