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,21 @@
1
+ /**
2
+ * .mapra Format Encoder — ASCII art + structured data
3
+ *
4
+ * A custom format using Unicode block chars for visual heatmaps
5
+ * and box-drawing chars for dependency flows. No coordinates —
6
+ * spatial relationships conveyed through grouping and visual density.
7
+ *
8
+ * Target: < 3KB total output.
9
+ */
10
+ import type { StrandGraph } from "../scanner/index.js";
11
+ import type { GraphAnalysis } from "../analyzer/index.js";
12
+ export interface EncodeOptions {
13
+ /** Short git hash at generation time (omitted from header if null/undefined) */
14
+ gitHash?: string | null | undefined;
15
+ }
16
+ /**
17
+ * Generate a .mapra format encoding of the codebase.
18
+ * Does NOT use the layout engine — no coordinates needed.
19
+ */
20
+ export declare function encodeToStrandFormat(graph: StrandGraph, analysis?: GraphAnalysis, options?: EncodeOptions): string;
21
+ //# sourceMappingURL=strand-format-encode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strand-format-encode.d.ts","sourceRoot":"","sources":["../../src/encoder/strand-format-encode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACrC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAsDlH"}
@@ -0,0 +1,562 @@
1
+ /**
2
+ * .mapra Format Encoder — ASCII art + structured data
3
+ *
4
+ * A custom format using Unicode block chars for visual heatmaps
5
+ * and box-drawing chars for dependency flows. No coordinates —
6
+ * spatial relationships conveyed through grouping and visual density.
7
+ *
8
+ * Target: < 3KB total output.
9
+ */
10
+ import { getModuleId } from "../analyzer/graph-utils.js";
11
+ /**
12
+ * Generate a .mapra format encoding of the codebase.
13
+ * Does NOT use the layout engine — no coordinates needed.
14
+ */
15
+ export function encodeToStrandFormat(graph, analysis, options) {
16
+ let out = "";
17
+ // Header
18
+ const generated = new Date().toISOString().slice(0, 19);
19
+ const gitSuffix = options?.gitHash ? ` | git:${options.gitHash}` : "";
20
+ out += `MAPRA v3 | ${graph.projectName} | ${capitalize(graph.framework)} | ${graph.totalFiles} files | ${graph.totalLines.toLocaleString()} lines | generated ${generated}${gitSuffix}\n`;
21
+ out += `LEGEND: ×N=imported by N files | ═/·=coupling strong/weak | ×A→B=A direct, B total affected | dN=cascade depth | [AMP]=amplification≥2x | TN=N test files | NL=lines of code | Nx=co-change count | linked/no-import=import connection\n`;
22
+ out += `USAGE: planning→RISK,CONVENTIONS,INFRASTRUCTURE | debugging→FLOWS,CHURN,CO-CHANGE | refactoring→RISK,CHURN,CO-CHANGE | review→CONVENTIONS,RISK,CHURN | impact-analysis→RISK,CO-CHANGE\n\n`;
23
+ // RISK first — highest signal for change-impact questions
24
+ if (analysis) {
25
+ out += renderRisk(graph, analysis);
26
+ }
27
+ // CHURN — temporal change data
28
+ if (analysis) {
29
+ out += renderChurn(graph, analysis);
30
+ }
31
+ // CONVENTIONS — detected import patterns (with violations)
32
+ if (analysis) {
33
+ out += renderConventions(analysis);
34
+ }
35
+ // CO-CHANGE — files that change together in git history
36
+ if (analysis) {
37
+ out += renderCoChange(graph, analysis);
38
+ }
39
+ // FLOWS second — relational context for navigation questions
40
+ out += renderFlows(graph, analysis);
41
+ // MOST IMPORTED — file-level signals
42
+ // Note: HOTSPOTS removed — Exp 11 showed zero regression (0.71 vs 0.71 baseline),
43
+ // and its data overlaps heavily with API ROUTES (same files, same complexity scores).
44
+ out += renderMostImported(graph);
45
+ // INFRASTRUCTURE — inter-module topology
46
+ out += renderInfrastructure(graph);
47
+ // API ROUTES + PAGES — enumeration sections
48
+ out += renderApiRoutes(graph);
49
+ out += renderPages(graph);
50
+ // TEST COVERAGE — lowest signal, fine at end
51
+ out += renderTestCoverage(graph);
52
+ // DEAD CODE — unreachable files
53
+ if (analysis) {
54
+ out += renderDeadCode(analysis);
55
+ }
56
+ return out;
57
+ }
58
+ function renderInfrastructure(graph) {
59
+ let out = `─── INFRASTRUCTURE ──────────────────────────────────────\n`;
60
+ out += `Inter-module dependency roads\n\n`;
61
+ // Aggregate edges between modules
62
+ const moduleEdges = new Map();
63
+ for (const edge of graph.edges) {
64
+ const fromMod = getModuleId(edge.from);
65
+ const toMod = getModuleId(edge.to);
66
+ if (fromMod === toMod)
67
+ continue;
68
+ const key = `${fromMod}->${toMod}`;
69
+ if (!moduleEdges.has(key)) {
70
+ moduleEdges.set(key, { count: 0, categories: {} });
71
+ }
72
+ const agg = moduleEdges.get(key);
73
+ agg.count++;
74
+ const cat = classifyEdge(edge.from, edge.to);
75
+ agg.categories[cat] = (agg.categories[cat] || 0) + 1;
76
+ }
77
+ // Sort by count, show top edges
78
+ const sorted = [...moduleEdges.entries()]
79
+ .sort((a, b) => b[1].count - a[1].count)
80
+ .slice(0, 10);
81
+ for (const [key, data] of sorted) {
82
+ const [from, to] = key.split("->");
83
+ const fromName = from.split("/").pop() ?? from;
84
+ const toName = to.split("/").pop() ?? to;
85
+ // Visual line style based on coupling strength
86
+ const line = data.count >= 10 ? "═══════" : data.count >= 5 ? "───────" : "·······";
87
+ const connector = "╢";
88
+ const categories = Object.entries(data.categories)
89
+ .sort((a, b) => b[1] - a[1])
90
+ .map(([cat, count]) => `${cat}:${count}`)
91
+ .join(" ");
92
+ out += `${fromName.padEnd(12)} ${line}${connector} ${toName.padEnd(14)} ×${data.count.toString().padStart(2)} ${categories}\n`;
93
+ }
94
+ out += `\n`;
95
+ return out;
96
+ }
97
+ function renderRisk(graph, analysis) {
98
+ // Filter out test files from risk — test infra inflates blast radius
99
+ const testNodeIds = new Set(graph.nodes.filter(n => n.type === "test").map(n => n.id));
100
+ const filtered = analysis.risk.filter(r => !testNodeIds.has(r.nodeId));
101
+ if (filtered.length === 0)
102
+ return "";
103
+ // Tiered selection: Tier 1 (top 5) + Tier 2 (3 mid-level from remaining modules)
104
+ const TIER1_SLOTS = 5;
105
+ const TIER2_SLOTS = 3;
106
+ const tier1 = [];
107
+ const tier1Modules = new Map(); // moduleId -> index in tier1
108
+ let tier1Collapsed = 0;
109
+ // Fill Tier 1 with highest-amp entries (module-deduped)
110
+ for (const r of filtered) {
111
+ const mod = getModuleId(r.nodeId);
112
+ const existingIdx = tier1Modules.get(mod);
113
+ if (existingIdx !== undefined) {
114
+ tier1[existingIdx].similarCount++;
115
+ tier1Collapsed++;
116
+ }
117
+ else if (tier1.length < TIER1_SLOTS) {
118
+ tier1Modules.set(mod, tier1.length);
119
+ tier1.push({ entry: r, similarCount: 0 });
120
+ }
121
+ }
122
+ // Fill Tier 2 from remaining entries not in Tier 1 modules
123
+ const tier2 = [];
124
+ const tier2Modules = new Set();
125
+ for (const r of filtered) {
126
+ const mod = getModuleId(r.nodeId);
127
+ if (tier1Modules.has(mod))
128
+ continue; // Skip Tier 1 modules entirely
129
+ if (tier2Modules.has(mod))
130
+ continue; // Already have this module in Tier 2
131
+ if (tier2.length >= TIER2_SLOTS)
132
+ break;
133
+ tier2Modules.add(mod);
134
+ tier2.push({ entry: r, similarCount: 0 });
135
+ }
136
+ const selected = [...tier1, ...tier2];
137
+ if (selected.length === 0)
138
+ return "";
139
+ // Build node lookup and test edge counts
140
+ const nodeMap = new Map(graph.nodes.map((n) => [n.id, n]));
141
+ const testCounts = new Map();
142
+ for (const edge of graph.edges) {
143
+ if (edge.type === "tests") {
144
+ testCounts.set(edge.to, (testCounts.get(edge.to) ?? 0) + 1);
145
+ }
146
+ }
147
+ let out = `─── RISK (blast radius — modifying these cascades broadly) ─\n`;
148
+ for (let i = 0; i < selected.length; i++) {
149
+ // Blank line separator between Tier 1 and Tier 2
150
+ if (i === tier1.length && tier2.length > 0) {
151
+ out += `\n`;
152
+ }
153
+ const { entry: r, similarCount } = selected[i];
154
+ const isAmplified = r.amplificationRatio >= 2.0;
155
+ const marker = isAmplified ? "[AMP]" : " ";
156
+ const amp = `amp${r.amplificationRatio.toFixed(1)}`.padEnd(7);
157
+ const flow = `×${r.directImporters}→${r.affectedCount}`.padEnd(9);
158
+ const depth = `d${r.maxDepth}`.padEnd(4);
159
+ const mods = `${r.modulesAffected}mod`.padEnd(5);
160
+ const tests = `T${testCounts.get(r.nodeId) ?? 0}`.padEnd(4);
161
+ out += `${marker} ${amp} ${flow} ${depth} ${mods} ${tests} ${r.nodeId}\n`;
162
+ // Cascade targets — which modules get hit
163
+ if (r.affectedModuleNames && r.affectedModuleNames.length > 0) {
164
+ const sourceModule = getModuleId(r.nodeId);
165
+ const otherModules = r.affectedModuleNames.filter(m => m !== sourceModule);
166
+ if (otherModules.length > 0) {
167
+ const shown = otherModules.slice(0, 5);
168
+ const suffix = otherModules.length > 5 ? `, +${otherModules.length - 5} more` : "";
169
+ out += ` cascades to: ${shown.join(", ")}${suffix}\n`;
170
+ }
171
+ }
172
+ // Export symbols (max 5, skip if empty)
173
+ const node = nodeMap.get(r.nodeId);
174
+ const exports = node?.exports?.filter((e) => e !== "default") ?? [];
175
+ if (exports.length > 0) {
176
+ const shown = exports.slice(0, 5);
177
+ const suffix = exports.length > 5 ? `, +${exports.length - 5} more` : "";
178
+ out += ` exports: ${shown.join(", ")}${suffix}\n`;
179
+ }
180
+ // +N similar line for collapsed entries from same module
181
+ if (similarCount > 0) {
182
+ out += ` +${similarCount} similar in ${getModuleId(r.nodeId)}\n`;
183
+ }
184
+ }
185
+ const remaining = filtered.length - selected.length - tier1Collapsed;
186
+ if (remaining > 0) {
187
+ out += ` +${remaining} more with blast radius > 1\n`;
188
+ }
189
+ out += `\n`;
190
+ return out;
191
+ }
192
+ function renderChurn(graph, analysis) {
193
+ if (!analysis.churn || analysis.churn.size === 0)
194
+ return "";
195
+ // Only show files that exist in the scanner graph (filters out .md, lock files, .mapra, etc.)
196
+ const graphNodeIds = new Set(graph.nodes.map(n => n.id));
197
+ // Get files with >= 3 commits (high churn)
198
+ const highChurn = [...analysis.churn.values()]
199
+ .filter((c) => c.commits30d >= 3 && graphNodeIds.has(c.nodeId))
200
+ .sort((a, b) => b.commits30d - a.commits30d)
201
+ .slice(0, 10);
202
+ if (highChurn.length === 0)
203
+ return "";
204
+ let out = `─── CHURN (last 30 days, top movers) ─────────────────────\n`;
205
+ for (const c of highChurn) {
206
+ const commits = `${c.commits30d} commits`.padEnd(12);
207
+ const delta = `+${c.linesAdded30d} -${c.linesRemoved30d}`.padEnd(12);
208
+ const msg = c.lastCommitMsg.length > 50
209
+ ? c.lastCommitMsg.slice(0, 47) + "..."
210
+ : c.lastCommitMsg;
211
+ out += `${commits} ${delta} ${c.nodeId} "${msg}"\n`;
212
+ }
213
+ out += `\n`;
214
+ return out;
215
+ }
216
+ function renderConventions(analysis) {
217
+ if (!analysis.conventions || analysis.conventions.length === 0)
218
+ return "";
219
+ // Cap at 8 conventions
220
+ const top = analysis.conventions.slice(0, 8);
221
+ let out = `─── CONVENTIONS ─────────────────────────────────────────\n`;
222
+ for (const c of top) {
223
+ const exports = c.anchorExports.slice(0, 3).join(", ");
224
+ const label = exports || c.anchorFile.split("/").pop()?.replace(/\.(ts|tsx|js|jsx)$/, "") || "?";
225
+ const coverage = `${c.adoption}/${c.total} ${c.consumerType}`;
226
+ out += `${label.padEnd(32)} ${coverage.padEnd(16)} ${c.anchorFile}\n`;
227
+ // Show violators for strong conventions (>= 70% adoption)
228
+ if (c.violators && c.violators.length > 0 && c.coverage >= 0.7) {
229
+ const shown = c.violators.slice(0, 5);
230
+ const suffix = c.violators.length > 5 ? `, +${c.violators.length - 5} more` : "";
231
+ const shortNames = shown.map((v) => v.split("/").pop()?.replace(/\.(ts|tsx|js|jsx)$/, "") || v);
232
+ out += ` exceptions: ${shortNames.join(", ")}${suffix}\n`;
233
+ }
234
+ }
235
+ out += `\n`;
236
+ return out;
237
+ }
238
+ function renderCoChange(graph, analysis) {
239
+ if (!analysis.coChanges || analysis.coChanges.length === 0)
240
+ return "";
241
+ // Only show pairs where BOTH files exist in the scanner graph
242
+ const graphNodeIds = new Set(graph.nodes.map(n => n.id));
243
+ const filtered = analysis.coChanges.filter(pair => graphNodeIds.has(pair.fileA) && graphNodeIds.has(pair.fileB));
244
+ if (filtered.length === 0)
245
+ return "";
246
+ let out = `─── CO-CHANGE (files that change together) ───────────────\n`;
247
+ for (const pair of filtered) {
248
+ const shortA = shortenCoChangePath(pair.fileA);
249
+ const shortB = shortenCoChangePath(pair.fileB);
250
+ const freq = `${pair.coChangeCount}×`;
251
+ const conf = `${Math.round(pair.confidence * 100)}%`;
252
+ const link = pair.importConnected ? "linked" : "no-import";
253
+ out += `${freq.padEnd(5)} ${shortA} ↔ ${shortB} (${conf} ${link})\n`;
254
+ }
255
+ out += `\n`;
256
+ return out;
257
+ }
258
+ function renderApiRoutes(graph) {
259
+ const apiRoutes = graph.nodes
260
+ .filter((n) => n.type === "api-route")
261
+ .sort((a, b) => b.complexity - a.complexity || b.lines - a.lines);
262
+ if (apiRoutes.length === 0)
263
+ return "";
264
+ let out = `─── API ROUTES (${apiRoutes.length}) ─────────────────────────────────\n`;
265
+ for (const route of apiRoutes) {
266
+ const methods = route.framework?.metadata?.methods?.join(",") || "?";
267
+ const routePath = route.framework?.metadata?.routePath ||
268
+ route.path;
269
+ const lines = `${route.lines}L`.padStart(5);
270
+ const complexity = route.complexity.toFixed(2);
271
+ out += `${methods.padEnd(7)}${routePath.padEnd(50)} ${lines} ${complexity}\n`;
272
+ }
273
+ out += `\n`;
274
+ return out;
275
+ }
276
+ function renderPages(graph) {
277
+ const pages = graph.nodes
278
+ .filter((n) => n.type === "route")
279
+ .sort((a, b) => b.complexity - a.complexity || b.lines - a.lines);
280
+ if (pages.length === 0)
281
+ return "";
282
+ let out = `─── PAGES (${pages.length}) ──────────────────────────────────────────\n`;
283
+ for (const page of pages) {
284
+ const routePath = page.framework?.metadata?.routePath ||
285
+ page.path;
286
+ const client = page.framework?.metadata
287
+ ?.isClientComponent
288
+ ? " [client]"
289
+ : "";
290
+ const lines = `${page.lines}L`.padStart(5);
291
+ const complexity = page.complexity.toFixed(2);
292
+ out += `${(routePath + client).padEnd(44)} ${lines} ${complexity}\n`;
293
+ }
294
+ out += `\n`;
295
+ return out;
296
+ }
297
+ function renderMostImported(graph) {
298
+ // Filter out test files from most imported
299
+ const testNodeIds = new Set(graph.nodes.filter(n => n.type === "test").map(n => n.id));
300
+ const edgeCounts = new Map();
301
+ for (const edge of graph.edges) {
302
+ if (testNodeIds.has(edge.from))
303
+ continue;
304
+ if (testNodeIds.has(edge.to))
305
+ continue;
306
+ edgeCounts.set(edge.to, (edgeCounts.get(edge.to) || 0) + 1);
307
+ }
308
+ const mostImported = [...edgeCounts.entries()]
309
+ .sort((a, b) => b[1] - a[1])
310
+ .slice(0, 8);
311
+ if (mostImported.length === 0)
312
+ return "";
313
+ let out = `─── MOST IMPORTED ───────────────────────────────────────\n`;
314
+ for (const [fileId, count] of mostImported) {
315
+ out += `×${count} ${fileId}\n`;
316
+ }
317
+ out += `\n`;
318
+ return out;
319
+ }
320
+ function renderTestCoverage(graph) {
321
+ const testNodes = graph.nodes.filter((n) => n.type === "test");
322
+ const testEdges = graph.edges.filter((e) => e.type === "tests");
323
+ const testedFiles = new Set(testEdges.map((e) => e.to));
324
+ const testableFiles = graph.nodes.filter((n) => n.type !== "test" && n.type !== "config");
325
+ const coveragePercent = testableFiles.length > 0
326
+ ? ((testedFiles.size / testableFiles.length) * 100).toFixed(1)
327
+ : "0";
328
+ let out = `─── TEST COVERAGE ───────────────────────────────────────\n`;
329
+ out += `${testNodes.length} test files | ${testedFiles.size}/${testableFiles.length} testable files with direct test edges (${coveragePercent}%)\n`;
330
+ return out;
331
+ }
332
+ // ─── FLOWS ──────────────────────────────────────────────
333
+ /**
334
+ * Finer-grained module ID for FLOWS.
335
+ * Uses 3 path segments for src/lib and src/app to distinguish sub-modules.
336
+ * e.g., "src/lib/teacher-club" vs "src/lib/cluster-pos"
337
+ */
338
+ function getFlowModuleId(nodePath) {
339
+ const parts = nodePath.split("/");
340
+ if (parts.length > 3 &&
341
+ parts[0] === "src" &&
342
+ (parts[1] === "lib" || parts[1] === "app" || parts[1] === "components")) {
343
+ return parts.slice(0, 3).join("/");
344
+ }
345
+ return parts.length > 2
346
+ ? parts.slice(0, 2).join("/")
347
+ : (parts[0] ?? nodePath);
348
+ }
349
+ /**
350
+ * Classify a single file path into a domain.
351
+ * Uses word boundaries on "test" to avoid matching "contest", "latest", etc.
352
+ */
353
+ function classifyNodeDomain(nodePath) {
354
+ if (/auth|session|login|magic-link|trusted-device|verify/.test(nodePath))
355
+ return "auth";
356
+ if (/payment|authorize-net|order|cart|price|tip/.test(nodePath))
357
+ return "payment";
358
+ if (/\btest\b|\.spec\.|__tests__/.test(nodePath))
359
+ return "test";
360
+ return "other";
361
+ }
362
+ /**
363
+ * Classify an entire flow (entry point + dependencies) by domain.
364
+ * Entry point path takes priority; falls back to majority-vote on deps.
365
+ */
366
+ function classifyFlow(entryPath, depPaths) {
367
+ // Primary: classify by entry point
368
+ const entryDomain = classifyNodeDomain(entryPath);
369
+ if (entryDomain !== "other" && entryDomain !== "test")
370
+ return entryDomain;
371
+ // Fallback: majority vote on dependency paths
372
+ const votes = new Map();
373
+ for (const p of depPaths) {
374
+ const d = classifyNodeDomain(p);
375
+ if (d !== "other" && d !== "test") {
376
+ votes.set(d, (votes.get(d) || 0) + 1);
377
+ }
378
+ }
379
+ let best = "data";
380
+ let bestCount = 0;
381
+ for (const [domain, count] of votes) {
382
+ if (count > bestCount) {
383
+ best = domain;
384
+ bestCount = count;
385
+ }
386
+ }
387
+ return best;
388
+ }
389
+ /**
390
+ * Shorten a file path for display in FLOWS.
391
+ * Strips src/, file extensions, and /route /page suffixes.
392
+ */
393
+ function shortenPath(fullPath) {
394
+ return fullPath
395
+ .replace(/^src\//, "")
396
+ .replace(/\.(ts|tsx|js|jsx)$/, "")
397
+ .replace(/\/route$/, "")
398
+ .replace(/\/page$/, "");
399
+ }
400
+ /**
401
+ * Auto-detect business flows by finding API route entry points and their
402
+ * cross-sub-module dependencies. Renders as hub-and-spoke: each entry point
403
+ * lists its direct dependencies, classified by domain.
404
+ *
405
+ * This design handles star patterns (one hub importing many leaves) correctly,
406
+ * which is the actual topology of business logic in Next.js API routes.
407
+ */
408
+ function renderFlows(graph, analysis) {
409
+ // 1. Build adjacency from ALL non-test import edges across sub-modules
410
+ const adj = new Map();
411
+ for (const edge of graph.edges) {
412
+ if (edge.type === "tests")
413
+ continue;
414
+ const fromMod = getFlowModuleId(edge.from);
415
+ const toMod = getFlowModuleId(edge.to);
416
+ if (fromMod === toMod)
417
+ continue;
418
+ if (!adj.has(edge.from))
419
+ adj.set(edge.from, new Set());
420
+ adj.get(edge.from).add(edge.to);
421
+ }
422
+ // 2. Find entry points: API routes with outgoing cross-sub-module edges
423
+ const entryPoints = graph.nodes
424
+ .filter((n) => n.type === "api-route" && adj.has(n.id))
425
+ .sort((a, b) => b.complexity - a.complexity || b.lines - a.lines);
426
+ // SPA fallback: no API routes — use top hub files by amplification ratio
427
+ if (entryPoints.length === 0) {
428
+ if (!analysis || analysis.risk.length === 0)
429
+ return "";
430
+ return renderFlowsFromHubs(graph, analysis, adj);
431
+ }
432
+ const flows = [];
433
+ for (const ep of entryPoints) {
434
+ const deps = [...(adj.get(ep.id) || [])];
435
+ if (deps.length === 0)
436
+ continue;
437
+ // Sort deps by complexity (most significant first)
438
+ const nodeMap = new Map(graph.nodes.map((n) => [n.id, n]));
439
+ deps.sort((a, b) => {
440
+ const ca = nodeMap.get(a)?.complexity ?? 0;
441
+ const cb = nodeMap.get(b)?.complexity ?? 0;
442
+ return cb - ca;
443
+ });
444
+ const domain = classifyFlow(ep.id, deps);
445
+ if (domain === "test")
446
+ continue;
447
+ flows.push({ entry: ep.id, deps, domain });
448
+ }
449
+ if (flows.length === 0)
450
+ return "";
451
+ // 4. Group by domain, limit to top 3 flows per domain (by entry complexity)
452
+ const grouped = new Map();
453
+ for (const flow of flows) {
454
+ if (!grouped.has(flow.domain))
455
+ grouped.set(flow.domain, []);
456
+ const domainFlows = grouped.get(flow.domain);
457
+ if (domainFlows.length < 3) {
458
+ domainFlows.push(flow);
459
+ }
460
+ }
461
+ // 5. Render
462
+ let out = `─── FLOWS ──────────────────────────────────────────────\n`;
463
+ out += `Entry points and their cross-module dependencies\n\n`;
464
+ // Sort domains: payment first, then auth, then rest alphabetically
465
+ const domainOrder = ["payment", "auth", "data"];
466
+ const sortedDomains = [...grouped.keys()].sort((a, b) => {
467
+ const ai = domainOrder.indexOf(a);
468
+ const bi = domainOrder.indexOf(b);
469
+ return (ai === -1 ? 99 : ai) - (bi === -1 ? 99 : bi);
470
+ });
471
+ for (const domain of sortedDomains) {
472
+ const domainFlows = grouped.get(domain);
473
+ const label = `${domain}:`.padEnd(12);
474
+ for (let i = 0; i < domainFlows.length; i++) {
475
+ const flow = domainFlows[i];
476
+ const entryStr = shortenPath(flow.entry);
477
+ const depStr = flow.deps.map((p) => shortenPath(p)).join(", ");
478
+ if (i === 0) {
479
+ out += `${label}${entryStr} -> ${depStr}\n`;
480
+ }
481
+ else {
482
+ out += `${"".padEnd(12)}${entryStr} -> ${depStr}\n`;
483
+ }
484
+ }
485
+ }
486
+ out += `\n`;
487
+ return out;
488
+ }
489
+ /**
490
+ * SPA fallback for FLOWS: use high-amplification hub files as implicit entry points.
491
+ * Shows their cross-module dependencies in the same format as API-route FLOWS.
492
+ */
493
+ function renderFlowsFromHubs(graph, analysis, adj) {
494
+ // Take top 5 by amplificationRatio that have cross-module outgoing edges
495
+ const hubs = analysis.risk
496
+ .filter((r) => adj.has(r.nodeId))
497
+ .slice(0, 5);
498
+ if (hubs.length === 0)
499
+ return "";
500
+ let out = `─── FLOWS (entry hubs) ──────────────────────────────────\n`;
501
+ out += `High-amplification hubs and their cross-module dependencies\n\n`;
502
+ const nodeMap = new Map(graph.nodes.map((n) => [n.id, n]));
503
+ for (const hub of hubs) {
504
+ const deps = [...(adj.get(hub.nodeId) || [])];
505
+ if (deps.length === 0)
506
+ continue;
507
+ // Sort deps by complexity
508
+ deps.sort((a, b) => {
509
+ const ca = nodeMap.get(a)?.complexity ?? 0;
510
+ const cb = nodeMap.get(b)?.complexity ?? 0;
511
+ return cb - ca;
512
+ });
513
+ const entryStr = shortenPath(hub.nodeId);
514
+ const depStr = deps.map((p) => shortenPath(p)).join(", ");
515
+ const marker = hub.amplificationRatio >= 2.0 ? "[AMP]" : " ";
516
+ out += `${marker} ${entryStr} -> ${depStr}\n`;
517
+ }
518
+ out += `\n`;
519
+ return out;
520
+ }
521
+ function renderDeadCode(analysis) {
522
+ if (!analysis.deadCode || analysis.deadCode.length === 0)
523
+ return "";
524
+ const total = analysis.deadCode.length;
525
+ let out = `─── DEAD CODE (${total} unreachable files) ─────────────────\n`;
526
+ const shown = analysis.deadCode.slice(0, 15);
527
+ for (const file of shown) {
528
+ out += `${file}\n`;
529
+ }
530
+ if (total > shown.length) {
531
+ out += `+${total - shown.length} more\n`;
532
+ }
533
+ return out;
534
+ }
535
+ // ─── Helpers ────────────────────────────────────────────
536
+ function classifyEdge(fromPath, toPath) {
537
+ const combined = fromPath + " " + toPath;
538
+ if (/auth|session|login|magic-link|trusted-device|verify/.test(combined))
539
+ return "auth";
540
+ if (/payment|authorize|order|cart|price|tip/.test(combined))
541
+ return "payment";
542
+ if (/test|spec|__tests__/.test(combined))
543
+ return "test";
544
+ if (/component|page|layout|\.tsx$/.test(combined))
545
+ return "rendering";
546
+ return "data";
547
+ }
548
+ /**
549
+ * Shorten a file path for CO-CHANGE display.
550
+ * Uses last 2 path segments (parent/filename) to avoid ambiguity
551
+ * when multiple files share the same basename (e.g., route.ts).
552
+ */
553
+ function shortenCoChangePath(filePath) {
554
+ const parts = filePath.split("/");
555
+ return parts.length >= 2
556
+ ? parts.slice(-2).join("/")
557
+ : parts[0] ?? filePath;
558
+ }
559
+ function capitalize(s) {
560
+ return s.charAt(0).toUpperCase() + s.slice(1);
561
+ }
562
+ //# sourceMappingURL=strand-format-encode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strand-format-encode.js","sourceRoot":"","sources":["../../src/encoder/strand-format-encode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Text Encoder — generates a structured text representation of the same graph
3
+ * Used as the baseline comparison for the visual encoding experiment.
4
+ * This represents "the best text can do" — well-structured YAML-like format.
5
+ */
6
+ import type { StrandGraph } from "../scanner/index.js";
7
+ import type { GraphAnalysis } from "../analyzer/index.js";
8
+ export interface TextEncodeOptions {
9
+ /** Strip structural analysis (Risk, Complexity, Most Imported, Test Coverage) */
10
+ bare?: boolean;
11
+ }
12
+ export declare function encodeToText(graph: StrandGraph, analysis?: GraphAnalysis, options?: TextEncodeOptions): string;
13
+ //# sourceMappingURL=text-encode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-encode.d.ts","sourceRoot":"","sources":["../../src/encoder/text-encode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,WAAW,EAClB,QAAQ,CAAC,EAAE,aAAa,EACxB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM,CA4IR"}