mapra 0.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.
Files changed (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +144 -0
  3. package/dist/analyzer/blast-radius.d.ts +27 -0
  4. package/dist/analyzer/blast-radius.d.ts.map +1 -0
  5. package/dist/analyzer/blast-radius.js +58 -0
  6. package/dist/analyzer/blast-radius.js.map +1 -0
  7. package/dist/analyzer/churn.d.ts +26 -0
  8. package/dist/analyzer/churn.d.ts.map +1 -0
  9. package/dist/analyzer/churn.js +96 -0
  10. package/dist/analyzer/churn.js.map +1 -0
  11. package/dist/analyzer/co-change.d.ts +60 -0
  12. package/dist/analyzer/co-change.d.ts.map +1 -0
  13. package/dist/analyzer/co-change.js +153 -0
  14. package/dist/analyzer/co-change.js.map +1 -0
  15. package/dist/analyzer/conventions.d.ts +22 -0
  16. package/dist/analyzer/conventions.d.ts.map +1 -0
  17. package/dist/analyzer/conventions.js +81 -0
  18. package/dist/analyzer/conventions.js.map +1 -0
  19. package/dist/analyzer/git-hash.d.ts +11 -0
  20. package/dist/analyzer/git-hash.d.ts.map +1 -0
  21. package/dist/analyzer/git-hash.js +25 -0
  22. package/dist/analyzer/git-hash.js.map +1 -0
  23. package/dist/analyzer/graph-utils.d.ts +46 -0
  24. package/dist/analyzer/graph-utils.d.ts.map +1 -0
  25. package/dist/analyzer/graph-utils.js +145 -0
  26. package/dist/analyzer/graph-utils.js.map +1 -0
  27. package/dist/analyzer/index.d.ts +34 -0
  28. package/dist/analyzer/index.d.ts.map +1 -0
  29. package/dist/analyzer/index.js +63 -0
  30. package/dist/analyzer/index.js.map +1 -0
  31. package/dist/cli/hooks.d.ts +24 -0
  32. package/dist/cli/hooks.d.ts.map +1 -0
  33. package/dist/cli/hooks.js +126 -0
  34. package/dist/cli/hooks.js.map +1 -0
  35. package/dist/cli/index.d.ts +18 -0
  36. package/dist/cli/index.d.ts.map +1 -0
  37. package/dist/cli/index.js +818 -0
  38. package/dist/cli/index.js.map +1 -0
  39. package/dist/cli/plan-parser.d.ts +20 -0
  40. package/dist/cli/plan-parser.d.ts.map +1 -0
  41. package/dist/cli/plan-parser.js +104 -0
  42. package/dist/cli/plan-parser.js.map +1 -0
  43. package/dist/cli/shim.d.ts +3 -0
  44. package/dist/cli/shim.d.ts.map +1 -0
  45. package/dist/cli/shim.js +33 -0
  46. package/dist/cli/shim.js.map +1 -0
  47. package/dist/cli/templates.d.ts +28 -0
  48. package/dist/cli/templates.d.ts.map +1 -0
  49. package/dist/cli/templates.js +91 -0
  50. package/dist/cli/templates.js.map +1 -0
  51. package/dist/encoder/encode.d.ts +17 -0
  52. package/dist/encoder/encode.d.ts.map +1 -0
  53. package/dist/encoder/encode.js +270 -0
  54. package/dist/encoder/encode.js.map +1 -0
  55. package/dist/encoder/layer-infrastructure.d.ts +17 -0
  56. package/dist/encoder/layer-infrastructure.d.ts.map +1 -0
  57. package/dist/encoder/layer-infrastructure.js +232 -0
  58. package/dist/encoder/layer-infrastructure.js.map +1 -0
  59. package/dist/encoder/layer-labels.d.ts +18 -0
  60. package/dist/encoder/layer-labels.d.ts.map +1 -0
  61. package/dist/encoder/layer-labels.js +172 -0
  62. package/dist/encoder/layer-labels.js.map +1 -0
  63. package/dist/encoder/layer-terrain.d.ts +18 -0
  64. package/dist/encoder/layer-terrain.d.ts.map +1 -0
  65. package/dist/encoder/layer-terrain.js +135 -0
  66. package/dist/encoder/layer-terrain.js.map +1 -0
  67. package/dist/encoder/layout.d.ts +53 -0
  68. package/dist/encoder/layout.d.ts.map +1 -0
  69. package/dist/encoder/layout.js +178 -0
  70. package/dist/encoder/layout.js.map +1 -0
  71. package/dist/encoder/parse-strand-header.d.ts +29 -0
  72. package/dist/encoder/parse-strand-header.d.ts.map +1 -0
  73. package/dist/encoder/parse-strand-header.js +59 -0
  74. package/dist/encoder/parse-strand-header.js.map +1 -0
  75. package/dist/encoder/spatial-text-encode.d.ts +22 -0
  76. package/dist/encoder/spatial-text-encode.d.ts.map +1 -0
  77. package/dist/encoder/spatial-text-encode.js +199 -0
  78. package/dist/encoder/spatial-text-encode.js.map +1 -0
  79. package/dist/encoder/strand-format-encode-v1.d.ts +16 -0
  80. package/dist/encoder/strand-format-encode-v1.d.ts.map +1 -0
  81. package/dist/encoder/strand-format-encode-v1.js +296 -0
  82. package/dist/encoder/strand-format-encode-v1.js.map +1 -0
  83. package/dist/encoder/strand-format-encode.d.ts +21 -0
  84. package/dist/encoder/strand-format-encode.d.ts.map +1 -0
  85. package/dist/encoder/strand-format-encode.js +562 -0
  86. package/dist/encoder/strand-format-encode.js.map +1 -0
  87. package/dist/encoder/text-encode.d.ts +13 -0
  88. package/dist/encoder/text-encode.d.ts.map +1 -0
  89. package/dist/encoder/text-encode.js +123 -0
  90. package/dist/encoder/text-encode.js.map +1 -0
  91. package/dist/query/blast-radius.d.ts +14 -0
  92. package/dist/query/blast-radius.d.ts.map +1 -0
  93. package/dist/query/blast-radius.js +81 -0
  94. package/dist/query/blast-radius.js.map +1 -0
  95. package/dist/query/cache.d.ts +29 -0
  96. package/dist/query/cache.d.ts.map +1 -0
  97. package/dist/query/cache.js +138 -0
  98. package/dist/query/cache.js.map +1 -0
  99. package/dist/query/index.d.ts +2 -0
  100. package/dist/query/index.d.ts.map +1 -0
  101. package/dist/query/index.js +46 -0
  102. package/dist/query/index.js.map +1 -0
  103. package/dist/query/resolve.d.ts +7 -0
  104. package/dist/query/resolve.d.ts.map +1 -0
  105. package/dist/query/resolve.js +24 -0
  106. package/dist/query/resolve.js.map +1 -0
  107. package/dist/query/risk-profile.d.ts +30 -0
  108. package/dist/query/risk-profile.d.ts.map +1 -0
  109. package/dist/query/risk-profile.js +94 -0
  110. package/dist/query/risk-profile.js.map +1 -0
  111. package/dist/query/test-map.d.ts +13 -0
  112. package/dist/query/test-map.d.ts.map +1 -0
  113. package/dist/query/test-map.js +43 -0
  114. package/dist/query/test-map.js.map +1 -0
  115. package/dist/scanner/index.d.ts +51 -0
  116. package/dist/scanner/index.d.ts.map +1 -0
  117. package/dist/scanner/index.js +480 -0
  118. package/dist/scanner/index.js.map +1 -0
  119. package/dist/scanner/workspace.d.ts +11 -0
  120. package/dist/scanner/workspace.d.ts.map +1 -0
  121. package/dist/scanner/workspace.js +243 -0
  122. package/dist/scanner/workspace.js.map +1 -0
  123. package/package.json +52 -0
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Layer 3 — Labels (Precise Detail)
3
+ *
4
+ * Encodes: File names, function signatures, HTTP methods, model names.
5
+ * - Each node labeled with file name and key exports
6
+ * - API routes with HTTP methods (GET, POST, etc.)
7
+ * - Prisma models with field counts
8
+ * - Test coverage indicators
9
+ * - High-resolution, text-focused, minimal visual noise
10
+ *
11
+ * What the LLM learns: The precise details that Layer 1 and 2 can't show.
12
+ * File paths, function names, exact counts.
13
+ */
14
+ import { computeLayout, escapeXml, TYPE_COLORS, } from "./layout.js";
15
+ export function encodeLabelsSVG(graph) {
16
+ const layout = computeLayout(graph);
17
+ return renderLabels(layout, graph);
18
+ }
19
+ export function encodeLabelsSVGFromLayout(layout, graph) {
20
+ return renderLabels(layout, graph);
21
+ }
22
+ function renderLabels(layout, graph) {
23
+ const { width, height, modules } = layout;
24
+ let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" width="${width}" height="${height}">
25
+ <style>
26
+ text { font-family: monospace; }
27
+ .layer-title { font-size: 14px; font-weight: bold; fill: #111; }
28
+ .layer-subtitle { font-size: 10px; fill: #666; }
29
+ .module-header { font-size: 11px; font-weight: bold; fill: #111; }
30
+ .module-stats { font-size: 8px; fill: #888; }
31
+ .file-label { font-size: 7px; fill: #333; }
32
+ .export-label { font-size: 6px; fill: #666; }
33
+ .method-badge { font-size: 6px; font-weight: bold; }
34
+ .type-indicator { font-size: 6px; fill: #999; }
35
+ </style>
36
+ <rect width="100%" height="100%" fill="#F8F9FA"/>
37
+ `;
38
+ // Title
39
+ svg += `<text x="60" y="30" class="layer-title">L3: Labels — ${escapeXml(graph.projectName)}</text>\n`;
40
+ svg += `<text x="60" y="45" class="layer-subtitle">${graph.totalFiles} files · ${graph.totalLines.toLocaleString()} lines · ${graph.modules.length} modules</text>\n`;
41
+ // Compute test coverage map for indicators
42
+ const testedFiles = new Set();
43
+ for (const edge of graph.edges) {
44
+ if (edge.type === "tests") {
45
+ testedFiles.add(edge.to);
46
+ }
47
+ }
48
+ // Draw each module with detailed labels
49
+ for (const mod of modules) {
50
+ svg += drawModuleLabels(mod, testedFiles);
51
+ }
52
+ // Legend — type abbreviations
53
+ svg += drawLabelsLegend(width - 180, 10);
54
+ svg += `</svg>`;
55
+ return svg;
56
+ }
57
+ function drawModuleLabels(mod, testedFiles) {
58
+ let svg = "";
59
+ // Module boundary — light dashed outline
60
+ svg += `<rect x="${mod.x}" y="${mod.y}" width="${mod.width}" height="${mod.height}" rx="8" fill="white" stroke="#DEE2E6" stroke-width="1" opacity="0.5"/>\n`;
61
+ // Module header with stats
62
+ svg += `<text x="${mod.x + 8}" y="${mod.y + 14}" class="module-header">${escapeXml(mod.name)}/</text>\n`;
63
+ svg += `<text x="${mod.x + 8}" y="${mod.y + 24}" class="module-stats">${mod.nodes.length} files · ${mod.totalLines} lines</text>\n`;
64
+ // Label each node
65
+ for (const node of mod.nodes) {
66
+ svg += drawNodeLabel(node, testedFiles);
67
+ }
68
+ return svg;
69
+ }
70
+ /**
71
+ * Draw a label at each node position with:
72
+ * - Tiny type-colored dot (for spatial reference)
73
+ * - File name (without extension)
74
+ * - Key exports or metadata (HTTP methods, models)
75
+ * - Test coverage indicator
76
+ */
77
+ function drawNodeLabel(node, testedFiles) {
78
+ let svg = "";
79
+ // Tiny dot for spatial reference (matches node position from other layers)
80
+ svg += `<circle cx="${node.x.toFixed(1)}" cy="${node.y.toFixed(1)}" r="2" fill="${node.color}" opacity="0.5"/>\n`;
81
+ const shortName = node.name.replace(/\.(ts|tsx|js|jsx|prisma)$/, "");
82
+ const isTested = testedFiles.has(node.id);
83
+ // Build label parts
84
+ const parts = [];
85
+ // Type prefix
86
+ const typePrefix = getTypePrefix(node.type);
87
+ // For API routes: show HTTP methods
88
+ if (node.type === "api-route") {
89
+ const methods = node.framework?.metadata?.methods ?? [];
90
+ const routePath = node.framework?.metadata?.routePath ?? "";
91
+ parts.push(`${methods.join(",")} ${routePath}`);
92
+ }
93
+ else if (node.type === "route") {
94
+ const routePath = node.framework?.metadata?.routePath ?? "";
95
+ const isClient = node.framework?.metadata?.isClientComponent;
96
+ parts.push(routePath || shortName);
97
+ if (isClient)
98
+ parts.push("[client]");
99
+ }
100
+ else if (node.type === "schema") {
101
+ const models = node.framework?.metadata?.models ?? [];
102
+ if (models.length > 0) {
103
+ parts.push(`${models.length} models: ${models.slice(0, 4).join(", ")}`);
104
+ if (models.length > 4)
105
+ parts.push(`+${models.length - 4}`);
106
+ }
107
+ }
108
+ else {
109
+ parts.push(shortName);
110
+ }
111
+ // Main label
112
+ const mainLabel = `${typePrefix} ${parts.join(" ")}`;
113
+ const labelColor = node.type === "api-route" ? "#E63946" : "#333";
114
+ svg += `<text x="${(node.x + 5).toFixed(1)}" y="${(node.y + 1).toFixed(1)}" class="file-label" fill="${labelColor}">${escapeXml(mainLabel)}</text>\n`;
115
+ // Key exports (for non-routes, show top 3 exports)
116
+ if (node.type !== "api-route" &&
117
+ node.type !== "route" &&
118
+ node.exports.length > 0) {
119
+ const exportList = node.exports.slice(0, 3).join(", ");
120
+ const suffix = node.exports.length > 3 ? ` +${node.exports.length - 3}` : "";
121
+ svg += `<text x="${(node.x + 5).toFixed(1)}" y="${(node.y + 8).toFixed(1)}" class="export-label">→ ${escapeXml(exportList + suffix)}</text>\n`;
122
+ }
123
+ // Lines count + test indicator
124
+ const meta = `${node.lines}L`;
125
+ const testMark = isTested ? " ✓" : "";
126
+ svg += `<text x="${(node.x + 5).toFixed(1)}" y="${(node.y + (node.exports.length > 0 ? 15 : 8)).toFixed(1)}" class="type-indicator">${meta}${testMark}</text>\n`;
127
+ return svg;
128
+ }
129
+ function getTypePrefix(type) {
130
+ switch (type) {
131
+ case "api-route":
132
+ return "◆";
133
+ case "route":
134
+ return "▪";
135
+ case "component":
136
+ return "●";
137
+ case "layout":
138
+ return "◻";
139
+ case "middleware":
140
+ return "◈";
141
+ case "schema":
142
+ return "⬡";
143
+ case "test":
144
+ return "▲";
145
+ case "config":
146
+ return "⚙";
147
+ default:
148
+ return "○";
149
+ }
150
+ }
151
+ function drawLabelsLegend(x, y) {
152
+ let svg = `<g transform="translate(${x},${y})">\n`;
153
+ svg += `<rect x="0" y="0" width="170" height="130" rx="4" fill="white" stroke="#DEE2E6" stroke-width="1" opacity="0.9"/>\n`;
154
+ svg += `<text x="8" y="14" font-family="monospace" font-size="9" font-weight="bold" fill="#333">Node Types</text>\n`;
155
+ const items = [
156
+ { prefix: "◆", label: "API Route", color: TYPE_COLORS["api-route"] },
157
+ { prefix: "▪", label: "Page/Route", color: TYPE_COLORS.route },
158
+ { prefix: "●", label: "Component", color: TYPE_COLORS.component },
159
+ { prefix: "⬡", label: "Schema", color: TYPE_COLORS.schema },
160
+ { prefix: "○", label: "Utility", color: TYPE_COLORS.utility },
161
+ { prefix: "▲", label: "Test", color: TYPE_COLORS.test },
162
+ ];
163
+ items.forEach((item, i) => {
164
+ const iy = 28 + i * 14;
165
+ svg += `<text x="8" y="${iy}" font-family="monospace" font-size="8" fill="${item.color}">${item.prefix}</text>\n`;
166
+ svg += `<text x="20" y="${iy}" font-family="monospace" font-size="8" fill="#555">${item.label}</text>\n`;
167
+ });
168
+ svg += `<text x="8" y="118" font-family="monospace" font-size="7" fill="#888">✓ = has test coverage</text>\n`;
169
+ svg += `</g>\n`;
170
+ return svg;
171
+ }
172
+ //# sourceMappingURL=layer-labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-labels.js","sourceRoot":"","sources":["../../src/encoder/layer-labels.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Layer 1 — Terrain (Complexity Topography)
3
+ *
4
+ * Encodes: Module boundaries and complexity as contour lines.
5
+ * - Dense contour lines = complex areas (many files, high coupling)
6
+ * - Sparse contour lines = simple modules
7
+ * - Color gradient green (simple) → yellow → red (complex)
8
+ * - Module boundaries as labeled regions
9
+ * - NO file-level text labels — pure visual signal
10
+ *
11
+ * What the LLM learns: Where the "mountains" are. Which areas are
12
+ * flat/simple vs steep/complex. At a glance.
13
+ */
14
+ import type { StrandGraph } from "../scanner/index.js";
15
+ import { type CanvasLayout } from "./layout.js";
16
+ export declare function encodeTerrainSVG(graph: StrandGraph): string;
17
+ export declare function encodeTerrainSVGFromLayout(layout: CanvasLayout, graph: StrandGraph): string;
18
+ //# sourceMappingURL=layer-terrain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-terrain.d.ts","sourceRoot":"","sources":["../../src/encoder/layer-terrain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAIL,KAAK,YAAY,EAGlB,MAAM,aAAa,CAAC;AA+BrB,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAG3D;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,WAAW,GACjB,MAAM,CAER"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Layer 1 — Terrain (Complexity Topography)
3
+ *
4
+ * Encodes: Module boundaries and complexity as contour lines.
5
+ * - Dense contour lines = complex areas (many files, high coupling)
6
+ * - Sparse contour lines = simple modules
7
+ * - Color gradient green (simple) → yellow → red (complex)
8
+ * - Module boundaries as labeled regions
9
+ * - NO file-level text labels — pure visual signal
10
+ *
11
+ * What the LLM learns: Where the "mountains" are. Which areas are
12
+ * flat/simple vs steep/complex. At a glance.
13
+ */
14
+ import { computeLayout, escapeXml, lerpColor, } from "./layout.js";
15
+ // Complexity color ramp: green → yellow → orange → red
16
+ const COMPLEXITY_COLORS = [
17
+ "#2D6A4F",
18
+ "#52B788",
19
+ "#B5E48C",
20
+ "#FED766",
21
+ "#F4845F",
22
+ "#E63946",
23
+ ];
24
+ /**
25
+ * Get a color from the complexity ramp (t: 0-1)
26
+ * 0 = deep green (simple), 1 = hot red (complex)
27
+ */
28
+ function complexityColor(t) {
29
+ const clamped = Math.max(0, Math.min(1, t));
30
+ const segmentCount = COMPLEXITY_COLORS.length - 1;
31
+ const segment = Math.min(Math.floor(clamped * segmentCount), segmentCount - 1);
32
+ const localT = clamped * segmentCount - segment;
33
+ return lerpColor(COMPLEXITY_COLORS[segment], COMPLEXITY_COLORS[segment + 1], localT);
34
+ }
35
+ export function encodeTerrainSVG(graph) {
36
+ const layout = computeLayout(graph);
37
+ return renderTerrain(layout, graph);
38
+ }
39
+ export function encodeTerrainSVGFromLayout(layout, graph) {
40
+ return renderTerrain(layout, graph);
41
+ }
42
+ function renderTerrain(layout, graph) {
43
+ const { width, height, modules } = layout;
44
+ let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" width="${width}" height="${height}">
45
+ <style>
46
+ text { font-family: monospace; }
47
+ .layer-title { font-size: 14px; font-weight: bold; fill: #111; }
48
+ .layer-subtitle { font-size: 10px; fill: #666; }
49
+ .module-label { font-size: 11px; font-weight: bold; fill: #333; opacity: 0.8; }
50
+ </style>
51
+ <rect width="100%" height="100%" fill="#F8F9FA"/>
52
+ `;
53
+ // Title
54
+ svg += `<text x="60" y="30" class="layer-title">L1: Terrain — ${escapeXml(graph.projectName)}</text>\n`;
55
+ svg += `<text x="60" y="45" class="layer-subtitle">Complexity topography · Dense contours = complex areas</text>\n`;
56
+ // Draw modules as elevation regions with contour lines
57
+ for (const mod of modules) {
58
+ svg += drawModuleTerrain(mod, graph);
59
+ }
60
+ // Draw complexity heat dots at each node position (NO labels)
61
+ for (const node of layout.allNodes) {
62
+ svg += drawComplexityDot(node);
63
+ }
64
+ // Legend — complexity ramp
65
+ svg += drawTerrainLegend(width - 180, 10);
66
+ svg += `</svg>`;
67
+ return svg;
68
+ }
69
+ /**
70
+ * Draw a module as an elevation region with contour lines.
71
+ * More complex modules get denser contour lines and warmer colors.
72
+ */
73
+ function drawModuleTerrain(mod, graph) {
74
+ let svg = "";
75
+ // Module background — colored by average complexity
76
+ const bgColor = complexityColor(mod.avgComplexity * 0.5); // muted base color
77
+ svg += `<rect x="${mod.x}" y="${mod.y}" width="${mod.width}" height="${mod.height}" rx="8" fill="${bgColor}" opacity="0.15" stroke="${bgColor}" stroke-width="1.5" stroke-opacity="0.4"/>\n`;
78
+ // Contour lines — number of rings based on complexity and node count
79
+ // More nodes + higher complexity = more contour rings (max 6)
80
+ const contourCount = Math.min(Math.max(1, Math.round(mod.avgComplexity * 5 + mod.nodes.length / 8)), 6);
81
+ const cx = mod.x + mod.width / 2;
82
+ const cy = mod.y + mod.height / 2 + 5;
83
+ const maxRx = (mod.width / 2) * 0.85;
84
+ const maxRy = (mod.height / 2) * 0.85;
85
+ for (let i = contourCount; i >= 1; i--) {
86
+ const t = i / contourCount;
87
+ const rx = maxRx * t;
88
+ const ry = maxRy * t;
89
+ const ringColor = complexityColor(mod.avgComplexity * t);
90
+ const opacity = 0.1 + (1 - t) * 0.2; // inner rings more visible
91
+ svg += `<ellipse cx="${cx}" cy="${cy}" rx="${rx}" ry="${ry}" fill="none" stroke="${ringColor}" stroke-width="1" opacity="${opacity.toFixed(2)}"/>\n`;
92
+ }
93
+ // Inner fill — a small filled ellipse at the center showing "peak" elevation
94
+ const peakRx = maxRx * 0.15;
95
+ const peakRy = maxRy * 0.15;
96
+ const peakColor = complexityColor(mod.avgComplexity);
97
+ svg += `<ellipse cx="${cx}" cy="${cy}" rx="${peakRx}" ry="${peakRy}" fill="${peakColor}" opacity="0.3"/>\n`;
98
+ // Module label — positioned at top-left of module
99
+ svg += `<text x="${mod.x + 8}" y="${mod.y + 16}" class="module-label">${escapeXml(mod.name)}</text>\n`;
100
+ return svg;
101
+ }
102
+ /**
103
+ * Draw a dot at each node's position, sized and colored by complexity.
104
+ * No labels — this is pure visual signal.
105
+ */
106
+ function drawComplexityDot(node) {
107
+ const color = complexityColor(node.complexity);
108
+ const r = 2 + node.complexity * 6; // 2px min, 8px max
109
+ return `<circle cx="${node.x.toFixed(1)}" cy="${node.y.toFixed(1)}" r="${r.toFixed(1)}" fill="${color}" opacity="0.7"/>\n`;
110
+ }
111
+ function drawTerrainLegend(x, y) {
112
+ let svg = `<g transform="translate(${x},${y})">\n`;
113
+ svg += `<rect x="0" y="0" width="170" height="90" rx="4" fill="white" stroke="#DEE2E6" stroke-width="1" opacity="0.9"/>\n`;
114
+ svg += `<text x="8" y="14" font-family="monospace" font-size="9" font-weight="bold" fill="#333">Complexity</text>\n`;
115
+ // Gradient bar
116
+ const barY = 22;
117
+ const barWidth = 154;
118
+ const barHeight = 12;
119
+ const steps = 20;
120
+ for (let i = 0; i < steps; i++) {
121
+ const t = i / (steps - 1);
122
+ const color = complexityColor(t);
123
+ const segWidth = barWidth / steps;
124
+ svg += `<rect x="${8 + i * segWidth}" y="${barY}" width="${segWidth + 0.5}" height="${barHeight}" fill="${color}"/>\n`;
125
+ }
126
+ svg += `<text x="8" y="${barY + barHeight + 12}" font-family="monospace" font-size="7" fill="#666">Simple</text>\n`;
127
+ svg += `<text x="${barWidth - 24}" y="${barY + barHeight + 12}" font-family="monospace" font-size="7" fill="#666">Complex</text>\n`;
128
+ // Contour explanation
129
+ svg += `<text x="8" y="62" font-family="monospace" font-size="7" fill="#666">Dense contours = high complexity</text>\n`;
130
+ svg += `<text x="8" y="72" font-family="monospace" font-size="7" fill="#666">Sparse contours = low complexity</text>\n`;
131
+ svg += `<text x="8" y="82" font-family="monospace" font-size="7" fill="#666">Dot size = file complexity</text>\n`;
132
+ svg += `</g>\n`;
133
+ return svg;
134
+ }
135
+ //# sourceMappingURL=layer-terrain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer-terrain.js","sourceRoot":"","sources":["../../src/encoder/layer-terrain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Shared Layout Engine — deterministic positioning for all visual layers
3
+ *
4
+ * All topographic layers (terrain, infrastructure, labels) share the same
5
+ * canvas size and node positions so the LLM can mentally overlay them.
6
+ *
7
+ * Extracted from encode.ts to ensure consistency across layers.
8
+ */
9
+ import type { StrandGraph, StrandNode } from "../scanner/index.js";
10
+ export interface Point {
11
+ x: number;
12
+ y: number;
13
+ }
14
+ export interface LayoutNode extends StrandNode {
15
+ x: number;
16
+ y: number;
17
+ radius: number;
18
+ color: string;
19
+ moduleId: string;
20
+ }
21
+ export interface LayoutModule {
22
+ id: string;
23
+ name: string;
24
+ x: number;
25
+ y: number;
26
+ width: number;
27
+ height: number;
28
+ nodes: LayoutNode[];
29
+ /** Average complexity of nodes in this module (0-1) */
30
+ avgComplexity: number;
31
+ /** Total lines in this module */
32
+ totalLines: number;
33
+ }
34
+ export interface CanvasLayout {
35
+ width: number;
36
+ height: number;
37
+ modules: LayoutModule[];
38
+ nodes: Map<string, LayoutNode>;
39
+ /** All nodes as a flat array for iteration */
40
+ allNodes: LayoutNode[];
41
+ }
42
+ export declare const TYPE_COLORS: Record<string, string>;
43
+ /**
44
+ * Compute the full layout for a StrandGraph.
45
+ * Returns canvas dimensions, module positions, and node positions.
46
+ * All layers MUST use this to ensure spatial consistency.
47
+ */
48
+ export declare function computeLayout(graph: StrandGraph): CanvasLayout;
49
+ /** XML-safe string escaping */
50
+ export declare function escapeXml(str: string): string;
51
+ /** Interpolate between two hex colors based on t (0-1) */
52
+ export declare function lerpColor(color1: string, color2: string, t: number): string;
53
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/encoder/layout.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EAEX,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,KAAK;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,uDAAuD;IACvD,aAAa,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/B,8CAA8C;IAC9C,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAGD,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAW9C,CAAC;AAOF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAyB9D;AAkID,+BAA+B;AAC/B,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM7C;AAED,0DAA0D;AAC1D,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAO3E"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Shared Layout Engine — deterministic positioning for all visual layers
3
+ *
4
+ * All topographic layers (terrain, infrastructure, labels) share the same
5
+ * canvas size and node positions so the LLM can mentally overlay them.
6
+ *
7
+ * Extracted from encode.ts to ensure consistency across layers.
8
+ */
9
+ // Color palette — same as encode.ts for consistency
10
+ export const TYPE_COLORS = {
11
+ route: "#FF6B35",
12
+ "api-route": "#E63946",
13
+ component: "#457B9D",
14
+ layout: "#A8DADC",
15
+ middleware: "#F4A261",
16
+ schema: "#2A9D8F",
17
+ test: "#6C757D",
18
+ config: "#ADB5BD",
19
+ utility: "#264653",
20
+ module: "#E9ECEF",
21
+ };
22
+ const PADDING = 60;
23
+ const MODULE_PADDING = 30;
24
+ const MIN_NODE_RADIUS = 4;
25
+ const MAX_NODE_RADIUS = 18;
26
+ /**
27
+ * Compute the full layout for a StrandGraph.
28
+ * Returns canvas dimensions, module positions, and node positions.
29
+ * All layers MUST use this to ensure spatial consistency.
30
+ */
31
+ export function computeLayout(graph) {
32
+ // Step 1: Layout modules in a grid
33
+ const layoutModules = layoutModulesInGrid(graph);
34
+ // Step 2: Position nodes within their modules
35
+ const nodeMap = positionNodesInModules(graph.nodes, layoutModules, graph.modules);
36
+ // Step 3: Calculate canvas size
37
+ const allNodes = layoutModules.flatMap((m) => m.nodes);
38
+ const maxX = Math.max(...layoutModules.map((m) => m.x + m.width)) + PADDING;
39
+ const maxY = Math.max(...layoutModules.map((m) => m.y + m.height)) + PADDING;
40
+ const canvasWidth = Math.max(maxX, 800);
41
+ const canvasHeight = Math.max(maxY, 600);
42
+ return {
43
+ width: canvasWidth,
44
+ height: canvasHeight,
45
+ modules: layoutModules,
46
+ nodes: nodeMap,
47
+ allNodes,
48
+ };
49
+ }
50
+ function layoutModulesInGrid(graph) {
51
+ const modules = graph.modules
52
+ .filter((m) => m.nodeCount > 0)
53
+ .sort((a, b) => b.totalLines - a.totalLines);
54
+ const cols = Math.ceil(Math.sqrt(modules.length));
55
+ const layoutModules = [];
56
+ let currentX = PADDING;
57
+ let currentY = 60; // below title area
58
+ let rowHeight = 0;
59
+ let col = 0;
60
+ for (const mod of modules) {
61
+ const nodesPerRow = Math.ceil(Math.sqrt(mod.nodeCount));
62
+ const estimatedWidth = Math.max(nodesPerRow * 30 + MODULE_PADDING * 2, 120);
63
+ const estimatedHeight = Math.max(Math.ceil(mod.nodeCount / nodesPerRow) * 30 + MODULE_PADDING * 2 + 20, 80);
64
+ if (col >= cols && currentX + estimatedWidth > 1200) {
65
+ currentX = PADDING;
66
+ currentY += rowHeight + 20;
67
+ rowHeight = 0;
68
+ col = 0;
69
+ }
70
+ layoutModules.push({
71
+ id: mod.id,
72
+ name: mod.name,
73
+ x: currentX,
74
+ y: currentY,
75
+ width: estimatedWidth,
76
+ height: estimatedHeight,
77
+ nodes: [],
78
+ avgComplexity: 0,
79
+ totalLines: mod.totalLines,
80
+ });
81
+ currentX += estimatedWidth + 15;
82
+ rowHeight = Math.max(rowHeight, estimatedHeight);
83
+ col++;
84
+ }
85
+ return layoutModules;
86
+ }
87
+ function positionNodesInModules(nodes, layoutModules, modules) {
88
+ const nodeMap = new Map();
89
+ const moduleMap = new Map(layoutModules.map((m) => [m.id, m]));
90
+ // Assign nodes to modules
91
+ for (const node of nodes) {
92
+ const parts = node.path.split("/");
93
+ const moduleKey = parts.length > 2 ? parts.slice(0, 2).join("/") : (parts[0] ?? "");
94
+ const layoutMod = moduleMap.get(moduleKey);
95
+ if (!layoutMod)
96
+ continue;
97
+ const radius = MIN_NODE_RADIUS +
98
+ (MAX_NODE_RADIUS - MIN_NODE_RADIUS) * Math.min(node.complexity, 1);
99
+ const layoutNode = {
100
+ ...node,
101
+ x: 0,
102
+ y: 0,
103
+ radius,
104
+ color: TYPE_COLORS[node.type] ?? TYPE_COLORS.utility,
105
+ moduleId: layoutMod.id,
106
+ };
107
+ layoutMod.nodes.push(layoutNode);
108
+ nodeMap.set(node.id, layoutNode);
109
+ }
110
+ // Position nodes within each module using spiral layout
111
+ for (const mod of layoutModules) {
112
+ const centerX = mod.x + mod.width / 2;
113
+ const centerY = mod.y + mod.height / 2 + 10;
114
+ if (mod.nodes.length === 1) {
115
+ mod.nodes[0].x = centerX;
116
+ mod.nodes[0].y = centerY;
117
+ }
118
+ else if (mod.nodes.length > 1) {
119
+ // Sort: entry points first, then by complexity
120
+ mod.nodes.sort((a, b) => {
121
+ const aEntry = modules
122
+ .find((m) => m.id === mod.id)
123
+ ?.entryPoints.includes(a.id)
124
+ ? -1
125
+ : 0;
126
+ const bEntry = modules
127
+ .find((m) => m.id === mod.id)
128
+ ?.entryPoints.includes(b.id)
129
+ ? -1
130
+ : 0;
131
+ if (aEntry !== bEntry)
132
+ return aEntry - bEntry;
133
+ return b.complexity - a.complexity;
134
+ });
135
+ // Spiral layout — golden angle for even distribution
136
+ const angleStep = (2 * Math.PI) / Math.max(mod.nodes.length, 1);
137
+ const maxR = Math.min(mod.width, mod.height) / 2 - 25;
138
+ for (let i = 0; i < mod.nodes.length; i++) {
139
+ const angle = i * angleStep * 1.618;
140
+ const r = (maxR * Math.sqrt(i + 1)) / Math.sqrt(mod.nodes.length);
141
+ mod.nodes[i].x = centerX + r * Math.cos(angle);
142
+ mod.nodes[i].y = centerY + r * Math.sin(angle);
143
+ }
144
+ }
145
+ // Calculate average complexity for this module
146
+ if (mod.nodes.length > 0) {
147
+ mod.avgComplexity =
148
+ mod.nodes.reduce((sum, n) => sum + n.complexity, 0) / mod.nodes.length;
149
+ }
150
+ }
151
+ return nodeMap;
152
+ }
153
+ /** XML-safe string escaping */
154
+ export function escapeXml(str) {
155
+ return str
156
+ .replace(/&/g, "&amp;")
157
+ .replace(/</g, "&lt;")
158
+ .replace(/>/g, "&gt;")
159
+ .replace(/"/g, "&quot;");
160
+ }
161
+ /** Interpolate between two hex colors based on t (0-1) */
162
+ export function lerpColor(color1, color2, t) {
163
+ const c1 = hexToRgb(color1);
164
+ const c2 = hexToRgb(color2);
165
+ const r = Math.round(c1.r + (c2.r - c1.r) * t);
166
+ const g = Math.round(c1.g + (c2.g - c1.g) * t);
167
+ const b = Math.round(c1.b + (c2.b - c1.b) * t);
168
+ return `rgb(${r},${g},${b})`;
169
+ }
170
+ function hexToRgb(hex) {
171
+ const clean = hex.replace("#", "");
172
+ return {
173
+ r: parseInt(clean.substring(0, 2), 16),
174
+ g: parseInt(clean.substring(2, 4), 16),
175
+ b: parseInt(clean.substring(4, 6), 16),
176
+ };
177
+ }
178
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/encoder/layout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * .mapra Header Parser — extracts metadata from the MAPRA header line.
3
+ *
4
+ * Parses headers like:
5
+ * MAPRA v3 | project | Typescript | 76 files | 12,629 lines | generated 2026-03-07T05:21:49 | git:f9e429a
6
+ * MAPRA v3 | project | Typescript | 76 files | 12,629 lines | generated 2026-03-07T05:21:49
7
+ */
8
+ export interface StrandHeaderInfo {
9
+ /** Format version string, e.g. "v3" */
10
+ version: string;
11
+ /** Project name */
12
+ projectName: string;
13
+ /** Framework/language, e.g. "Typescript" */
14
+ framework: string;
15
+ /** Total file count */
16
+ fileCount: number;
17
+ /** Total line count */
18
+ lineCount: number;
19
+ /** Generation timestamp (ISO-8601 without timezone, e.g. "2026-03-07T05:21:49") */
20
+ timestamp: string;
21
+ /** Short git hash at generation time, or null if not present (legacy format) */
22
+ gitHash: string | null;
23
+ }
24
+ /**
25
+ * Parse a .mapra file's header line and extract structured metadata.
26
+ * Returns null if the content doesn't contain a valid MAPRA header.
27
+ */
28
+ export declare function parseStrandHeader(content: string): StrandHeaderInfo | null;
29
+ //# sourceMappingURL=parse-strand-header.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-strand-header.d.ts","sourceRoot":"","sources":["../../src/encoder/parse-strand-header.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAmD1E"}