@mohantn/gate-keeper 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/instructions/dotnet-api-integration.instructions.md +416 -0
- package/.github/instructions/dotnet-development.instructions.md +353 -0
- package/.github/instructions/dotnet-testing.instructions.md +406 -0
- package/.github/instructions/gate-keeper.instructions.md +91 -0
- package/.github/instructions/react-development.instructions.md +315 -0
- package/.github/instructions/react-testing-optimization.instructions.md +373 -0
- package/.github/instructions/uiux.instructions.md +261 -0
- package/LICENSE +21 -0
- package/README.md +181 -0
- package/dist/analyzer/coverage-analyzer.d.ts +126 -0
- package/dist/analyzer/coverage-analyzer.d.ts.map +1 -0
- package/dist/analyzer/coverage-analyzer.js +633 -0
- package/dist/analyzer/coverage-analyzer.js.map +1 -0
- package/dist/analyzer/csharp-analyzer.d.ts +28 -0
- package/dist/analyzer/csharp-analyzer.d.ts.map +1 -0
- package/dist/analyzer/csharp-analyzer.js +437 -0
- package/dist/analyzer/csharp-analyzer.js.map +1 -0
- package/dist/analyzer/pattern-detector.d.ts +5 -0
- package/dist/analyzer/pattern-detector.d.ts.map +1 -0
- package/dist/analyzer/pattern-detector.js +74 -0
- package/dist/analyzer/pattern-detector.js.map +1 -0
- package/dist/analyzer/refactoring-advisor.d.ts +7 -0
- package/dist/analyzer/refactoring-advisor.d.ts.map +1 -0
- package/dist/analyzer/refactoring-advisor.js +280 -0
- package/dist/analyzer/refactoring-advisor.js.map +1 -0
- package/dist/analyzer/sonar-eslint-runner.d.ts +3 -0
- package/dist/analyzer/sonar-eslint-runner.d.ts.map +1 -0
- package/dist/analyzer/sonar-eslint-runner.js +136 -0
- package/dist/analyzer/sonar-eslint-runner.js.map +1 -0
- package/dist/analyzer/sonar-rule-map.d.ts +19 -0
- package/dist/analyzer/sonar-rule-map.d.ts.map +1 -0
- package/dist/analyzer/sonar-rule-map.js +67 -0
- package/dist/analyzer/sonar-rule-map.js.map +1 -0
- package/dist/analyzer/string-analyzer.d.ts +27 -0
- package/dist/analyzer/string-analyzer.d.ts.map +1 -0
- package/dist/analyzer/string-analyzer.js +274 -0
- package/dist/analyzer/string-analyzer.js.map +1 -0
- package/dist/analyzer/typescript-analyzer.d.ts +27 -0
- package/dist/analyzer/typescript-analyzer.d.ts.map +1 -0
- package/dist/analyzer/typescript-analyzer.js +437 -0
- package/dist/analyzer/typescript-analyzer.js.map +1 -0
- package/dist/analyzer/universal-analyzer.d.ts +10 -0
- package/dist/analyzer/universal-analyzer.d.ts.map +1 -0
- package/dist/analyzer/universal-analyzer.js +155 -0
- package/dist/analyzer/universal-analyzer.js.map +1 -0
- package/dist/cache/quality-cache.d.ts +119 -0
- package/dist/cache/quality-cache.d.ts.map +1 -0
- package/dist/cache/quality-cache.js +130 -0
- package/dist/cache/quality-cache.js.map +1 -0
- package/dist/cache/sqlite-cache.d.ts +43 -0
- package/dist/cache/sqlite-cache.d.ts.map +1 -0
- package/dist/cache/sqlite-cache.js +346 -0
- package/dist/cache/sqlite-cache.js.map +1 -0
- package/dist/cli/query-repl.d.ts +37 -0
- package/dist/cli/query-repl.d.ts.map +1 -0
- package/dist/cli/query-repl.js +298 -0
- package/dist/cli/query-repl.js.map +1 -0
- package/dist/cli/repl-algorithms.d.ts +49 -0
- package/dist/cli/repl-algorithms.d.ts.map +1 -0
- package/dist/cli/repl-algorithms.js +147 -0
- package/dist/cli/repl-algorithms.js.map +1 -0
- package/dist/cli/setup-core.d.ts +38 -0
- package/dist/cli/setup-core.d.ts.map +1 -0
- package/dist/cli/setup-core.js +427 -0
- package/dist/cli/setup-core.js.map +1 -0
- package/dist/cli/setup.d.ts +25 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +159 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cli-entry.d.ts +19 -0
- package/dist/cli-entry.d.ts.map +1 -0
- package/dist/cli-entry.js +178 -0
- package/dist/cli-entry.js.map +1 -0
- package/dist/daemon/watch-mode.d.ts +41 -0
- package/dist/daemon/watch-mode.d.ts.map +1 -0
- package/dist/daemon/watch-mode.js +163 -0
- package/dist/daemon/watch-mode.js.map +1 -0
- package/dist/daemon.d.ts +24 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +357 -0
- package/dist/daemon.js.map +1 -0
- package/dist/github/app.d.ts +34 -0
- package/dist/github/app.d.ts.map +1 -0
- package/dist/github/app.js +261 -0
- package/dist/github/app.js.map +1 -0
- package/dist/github/commenter.d.ts +67 -0
- package/dist/github/commenter.d.ts.map +1 -0
- package/dist/github/commenter.js +155 -0
- package/dist/github/commenter.js.map +1 -0
- package/dist/graph/dependency-graph.d.ts +28 -0
- package/dist/graph/dependency-graph.d.ts.map +1 -0
- package/dist/graph/dependency-graph.js +198 -0
- package/dist/graph/dependency-graph.js.map +1 -0
- package/dist/graph/global-graph.d.ts +65 -0
- package/dist/graph/global-graph.d.ts.map +1 -0
- package/dist/graph/global-graph.js +153 -0
- package/dist/graph/global-graph.js.map +1 -0
- package/dist/graph/graph-algorithms.d.ts +90 -0
- package/dist/graph/graph-algorithms.d.ts.map +1 -0
- package/dist/graph/graph-algorithms.js +180 -0
- package/dist/graph/graph-algorithms.js.map +1 -0
- package/dist/graph/graph-export.d.ts +68 -0
- package/dist/graph/graph-export.d.ts.map +1 -0
- package/dist/graph/graph-export.js +264 -0
- package/dist/graph/graph-export.js.map +1 -0
- package/dist/graph/graph-report.d.ts +34 -0
- package/dist/graph/graph-report.d.ts.map +1 -0
- package/dist/graph/graph-report.js +136 -0
- package/dist/graph/graph-report.js.map +1 -0
- package/dist/graph/graph-summary.d.ts +68 -0
- package/dist/graph/graph-summary.d.ts.map +1 -0
- package/dist/graph/graph-summary.js +213 -0
- package/dist/graph/graph-summary.js.map +1 -0
- package/dist/graph/graphify-ignore.d.ts +32 -0
- package/dist/graph/graphify-ignore.d.ts.map +1 -0
- package/dist/graph/graphify-ignore.js +124 -0
- package/dist/graph/graphify-ignore.js.map +1 -0
- package/dist/graph/question-suggester.d.ts +30 -0
- package/dist/graph/question-suggester.d.ts.map +1 -0
- package/dist/graph/question-suggester.js +113 -0
- package/dist/graph/question-suggester.js.map +1 -0
- package/dist/graph/relationship-extractor.d.ts +40 -0
- package/dist/graph/relationship-extractor.d.ts.map +1 -0
- package/dist/graph/relationship-extractor.js +254 -0
- package/dist/graph/relationship-extractor.js.map +1 -0
- package/dist/graph/relationship-types.d.ts +24 -0
- package/dist/graph/relationship-types.d.ts.map +1 -0
- package/dist/graph/relationship-types.js +21 -0
- package/dist/graph/relationship-types.js.map +1 -0
- package/dist/graph/surprising-connections.d.ts +39 -0
- package/dist/graph/surprising-connections.d.ts.map +1 -0
- package/dist/graph/surprising-connections.js +127 -0
- package/dist/graph/surprising-connections.js.map +1 -0
- package/dist/hook-pre-tool-use.d.ts +14 -0
- package/dist/hook-pre-tool-use.d.ts.map +1 -0
- package/dist/hook-pre-tool-use.js +167 -0
- package/dist/hook-pre-tool-use.js.map +1 -0
- package/dist/hook-receiver.d.ts +29 -0
- package/dist/hook-receiver.d.ts.map +1 -0
- package/dist/hook-receiver.js +327 -0
- package/dist/hook-receiver.js.map +1 -0
- package/dist/hooks/git-hooks.d.ts +30 -0
- package/dist/hooks/git-hooks.d.ts.map +1 -0
- package/dist/hooks/git-hooks.js +179 -0
- package/dist/hooks/git-hooks.js.map +1 -0
- package/dist/mcp/cache-preload.d.ts +29 -0
- package/dist/mcp/cache-preload.d.ts.map +1 -0
- package/dist/mcp/cache-preload.js +103 -0
- package/dist/mcp/cache-preload.js.map +1 -0
- package/dist/mcp/handlers/analysis.d.ts +4 -0
- package/dist/mcp/handlers/analysis.d.ts.map +1 -0
- package/dist/mcp/handlers/analysis.js +196 -0
- package/dist/mcp/handlers/analysis.js.map +1 -0
- package/dist/mcp/handlers/context.d.ts +25 -0
- package/dist/mcp/handlers/context.d.ts.map +1 -0
- package/dist/mcp/handlers/context.js +382 -0
- package/dist/mcp/handlers/context.js.map +1 -0
- package/dist/mcp/handlers/graph-intelligence.d.ts +26 -0
- package/dist/mcp/handlers/graph-intelligence.d.ts.map +1 -0
- package/dist/mcp/handlers/graph-intelligence.js +371 -0
- package/dist/mcp/handlers/graph-intelligence.js.map +1 -0
- package/dist/mcp/handlers/graph-query.d.ts +25 -0
- package/dist/mcp/handlers/graph-query.d.ts.map +1 -0
- package/dist/mcp/handlers/graph-query.js +410 -0
- package/dist/mcp/handlers/graph-query.js.map +1 -0
- package/dist/mcp/handlers/graph.d.ts +5 -0
- package/dist/mcp/handlers/graph.d.ts.map +1 -0
- package/dist/mcp/handlers/graph.js +283 -0
- package/dist/mcp/handlers/graph.js.map +1 -0
- package/dist/mcp/handlers/impact-format.d.ts +9 -0
- package/dist/mcp/handlers/impact-format.d.ts.map +1 -0
- package/dist/mcp/handlers/impact-format.js +189 -0
- package/dist/mcp/handlers/impact-format.js.map +1 -0
- package/dist/mcp/handlers/impact.d.ts +4 -0
- package/dist/mcp/handlers/impact.d.ts.map +1 -0
- package/dist/mcp/handlers/impact.js +139 -0
- package/dist/mcp/handlers/impact.js.map +1 -0
- package/dist/mcp/handlers/improvement.d.ts +4 -0
- package/dist/mcp/handlers/improvement.d.ts.map +1 -0
- package/dist/mcp/handlers/improvement.js +136 -0
- package/dist/mcp/handlers/improvement.js.map +1 -0
- package/dist/mcp/handlers/index.d.ts +14 -0
- package/dist/mcp/handlers/index.d.ts.map +1 -0
- package/dist/mcp/handlers/index.js +36 -0
- package/dist/mcp/handlers/index.js.map +1 -0
- package/dist/mcp/handlers/platform-installer.d.ts +10 -0
- package/dist/mcp/handlers/platform-installer.d.ts.map +1 -0
- package/dist/mcp/handlers/platform-installer.js +168 -0
- package/dist/mcp/handlers/platform-installer.js.map +1 -0
- package/dist/mcp/handlers/pr-review.d.ts +33 -0
- package/dist/mcp/handlers/pr-review.d.ts.map +1 -0
- package/dist/mcp/handlers/pr-review.js +170 -0
- package/dist/mcp/handlers/pr-review.js.map +1 -0
- package/dist/mcp/handlers/shared.d.ts +20 -0
- package/dist/mcp/handlers/shared.d.ts.map +1 -0
- package/dist/mcp/handlers/shared.js +27 -0
- package/dist/mcp/handlers/shared.js.map +1 -0
- package/dist/mcp/handlers/types.d.ts +46 -0
- package/dist/mcp/handlers/types.d.ts.map +1 -0
- package/dist/mcp/handlers/types.js +3 -0
- package/dist/mcp/handlers/types.js.map +1 -0
- package/dist/mcp/helpers.d.ts +36 -0
- package/dist/mcp/helpers.d.ts.map +1 -0
- package/dist/mcp/helpers.js +199 -0
- package/dist/mcp/helpers.js.map +1 -0
- package/dist/mcp/installer.d.ts +22 -0
- package/dist/mcp/installer.d.ts.map +1 -0
- package/dist/mcp/installer.js +341 -0
- package/dist/mcp/installer.js.map +1 -0
- package/dist/mcp/server.d.ts +111 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +216 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/token-tracker.d.ts +47 -0
- package/dist/mcp/token-tracker.d.ts.map +1 -0
- package/dist/mcp/token-tracker.js +93 -0
- package/dist/mcp/token-tracker.js.map +1 -0
- package/dist/quality-loop/file-lock.d.ts +12 -0
- package/dist/quality-loop/file-lock.d.ts.map +1 -0
- package/dist/quality-loop/file-lock.js +38 -0
- package/dist/quality-loop/file-lock.js.map +1 -0
- package/dist/quality-loop/fix-worker.d.ts +44 -0
- package/dist/quality-loop/fix-worker.d.ts.map +1 -0
- package/dist/quality-loop/fix-worker.js +414 -0
- package/dist/quality-loop/fix-worker.js.map +1 -0
- package/dist/quality-loop/orchestrator.d.ts +137 -0
- package/dist/quality-loop/orchestrator.d.ts.map +1 -0
- package/dist/quality-loop/orchestrator.js +894 -0
- package/dist/quality-loop/orchestrator.js.map +1 -0
- package/dist/quality-loop/queue-manager.d.ts +45 -0
- package/dist/quality-loop/queue-manager.d.ts.map +1 -0
- package/dist/quality-loop/queue-manager.js +173 -0
- package/dist/quality-loop/queue-manager.js.map +1 -0
- package/dist/rating/rating-calculator.d.ts +15 -0
- package/dist/rating/rating-calculator.d.ts.map +1 -0
- package/dist/rating/rating-calculator.js +136 -0
- package/dist/rating/rating-calculator.js.map +1 -0
- package/dist/types/agent.d.ts +49 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +7 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types.d.ts +156 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/util/fix-text.d.ts +7 -0
- package/dist/util/fix-text.d.ts.map +1 -0
- package/dist/util/fix-text.js +13 -0
- package/dist/util/fix-text.js.map +1 -0
- package/dist/viz/graph-viz.d.ts +40 -0
- package/dist/viz/graph-viz.d.ts.map +1 -0
- package/dist/viz/graph-viz.js +332 -0
- package/dist/viz/graph-viz.js.map +1 -0
- package/dist/viz/viz-helpers.d.ts +13 -0
- package/dist/viz/viz-helpers.d.ts.map +1 -0
- package/dist/viz/viz-helpers.js +134 -0
- package/dist/viz/viz-helpers.js.map +1 -0
- package/dist/viz/viz-routes.d.ts +28 -0
- package/dist/viz/viz-routes.d.ts.map +1 -0
- package/dist/viz/viz-routes.js +333 -0
- package/dist/viz/viz-routes.js.map +1 -0
- package/dist/viz/viz-scanner.d.ts +20 -0
- package/dist/viz/viz-scanner.d.ts.map +1 -0
- package/dist/viz/viz-scanner.js +241 -0
- package/dist/viz/viz-scanner.js.map +1 -0
- package/dist/viz/viz-server.d.ts +38 -0
- package/dist/viz/viz-server.d.ts.map +1 -0
- package/dist/viz/viz-server.js +240 -0
- package/dist/viz/viz-server.js.map +1 -0
- package/package.json +89 -0
- package/scripts/postinstall.js +28 -0
- package/scripts/setup.sh +113 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Graph export engine — produces graphify-compatible JSON, GraphML, and Neo4j Cypher.
|
|
4
|
+
*
|
|
5
|
+
* All formats capture the full node+edge structure so external tools (graph
|
|
6
|
+
* databases, visualizers, other repos) can consume gate-keeper analysis.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.exportToJson = exportToJson;
|
|
10
|
+
exports.exportToGraphML = exportToGraphML;
|
|
11
|
+
exports.exportToNeo4j = exportToNeo4j;
|
|
12
|
+
exports.exportToSvg = exportToSvg;
|
|
13
|
+
exports.mergeGraphs = mergeGraphs;
|
|
14
|
+
exports.exportGraph = exportGraph;
|
|
15
|
+
const graph_algorithms_1 = require("./graph-algorithms");
|
|
16
|
+
const surprising_connections_1 = require("./surprising-connections");
|
|
17
|
+
const question_suggester_1 = require("./question-suggester");
|
|
18
|
+
// ── JSON (graphify-compatible) ─────────────────────────────
|
|
19
|
+
function exportToJson(nodes, edges, cycles, opts) {
|
|
20
|
+
const repoRoot = opts.repoRoot ?? '';
|
|
21
|
+
const centrality = (0, graph_algorithms_1.computeCentrality)(nodes, edges);
|
|
22
|
+
const godNodes = centrality.slice(0, 10).map(c => ({
|
|
23
|
+
id: c.path,
|
|
24
|
+
label: c.label,
|
|
25
|
+
inDegree: c.inDegree,
|
|
26
|
+
outDegree: c.outDegree,
|
|
27
|
+
totalDegree: c.totalDegree,
|
|
28
|
+
rating: c.rating,
|
|
29
|
+
}));
|
|
30
|
+
const surprising = repoRoot
|
|
31
|
+
? (0, surprising_connections_1.findSurprisingConnections)(nodes, edges, repoRoot, 10)
|
|
32
|
+
: [];
|
|
33
|
+
const questions = repoRoot
|
|
34
|
+
? (0, question_suggester_1.suggestQuestions)(nodes, edges, repoRoot, 5)
|
|
35
|
+
: [];
|
|
36
|
+
const graph = {
|
|
37
|
+
version: '2.0',
|
|
38
|
+
generatedAt: Date.now(),
|
|
39
|
+
repo: repoRoot,
|
|
40
|
+
overallRating: opts.overallRating ?? null,
|
|
41
|
+
nodes: nodes.map(n => ({
|
|
42
|
+
id: n.id,
|
|
43
|
+
type: 'file',
|
|
44
|
+
label: n.label,
|
|
45
|
+
rating: n.rating,
|
|
46
|
+
metrics: n.metrics ?? {},
|
|
47
|
+
violations: (n.violations ?? []).map(v => ({ type: v.type, severity: v.severity })),
|
|
48
|
+
})),
|
|
49
|
+
edges: edges.map(e => ({
|
|
50
|
+
source: e.source,
|
|
51
|
+
target: e.target,
|
|
52
|
+
type: (e.type ?? 'IMPORT').toUpperCase(),
|
|
53
|
+
confidence: 'EXTRACTED',
|
|
54
|
+
weight: e.strength ?? 1,
|
|
55
|
+
})),
|
|
56
|
+
godNodes,
|
|
57
|
+
surprisingConnections: surprising,
|
|
58
|
+
suggestedQuestions: questions.map(q => q.question),
|
|
59
|
+
cycles: cycles.map(c => c.nodes),
|
|
60
|
+
};
|
|
61
|
+
return JSON.stringify(graph, null, 2);
|
|
62
|
+
}
|
|
63
|
+
// ── GraphML ────────────────────────────────────────────────
|
|
64
|
+
function exportToGraphML(nodes, edges) {
|
|
65
|
+
const lines = [
|
|
66
|
+
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
67
|
+
'<graphml xmlns="http://graphml.graphdrawing.org/graphml">',
|
|
68
|
+
' <key id="rating" for="node" attr.name="rating" attr.type="double"/>',
|
|
69
|
+
' <key id="linesOfCode" for="node" attr.name="linesOfCode" attr.type="int"/>',
|
|
70
|
+
' <key id="label" for="node" attr.name="label" attr.type="string"/>',
|
|
71
|
+
' <key id="edgeType" for="edge" attr.name="type" attr.type="string"/>',
|
|
72
|
+
' <key id="weight" for="edge" attr.name="weight" attr.type="double"/>',
|
|
73
|
+
' <graph id="G" edgedefault="directed">',
|
|
74
|
+
];
|
|
75
|
+
for (const n of nodes) {
|
|
76
|
+
const safeId = escapeXml(n.id);
|
|
77
|
+
lines.push(` <node id="${safeId}">`);
|
|
78
|
+
lines.push(` <data key="label">${escapeXml(n.label)}</data>`);
|
|
79
|
+
lines.push(` <data key="rating">${n.rating}</data>`);
|
|
80
|
+
if (n.metrics?.linesOfCode !== undefined) {
|
|
81
|
+
lines.push(` <data key="linesOfCode">${n.metrics.linesOfCode}</data>`);
|
|
82
|
+
}
|
|
83
|
+
lines.push(' </node>');
|
|
84
|
+
}
|
|
85
|
+
for (let i = 0; i < edges.length; i++) {
|
|
86
|
+
const e = edges[i];
|
|
87
|
+
lines.push(` <edge id="e${i}" source="${escapeXml(e.source)}" target="${escapeXml(e.target)}">`);
|
|
88
|
+
lines.push(` <data key="edgeType">${escapeXml(e.type ?? 'IMPORT')}</data>`);
|
|
89
|
+
lines.push(` <data key="weight">${e.strength ?? 1}</data>`);
|
|
90
|
+
lines.push(' </edge>');
|
|
91
|
+
}
|
|
92
|
+
lines.push(' </graph>');
|
|
93
|
+
lines.push('</graphml>');
|
|
94
|
+
return lines.join('\n');
|
|
95
|
+
}
|
|
96
|
+
// ── Neo4j Cypher ───────────────────────────────────────────
|
|
97
|
+
function exportToNeo4j(nodes, edges) {
|
|
98
|
+
const lines = [
|
|
99
|
+
'// Gate Keeper — Neo4j Cypher import script',
|
|
100
|
+
'// Run: cypher-shell < graph.cypher',
|
|
101
|
+
'',
|
|
102
|
+
'// Clear existing (optional):',
|
|
103
|
+
'// MATCH (n:File) DETACH DELETE n;',
|
|
104
|
+
'',
|
|
105
|
+
'// Nodes',
|
|
106
|
+
];
|
|
107
|
+
for (const n of nodes) {
|
|
108
|
+
const props = [
|
|
109
|
+
`id: ${cyStr(n.id)}`,
|
|
110
|
+
`label: ${cyStr(n.label)}`,
|
|
111
|
+
`rating: ${n.rating}`,
|
|
112
|
+
];
|
|
113
|
+
if (n.metrics?.linesOfCode !== undefined)
|
|
114
|
+
props.push(`linesOfCode: ${n.metrics.linesOfCode}`);
|
|
115
|
+
if (n.metrics?.cyclomaticComplexity !== undefined)
|
|
116
|
+
props.push(`complexity: ${n.metrics.cyclomaticComplexity}`);
|
|
117
|
+
lines.push(`CREATE (:File {${props.join(', ')}});`);
|
|
118
|
+
}
|
|
119
|
+
lines.push('', '// Relationships');
|
|
120
|
+
for (const e of edges) {
|
|
121
|
+
const relType = (e.type ?? 'IMPORT').replace(/\W/g, '_').toUpperCase();
|
|
122
|
+
lines.push(`MATCH (a:File {id: ${cyStr(e.source)}}), (b:File {id: ${cyStr(e.target)}}) ` +
|
|
123
|
+
`CREATE (a)-[:${relType} {weight: ${e.strength ?? 1}}]->(b);`);
|
|
124
|
+
}
|
|
125
|
+
return lines.join('\n');
|
|
126
|
+
}
|
|
127
|
+
// ── SVG (circular layout) ──────────────────────────────────
|
|
128
|
+
/**
|
|
129
|
+
* Render the graph as SVG using a circular node layout.
|
|
130
|
+
* Nodes are placed evenly around a circle; edges are straight lines.
|
|
131
|
+
* Node colour encodes rating; node radius encodes in-degree.
|
|
132
|
+
*/
|
|
133
|
+
function exportToSvg(nodes, edges, opts = {}) {
|
|
134
|
+
const W = opts.width ?? 900;
|
|
135
|
+
const H = opts.height ?? 900;
|
|
136
|
+
const cx = W / 2;
|
|
137
|
+
const cy = H / 2;
|
|
138
|
+
const layoutR = Math.min(W, H) * 0.38;
|
|
139
|
+
const MIN_NR = 5;
|
|
140
|
+
const MAX_NR = 14;
|
|
141
|
+
// Compute in-degree for node sizing
|
|
142
|
+
const inDeg = new Map(nodes.map(n => [n.id, 0]));
|
|
143
|
+
for (const e of edges)
|
|
144
|
+
inDeg.set(e.target, (inDeg.get(e.target) ?? 0) + 1);
|
|
145
|
+
const maxIn = Math.max(1, ...inDeg.values());
|
|
146
|
+
// Circular positions
|
|
147
|
+
const pos = new Map();
|
|
148
|
+
nodes.forEach((n, i) => {
|
|
149
|
+
const angle = (2 * Math.PI * i) / Math.max(nodes.length, 1) - Math.PI / 2;
|
|
150
|
+
pos.set(n.id, { x: cx + layoutR * Math.cos(angle), y: cy + layoutR * Math.sin(angle) });
|
|
151
|
+
});
|
|
152
|
+
const ratingColor = (r) => r >= 8 ? '#4caf50' : r >= 6 ? '#ffc107' : r >= 4 ? '#ff9800' : '#f44336';
|
|
153
|
+
const nodeRadius = (id) => {
|
|
154
|
+
const d = inDeg.get(id) ?? 0;
|
|
155
|
+
return MIN_NR + ((d / maxIn) * (MAX_NR - MIN_NR));
|
|
156
|
+
};
|
|
157
|
+
const lines = [
|
|
158
|
+
`<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="0 0 ${W} ${H}">`,
|
|
159
|
+
`<defs>`,
|
|
160
|
+
` <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5"`,
|
|
161
|
+
` markerWidth="6" markerHeight="6" orient="auto-start-reverse">`,
|
|
162
|
+
` <path d="M 0 0 L 10 5 L 0 10 z" fill="#ccc"/>`,
|
|
163
|
+
` </marker>`,
|
|
164
|
+
`</defs>`,
|
|
165
|
+
`<style>`,
|
|
166
|
+
` text { font-family: sans-serif; font-size: 9px; fill: #333; pointer-events: none; }`,
|
|
167
|
+
` .edge { stroke: #ccc; stroke-width: 1; fill: none; marker-end: url(#arrow); }`,
|
|
168
|
+
` .node { cursor: pointer; }`,
|
|
169
|
+
` .node:hover circle { stroke-width: 3; }`,
|
|
170
|
+
`</style>`,
|
|
171
|
+
`<rect width="${W}" height="${H}" fill="#fafafa"/>`,
|
|
172
|
+
`<g class="edges">`,
|
|
173
|
+
];
|
|
174
|
+
for (const e of edges) {
|
|
175
|
+
const s = pos.get(e.source);
|
|
176
|
+
const t = pos.get(e.target);
|
|
177
|
+
if (!s || !t || e.source === e.target)
|
|
178
|
+
continue;
|
|
179
|
+
// Shorten line so it doesn't overlap node circles
|
|
180
|
+
const tr = nodeRadius(e.target);
|
|
181
|
+
const dx = t.x - s.x;
|
|
182
|
+
const dy = t.y - s.y;
|
|
183
|
+
const len = Math.sqrt(dx * dx + dy * dy);
|
|
184
|
+
const ux = len > 0 ? dx / len : 0;
|
|
185
|
+
const uy = len > 0 ? dy / len : 0;
|
|
186
|
+
const tx = t.x - ux * (tr + 2);
|
|
187
|
+
const ty = t.y - uy * (tr + 2);
|
|
188
|
+
lines.push(` <line class="edge" x1="${s.x.toFixed(1)}" y1="${s.y.toFixed(1)}" ` +
|
|
189
|
+
`x2="${tx.toFixed(1)}" y2="${ty.toFixed(1)}"/>`);
|
|
190
|
+
}
|
|
191
|
+
lines.push(`</g>`, `<g class="nodes">`);
|
|
192
|
+
for (const n of nodes) {
|
|
193
|
+
const p = pos.get(n.id);
|
|
194
|
+
if (!p)
|
|
195
|
+
continue;
|
|
196
|
+
const r = nodeRadius(n.id);
|
|
197
|
+
const color = ratingColor(n.rating);
|
|
198
|
+
const lx = p.x + r + 3;
|
|
199
|
+
const ly = p.y + 3;
|
|
200
|
+
lines.push(` <g class="node">`, ` <title>${escapeXml(n.label)}: ${n.rating}/10, ` +
|
|
201
|
+
`${n.metrics?.linesOfCode ?? '?'} LOC, in-degree ${inDeg.get(n.id) ?? 0}</title>`, ` <circle cx="${p.x.toFixed(1)}" cy="${p.y.toFixed(1)}" r="${r.toFixed(1)}" ` +
|
|
202
|
+
`fill="${color}" stroke="white" stroke-width="1.5"/>`, ` <text x="${lx.toFixed(1)}" y="${ly.toFixed(1)}">${escapeXml(n.label)}</text>`, ` </g>`);
|
|
203
|
+
}
|
|
204
|
+
// Legend
|
|
205
|
+
const legend = [
|
|
206
|
+
{ color: '#4caf50', label: '≥8 Excellent' },
|
|
207
|
+
{ color: '#ffc107', label: '6–7.9 Good' },
|
|
208
|
+
{ color: '#ff9800', label: '4–5.9 Poor' },
|
|
209
|
+
{ color: '#f44336', label: '<4 Critical' },
|
|
210
|
+
];
|
|
211
|
+
lines.push(`</g>`, `<g class="legend" transform="translate(12,${H - 80})">`);
|
|
212
|
+
legend.forEach(({ color, label }, i) => {
|
|
213
|
+
const y = i * 18;
|
|
214
|
+
lines.push(` <circle cx="7" cy="${y}" r="6" fill="${color}"/>`, ` <text x="16" y="${y + 4}">${label}</text>`);
|
|
215
|
+
});
|
|
216
|
+
lines.push(`</g>`, `<text x="${W - 10}" y="${H - 6}" font-size="8" fill="#aaa" text-anchor="end">` +
|
|
217
|
+
`Gate Keeper — ${nodes.length} files, ${edges.length} edges</text>`, `</svg>`);
|
|
218
|
+
return lines.join('\n');
|
|
219
|
+
}
|
|
220
|
+
function mergeGraphs(graphA, graphB) {
|
|
221
|
+
const nodeMap = new Map();
|
|
222
|
+
const conflicts = [];
|
|
223
|
+
for (const n of graphA.nodes)
|
|
224
|
+
nodeMap.set(n.id, n);
|
|
225
|
+
for (const n of graphB.nodes) {
|
|
226
|
+
const existing = nodeMap.get(n.id);
|
|
227
|
+
if (existing && existing.rating !== n.rating) {
|
|
228
|
+
// Conflict: take the minimum rating (conservative / most honest)
|
|
229
|
+
const resolved = Math.min(existing.rating, n.rating);
|
|
230
|
+
conflicts.push({ id: n.id, ratingA: existing.rating, ratingB: n.rating, resolved });
|
|
231
|
+
nodeMap.set(n.id, { ...n, rating: resolved });
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
nodeMap.set(n.id, n);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// Union edges, deduplicating by source+target
|
|
238
|
+
const edgeSet = new Set();
|
|
239
|
+
const edges = [];
|
|
240
|
+
for (const e of [...graphA.edges, ...graphB.edges]) {
|
|
241
|
+
const key = `${e.source}→${e.target}`;
|
|
242
|
+
if (!edgeSet.has(key)) {
|
|
243
|
+
edgeSet.add(key);
|
|
244
|
+
edges.push(e);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return { nodes: [...nodeMap.values()], edges, conflicts };
|
|
248
|
+
}
|
|
249
|
+
// ── Dispatch ───────────────────────────────────────────────
|
|
250
|
+
function exportGraph(nodes, edges, cycles, opts) {
|
|
251
|
+
switch (opts.format) {
|
|
252
|
+
case 'json': return exportToJson(nodes, edges, cycles, opts);
|
|
253
|
+
case 'graphml': return exportToGraphML(nodes, edges);
|
|
254
|
+
case 'neo4j': return exportToNeo4j(nodes, edges);
|
|
255
|
+
case 'svg': return exportToSvg(nodes, edges);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function escapeXml(s) {
|
|
259
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
260
|
+
}
|
|
261
|
+
function cyStr(s) {
|
|
262
|
+
return `'${s.replace(/'/g, "\\'")}'`;
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=graph-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-export.js","sourceRoot":"","sources":["../../src/graph/graph-export.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AA2BH,oCAoDC;AAID,0CAqCC;AAID,sCAmCC;AASD,kCAiHC;AAUD,kCAiCC;AAID,kCAYC;AAlVD,yDAAuD;AACvD,qEAAqE;AACrE,6DAAwD;AAqBxD,8DAA8D;AAE9D,SAAgB,YAAY,CAC1B,KAA2B,EAC3B,KAA2B,EAC3B,MAAgC,EAChC,IAAmB;IAEnB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;IACrC,MAAM,UAAU,GAAG,IAAA,oCAAiB,EAAC,KAAgB,EAAE,KAAgB,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACjD,EAAE,EAAE,CAAC,CAAC,IAAI;QACV,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;KACjB,CAAC,CAAC,CAAC;IAEJ,MAAM,UAAU,GAAG,QAAQ;QACzB,CAAC,CAAC,IAAA,kDAAyB,EAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC;QACvD,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,SAAS,GAAG,QAAQ;QACxB,CAAC,CAAC,IAAA,qCAAgB,EAAC,KAAgB,EAAE,KAAgB,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnE,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,KAAK,GAAG;QACZ,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;QACvB,IAAI,EAAE,QAAQ;QACd,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI;QACzC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE;YACxB,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;SACpF,CAAC,CAAC;QACH,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC,WAAW,EAAE;YACxC,UAAU,EAAE,WAAW;YACvB,MAAM,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC;SACxB,CAAC,CAAC;QACH,QAAQ;QACR,qBAAqB,EAAE,UAAU;QACjC,kBAAkB,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAClD,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;KACjC,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,8DAA8D;AAE9D,SAAgB,eAAe,CAC7B,KAA2B,EAC3B,KAA2B;IAE3B,MAAM,KAAK,GAAa;QACtB,wCAAwC;QACxC,2DAA2D;QAC3D,uEAAuE;QACvE,8EAA8E;QAC9E,qEAAqE;QACrE,uEAAuE;QACvE,uEAAuE;QACvE,yCAAyC;KAC1C,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,IAAI,CAAC,CAAC;QACxC,KAAK,CAAC,IAAI,CAAC,2BAA2B,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACnE,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC;QAC1D,IAAI,CAAC,CAAC,OAAO,EAAE,WAAW,KAAK,SAAS,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,OAAO,CAAC,WAAW,SAAS,CAAC,CAAC;QAC9E,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,aAAa,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpG,KAAK,CAAC,IAAI,CAAC,8BAA8B,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC;QACjF,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,QAAQ,IAAI,CAAC,SAAS,CAAC,CAAC;QACjE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,8DAA8D;AAE9D,SAAgB,aAAa,CAC3B,KAA2B,EAC3B,KAA2B;IAE3B,MAAM,KAAK,GAAa;QACtB,6CAA6C;QAC7C,qCAAqC;QACrC,EAAE;QACF,+BAA+B;QAC/B,oCAAoC;QACpC,EAAE;QACF,UAAU;KACX,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG;YACZ,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;YACpB,UAAU,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;YAC1B,WAAW,CAAC,CAAC,MAAM,EAAE;SACtB,CAAC;QACF,IAAI,CAAC,CAAC,OAAO,EAAE,WAAW,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9F,IAAI,CAAC,CAAC,OAAO,EAAE,oBAAoB,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;QAC/G,KAAK,CAAC,IAAI,CAAC,kBAAkB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QACvE,KAAK,CAAC,IAAI,CACR,sBAAsB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,oBAAoB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK;YAC7E,gBAAgB,OAAO,aAAa,CAAC,CAAC,QAAQ,IAAI,CAAC,UAAU,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,8DAA8D;AAE9D;;;;GAIG;AACH,SAAgB,WAAW,CACzB,KAA2B,EAC3B,KAA2B,EAC3B,OAA4C,EAAE;IAE9C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC;IAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC;IAC7B,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IACtC,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,MAAM,GAAG,EAAE,CAAC;IAElB,oCAAoC;IACpC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAiB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7C,qBAAqB;IACrB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoC,CAAC;IACxD,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QAC1E,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,CAAC,CAAS,EAAE,EAAE,CAChC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IAE3E,MAAM,UAAU,GAAG,CAAC,EAAU,EAAU,EAAE;QACxC,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAC7B,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC;IAEF,MAAM,KAAK,GAAa;QACtB,kDAAkD,CAAC,aAAa,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI;QAC7F,QAAQ;QACR,4DAA4D;QAC5D,mEAAmE;QACnE,mDAAmD;QACnD,aAAa;QACb,SAAS;QACT,SAAS;QACT,uFAAuF;QACvF,iFAAiF;QACjF,8BAA8B;QAC9B,2CAA2C;QAC3C,UAAU;QACV,gBAAgB,CAAC,aAAa,CAAC,oBAAoB;QACnD,mBAAmB;KACpB,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;YAAE,SAAS;QAChD,kDAAkD;QAClD,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/B,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/B,KAAK,CAAC,IAAI,CACR,4BAA4B,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YACrE,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAChD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAExC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3B,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACnB,KAAK,CAAC,IAAI,CACR,oBAAoB,EACpB,cAAc,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,OAAO;YACpD,GAAG,CAAC,CAAC,OAAO,EAAE,WAAW,IAAI,GAAG,mBAAmB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,EACjF,mBAAmB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YAChF,SAAS,KAAK,uCAAuC,EACrD,gBAAgB,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAClF,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,SAAS;IACT,MAAM,MAAM,GAAG;QACb,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE;QAC3C,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE;QACzC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE;QACzC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE;KAC3C,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,6CAA6C,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7E,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACrC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CACR,wBAAwB,CAAC,iBAAiB,KAAK,KAAK,EACpD,qBAAqB,CAAC,GAAG,CAAC,KAAK,KAAK,SAAS,CAC9C,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CACR,MAAM,EACN,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,gDAAgD;QAC/E,iBAAiB,KAAK,CAAC,MAAM,WAAW,KAAK,CAAC,MAAM,eAAe,EACnE,QAAQ,CACT,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAUD,SAAgB,WAAW,CACzB,MAA0C,EAC1C,MAA0C;IAE1C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAiB,CAAC;IACzC,MAAM,SAAS,GAA6B,EAAE,CAAC;IAE/C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK;QAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAEnD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;YAC7C,iEAAiE;YACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;YACrD,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YACpF,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,KAAK,GAAY,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACtC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC5D,CAAC;AAED,8DAA8D;AAE9D,SAAgB,WAAW,CACzB,KAA2B,EAC3B,KAA2B,EAC3B,MAAgC,EAChC,IAAmB;IAEnB,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;QACpB,KAAK,MAAM,CAAC,CAAC,OAAO,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC7D,KAAK,SAAS,CAAC,CAAC,OAAO,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACrD,KAAK,OAAO,CAAC,CAAC,OAAO,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACjD,KAAK,KAAK,CAAC,CAAC,OAAO,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACtG,CAAC;AAED,SAAS,KAAK,CAAC,CAAS;IACtB,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Narrative knowledge-graph report generator (graphify-style GRAPH_REPORT.md).
|
|
3
|
+
*
|
|
4
|
+
* Produces a Markdown document with:
|
|
5
|
+
* - God nodes (highest centrality)
|
|
6
|
+
* - Surprising cross-module connections
|
|
7
|
+
* - Auto-generated suggested questions
|
|
8
|
+
* - Architecture overview (module breakdown + cycles)
|
|
9
|
+
*
|
|
10
|
+
* Pure function — no I/O, no daemon dependency.
|
|
11
|
+
*/
|
|
12
|
+
interface GNode {
|
|
13
|
+
id: string;
|
|
14
|
+
label: string;
|
|
15
|
+
rating: number;
|
|
16
|
+
metrics?: {
|
|
17
|
+
linesOfCode?: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
interface GEdge {
|
|
21
|
+
source: string;
|
|
22
|
+
target: string;
|
|
23
|
+
}
|
|
24
|
+
interface CycleInfo {
|
|
25
|
+
nodes: string[];
|
|
26
|
+
}
|
|
27
|
+
export interface GraphReportOptions {
|
|
28
|
+
topGodNodes?: number;
|
|
29
|
+
topSurprising?: number;
|
|
30
|
+
maxQuestions?: number;
|
|
31
|
+
}
|
|
32
|
+
export declare function generateGraphReport(nodes: ReadonlyArray<GNode>, edges: ReadonlyArray<GEdge>, cycles: ReadonlyArray<CycleInfo>, repoRoot: string, overallRating: number | null, opts?: GraphReportOptions): string;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=graph-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-report.d.ts","sourceRoot":"","sources":["../../src/graph/graph-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,UAAU,KAAK;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE;AACjG,UAAU,KAAK;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAClD,UAAU,SAAS;IAAG,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE;AAEvC,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,EAC3B,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,EAC3B,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,EAChC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,IAAI,GAAE,kBAAuB,GAC5B,MAAM,CAqGR"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Narrative knowledge-graph report generator (graphify-style GRAPH_REPORT.md).
|
|
4
|
+
*
|
|
5
|
+
* Produces a Markdown document with:
|
|
6
|
+
* - God nodes (highest centrality)
|
|
7
|
+
* - Surprising cross-module connections
|
|
8
|
+
* - Auto-generated suggested questions
|
|
9
|
+
* - Architecture overview (module breakdown + cycles)
|
|
10
|
+
*
|
|
11
|
+
* Pure function — no I/O, no daemon dependency.
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.generateGraphReport = generateGraphReport;
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const graph_algorithms_1 = require("./graph-algorithms");
|
|
50
|
+
const surprising_connections_1 = require("./surprising-connections");
|
|
51
|
+
const question_suggester_1 = require("./question-suggester");
|
|
52
|
+
function generateGraphReport(nodes, edges, cycles, repoRoot, overallRating, opts = {}) {
|
|
53
|
+
const { topGodNodes = 5, topSurprising = 5, maxQuestions = 5 } = opts;
|
|
54
|
+
const repoName = path.basename(repoRoot);
|
|
55
|
+
const centrality = (0, graph_algorithms_1.computeCentrality)(nodes, edges);
|
|
56
|
+
const godNodes = centrality.slice(0, topGodNodes);
|
|
57
|
+
const surprising = (0, surprising_connections_1.findSurprisingConnections)(nodes, edges, repoRoot, topSurprising);
|
|
58
|
+
const questions = (0, question_suggester_1.suggestQuestions)(nodes, edges, repoRoot, maxQuestions);
|
|
59
|
+
const lines = [];
|
|
60
|
+
lines.push(`# Knowledge Graph: ${repoName}`);
|
|
61
|
+
lines.push('');
|
|
62
|
+
lines.push(`**Files:** ${nodes.length} | **Relationships:** ${edges.length} | ` +
|
|
63
|
+
`**Overall Quality:** ${overallRating?.toFixed(1) ?? 'N/A'}/10 | ` +
|
|
64
|
+
`**Cycles:** ${cycles.length}`);
|
|
65
|
+
lines.push('');
|
|
66
|
+
// God Nodes
|
|
67
|
+
if (godNodes.length > 0) {
|
|
68
|
+
lines.push('## God Nodes (Highest Blast Radius)');
|
|
69
|
+
lines.push('_These files are most dangerous to change — many others depend on them._');
|
|
70
|
+
lines.push('');
|
|
71
|
+
for (let i = 0; i < godNodes.length; i++) {
|
|
72
|
+
const n = godNodes[i];
|
|
73
|
+
const rel = path.relative(repoRoot, n.path);
|
|
74
|
+
const riskIcon = n.rating < 6 ? '🔴' : n.rating < 8 ? '🟡' : '🟢';
|
|
75
|
+
lines.push(`${i + 1}. ${riskIcon} **${rel}** — ${n.totalDegree} connections ` +
|
|
76
|
+
`(in: ${n.inDegree}, out: ${n.outDegree}), rating ${n.rating}/10`);
|
|
77
|
+
}
|
|
78
|
+
lines.push('');
|
|
79
|
+
}
|
|
80
|
+
// Surprising Connections
|
|
81
|
+
if (surprising.length > 0) {
|
|
82
|
+
lines.push('## Surprising Connections');
|
|
83
|
+
lines.push('_Cross-module dependencies that may indicate unexpected coupling._');
|
|
84
|
+
lines.push('');
|
|
85
|
+
for (const s of surprising) {
|
|
86
|
+
const src = path.relative(repoRoot, s.source);
|
|
87
|
+
const tgt = path.relative(repoRoot, s.target);
|
|
88
|
+
lines.push(`- **${src}** → **${tgt}**`);
|
|
89
|
+
lines.push(` _${s.explanation}_`);
|
|
90
|
+
}
|
|
91
|
+
lines.push('');
|
|
92
|
+
}
|
|
93
|
+
// Suggested Questions
|
|
94
|
+
if (questions.length > 0) {
|
|
95
|
+
lines.push('## Suggested Questions');
|
|
96
|
+
lines.push('_Questions the graph is positioned to answer with a single MCP call._');
|
|
97
|
+
lines.push('');
|
|
98
|
+
questions.forEach((q, i) => {
|
|
99
|
+
lines.push(`${i + 1}. ${q.question}`);
|
|
100
|
+
lines.push(` → \`${q.tool}\` with \`${JSON.stringify(q.params)}\``);
|
|
101
|
+
});
|
|
102
|
+
lines.push('');
|
|
103
|
+
}
|
|
104
|
+
// Architecture Overview
|
|
105
|
+
lines.push('## Architecture Overview');
|
|
106
|
+
const moduleCounts = new Map();
|
|
107
|
+
const moduleRatings = new Map();
|
|
108
|
+
for (const n of nodes) {
|
|
109
|
+
const mod = (0, surprising_connections_1.getModule)(n.id, repoRoot);
|
|
110
|
+
moduleCounts.set(mod, (moduleCounts.get(mod) ?? 0) + 1);
|
|
111
|
+
(moduleRatings.get(mod) ?? moduleRatings.set(mod, []).get(mod)).push(n.rating);
|
|
112
|
+
}
|
|
113
|
+
const moduleList = [...moduleCounts.entries()]
|
|
114
|
+
.sort((a, b) => b[1] - a[1])
|
|
115
|
+
.slice(0, 8);
|
|
116
|
+
lines.push('');
|
|
117
|
+
lines.push('| Module | Files | Avg Rating |');
|
|
118
|
+
lines.push('|--------|-------|------------|');
|
|
119
|
+
for (const [mod, count] of moduleList) {
|
|
120
|
+
const ratings = moduleRatings.get(mod) ?? [];
|
|
121
|
+
const avg = ratings.length > 0
|
|
122
|
+
? (ratings.reduce((s, r) => s + r, 0) / ratings.length).toFixed(1)
|
|
123
|
+
: 'N/A';
|
|
124
|
+
lines.push(`| ${mod} | ${count} | ${avg}/10 |`);
|
|
125
|
+
}
|
|
126
|
+
if (cycles.length > 0) {
|
|
127
|
+
lines.push('');
|
|
128
|
+
lines.push(`⚠️ **${cycles.length} circular dependency cycle${cycles.length !== 1 ? 's' : ''} detected** ` +
|
|
129
|
+
`— each costs −1.0 rating. Run \`get_graph_summary\` to see the full list.`);
|
|
130
|
+
}
|
|
131
|
+
lines.push('');
|
|
132
|
+
lines.push('---');
|
|
133
|
+
lines.push(`_Generated by Gate Keeper at ${new Date().toISOString()}_`);
|
|
134
|
+
return lines.join('\n');
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=graph-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-report.js","sourceRoot":"","sources":["../../src/graph/graph-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-computed analytics for the dependency graph response.
|
|
3
|
+
*
|
|
4
|
+
* Surfaces the signals AI agents otherwise have to derive with custom code:
|
|
5
|
+
* rating distribution, top fan-in / fan-out hotspots, worst-rated files, and
|
|
6
|
+
* cross-module coupling. All functions are pure and operate on the raw
|
|
7
|
+
* GraphResponse shape from the daemon.
|
|
8
|
+
*/
|
|
9
|
+
export interface GraphNodeInput {
|
|
10
|
+
id: string;
|
|
11
|
+
rating: number;
|
|
12
|
+
label?: string;
|
|
13
|
+
metrics: {
|
|
14
|
+
linesOfCode: number;
|
|
15
|
+
};
|
|
16
|
+
violations: ReadonlyArray<unknown>;
|
|
17
|
+
}
|
|
18
|
+
export interface GraphEdgeInput {
|
|
19
|
+
source: string;
|
|
20
|
+
target: string;
|
|
21
|
+
type: string;
|
|
22
|
+
}
|
|
23
|
+
export interface CycleInput {
|
|
24
|
+
nodes: string[];
|
|
25
|
+
}
|
|
26
|
+
export interface HotspotEntry {
|
|
27
|
+
path: string;
|
|
28
|
+
inDegree: number;
|
|
29
|
+
outDegree: number;
|
|
30
|
+
rating: number;
|
|
31
|
+
loc: number;
|
|
32
|
+
/** High fan-in + below-threshold rating = hub that's risky to change */
|
|
33
|
+
fragileHub?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface WorstFileEntry {
|
|
36
|
+
path: string;
|
|
37
|
+
rating: number;
|
|
38
|
+
loc: number;
|
|
39
|
+
violations: number;
|
|
40
|
+
}
|
|
41
|
+
export interface ModuleCouplingEntry {
|
|
42
|
+
from: string;
|
|
43
|
+
to: string;
|
|
44
|
+
count: number;
|
|
45
|
+
}
|
|
46
|
+
export interface RatingDistribution {
|
|
47
|
+
excellent: number;
|
|
48
|
+
good: number;
|
|
49
|
+
warning: number;
|
|
50
|
+
critical: number;
|
|
51
|
+
}
|
|
52
|
+
export interface GraphSummary {
|
|
53
|
+
fileCount: number;
|
|
54
|
+
edgeCount: number;
|
|
55
|
+
cycleCount: number;
|
|
56
|
+
avgRating: number;
|
|
57
|
+
ratingDistribution: RatingDistribution;
|
|
58
|
+
mostDependedOn: HotspotEntry[];
|
|
59
|
+
mostDependencies: HotspotEntry[];
|
|
60
|
+
worstFiles: WorstFileEntry[];
|
|
61
|
+
moduleCoupling: ModuleCouplingEntry[];
|
|
62
|
+
}
|
|
63
|
+
/** Derive a stable module label from a file path, handling sub-projects. */
|
|
64
|
+
export declare function moduleOf(filePath: string, repo: string): string;
|
|
65
|
+
export declare function buildGraphSummary(nodes: ReadonlyArray<GraphNodeInput>, edges: ReadonlyArray<GraphEdgeInput>, cycles: ReadonlyArray<CycleInput>, repo: string): GraphSummary;
|
|
66
|
+
/** Format the summary as compact markdown for the human-readable channel. */
|
|
67
|
+
export declare function formatGraphSummaryMarkdown(summary: GraphSummary, repo: string): string;
|
|
68
|
+
//# sourceMappingURL=graph-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-summary.d.ts","sourceRoot":"","sources":["../../src/graph/graph-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,UAAU,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B,gBAAgB,EAAE,YAAY,EAAE,CAAC;IACjC,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,cAAc,EAAE,mBAAmB,EAAE,CAAC;CACvC;AAOD,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAO/D;AAuFD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,aAAa,CAAC,cAAc,CAAC,EACpC,KAAK,EAAE,aAAa,CAAC,cAAc,CAAC,EACpC,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,EACjC,IAAI,EAAE,MAAM,GACX,YAAY,CAmBd;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CA6DtF"}
|