@codeledger/cli 0.6.7 → 0.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/architecture-graph/dependency-scanner.d.ts +16 -0
- package/dist/architecture-graph/dependency-scanner.d.ts.map +1 -0
- package/dist/architecture-graph/dependency-scanner.js +96 -0
- package/dist/architecture-graph/dependency-scanner.js.map +1 -0
- package/dist/architecture-graph/graph-builder.d.ts +70 -0
- package/dist/architecture-graph/graph-builder.d.ts.map +1 -0
- package/dist/architecture-graph/graph-builder.js +231 -0
- package/dist/architecture-graph/graph-builder.js.map +1 -0
- package/dist/architecture-graph/index.d.ts +4 -0
- package/dist/architecture-graph/index.d.ts.map +1 -0
- package/dist/architecture-graph/index.js +7 -0
- package/dist/architecture-graph/index.js.map +1 -0
- package/dist/architecture-graph/service-scanner.d.ts +22 -0
- package/dist/architecture-graph/service-scanner.d.ts.map +1 -0
- package/dist/architecture-graph/service-scanner.js +181 -0
- package/dist/architecture-graph/service-scanner.js.map +1 -0
- package/dist/commands/activate.d.ts.map +1 -1
- package/dist/commands/activate.js +16 -1
- package/dist/commands/activate.js.map +1 -1
- package/dist/commands/audit-export.d.ts +8 -0
- package/dist/commands/audit-export.d.ts.map +1 -0
- package/dist/commands/audit-export.js +190 -0
- package/dist/commands/audit-export.js.map +1 -0
- package/dist/commands/commit-msg.d.ts +58 -0
- package/dist/commands/commit-msg.d.ts.map +1 -0
- package/dist/commands/commit-msg.js +461 -0
- package/dist/commands/commit-msg.js.map +1 -0
- package/dist/commands/fix.d.ts +7 -0
- package/dist/commands/fix.d.ts.map +1 -0
- package/dist/commands/fix.js +107 -0
- package/dist/commands/fix.js.map +1 -0
- package/dist/commands/graph.d.ts +8 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +29 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +14 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/intent.d.ts +3 -1
- package/dist/commands/intent.d.ts.map +1 -1
- package/dist/commands/intent.js +68 -2
- package/dist/commands/intent.js.map +1 -1
- package/dist/commands/learn.d.ts +8 -0
- package/dist/commands/learn.d.ts.map +1 -0
- package/dist/commands/learn.js +33 -0
- package/dist/commands/learn.js.map +1 -0
- package/dist/commands/pack.d.ts +12 -0
- package/dist/commands/pack.d.ts.map +1 -0
- package/dist/commands/pack.js +75 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/pr-summary.d.ts +59 -0
- package/dist/commands/pr-summary.d.ts.map +1 -0
- package/dist/commands/pr-summary.js +524 -0
- package/dist/commands/pr-summary.js.map +1 -0
- package/dist/commands/serve.d.ts +13 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +179 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/session-cleanup.js +1 -0
- package/dist/commands/session-cleanup.js.map +1 -1
- package/dist/commands/session-summary.d.ts.map +1 -1
- package/dist/commands/session-summary.js +135 -3
- package/dist/commands/session-summary.js.map +1 -1
- package/dist/commands/setup-ci.d.ts +6 -4
- package/dist/commands/setup-ci.d.ts.map +1 -1
- package/dist/commands/setup-ci.js +228 -23
- package/dist/commands/setup-ci.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +35 -3
- package/dist/commands/verify.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +127 -4
- package/dist/index.js.map +1 -1
- package/dist/intent/extractor.d.ts +15 -0
- package/dist/intent/extractor.d.ts.map +1 -0
- package/dist/intent/extractor.js +149 -0
- package/dist/intent/extractor.js.map +1 -0
- package/dist/intent/fetcher.d.ts +33 -0
- package/dist/intent/fetcher.d.ts.map +1 -0
- package/dist/intent/fetcher.js +364 -0
- package/dist/intent/fetcher.js.map +1 -0
- package/dist/intent/loader.d.ts +26 -0
- package/dist/intent/loader.d.ts.map +1 -0
- package/dist/intent/loader.js +80 -0
- package/dist/intent/loader.js.map +1 -0
- package/dist/intent/types.d.ts +33 -0
- package/dist/intent/types.d.ts.map +1 -0
- package/dist/intent/types.js +9 -0
- package/dist/intent/types.js.map +1 -0
- package/dist/project-config.d.ts +38 -0
- package/dist/project-config.d.ts.map +1 -0
- package/dist/project-config.js +206 -0
- package/dist/project-config.js.map +1 -0
- package/dist/review-intelligence/detectors/architecture-graph.d.ts +18 -0
- package/dist/review-intelligence/detectors/architecture-graph.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/architecture-graph.js +73 -0
- package/dist/review-intelligence/detectors/architecture-graph.js.map +1 -0
- package/dist/review-intelligence/detectors/cjs-named-import.d.ts +13 -0
- package/dist/review-intelligence/detectors/cjs-named-import.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/cjs-named-import.js +134 -0
- package/dist/review-intelligence/detectors/cjs-named-import.js.map +1 -0
- package/dist/review-intelligence/detectors/exact-count-assertion.d.ts +17 -0
- package/dist/review-intelligence/detectors/exact-count-assertion.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/exact-count-assertion.js +93 -0
- package/dist/review-intelligence/detectors/exact-count-assertion.js.map +1 -0
- package/dist/review-intelligence/detectors/exports-map-missing.d.ts +14 -0
- package/dist/review-intelligence/detectors/exports-map-missing.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/exports-map-missing.js +131 -0
- package/dist/review-intelligence/detectors/exports-map-missing.js.map +1 -0
- package/dist/review-intelligence/detectors/fixture-keyword-drift.d.ts +12 -0
- package/dist/review-intelligence/detectors/fixture-keyword-drift.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/fixture-keyword-drift.js +82 -0
- package/dist/review-intelligence/detectors/fixture-keyword-drift.js.map +1 -0
- package/dist/review-intelligence/detectors/optional-infra-crash.d.ts +12 -0
- package/dist/review-intelligence/detectors/optional-infra-crash.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/optional-infra-crash.js +97 -0
- package/dist/review-intelligence/detectors/optional-infra-crash.js.map +1 -0
- package/dist/review-intelligence/detectors/pack-rules.d.ts +16 -0
- package/dist/review-intelligence/detectors/pack-rules.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/pack-rules.js +107 -0
- package/dist/review-intelligence/detectors/pack-rules.js.map +1 -0
- package/dist/review-intelligence/detectors/undeclared-dependency.d.ts +11 -0
- package/dist/review-intelligence/detectors/undeclared-dependency.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/undeclared-dependency.js +100 -0
- package/dist/review-intelligence/detectors/undeclared-dependency.js.map +1 -0
- package/dist/review-intelligence/engine/ast-parser.d.ts +90 -0
- package/dist/review-intelligence/engine/ast-parser.d.ts.map +1 -0
- package/dist/review-intelligence/engine/ast-parser.js +266 -0
- package/dist/review-intelligence/engine/ast-parser.js.map +1 -0
- package/dist/review-intelligence/engine/dataflow.d.ts +34 -0
- package/dist/review-intelligence/engine/dataflow.d.ts.map +1 -0
- package/dist/review-intelligence/engine/dataflow.js +115 -0
- package/dist/review-intelligence/engine/dataflow.js.map +1 -0
- package/dist/review-intelligence/engine/index.d.ts +7 -0
- package/dist/review-intelligence/engine/index.d.ts.map +1 -0
- package/dist/review-intelligence/engine/index.js +7 -0
- package/dist/review-intelligence/engine/index.js.map +1 -0
- package/dist/review-intelligence/engine/symbol-resolver.d.ts +34 -0
- package/dist/review-intelligence/engine/symbol-resolver.d.ts.map +1 -0
- package/dist/review-intelligence/engine/symbol-resolver.js +106 -0
- package/dist/review-intelligence/engine/symbol-resolver.js.map +1 -0
- package/dist/review-intelligence/fixes/index.d.ts +54 -0
- package/dist/review-intelligence/fixes/index.d.ts.map +1 -0
- package/dist/review-intelligence/fixes/index.js +346 -0
- package/dist/review-intelligence/fixes/index.js.map +1 -0
- package/dist/review-intelligence/index.d.ts +4 -1
- package/dist/review-intelligence/index.d.ts.map +1 -1
- package/dist/review-intelligence/index.js +22 -3
- package/dist/review-intelligence/index.js.map +1 -1
- package/dist/review-intelligence/invariants.d.ts +15 -0
- package/dist/review-intelligence/invariants.d.ts.map +1 -1
- package/dist/review-intelligence/invariants.js +48 -4
- package/dist/review-intelligence/invariants.js.map +1 -1
- package/dist/review-intelligence/learning/index.d.ts +39 -0
- package/dist/review-intelligence/learning/index.d.ts.map +1 -0
- package/dist/review-intelligence/learning/index.js +265 -0
- package/dist/review-intelligence/learning/index.js.map +1 -0
- package/dist/review-intelligence/packs/index.d.ts +69 -0
- package/dist/review-intelligence/packs/index.d.ts.map +1 -0
- package/dist/review-intelligence/packs/index.js +168 -0
- package/dist/review-intelligence/packs/index.js.map +1 -0
- package/dist/review-intelligence/repair-guidance.d.ts.map +1 -1
- package/dist/review-intelligence/repair-guidance.js +46 -0
- package/dist/review-intelligence/repair-guidance.js.map +1 -1
- package/dist/review-intelligence/types.d.ts +18 -9
- package/dist/review-intelligence/types.d.ts.map +1 -1
- package/dist/review-intelligence/types.js +9 -1
- package/dist/review-intelligence/types.js.map +1 -1
- package/dist/templates/claude-md.d.ts.map +1 -1
- package/dist/templates/claude-md.js +23 -128
- package/dist/templates/claude-md.js.map +1 -1
- package/dist/templates/hooks.d.ts.map +1 -1
- package/dist/templates/hooks.js +39 -0
- package/dist/templates/hooks.js.map +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
// ─── Auto-Fix Engine ────────────────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// Each fixer takes a ReviewFinding and file content, and returns a patched
|
|
4
|
+
// version of the content (or undefined if no fix can be applied).
|
|
5
|
+
/**
|
|
6
|
+
* Mutable fixer registry, keyed by rule_id. Built-in fixers are
|
|
7
|
+
* pre-populated; packs can register additional fixers via registerFixer().
|
|
8
|
+
*/
|
|
9
|
+
const fixerRegistry = {
|
|
10
|
+
'RI-RV-001': fixRuntimeValidationMissing,
|
|
11
|
+
'RI-PH-001': fixHelperDriftErrorResponse,
|
|
12
|
+
'RI-CJS-001': fixCjsNamedImport,
|
|
13
|
+
'RI-UD-001': fixUndeclaredDependency,
|
|
14
|
+
'RI-EC-001': fixExactCountAssertion,
|
|
15
|
+
'RI-IC-001': fixOptionalInfraCrash,
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Fallback fixers: checked when no exact rule_id match exists.
|
|
19
|
+
* Each entry has a predicate (matches finding?) and a fixer function.
|
|
20
|
+
* Used for pack rules with dynamic IDs (PACK-*, LEARNED-*).
|
|
21
|
+
*/
|
|
22
|
+
const fallbackFixers = [
|
|
23
|
+
{
|
|
24
|
+
matches: (f) => f.category === 'pack_rules' && f.missing_companions.length > 0,
|
|
25
|
+
fixer: fixPackRuleViolation,
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* Register a fixer for a rule ID. Replaces any existing fixer for that rule.
|
|
30
|
+
*/
|
|
31
|
+
export function registerFixer(ruleId, fixer) {
|
|
32
|
+
fixerRegistry[ruleId] = fixer;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Remove a registered fixer by rule ID. No-op if not found.
|
|
36
|
+
*/
|
|
37
|
+
export function unregisterFixer(ruleId) {
|
|
38
|
+
delete fixerRegistry[ruleId];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Register a fallback fixer that applies to findings matching a predicate.
|
|
42
|
+
*/
|
|
43
|
+
export function registerFallbackFixer(matches, fixer) {
|
|
44
|
+
fallbackFixers.push({ matches, fixer });
|
|
45
|
+
}
|
|
46
|
+
function resolveFixer(finding) {
|
|
47
|
+
const exact = fixerRegistry[finding.rule_id];
|
|
48
|
+
if (exact)
|
|
49
|
+
return exact;
|
|
50
|
+
for (const fb of fallbackFixers) {
|
|
51
|
+
if (fb.matches(finding))
|
|
52
|
+
return fb.fixer;
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check if a finding has an auto-fix available.
|
|
58
|
+
*/
|
|
59
|
+
export function isFixable(finding) {
|
|
60
|
+
return resolveFixer(finding) !== undefined;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Apply an auto-fix to a finding.
|
|
64
|
+
* Returns undefined if no fix is available or the fix cannot be applied safely.
|
|
65
|
+
*/
|
|
66
|
+
export function applyFix(finding, content) {
|
|
67
|
+
const fixer = resolveFixer(finding);
|
|
68
|
+
if (!fixer)
|
|
69
|
+
return undefined;
|
|
70
|
+
return fixer(finding, content);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Apply all available fixes to a file's findings.
|
|
74
|
+
* Applies fixes in reverse line order to preserve line numbers.
|
|
75
|
+
*/
|
|
76
|
+
export function applyAllFixes(findings, content) {
|
|
77
|
+
const fixable = findings.filter(isFixable);
|
|
78
|
+
// Sort by line descending to apply from bottom to top
|
|
79
|
+
const sorted = [...fixable].sort((a, b) => b.line - a.line);
|
|
80
|
+
let currentContent = content;
|
|
81
|
+
const applied = [];
|
|
82
|
+
for (const finding of sorted) {
|
|
83
|
+
const result = applyFix(finding, currentContent);
|
|
84
|
+
if (result) {
|
|
85
|
+
currentContent = result.newContent;
|
|
86
|
+
applied.push(result);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return { newContent: currentContent, applied };
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get all fixable rule IDs.
|
|
93
|
+
*/
|
|
94
|
+
export function getFixableRuleIds() {
|
|
95
|
+
return Object.keys(fixerRegistry);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Stamp `fixable: true` on findings that have a registered fixer
|
|
99
|
+
* (exact match OR fallback). Called by the engine after detectors run,
|
|
100
|
+
* before returning results.
|
|
101
|
+
*/
|
|
102
|
+
export function annotateFixable(findings) {
|
|
103
|
+
for (const finding of findings) {
|
|
104
|
+
if (resolveFixer(finding) !== undefined) {
|
|
105
|
+
finding.fixable = true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// ─── Individual Fixers ──────────────────────────────────────────────────────
|
|
110
|
+
function fixRuntimeValidationMissing(finding, content) {
|
|
111
|
+
const lines = content.split('\n');
|
|
112
|
+
const targetLine = finding.line - 1;
|
|
113
|
+
if (targetLine < 0 || targetLine >= lines.length)
|
|
114
|
+
return undefined;
|
|
115
|
+
// Find the route handler opening brace
|
|
116
|
+
let handlerStart = -1;
|
|
117
|
+
for (let i = targetLine; i < Math.min(targetLine + 10, lines.length); i++) {
|
|
118
|
+
if (lines[i].includes('{')) {
|
|
119
|
+
handlerStart = i;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (handlerStart === -1)
|
|
124
|
+
return undefined;
|
|
125
|
+
const validationSnippet = [
|
|
126
|
+
' // TODO: Add runtime validation for request body',
|
|
127
|
+
' // const parsed = YourSchema.safeParse(request.body);',
|
|
128
|
+
' // if (!parsed.success) return reply.status(400).send({ error: parsed.error });',
|
|
129
|
+
].join('\n');
|
|
130
|
+
const newLines = [...lines];
|
|
131
|
+
newLines.splice(handlerStart + 1, 0, validationSnippet);
|
|
132
|
+
return {
|
|
133
|
+
rule_id: finding.rule_id,
|
|
134
|
+
file: finding.file,
|
|
135
|
+
newContent: newLines.join('\n'),
|
|
136
|
+
description: 'Added runtime validation scaffold (requires completion)',
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function fixHelperDriftErrorResponse(finding, content) {
|
|
140
|
+
if (!finding.repo_standard)
|
|
141
|
+
return undefined;
|
|
142
|
+
const helperName = finding.repo_standard.helper_name;
|
|
143
|
+
const lines = content.split('\n');
|
|
144
|
+
const targetLine = finding.line - 1;
|
|
145
|
+
if (targetLine < 0 || targetLine >= lines.length)
|
|
146
|
+
return undefined;
|
|
147
|
+
const line = lines[targetLine];
|
|
148
|
+
// Match reply.status(4xx).send(...) or res.status(4xx).send(...)
|
|
149
|
+
const errorPattern = /(\b(?:reply|res|response))\s*\.\s*(?:status|code)\s*\(\s*(4\d{2}|5\d{2})\s*\)\s*\.\s*send\s*\(([^)]*)\)/;
|
|
150
|
+
const match = errorPattern.exec(line);
|
|
151
|
+
if (!match)
|
|
152
|
+
return undefined;
|
|
153
|
+
const replyVar = match[1];
|
|
154
|
+
const statusCode = match[2];
|
|
155
|
+
// Replace with helper call
|
|
156
|
+
const replacement = line.replace(errorPattern, `${helperName}(${replyVar}, ${statusCode})`);
|
|
157
|
+
const newLines = [...lines];
|
|
158
|
+
newLines[targetLine] = replacement;
|
|
159
|
+
// Check if we need to add an import for the helper
|
|
160
|
+
const hasImport = content.includes(helperName);
|
|
161
|
+
let newContent = newLines.join('\n');
|
|
162
|
+
if (!hasImport && finding.repo_standard.example_paths.length > 0) {
|
|
163
|
+
newContent = `import { ${helperName} } from '${finding.repo_standard.example_paths[0]}';\n` + newContent;
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
rule_id: finding.rule_id,
|
|
167
|
+
file: finding.file,
|
|
168
|
+
newContent,
|
|
169
|
+
description: `Replaced raw error response with ${helperName}`,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function fixCjsNamedImport(finding, content) {
|
|
173
|
+
const lines = content.split('\n');
|
|
174
|
+
const targetLine = finding.line - 1;
|
|
175
|
+
if (targetLine < 0 || targetLine >= lines.length)
|
|
176
|
+
return undefined;
|
|
177
|
+
const line = lines[targetLine];
|
|
178
|
+
// Match: import { a, b } from 'package'
|
|
179
|
+
const namedImportPattern = /^(import\s+)\{([^}]+)\}\s+(from\s+['"][^'"]+['"])/;
|
|
180
|
+
const match = namedImportPattern.exec(line.trim());
|
|
181
|
+
if (!match)
|
|
182
|
+
return undefined;
|
|
183
|
+
const namedImports = match[2].split(',').map((n) => n.trim());
|
|
184
|
+
const fromClause = match[3];
|
|
185
|
+
// Extract package name for the default import variable
|
|
186
|
+
const pkgMatch = /from\s+['"]([^'"]+)['"]/.exec(fromClause);
|
|
187
|
+
if (!pkgMatch)
|
|
188
|
+
return undefined;
|
|
189
|
+
const pkgName = pkgMatch[1]
|
|
190
|
+
.split('/')
|
|
191
|
+
.pop()
|
|
192
|
+
.replace(/[^a-zA-Z0-9]/g, '');
|
|
193
|
+
const defaultVarName = pkgName || 'mod';
|
|
194
|
+
// Rewrite: import pkg from 'package'; const { a, b } = pkg;
|
|
195
|
+
const indent = line.match(/^(\s*)/)?.[1] ?? '';
|
|
196
|
+
const newImport = `${indent}import ${defaultVarName} ${fromClause};`;
|
|
197
|
+
const destructure = `${indent}const { ${namedImports.join(', ')} } = ${defaultVarName};`;
|
|
198
|
+
const newLines = [...lines];
|
|
199
|
+
newLines[targetLine] = newImport + '\n' + destructure;
|
|
200
|
+
return {
|
|
201
|
+
rule_id: finding.rule_id,
|
|
202
|
+
file: finding.file,
|
|
203
|
+
newContent: newLines.join('\n'),
|
|
204
|
+
description: `Rewrote named CJS import to default import with destructure`,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function fixUndeclaredDependency(finding, content) {
|
|
208
|
+
// The trigger text contains the package name: "import '<pkg>' — not in dependencies"
|
|
209
|
+
const triggerMatch = /import\s+'([^']+)'/.exec(finding.trigger);
|
|
210
|
+
if (!triggerMatch)
|
|
211
|
+
return undefined;
|
|
212
|
+
const packageName = triggerMatch[1];
|
|
213
|
+
// content here is the source file, not package.json — we can add a
|
|
214
|
+
// TODO comment at the import line to flag it for the developer.
|
|
215
|
+
const lines = content.split('\n');
|
|
216
|
+
const targetLine = finding.line - 1;
|
|
217
|
+
if (targetLine < 0 || targetLine >= lines.length)
|
|
218
|
+
return undefined;
|
|
219
|
+
const indent = lines[targetLine].match(/^(\s*)/)?.[1] ?? '';
|
|
220
|
+
const todoComment = `${indent}// TODO(codeledger-fix): add '${packageName}' to package.json dependencies`;
|
|
221
|
+
// Don't duplicate if already present
|
|
222
|
+
if (content.includes(todoComment))
|
|
223
|
+
return undefined;
|
|
224
|
+
const newLines = [...lines];
|
|
225
|
+
newLines.splice(targetLine, 0, todoComment);
|
|
226
|
+
return {
|
|
227
|
+
rule_id: finding.rule_id,
|
|
228
|
+
file: finding.file,
|
|
229
|
+
newContent: newLines.join('\n'),
|
|
230
|
+
description: `Flagged undeclared dependency '${packageName}' with TODO comment`,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function fixExactCountAssertion(finding, content) {
|
|
234
|
+
const lines = content.split('\n');
|
|
235
|
+
const targetLine = finding.line - 1;
|
|
236
|
+
if (targetLine < 0 || targetLine >= lines.length)
|
|
237
|
+
return undefined;
|
|
238
|
+
const line = lines[targetLine];
|
|
239
|
+
// Replace .toBe(N) with .toBeGreaterThan(0) for small N, keep comment
|
|
240
|
+
const toBeMatch = /expect\s*\(([^)]*\.length)\s*\)\s*\.toBe\s*\(\s*(\d+)\s*\)/.exec(line);
|
|
241
|
+
if (toBeMatch) {
|
|
242
|
+
const expr = toBeMatch[1];
|
|
243
|
+
const count = toBeMatch[2];
|
|
244
|
+
const replacement = line.replace(toBeMatch[0], `expect(${expr}).toBeGreaterThan(0) /* was .toBe(${count}) */`);
|
|
245
|
+
const newLines = [...lines];
|
|
246
|
+
newLines[targetLine] = replacement;
|
|
247
|
+
return {
|
|
248
|
+
rule_id: finding.rule_id,
|
|
249
|
+
file: finding.file,
|
|
250
|
+
newContent: newLines.join('\n'),
|
|
251
|
+
description: `Replaced brittle .toBe(${count}) with .toBeGreaterThan(0)`,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
// Replace .toHaveLength(N) with .toBeGreaterThan(0) on .length
|
|
255
|
+
const haveLengthMatch = /expect\s*\(([^)]*)\)\s*\.toHaveLength\s*\(\s*(\d+)\s*\)/.exec(line);
|
|
256
|
+
if (haveLengthMatch) {
|
|
257
|
+
const expr = haveLengthMatch[1];
|
|
258
|
+
const count = haveLengthMatch[2];
|
|
259
|
+
const replacement = line.replace(haveLengthMatch[0], `expect(${expr}.length).toBeGreaterThan(0) /* was .toHaveLength(${count}) */`);
|
|
260
|
+
const newLines = [...lines];
|
|
261
|
+
newLines[targetLine] = replacement;
|
|
262
|
+
return {
|
|
263
|
+
rule_id: finding.rule_id,
|
|
264
|
+
file: finding.file,
|
|
265
|
+
newContent: newLines.join('\n'),
|
|
266
|
+
description: `Replaced brittle .toHaveLength(${count}) with .toBeGreaterThan(0)`,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
// Replace assert.equal(x.length, N)
|
|
270
|
+
const assertMatch = /assert\s*\.(equal|strictEqual)\s*\(([^,]*\.length)\s*,\s*(\d+)\s*\)/.exec(line);
|
|
271
|
+
if (assertMatch) {
|
|
272
|
+
const method = assertMatch[1];
|
|
273
|
+
const expr = assertMatch[2];
|
|
274
|
+
const count = assertMatch[3];
|
|
275
|
+
const replacement = line.replace(assertMatch[0], `assert.ok(${expr} > 0) /* was assert.${method}(${expr}, ${count}) */`);
|
|
276
|
+
const newLines = [...lines];
|
|
277
|
+
newLines[targetLine] = replacement;
|
|
278
|
+
return {
|
|
279
|
+
rule_id: finding.rule_id,
|
|
280
|
+
file: finding.file,
|
|
281
|
+
newContent: newLines.join('\n'),
|
|
282
|
+
description: `Replaced brittle assert.${method}(x.length, ${count}) with assert.ok(x.length > 0)`,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
function fixOptionalInfraCrash(finding, content) {
|
|
288
|
+
const lines = content.split('\n');
|
|
289
|
+
const targetLine = finding.line - 1;
|
|
290
|
+
if (targetLine < 0 || targetLine >= lines.length)
|
|
291
|
+
return undefined;
|
|
292
|
+
const line = lines[targetLine];
|
|
293
|
+
const indent = line.match(/^(\s*)/)?.[1] ?? '';
|
|
294
|
+
// Find the end of the statement (semicolon or next line)
|
|
295
|
+
let endLine = targetLine;
|
|
296
|
+
for (let i = targetLine; i < Math.min(targetLine + 5, lines.length); i++) {
|
|
297
|
+
if (lines[i].includes(';') || lines[i].includes('}')) {
|
|
298
|
+
endLine = i;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// Extract the statement lines
|
|
303
|
+
const stmtLines = lines.slice(targetLine, endLine + 1);
|
|
304
|
+
const wrappedStmt = stmtLines.map((l) => `${indent} ${l.trim()}`).join('\n');
|
|
305
|
+
const tryCatch = [
|
|
306
|
+
`${indent}try {`,
|
|
307
|
+
wrappedStmt,
|
|
308
|
+
`${indent}} catch (err) {`,
|
|
309
|
+
`${indent} // Optional infra — degrade gracefully`,
|
|
310
|
+
`${indent} console.warn('Optional infra init failed:', err);`,
|
|
311
|
+
`${indent}}`,
|
|
312
|
+
].join('\n');
|
|
313
|
+
const newLines = [...lines];
|
|
314
|
+
newLines.splice(targetLine, endLine - targetLine + 1, tryCatch);
|
|
315
|
+
return {
|
|
316
|
+
rule_id: finding.rule_id,
|
|
317
|
+
file: finding.file,
|
|
318
|
+
newContent: newLines.join('\n'),
|
|
319
|
+
description: 'Wrapped optional infra initialization in try/catch',
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Generic fixer for pack rule violations (PACK-* and LEARNED-* rules).
|
|
324
|
+
* Adds a TODO comment above the offending line referencing the sanctioned helper.
|
|
325
|
+
*/
|
|
326
|
+
function fixPackRuleViolation(finding, content) {
|
|
327
|
+
const lines = content.split('\n');
|
|
328
|
+
const targetLine = finding.line - 1;
|
|
329
|
+
if (targetLine < 0 || targetLine >= lines.length)
|
|
330
|
+
return undefined;
|
|
331
|
+
const indent = lines[targetLine].match(/^(\s*)/)?.[1] ?? '';
|
|
332
|
+
const companion = finding.missing_companions[0] ?? 'Replace with sanctioned pattern';
|
|
333
|
+
const todoComment = `${indent}// TODO(codeledger-fix): ${companion} [${finding.rule_id}]`;
|
|
334
|
+
// Don't duplicate if already present
|
|
335
|
+
if (content.includes(`[${finding.rule_id}]`))
|
|
336
|
+
return undefined;
|
|
337
|
+
const newLines = [...lines];
|
|
338
|
+
newLines.splice(targetLine, 0, todoComment);
|
|
339
|
+
return {
|
|
340
|
+
rule_id: finding.rule_id,
|
|
341
|
+
file: finding.file,
|
|
342
|
+
newContent: newLines.join('\n'),
|
|
343
|
+
description: `Flagged pack rule violation: ${companion}`,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/review-intelligence/fixes/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { ReviewIntelligenceResult, ReviewIntelligenceOptions, ReviewIntelligencePolicy } from './types.js';
|
|
2
2
|
export type { ReviewIntelligenceResult, ReviewIntelligenceOptions, ReviewIntelligencePolicy, ReviewFinding, } from './types.js';
|
|
3
|
-
export { getAvailableInvariantNames } from './invariants.js';
|
|
3
|
+
export { getAvailableInvariantNames, registerDetector, unregisterDetector } from './invariants.js';
|
|
4
|
+
export { registerFixer, unregisterFixer, getFixableRuleIds, annotateFixable } from './fixes/index.js';
|
|
5
|
+
export { listPacks, enablePack, disablePack, addPack, getEnabledPackRules } from './packs/index.js';
|
|
6
|
+
export type { InvariantPack, PackRule, PackRegistry } from './packs/index.js';
|
|
4
7
|
export { formatHumanOutput, formatJsonOutput, formatDebugOutput, formatVerifySummaryLine } from './output.js';
|
|
5
8
|
export { loadBaseline, createBaselineFromFindings as createBaseline, saveBaseline, filterBaselined as filterNewFindings, updateBaseline as mergeIntoBaseline, DEFAULT_BASELINE_PATH, } from './baseline.js';
|
|
6
9
|
/** Default policy when no review_intelligence config is present */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/review-intelligence/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EAIzB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/review-intelligence/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EAIzB,MAAM,YAAY,CAAC;AAiBpB,YAAY,EACV,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACxB,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACtG,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACpG,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC9G,OAAO,EACL,YAAY,EACZ,0BAA0B,IAAI,cAAc,EAC5C,YAAY,EACZ,eAAe,IAAI,iBAAiB,EACpC,cAAc,IAAI,iBAAiB,EACnC,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAEvB,mEAAmE;AACnE,eAAO,MAAM,kCAAkC,EAAE,wBAWhD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,yBAAyB,GACjC,wBAAwB,CAmI1B"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { getEnabledDetectors, getAvailableInvariantNames } from './invariants.js';
|
|
4
|
+
import { annotateFixable } from './fixes/index.js';
|
|
5
|
+
import { getEnabledPackRules } from './packs/index.js';
|
|
6
|
+
import { createPackRulesDetector } from './detectors/pack-rules.js';
|
|
4
7
|
import { discoverRepoStandards } from './standards-discovery.js';
|
|
5
8
|
import { sortFindings, determineStatus } from './severity.js';
|
|
6
9
|
import { filterSuppressed } from './suppressions.js';
|
|
7
10
|
import { loadBaseline, filterBaselined, createBaselineFromFindings, updateBaseline, saveBaseline, DEFAULT_BASELINE_PATH, } from './baseline.js';
|
|
8
|
-
export { getAvailableInvariantNames } from './invariants.js';
|
|
11
|
+
export { getAvailableInvariantNames, registerDetector, unregisterDetector } from './invariants.js';
|
|
12
|
+
export { registerFixer, unregisterFixer, getFixableRuleIds, annotateFixable } from './fixes/index.js';
|
|
13
|
+
export { listPacks, enablePack, disablePack, addPack, getEnabledPackRules } from './packs/index.js';
|
|
9
14
|
export { formatHumanOutput, formatJsonOutput, formatDebugOutput, formatVerifySummaryLine } from './output.js';
|
|
10
15
|
export { loadBaseline, createBaselineFromFindings as createBaseline, saveBaseline, filterBaselined as filterNewFindings, updateBaseline as mergeIntoBaseline, DEFAULT_BASELINE_PATH, } from './baseline.js';
|
|
11
16
|
/** Default policy when no review_intelligence config is present */
|
|
@@ -16,6 +21,9 @@ export const DEFAULT_REVIEW_INTELLIGENCE_POLICY = {
|
|
|
16
21
|
runtime_validation: { enabled: true },
|
|
17
22
|
outbound_io: { enabled: true },
|
|
18
23
|
platform_helpers: { enabled: true },
|
|
24
|
+
build_runtime: { enabled: true },
|
|
25
|
+
test_integrity: { enabled: true },
|
|
26
|
+
architecture_graph: { enabled: true },
|
|
19
27
|
},
|
|
20
28
|
};
|
|
21
29
|
/**
|
|
@@ -35,8 +43,9 @@ export function runReviewIntelligence(options) {
|
|
|
35
43
|
// Validate invariant filter
|
|
36
44
|
if (options.invariant) {
|
|
37
45
|
const available = getAvailableInvariantNames();
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
// 'pack_rules' is always valid — it's the dynamic pack rules detector
|
|
47
|
+
if (options.invariant !== 'pack_rules' && !available.includes(options.invariant)) {
|
|
48
|
+
throw new Error(`Unknown invariant "${options.invariant}". Available: ${[...available, 'pack_rules'].join(', ')}`);
|
|
40
49
|
}
|
|
41
50
|
}
|
|
42
51
|
// 1. Load file contents
|
|
@@ -65,6 +74,16 @@ export function runReviewIntelligence(options) {
|
|
|
65
74
|
for (const detector of detectors) {
|
|
66
75
|
rawFindings.push(...detector.analyze(ctx));
|
|
67
76
|
}
|
|
77
|
+
// 3a. Run enabled pack rules (if any packs are enabled and not filtered out)
|
|
78
|
+
if (!options.invariant || options.invariant === 'pack_rules') {
|
|
79
|
+
const packRules = getEnabledPackRules(options.cwd);
|
|
80
|
+
if (packRules.length > 0) {
|
|
81
|
+
const packDetector = createPackRulesDetector(packRules);
|
|
82
|
+
rawFindings.push(...packDetector.analyze(ctx));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// 3b. Annotate fixable findings (stamp fixable: true where a fixer exists)
|
|
86
|
+
annotateFixable(rawFindings);
|
|
68
87
|
const rawTotal = rawFindings.length;
|
|
69
88
|
// 4. Filter suppressions (inline codeledger: ignore directives)
|
|
70
89
|
const { active: afterSuppression, suppressed: suppressedPairs } = filterSuppressed(rawFindings, fileContents);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/review-intelligence/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AASjC,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,YAAY,EACZ,qBAAqB,GACtB,MAAM,eAAe,CAAC;AASvB,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/review-intelligence/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import type { InvariantDetector, ReviewIntelligencePolicy } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Register a new invariant detector. The detector is appended to the
|
|
4
|
+
* registry. Multiple detectors may share a name (category grouping) —
|
|
5
|
+
* this is by design for built-ins like `build_runtime` and `test_integrity`.
|
|
6
|
+
*
|
|
7
|
+
* If you want to replace a specific detector, unregister it first.
|
|
8
|
+
*/
|
|
9
|
+
export declare function registerDetector(detector: InvariantDetector): void;
|
|
10
|
+
/**
|
|
11
|
+
* Remove a registered detector by name. No-op if the name is not found.
|
|
12
|
+
*/
|
|
13
|
+
export declare function unregisterDetector(name: string): void;
|
|
2
14
|
/**
|
|
3
15
|
* Get enabled detectors based on policy configuration and optional filter.
|
|
4
16
|
*/
|
|
5
17
|
export declare function getEnabledDetectors(policy: ReviewIntelligencePolicy, invariantFilter?: string): InvariantDetector[];
|
|
6
18
|
/**
|
|
7
19
|
* Get all available detector names (for --invariant flag validation).
|
|
20
|
+
* Deduplicated because multiple detectors may share a category name
|
|
21
|
+
* (e.g. build_runtime groups undeclared-dependency, exports-map-missing,
|
|
22
|
+
* cjs-named-import, and optional-infra-crash).
|
|
8
23
|
*/
|
|
9
24
|
export declare function getAvailableInvariantNames(): string[];
|
|
10
25
|
//# sourceMappingURL=invariants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invariants.d.ts","sourceRoot":"","sources":["../../src/review-intelligence/invariants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"invariants.d.ts","sourceRoot":"","sources":["../../src/review-intelligence/invariants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAkC9E;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAElE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKrD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,wBAAwB,EAChC,eAAe,CAAC,EAAE,MAAM,GACvB,iBAAiB,EAAE,CAWrB;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,EAAE,CAErD"}
|
|
@@ -1,17 +1,58 @@
|
|
|
1
1
|
import { runtimeValidationDetector } from './detectors/runtime-validation.js';
|
|
2
2
|
import { outboundIODetector } from './detectors/outbound-io.js';
|
|
3
3
|
import { platformHelpersDetector } from './detectors/platform-helpers.js';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import { undeclaredDependencyDetector } from './detectors/undeclared-dependency.js';
|
|
5
|
+
import { exportsMapMissingDetector } from './detectors/exports-map-missing.js';
|
|
6
|
+
import { cjsNamedImportDetector } from './detectors/cjs-named-import.js';
|
|
7
|
+
import { optionalInfraCrashDetector } from './detectors/optional-infra-crash.js';
|
|
8
|
+
import { fixtureKeywordDriftDetector } from './detectors/fixture-keyword-drift.js';
|
|
9
|
+
import { exactCountAssertionDetector } from './detectors/exact-count-assertion.js';
|
|
10
|
+
import { architectureGraphDetector } from './detectors/architecture-graph.js';
|
|
11
|
+
/**
|
|
12
|
+
* Mutable detector registry. Built-in detectors are pre-populated; packs and
|
|
13
|
+
* external callers may register additional detectors via registerDetector().
|
|
14
|
+
*
|
|
15
|
+
* Note: Multiple detectors may share a `name` (category grouping). For
|
|
16
|
+
* example, `build_runtime` groups undeclared-dependency, exports-map-missing,
|
|
17
|
+
* cjs-named-import, and optional-infra-crash. The name controls which policy
|
|
18
|
+
* toggle (`invariants.build_runtime.enabled`) and `--invariant` filter apply.
|
|
19
|
+
*/
|
|
20
|
+
const detectorRegistry = [
|
|
6
21
|
runtimeValidationDetector,
|
|
7
22
|
outboundIODetector,
|
|
8
23
|
platformHelpersDetector,
|
|
24
|
+
undeclaredDependencyDetector,
|
|
25
|
+
exportsMapMissingDetector,
|
|
26
|
+
cjsNamedImportDetector,
|
|
27
|
+
optionalInfraCrashDetector,
|
|
28
|
+
fixtureKeywordDriftDetector,
|
|
29
|
+
exactCountAssertionDetector,
|
|
30
|
+
architectureGraphDetector,
|
|
9
31
|
];
|
|
32
|
+
/**
|
|
33
|
+
* Register a new invariant detector. The detector is appended to the
|
|
34
|
+
* registry. Multiple detectors may share a name (category grouping) —
|
|
35
|
+
* this is by design for built-ins like `build_runtime` and `test_integrity`.
|
|
36
|
+
*
|
|
37
|
+
* If you want to replace a specific detector, unregister it first.
|
|
38
|
+
*/
|
|
39
|
+
export function registerDetector(detector) {
|
|
40
|
+
detectorRegistry.push(detector);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Remove a registered detector by name. No-op if the name is not found.
|
|
44
|
+
*/
|
|
45
|
+
export function unregisterDetector(name) {
|
|
46
|
+
const idx = detectorRegistry.findIndex((d) => d.name === name);
|
|
47
|
+
if (idx !== -1) {
|
|
48
|
+
detectorRegistry.splice(idx, 1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
10
51
|
/**
|
|
11
52
|
* Get enabled detectors based on policy configuration and optional filter.
|
|
12
53
|
*/
|
|
13
54
|
export function getEnabledDetectors(policy, invariantFilter) {
|
|
14
|
-
let detectors =
|
|
55
|
+
let detectors = detectorRegistry.filter((d) => {
|
|
15
56
|
const config = policy.invariants[d.name];
|
|
16
57
|
return config?.enabled !== false;
|
|
17
58
|
});
|
|
@@ -22,8 +63,11 @@ export function getEnabledDetectors(policy, invariantFilter) {
|
|
|
22
63
|
}
|
|
23
64
|
/**
|
|
24
65
|
* Get all available detector names (for --invariant flag validation).
|
|
66
|
+
* Deduplicated because multiple detectors may share a category name
|
|
67
|
+
* (e.g. build_runtime groups undeclared-dependency, exports-map-missing,
|
|
68
|
+
* cjs-named-import, and optional-infra-crash).
|
|
25
69
|
*/
|
|
26
70
|
export function getAvailableInvariantNames() {
|
|
27
|
-
return
|
|
71
|
+
return [...new Set(detectorRegistry.map((d) => d.name))];
|
|
28
72
|
}
|
|
29
73
|
//# sourceMappingURL=invariants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invariants.js","sourceRoot":"","sources":["../../src/review-intelligence/invariants.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"invariants.js","sourceRoot":"","sources":["../../src/review-intelligence/invariants.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAE9E;;;;;;;;GAQG;AACH,MAAM,gBAAgB,GAAwB;IAC5C,yBAAyB;IACzB,kBAAkB;IAClB,uBAAuB;IACvB,4BAA4B;IAC5B,yBAAyB;IACzB,sBAAsB;IACtB,0BAA0B;IAC1B,2BAA2B;IAC3B,2BAA2B;IAC3B,yBAAyB;CAC1B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAA2B;IAC1D,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,GAAG,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAC/D,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAgC,EAChC,eAAwB;IAExB,IAAI,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzC,OAAO,MAAM,EAAE,OAAO,KAAK,KAAK,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,IAAI,eAAe,EAAE,CAAC;QACpB,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B;IACxC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { InvariantPack } from '../packs/index.js';
|
|
2
|
+
/** A discovered convention */
|
|
3
|
+
export interface DiscoveredConvention {
|
|
4
|
+
/** Category of convention */
|
|
5
|
+
category: ConventionCategory;
|
|
6
|
+
/** The helper/wrapper/pattern name */
|
|
7
|
+
name: string;
|
|
8
|
+
/** Usage count across the codebase */
|
|
9
|
+
usageCount: number;
|
|
10
|
+
/** Total callsites checked for this category */
|
|
11
|
+
totalInCategory: number;
|
|
12
|
+
/** Usage percentage */
|
|
13
|
+
percentage: number;
|
|
14
|
+
/** Files where this is defined */
|
|
15
|
+
definedIn: string[];
|
|
16
|
+
/** Sample usage locations */
|
|
17
|
+
sampleUsages: string[];
|
|
18
|
+
}
|
|
19
|
+
export type ConventionCategory = 'outbound_http' | 'cache_key' | 'error_response' | 'database_query' | 'logging' | 'validation';
|
|
20
|
+
/** Result of repository learning */
|
|
21
|
+
export interface LearnResult {
|
|
22
|
+
/** All discovered conventions */
|
|
23
|
+
conventions: DiscoveredConvention[];
|
|
24
|
+
/** Files scanned */
|
|
25
|
+
filesScanned: number;
|
|
26
|
+
/** Duration in milliseconds */
|
|
27
|
+
durationMs: number;
|
|
28
|
+
/** Generated pack suggestion (if conventions found) */
|
|
29
|
+
suggestedPack?: InvariantPack;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Scan the repository and discover conventions.
|
|
33
|
+
*/
|
|
34
|
+
export declare function learnConventions(cwd: string): LearnResult;
|
|
35
|
+
/**
|
|
36
|
+
* Format learn results for human-readable console output.
|
|
37
|
+
*/
|
|
38
|
+
export declare function formatLearnOutput(result: LearnResult): string;
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/learning/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAY,MAAM,mBAAmB,CAAC;AAEjE,8BAA8B;AAC9B,MAAM,WAAW,oBAAoB;IACnC,6BAA6B;IAC7B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,MAAM,kBAAkB,GAC1B,eAAe,GACf,WAAW,GACX,gBAAgB,GAChB,gBAAgB,GAChB,SAAS,GACT,YAAY,CAAC;AAEjB,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B,iCAAiC;IACjC,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,oBAAoB;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AA4DD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAsCzD;AAuGD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAuC7D"}
|