@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.
- package/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/cli/commands/mcp.d.ts +6 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -0
- package/dist/cli/commands/mcp.js +11 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/report.d.ts +6 -0
- package/dist/cli/commands/report.d.ts.map +1 -0
- package/dist/cli/commands/report.js +96 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/scan.d.ts +6 -0
- package/dist/cli/commands/scan.d.ts.map +1 -0
- package/dist/cli/commands/scan.js +118 -0
- package/dist/cli/commands/scan.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +6 -0
- package/dist/cli/commands/verify.d.ts.map +1 -0
- package/dist/cli/commands/verify.js +47 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +20 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/config.d.ts +53 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +106 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/constants.d.ts +31 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +31 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/graph.d.ts +61 -0
- package/dist/core/graph.d.ts.map +1 -0
- package/dist/core/graph.js +163 -0
- package/dist/core/graph.js.map +1 -0
- package/dist/core/hashing.d.ts +37 -0
- package/dist/core/hashing.d.ts.map +1 -0
- package/dist/core/hashing.js +66 -0
- package/dist/core/hashing.js.map +1 -0
- package/dist/core/indexers/go.d.ts +14 -0
- package/dist/core/indexers/go.d.ts.map +1 -0
- package/dist/core/indexers/go.js +175 -0
- package/dist/core/indexers/go.js.map +1 -0
- package/dist/core/indexers/index.d.ts +39 -0
- package/dist/core/indexers/index.d.ts.map +1 -0
- package/dist/core/indexers/index.js +76 -0
- package/dist/core/indexers/index.js.map +1 -0
- package/dist/core/indexers/python.d.ts +14 -0
- package/dist/core/indexers/python.d.ts.map +1 -0
- package/dist/core/indexers/python.js +186 -0
- package/dist/core/indexers/python.js.map +1 -0
- package/dist/core/indexers/rust.d.ts +14 -0
- package/dist/core/indexers/rust.d.ts.map +1 -0
- package/dist/core/indexers/rust.js +156 -0
- package/dist/core/indexers/rust.js.map +1 -0
- package/dist/core/indexers/typescript.d.ts +19 -0
- package/dist/core/indexers/typescript.d.ts.map +1 -0
- package/dist/core/indexers/typescript.js +223 -0
- package/dist/core/indexers/typescript.js.map +1 -0
- package/dist/core/reports/coverage.d.ts +38 -0
- package/dist/core/reports/coverage.d.ts.map +1 -0
- package/dist/core/reports/coverage.js +175 -0
- package/dist/core/reports/coverage.js.map +1 -0
- package/dist/core/reports/index.d.ts +10 -0
- package/dist/core/reports/index.d.ts.map +1 -0
- package/dist/core/reports/index.js +7 -0
- package/dist/core/reports/index.js.map +1 -0
- package/dist/core/reports/mermaid.d.ts +41 -0
- package/dist/core/reports/mermaid.d.ts.map +1 -0
- package/dist/core/reports/mermaid.js +171 -0
- package/dist/core/reports/mermaid.js.map +1 -0
- package/dist/core/reports/traceability.d.ts +45 -0
- package/dist/core/reports/traceability.d.ts.map +1 -0
- package/dist/core/reports/traceability.js +190 -0
- package/dist/core/reports/traceability.js.map +1 -0
- package/dist/core/scanner.d.ts +48 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +191 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/toolchain.d.ts +28 -0
- package/dist/core/toolchain.d.ts.map +1 -0
- package/dist/core/toolchain.js +68 -0
- package/dist/core/toolchain.js.map +1 -0
- package/dist/core/verify.d.ts +15 -0
- package/dist/core/verify.d.ts.map +1 -0
- package/dist/core/verify.js +182 -0
- package/dist/core/verify.js.map +1 -0
- package/dist/mcp/server.d.ts +46 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +421 -0
- package/dist/mcp/server.js.map +1 -0
- package/package.json +86 -0
- package/schemas/config.schema.json +140 -0
- package/schemas/graph.schema.json +132 -0
- package/schemas/repo-profile.schema.json +118 -0
- 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"}
|