@oddessentials/odd-repo-mapper 1.0.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.

Potentially problematic release.


This version of @oddessentials/odd-repo-mapper might be problematic. Click here for more details.

Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/cli/commands/mcp.d.ts +6 -0
  4. package/dist/cli/commands/mcp.d.ts.map +1 -0
  5. package/dist/cli/commands/mcp.js +11 -0
  6. package/dist/cli/commands/mcp.js.map +1 -0
  7. package/dist/cli/commands/report.d.ts +6 -0
  8. package/dist/cli/commands/report.d.ts.map +1 -0
  9. package/dist/cli/commands/report.js +96 -0
  10. package/dist/cli/commands/report.js.map +1 -0
  11. package/dist/cli/commands/scan.d.ts +6 -0
  12. package/dist/cli/commands/scan.d.ts.map +1 -0
  13. package/dist/cli/commands/scan.js +118 -0
  14. package/dist/cli/commands/scan.js.map +1 -0
  15. package/dist/cli/commands/verify.d.ts +6 -0
  16. package/dist/cli/commands/verify.d.ts.map +1 -0
  17. package/dist/cli/commands/verify.js +47 -0
  18. package/dist/cli/commands/verify.js.map +1 -0
  19. package/dist/cli/index.d.ts +5 -0
  20. package/dist/cli/index.d.ts.map +1 -0
  21. package/dist/cli/index.js +20 -0
  22. package/dist/cli/index.js.map +1 -0
  23. package/dist/core/config.d.ts +53 -0
  24. package/dist/core/config.d.ts.map +1 -0
  25. package/dist/core/config.js +106 -0
  26. package/dist/core/config.js.map +1 -0
  27. package/dist/core/constants.d.ts +31 -0
  28. package/dist/core/constants.d.ts.map +1 -0
  29. package/dist/core/constants.js +31 -0
  30. package/dist/core/constants.js.map +1 -0
  31. package/dist/core/graph.d.ts +61 -0
  32. package/dist/core/graph.d.ts.map +1 -0
  33. package/dist/core/graph.js +163 -0
  34. package/dist/core/graph.js.map +1 -0
  35. package/dist/core/hashing.d.ts +37 -0
  36. package/dist/core/hashing.d.ts.map +1 -0
  37. package/dist/core/hashing.js +66 -0
  38. package/dist/core/hashing.js.map +1 -0
  39. package/dist/core/indexers/go.d.ts +14 -0
  40. package/dist/core/indexers/go.d.ts.map +1 -0
  41. package/dist/core/indexers/go.js +175 -0
  42. package/dist/core/indexers/go.js.map +1 -0
  43. package/dist/core/indexers/index.d.ts +39 -0
  44. package/dist/core/indexers/index.d.ts.map +1 -0
  45. package/dist/core/indexers/index.js +76 -0
  46. package/dist/core/indexers/index.js.map +1 -0
  47. package/dist/core/indexers/python.d.ts +14 -0
  48. package/dist/core/indexers/python.d.ts.map +1 -0
  49. package/dist/core/indexers/python.js +186 -0
  50. package/dist/core/indexers/python.js.map +1 -0
  51. package/dist/core/indexers/rust.d.ts +14 -0
  52. package/dist/core/indexers/rust.d.ts.map +1 -0
  53. package/dist/core/indexers/rust.js +156 -0
  54. package/dist/core/indexers/rust.js.map +1 -0
  55. package/dist/core/indexers/typescript.d.ts +19 -0
  56. package/dist/core/indexers/typescript.d.ts.map +1 -0
  57. package/dist/core/indexers/typescript.js +223 -0
  58. package/dist/core/indexers/typescript.js.map +1 -0
  59. package/dist/core/reports/coverage.d.ts +38 -0
  60. package/dist/core/reports/coverage.d.ts.map +1 -0
  61. package/dist/core/reports/coverage.js +175 -0
  62. package/dist/core/reports/coverage.js.map +1 -0
  63. package/dist/core/reports/index.d.ts +10 -0
  64. package/dist/core/reports/index.d.ts.map +1 -0
  65. package/dist/core/reports/index.js +7 -0
  66. package/dist/core/reports/index.js.map +1 -0
  67. package/dist/core/reports/mermaid.d.ts +41 -0
  68. package/dist/core/reports/mermaid.d.ts.map +1 -0
  69. package/dist/core/reports/mermaid.js +171 -0
  70. package/dist/core/reports/mermaid.js.map +1 -0
  71. package/dist/core/reports/traceability.d.ts +45 -0
  72. package/dist/core/reports/traceability.d.ts.map +1 -0
  73. package/dist/core/reports/traceability.js +190 -0
  74. package/dist/core/reports/traceability.js.map +1 -0
  75. package/dist/core/scanner.d.ts +48 -0
  76. package/dist/core/scanner.d.ts.map +1 -0
  77. package/dist/core/scanner.js +191 -0
  78. package/dist/core/scanner.js.map +1 -0
  79. package/dist/core/toolchain.d.ts +28 -0
  80. package/dist/core/toolchain.d.ts.map +1 -0
  81. package/dist/core/toolchain.js +68 -0
  82. package/dist/core/toolchain.js.map +1 -0
  83. package/dist/core/verify.d.ts +15 -0
  84. package/dist/core/verify.d.ts.map +1 -0
  85. package/dist/core/verify.js +182 -0
  86. package/dist/core/verify.js.map +1 -0
  87. package/dist/mcp/server.d.ts +46 -0
  88. package/dist/mcp/server.d.ts.map +1 -0
  89. package/dist/mcp/server.js +421 -0
  90. package/dist/mcp/server.js.map +1 -0
  91. package/package.json +86 -0
  92. package/schemas/config.schema.json +140 -0
  93. package/schemas/graph.schema.json +132 -0
  94. package/schemas/repo-profile.schema.json +118 -0
  95. package/schemas/toolchain.schema.json +37 -0
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Mermaid diagram generator.
3
+ * Produces architecture diagrams from the knowledge graph.
4
+ */
5
+ import { writeFileSync, mkdirSync } from 'node:fs';
6
+ import { dirname } from 'node:path';
7
+ import { LIMITS } from '../constants.js';
8
+ /**
9
+ * Generate a Mermaid flowchart from the graph database.
10
+ */
11
+ export function generateMermaidDiagram(db, options = {}) {
12
+ const { maxNodes = LIMITS.maxNodesPerDiagram, direction = 'TB', nodeTypes, edgeKinds, groupByDirectory = true, } = options;
13
+ // Query nodes
14
+ let nodeQuery = 'SELECT id, type, path, name, language FROM nodes';
15
+ if (nodeTypes && nodeTypes.length > 0) {
16
+ const types = nodeTypes.map((t) => `'${t}'`).join(',');
17
+ nodeQuery += ` WHERE type IN (${types})`;
18
+ }
19
+ nodeQuery += ' ORDER BY path ASC, type ASC';
20
+ const allNodes = db.prepare(nodeQuery).all();
21
+ // Query edges
22
+ let edgeQuery = 'SELECT source, target, kind FROM edges';
23
+ if (edgeKinds && edgeKinds.length > 0) {
24
+ const kinds = edgeKinds.map((k) => `'${k}'`).join(',');
25
+ edgeQuery += ` WHERE kind IN (${kinds})`;
26
+ }
27
+ const allEdges = db.prepare(edgeQuery).all();
28
+ // Check if we need to truncate
29
+ const truncated = allNodes.length > maxNodes;
30
+ const nodes = allNodes.slice(0, maxNodes);
31
+ const nodeIds = new Set(nodes.map((n) => n.id));
32
+ // Filter edges to only include nodes we're showing
33
+ const edges = allEdges.filter((e) => nodeIds.has(e.source) && nodeIds.has(e.target));
34
+ // Build Mermaid output
35
+ const lines = [];
36
+ lines.push(`flowchart ${direction}`);
37
+ lines.push('');
38
+ // Group nodes by directory if requested
39
+ if (groupByDirectory) {
40
+ const groups = groupNodesByDirectory(nodes);
41
+ for (const [dir, groupNodes] of groups) {
42
+ if (dir) {
43
+ lines.push(` subgraph ${sanitizeId(dir)}["${escapeLabel(dir)}"]`);
44
+ for (const node of groupNodes) {
45
+ lines.push(` ${formatNode(node)}`);
46
+ }
47
+ lines.push(' end');
48
+ lines.push('');
49
+ }
50
+ else {
51
+ // Root-level nodes
52
+ for (const node of groupNodes) {
53
+ lines.push(` ${formatNode(node)}`);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ else {
59
+ for (const node of nodes) {
60
+ lines.push(` ${formatNode(node)}`);
61
+ }
62
+ }
63
+ lines.push('');
64
+ // Add edges
65
+ for (const edge of edges) {
66
+ lines.push(` ${formatEdge(edge)}`);
67
+ }
68
+ // Add styling
69
+ lines.push('');
70
+ lines.push(' %% Styling');
71
+ lines.push(' classDef file fill:#e1f5fe,stroke:#01579b');
72
+ lines.push(' classDef test fill:#fff3e0,stroke:#e65100');
73
+ lines.push(' classDef module fill:#e8f5e9,stroke:#1b5e20');
74
+ lines.push(' classDef entrypoint fill:#fce4ec,stroke:#880e4f');
75
+ return {
76
+ mermaid: lines.join('\n'),
77
+ nodeCount: nodes.length,
78
+ edgeCount: edges.length,
79
+ truncated,
80
+ };
81
+ }
82
+ function groupNodesByDirectory(nodes) {
83
+ const groups = new Map();
84
+ for (const node of nodes) {
85
+ const parts = node.path.split('/');
86
+ const dir = parts.length > 1 ? parts.slice(0, -1).join('/') : '';
87
+ if (!groups.has(dir)) {
88
+ groups.set(dir, []);
89
+ }
90
+ groups.get(dir).push(node);
91
+ }
92
+ return groups;
93
+ }
94
+ function formatNode(node) {
95
+ const id = sanitizeId(node.id);
96
+ const label = node.name || node.path.split('/').pop() || node.path;
97
+ const shape = getNodeShape(node.type);
98
+ const className = node.type;
99
+ return `${id}${shape[0]}"${escapeLabel(label)}"${shape[1]}:::${className}`;
100
+ }
101
+ function formatEdge(edge) {
102
+ const source = sanitizeId(edge.source);
103
+ const target = sanitizeId(edge.target);
104
+ const style = getEdgeStyle(edge.kind);
105
+ return `${source} ${style} ${target}`;
106
+ }
107
+ function getNodeShape(type) {
108
+ switch (type) {
109
+ case 'module':
110
+ return ['[[', ']]']; // Stadium shape
111
+ case 'entrypoint':
112
+ return ['([', '])']; // Stadium shape
113
+ case 'test':
114
+ return ['{{', '}}']; // Hexagon
115
+ default:
116
+ return ['[', ']']; // Rectangle
117
+ }
118
+ }
119
+ function getEdgeStyle(kind) {
120
+ switch (kind) {
121
+ case 'import':
122
+ return '-->';
123
+ case 'contains':
124
+ return '-.->';
125
+ case 'entrypoint':
126
+ return '==>';
127
+ case 'tests':
128
+ return '-.->';
129
+ default:
130
+ return '-->';
131
+ }
132
+ }
133
+ function sanitizeId(id) {
134
+ // Mermaid IDs must be alphanumeric or underscores
135
+ return 'n_' + id.replace(/[^a-zA-Z0-9]/g, '_').slice(0, 32);
136
+ }
137
+ function escapeLabel(label) {
138
+ return label.replace(/"/g, "'").replace(/[<>]/g, '');
139
+ }
140
+ /**
141
+ * Write Mermaid diagram to file.
142
+ */
143
+ export function writeMermaidDiagram(db, outPath, options = {}) {
144
+ const result = generateMermaidDiagram(db, options);
145
+ mkdirSync(dirname(outPath), { recursive: true });
146
+ writeFileSync(outPath, result.mermaid, 'utf8');
147
+ return result;
148
+ }
149
+ /**
150
+ * Generate an import graph focusing on module dependencies.
151
+ */
152
+ export function generateImportGraph(db) {
153
+ return generateMermaidDiagram(db, {
154
+ nodeTypes: ['file', 'module'],
155
+ edgeKinds: ['import'],
156
+ direction: 'LR',
157
+ groupByDirectory: true,
158
+ });
159
+ }
160
+ /**
161
+ * Generate a test coverage diagram.
162
+ */
163
+ export function generateTestGraph(db) {
164
+ return generateMermaidDiagram(db, {
165
+ nodeTypes: ['file', 'test'],
166
+ edgeKinds: ['tests', 'import'],
167
+ direction: 'TB',
168
+ groupByDirectory: true,
169
+ });
170
+ }
171
+ //# sourceMappingURL=mermaid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mermaid.js","sourceRoot":"","sources":["../../../src/core/reports/mermaid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Module-Test Traceability Matrix.
3
+ * Per D7: Fixed confidence precedence model.
4
+ */
5
+ import Database from 'better-sqlite3';
6
+ import type { CoverageData } from './coverage.js';
7
+ export interface TraceabilityEntry {
8
+ sourceFile: string;
9
+ testFile: string;
10
+ confidence: number;
11
+ linkType: 'coverage' | 'direct_import' | 'symbol_reference' | 'path_heuristic';
12
+ }
13
+ export interface TraceabilityMatrix {
14
+ entries: TraceabilityEntry[];
15
+ sourceFiles: string[];
16
+ testFiles: string[];
17
+ /** Minimum confidence threshold used */
18
+ minConfidence: number;
19
+ /** Summary statistics */
20
+ stats: {
21
+ totalLinks: number;
22
+ byLinkType: Record<string, number>;
23
+ averageConfidence: number;
24
+ };
25
+ }
26
+ export interface TraceabilityOptions {
27
+ minConfidence?: number;
28
+ includeBelowThreshold?: boolean;
29
+ coverageData?: CoverageData;
30
+ }
31
+ /**
32
+ * Build module-test traceability matrix from graph and coverage.
33
+ * Per D7: Confidence precedence - Coverage (100) > Direct Import (90) >
34
+ * Symbol Reference (70) > Path Heuristic (50)
35
+ */
36
+ export declare function buildTraceabilityMatrix(db: Database.Database, options?: TraceabilityOptions): TraceabilityMatrix;
37
+ /**
38
+ * Export traceability matrix to JSON.
39
+ */
40
+ export declare function writeTraceabilityMatrix(db: Database.Database, outPath: string, options?: TraceabilityOptions): TraceabilityMatrix;
41
+ /**
42
+ * Export traceability matrix to Markdown table.
43
+ */
44
+ export declare function writeTraceabilityMarkdown(db: Database.Database, outPath: string, options?: TraceabilityOptions): TraceabilityMatrix;
45
+ //# sourceMappingURL=traceability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceability.d.ts","sourceRoot":"","sources":["../../../src/core/reports/traceability.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAItC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,UAAU,GAAG,eAAe,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;CAClF;AAED,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,KAAK,EAAE;QACH,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,iBAAiB,EAAE,MAAM,CAAC;KAC7B,CAAC;CACL;AAED,MAAM,WAAW,mBAAmB;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACnC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,GAAE,mBAAwB,GAClC,kBAAkB,CAqKpB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACnC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAClC,kBAAkB,CAQpB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACrC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAClC,kBAAkB,CAuCpB"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Module-Test Traceability Matrix.
3
+ * Per D7: Fixed confidence precedence model.
4
+ */
5
+ import { writeFileSync, mkdirSync } from 'node:fs';
6
+ import { dirname, basename } from 'node:path';
7
+ import { LINK_CONFIDENCE, DEFAULT_MIN_CONFIDENCE } from '../constants.js';
8
+ /**
9
+ * Build module-test traceability matrix from graph and coverage.
10
+ * Per D7: Confidence precedence - Coverage (100) > Direct Import (90) >
11
+ * Symbol Reference (70) > Path Heuristic (50)
12
+ */
13
+ export function buildTraceabilityMatrix(db, options = {}) {
14
+ const { minConfidence = DEFAULT_MIN_CONFIDENCE, includeBelowThreshold = false, coverageData, } = options;
15
+ const entries = [];
16
+ const sourceFilesSet = new Set();
17
+ const testFilesSet = new Set();
18
+ // 1. Get all source files
19
+ const sourceFiles = db
20
+ .prepare(`
21
+ SELECT path FROM nodes
22
+ WHERE type = 'file' AND path NOT LIKE '%test%'
23
+ ORDER BY path
24
+ `)
25
+ .all();
26
+ // 2. Get all test files
27
+ const testFiles = db
28
+ .prepare(`
29
+ SELECT path FROM nodes
30
+ WHERE type = 'test'
31
+ ORDER BY path
32
+ `)
33
+ .all();
34
+ for (const source of sourceFiles) {
35
+ sourceFilesSet.add(source.path);
36
+ }
37
+ for (const test of testFiles) {
38
+ testFilesSet.add(test.path);
39
+ }
40
+ // 3. Link via coverage (highest confidence: 100)
41
+ if (coverageData) {
42
+ for (const covFile of coverageData.files) {
43
+ if (covFile.covered > 0) {
44
+ // Find tests that could have produced this coverage
45
+ // For now, we link to all tests in the same directory
46
+ const covDir = dirname(covFile.path);
47
+ for (const test of testFiles) {
48
+ const testDir = dirname(test.path);
49
+ if (testDir === covDir ||
50
+ test.path.includes(basename(covFile.path).replace(/\.[^.]+$/, ''))) {
51
+ entries.push({
52
+ sourceFile: covFile.path,
53
+ testFile: test.path,
54
+ confidence: LINK_CONFIDENCE.coverage,
55
+ linkType: 'coverage',
56
+ });
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ // 4. Link via direct import (confidence: 90)
63
+ const importEdges = db
64
+ .prepare(`
65
+ SELECT n1.path as testPath, n2.path as sourcePath
66
+ FROM edges e
67
+ JOIN nodes n1 ON e.source = n1.id
68
+ JOIN nodes n2 ON e.target = n2.id
69
+ WHERE e.kind = 'import' AND n1.type = 'test' AND n2.type = 'file'
70
+ `)
71
+ .all();
72
+ for (const edge of importEdges) {
73
+ // Don't duplicate if we already have a higher-confidence link
74
+ const existingEntry = entries.find((e) => e.sourceFile === edge.sourcePath && e.testFile === edge.testPath);
75
+ if (!existingEntry || existingEntry.confidence < LINK_CONFIDENCE.directImport) {
76
+ if (existingEntry) {
77
+ existingEntry.confidence = LINK_CONFIDENCE.directImport;
78
+ existingEntry.linkType = 'direct_import';
79
+ }
80
+ else {
81
+ entries.push({
82
+ sourceFile: edge.sourcePath,
83
+ testFile: edge.testPath,
84
+ confidence: LINK_CONFIDENCE.directImport,
85
+ linkType: 'direct_import',
86
+ });
87
+ }
88
+ }
89
+ }
90
+ // 5. Link via path heuristic (confidence: 50)
91
+ // Match test files to source files by name pattern
92
+ for (const source of sourceFiles) {
93
+ const sourceName = basename(source.path).replace(/\.[^.]+$/, '');
94
+ for (const test of testFiles) {
95
+ const testName = basename(test.path).replace(/\.[^.]+$/, '');
96
+ // Check if test name contains source name
97
+ const normalizedTestName = testName.toLowerCase().replace(/[._-]/g, '');
98
+ const normalizedSourceName = sourceName.toLowerCase().replace(/[._-]/g, '');
99
+ if (normalizedTestName.includes(normalizedSourceName) ||
100
+ normalizedSourceName.includes(normalizedTestName.replace('test', '').replace('spec', ''))) {
101
+ const existingEntry = entries.find((e) => e.sourceFile === source.path && e.testFile === test.path);
102
+ if (!existingEntry) {
103
+ entries.push({
104
+ sourceFile: source.path,
105
+ testFile: test.path,
106
+ confidence: LINK_CONFIDENCE.pathHeuristic,
107
+ linkType: 'path_heuristic',
108
+ });
109
+ }
110
+ }
111
+ }
112
+ }
113
+ // Filter by minimum confidence
114
+ const filteredEntries = includeBelowThreshold
115
+ ? entries
116
+ : entries.filter((e) => e.confidence >= minConfidence);
117
+ // Sort by confidence descending, then by source file
118
+ filteredEntries.sort((a, b) => {
119
+ if (b.confidence !== a.confidence)
120
+ return b.confidence - a.confidence;
121
+ return a.sourceFile.localeCompare(b.sourceFile);
122
+ });
123
+ // Calculate stats
124
+ const byLinkType = {};
125
+ for (const entry of filteredEntries) {
126
+ byLinkType[entry.linkType] = (byLinkType[entry.linkType] || 0) + 1;
127
+ }
128
+ const averageConfidence = filteredEntries.length > 0
129
+ ? Math.round(filteredEntries.reduce((sum, e) => sum + e.confidence, 0) / filteredEntries.length)
130
+ : 0;
131
+ return {
132
+ entries: filteredEntries,
133
+ sourceFiles: Array.from(sourceFilesSet),
134
+ testFiles: Array.from(testFilesSet),
135
+ minConfidence,
136
+ stats: {
137
+ totalLinks: filteredEntries.length,
138
+ byLinkType,
139
+ averageConfidence,
140
+ },
141
+ };
142
+ }
143
+ /**
144
+ * Export traceability matrix to JSON.
145
+ */
146
+ export function writeTraceabilityMatrix(db, outPath, options = {}) {
147
+ const matrix = buildTraceabilityMatrix(db, options);
148
+ mkdirSync(dirname(outPath), { recursive: true });
149
+ const json = JSON.stringify(matrix, null, 2).replace(/\r\n/g, '\n');
150
+ writeFileSync(outPath, json, 'utf8');
151
+ return matrix;
152
+ }
153
+ /**
154
+ * Export traceability matrix to Markdown table.
155
+ */
156
+ export function writeTraceabilityMarkdown(db, outPath, options = {}) {
157
+ const matrix = buildTraceabilityMatrix(db, options);
158
+ const lines = [];
159
+ lines.push('# Module-Test Traceability Matrix');
160
+ lines.push('');
161
+ lines.push(`> Generated with minimum confidence threshold: ${matrix.minConfidence}%`);
162
+ lines.push('');
163
+ lines.push('## Summary');
164
+ lines.push('');
165
+ lines.push(`- **Total Links**: ${matrix.stats.totalLinks}`);
166
+ lines.push(`- **Average Confidence**: ${matrix.stats.averageConfidence}%`);
167
+ lines.push(`- **Source Files**: ${matrix.sourceFiles.length}`);
168
+ lines.push(`- **Test Files**: ${matrix.testFiles.length}`);
169
+ lines.push('');
170
+ lines.push('### Links by Type');
171
+ lines.push('');
172
+ lines.push('| Type | Count | Confidence |');
173
+ lines.push('|------|-------|------------|');
174
+ lines.push(`| Coverage | ${matrix.stats.byLinkType['coverage'] || 0} | 100 |`);
175
+ lines.push(`| Direct Import | ${matrix.stats.byLinkType['direct_import'] || 0} | 90 |`);
176
+ lines.push(`| Symbol Reference | ${matrix.stats.byLinkType['symbol_reference'] || 0} | 70 |`);
177
+ lines.push(`| Path Heuristic | ${matrix.stats.byLinkType['path_heuristic'] || 0} | 50 |`);
178
+ lines.push('');
179
+ lines.push('## Matrix');
180
+ lines.push('');
181
+ lines.push('| Source File | Test File | Confidence | Link Type |');
182
+ lines.push('|-------------|-----------|------------|-----------|');
183
+ for (const entry of matrix.entries) {
184
+ lines.push(`| ${entry.sourceFile} | ${entry.testFile} | ${entry.confidence}% | ${entry.linkType} |`);
185
+ }
186
+ mkdirSync(dirname(outPath), { recursive: true });
187
+ writeFileSync(outPath, lines.join('\n'), 'utf8');
188
+ return matrix;
189
+ }
190
+ //# sourceMappingURL=traceability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceability.js","sourceRoot":"","sources":["../../../src/core/reports/traceability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Deterministic file scanner.
3
+ * Per D10: Lexicographic sorting, path normalization, hard limits.
4
+ */
5
+ import type { Toolchain } from './toolchain.js';
6
+ export interface FileEntry {
7
+ id: string;
8
+ path: string;
9
+ relativePath: string;
10
+ language: string;
11
+ tier: 1 | 2 | 3;
12
+ category: 'source' | 'test' | 'config' | 'other';
13
+ sizeBytes: number;
14
+ }
15
+ export interface ScanResult {
16
+ schemaVersion: string;
17
+ scanId: string;
18
+ rootDir: string;
19
+ files: {
20
+ total: number;
21
+ byLanguage: Record<string, number>;
22
+ byCategory: Record<string, number>;
23
+ };
24
+ languages: {
25
+ id: string;
26
+ tier: 1 | 2 | 3;
27
+ fileCount: number;
28
+ extensions: string[];
29
+ }[];
30
+ buildSystems: {
31
+ id: string;
32
+ detected: boolean;
33
+ manifests: string[];
34
+ }[];
35
+ toolchain: Toolchain;
36
+ warnings: string[];
37
+ /** Internal: file entries for indexers (not serialized to JSON) */
38
+ fileEntries?: FileEntry[];
39
+ }
40
+ export interface ScanOptions {
41
+ maxFiles?: number;
42
+ testPatterns?: string[];
43
+ }
44
+ /**
45
+ * Scan a directory and produce repo_profile.json content.
46
+ */
47
+ export declare function scanDirectory(rootDir: string, toolchain: Toolchain, options?: ScanOptions): ScanResult;
48
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/core/scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACjD,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QACH,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACtC,CAAC;IACF,SAAS,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,EAAE,CAAC;KACxB,EAAE,CAAC;IACJ,YAAY,EAAE;QACV,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,MAAM,EAAE,CAAC;KACvB,EAAE,CAAC;IACJ,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mEAAmE;IACnE,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC;CAC7B;AAyDD,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,aAAa,CACzB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE,WAAgB,GAC1B,UAAU,CA2JZ"}