@codeledger/cli 0.6.6 → 0.6.8
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/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/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/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/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/setup-ci.d.ts +6 -4
- package/dist/commands/setup-ci.d.ts.map +1 -1
- package/dist/commands/setup-ci.js +216 -23
- package/dist/commands/setup-ci.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +82 -3
- package/dist/index.js.map +1 -1
- 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/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 +36 -0
- package/dist/review-intelligence/fixes/index.d.ts.map +1 -0
- package/dist/review-intelligence/fixes/index.js +157 -0
- package/dist/review-intelligence/fixes/index.js.map +1 -0
- package/dist/review-intelligence/index.d.ts.map +1 -1
- package/dist/review-intelligence/index.js +2 -0
- package/dist/review-intelligence/index.js.map +1 -1
- package/dist/review-intelligence/invariants.d.ts.map +1 -1
- package/dist/review-intelligence/invariants.js +14 -1
- 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 +6 -1
- package/dist/review-intelligence/types.d.ts.map +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixture-keyword-drift.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/fixture-keyword-drift.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,aAAa,CAAC;AAErB;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,EAAE,iBAgDzC,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* INVARIANT — fixture_keyword_drift
|
|
3
|
+
*
|
|
4
|
+
* Detect test expectations that rely on specific string/keyword values
|
|
5
|
+
* that may have drifted from the actual fixture data. Common in search
|
|
6
|
+
* tests where the expected keyword must exist in the test fixtures.
|
|
7
|
+
*
|
|
8
|
+
* Severity: P2 (can cause flaky tests)
|
|
9
|
+
*/
|
|
10
|
+
export const fixtureKeywordDriftDetector = {
|
|
11
|
+
name: 'test_integrity',
|
|
12
|
+
analyze(ctx) {
|
|
13
|
+
const findings = [];
|
|
14
|
+
for (const filePath of ctx.files) {
|
|
15
|
+
const content = ctx.fileContents.get(filePath);
|
|
16
|
+
if (!content)
|
|
17
|
+
continue;
|
|
18
|
+
// Only analyze test files
|
|
19
|
+
if (!isTestFile(filePath))
|
|
20
|
+
continue;
|
|
21
|
+
const lines = content.split('\n');
|
|
22
|
+
for (let i = 0; i < lines.length; i++) {
|
|
23
|
+
const line = lines[i];
|
|
24
|
+
const trimmed = line.trim();
|
|
25
|
+
// Skip comments
|
|
26
|
+
if (trimmed.startsWith('//') || trimmed.startsWith('*'))
|
|
27
|
+
continue;
|
|
28
|
+
// Detect hardcoded search/filter expectations
|
|
29
|
+
// Pattern: searching for a specific keyword and then asserting results contain it
|
|
30
|
+
const searchAssertMatch = detectSearchKeywordAssertion(trimmed, lines, i);
|
|
31
|
+
if (searchAssertMatch) {
|
|
32
|
+
findings.push({
|
|
33
|
+
rule_id: 'RI-FK-001',
|
|
34
|
+
title: 'Test relies on hardcoded fixture keyword',
|
|
35
|
+
severity: 'P2',
|
|
36
|
+
category: 'test_integrity',
|
|
37
|
+
file: filePath,
|
|
38
|
+
line: i + 1,
|
|
39
|
+
trigger: searchAssertMatch,
|
|
40
|
+
missing_companions: [
|
|
41
|
+
'Extract keyword from fixture data or use a data-driven approach',
|
|
42
|
+
],
|
|
43
|
+
why_it_matters: 'Hardcoded keywords in test assertions can silently become wrong if fixture data changes. ' +
|
|
44
|
+
'Extract the expected keyword from the fixture or seed data to keep the test robust.',
|
|
45
|
+
confidence: 'medium',
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return findings;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Detect patterns where a test searches for a hardcoded string and then
|
|
55
|
+
* asserts on the results.
|
|
56
|
+
*/
|
|
57
|
+
function detectSearchKeywordAssertion(line, allLines, lineIndex) {
|
|
58
|
+
// Pattern 1: search/filter with a hardcoded string literal, followed by assertion
|
|
59
|
+
const searchPatterns = [
|
|
60
|
+
/(?:search|filter|find|query)\s*\(\s*['"]([^'"]{3,})['"]\s*\)/,
|
|
61
|
+
/(?:search|filter|find|query)\s*\(\s*\{[^}]*(?:keyword|query|term|q)\s*:\s*['"]([^'"]{3,})['"]/,
|
|
62
|
+
/(?:where|contains|includes|match)\s*\(\s*['"]([^'"]{3,})['"]\s*\)/,
|
|
63
|
+
];
|
|
64
|
+
for (const pattern of searchPatterns) {
|
|
65
|
+
const match = pattern.exec(line);
|
|
66
|
+
if (match) {
|
|
67
|
+
// Check if there's an assertion within the next 10 lines
|
|
68
|
+
const windowEnd = Math.min(allLines.length, lineIndex + 10);
|
|
69
|
+
for (let j = lineIndex + 1; j < windowEnd; j++) {
|
|
70
|
+
const nextLine = allLines[j];
|
|
71
|
+
if (nextLine && /expect\s*\(/.test(nextLine)) {
|
|
72
|
+
return `hardcoded search keyword '${match[1]}'`;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
function isTestFile(filePath) {
|
|
80
|
+
return /\.(?:test|spec|e2e)\.(?:ts|tsx|js|jsx|mts|mjs)$/.test(filePath);
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=fixture-keyword-drift.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixture-keyword-drift.js","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/fixture-keyword-drift.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAsB;IAC5D,IAAI,EAAE,gBAAgB;IAEtB,OAAO,CAAC,GAAoB;QAC1B,MAAM,QAAQ,GAAoB,EAAE,CAAC;QAErC,KAAK,MAAM,QAAQ,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC/C,IAAI,CAAC,OAAO;gBAAE,SAAS;YAEvB,0BAA0B;YAC1B,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;gBACvB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAE5B,gBAAgB;gBAChB,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,SAAS;gBAElE,8CAA8C;gBAC9C,kFAAkF;gBAClF,MAAM,iBAAiB,GAAG,4BAA4B,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;gBAC1E,IAAI,iBAAiB,EAAE,CAAC;oBACtB,QAAQ,CAAC,IAAI,CAAC;wBACZ,OAAO,EAAE,WAAW;wBACpB,KAAK,EAAE,0CAA0C;wBACjD,QAAQ,EAAE,IAAI;wBACd,QAAQ,EAAE,gBAAgB;wBAC1B,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,CAAC,GAAG,CAAC;wBACX,OAAO,EAAE,iBAAiB;wBAC1B,kBAAkB,EAAE;4BAClB,iEAAiE;yBAClE;wBACD,cAAc,EACZ,2FAA2F;4BAC3F,qFAAqF;wBACvF,UAAU,EAAE,QAAQ;qBACrB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF;;;GAGG;AACH,SAAS,4BAA4B,CACnC,IAAY,EACZ,QAAkB,EAClB,SAAiB;IAEjB,kFAAkF;IAClF,MAAM,cAAc,GAAG;QACrB,8DAA8D;QAC9D,+FAA+F;QAC/F,mEAAmE;KACpE,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,KAAK,EAAE,CAAC;YACV,yDAAyD;YACzD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,EAAE,CAAC,CAAC;YAC5D,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC7B,IAAI,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC7C,OAAO,6BAA6B,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;gBAClD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,UAAU,CAAC,QAAgB;IAClC,OAAO,iDAAiD,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { InvariantDetector } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* INVARIANT — optional_infra_crash
|
|
4
|
+
*
|
|
5
|
+
* Detect telemetry, metrics, tracing, or other optional infrastructure
|
|
6
|
+
* initialization that is NOT wrapped in try/catch. If these optional
|
|
7
|
+
* services are down, the application should not crash on startup.
|
|
8
|
+
*
|
|
9
|
+
* Severity: P1 (can crash production on infra issues)
|
|
10
|
+
*/
|
|
11
|
+
export declare const optionalInfraCrashDetector: InvariantDetector;
|
|
12
|
+
//# sourceMappingURL=optional-infra-crash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optional-infra-crash.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/optional-infra-crash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,aAAa,CAAC;AAGrB;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,EAAE,iBAgDxC,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { isInsideTryCatch } from '../engine/dataflow.js';
|
|
2
|
+
/**
|
|
3
|
+
* INVARIANT — optional_infra_crash
|
|
4
|
+
*
|
|
5
|
+
* Detect telemetry, metrics, tracing, or other optional infrastructure
|
|
6
|
+
* initialization that is NOT wrapped in try/catch. If these optional
|
|
7
|
+
* services are down, the application should not crash on startup.
|
|
8
|
+
*
|
|
9
|
+
* Severity: P1 (can crash production on infra issues)
|
|
10
|
+
*/
|
|
11
|
+
export const optionalInfraCrashDetector = {
|
|
12
|
+
name: 'build_runtime',
|
|
13
|
+
analyze(ctx) {
|
|
14
|
+
const findings = [];
|
|
15
|
+
for (const filePath of ctx.files) {
|
|
16
|
+
const content = ctx.fileContents.get(filePath);
|
|
17
|
+
if (!content)
|
|
18
|
+
continue;
|
|
19
|
+
if (!isAnalyzableFile(filePath))
|
|
20
|
+
continue;
|
|
21
|
+
const lines = content.split('\n');
|
|
22
|
+
for (let i = 0; i < lines.length; i++) {
|
|
23
|
+
const line = lines[i];
|
|
24
|
+
const trimmed = line.trim();
|
|
25
|
+
// Skip comments
|
|
26
|
+
if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*'))
|
|
27
|
+
continue;
|
|
28
|
+
if (trimmed.startsWith('import '))
|
|
29
|
+
continue;
|
|
30
|
+
// Detect optional infra initialization patterns
|
|
31
|
+
const infraMatch = matchesInfraInit(trimmed);
|
|
32
|
+
if (!infraMatch)
|
|
33
|
+
continue;
|
|
34
|
+
// Check if this line is inside a try/catch block
|
|
35
|
+
const tryCatchInfo = isInsideTryCatch(content, i + 1);
|
|
36
|
+
if (tryCatchInfo.isWrapped)
|
|
37
|
+
continue;
|
|
38
|
+
findings.push({
|
|
39
|
+
rule_id: 'RI-IC-001',
|
|
40
|
+
title: 'Optional infrastructure init without try/catch',
|
|
41
|
+
severity: 'P1',
|
|
42
|
+
category: 'build_runtime',
|
|
43
|
+
file: filePath,
|
|
44
|
+
line: i + 1,
|
|
45
|
+
trigger: infraMatch,
|
|
46
|
+
missing_companions: ['Wrap in try/catch to prevent crash when infra is unavailable'],
|
|
47
|
+
why_it_matters: 'Optional infrastructure (telemetry, metrics, tracing) should never crash the application ' +
|
|
48
|
+
'if the backing service is unavailable. Wrap initialization in try/catch and degrade gracefully.',
|
|
49
|
+
confidence: 'medium',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return findings;
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Check if a line matches an optional infra initialization pattern.
|
|
58
|
+
* Returns the matched description or undefined.
|
|
59
|
+
*/
|
|
60
|
+
function matchesInfraInit(line) {
|
|
61
|
+
const patterns = [
|
|
62
|
+
{
|
|
63
|
+
pattern: /\b(?:initTelemetry|setupTelemetry|startTelemetry|initTracing|setupTracing|startTracing)\s*\(/,
|
|
64
|
+
description: 'telemetry/tracing initialization',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
pattern: /\b(?:initMetrics|setupMetrics|startMetrics|metricsClient|statsClient)\s*[.(]/,
|
|
68
|
+
description: 'metrics initialization',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
pattern: /\b(?:DatadogTracer|dd-trace|opentelemetry|@opentelemetry)\b/,
|
|
72
|
+
description: 'tracing SDK initialization',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
pattern: /\b(?:StatsD|statsd|collectd|prometheus)\s*[.(]/i,
|
|
76
|
+
description: 'metrics SDK initialization',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
pattern: /\b(?:Sentry\.init|initSentry|setupSentry|Bugsnag\.start)\s*\(/,
|
|
80
|
+
description: 'error tracking initialization',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
pattern: /\b(?:newrelic|elasticApm|apm\.start)\b/,
|
|
84
|
+
description: 'APM initialization',
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
for (const { pattern, description } of patterns) {
|
|
88
|
+
if (pattern.test(line)) {
|
|
89
|
+
return description;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
function isAnalyzableFile(filePath) {
|
|
95
|
+
return /\.(?:ts|tsx|js|jsx|mts|mjs)$/.test(filePath);
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=optional-infra-crash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optional-infra-crash.js","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/optional-infra-crash.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { InvariantDetector } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* INVARIANT — undeclared_dependency
|
|
4
|
+
*
|
|
5
|
+
* Detect imports of external packages that are not declared in the
|
|
6
|
+
* nearest package.json's dependencies or devDependencies.
|
|
7
|
+
*
|
|
8
|
+
* Severity: P1 (can cause runtime failures in production/Docker builds)
|
|
9
|
+
*/
|
|
10
|
+
export declare const undeclaredDependencyDetector: InvariantDetector;
|
|
11
|
+
//# sourceMappingURL=undeclared-dependency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undeclared-dependency.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/undeclared-dependency.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,aAAa,CAAC;AAIrB;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,EAAE,iBAgD1C,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { parseImports } from '../engine/ast-parser.js';
|
|
4
|
+
import { resolveModule } from '../engine/symbol-resolver.js';
|
|
5
|
+
/**
|
|
6
|
+
* INVARIANT — undeclared_dependency
|
|
7
|
+
*
|
|
8
|
+
* Detect imports of external packages that are not declared in the
|
|
9
|
+
* nearest package.json's dependencies or devDependencies.
|
|
10
|
+
*
|
|
11
|
+
* Severity: P1 (can cause runtime failures in production/Docker builds)
|
|
12
|
+
*/
|
|
13
|
+
export const undeclaredDependencyDetector = {
|
|
14
|
+
name: 'build_runtime',
|
|
15
|
+
analyze(ctx) {
|
|
16
|
+
const findings = [];
|
|
17
|
+
const pkgJsonCache = new Map();
|
|
18
|
+
for (const filePath of ctx.files) {
|
|
19
|
+
const content = ctx.fileContents.get(filePath);
|
|
20
|
+
if (!content)
|
|
21
|
+
continue;
|
|
22
|
+
if (!isAnalyzableFile(filePath))
|
|
23
|
+
continue;
|
|
24
|
+
const imports = parseImports(content);
|
|
25
|
+
const declaredDeps = findDeclaredDependencies(ctx.cwd, filePath, pkgJsonCache);
|
|
26
|
+
if (!declaredDeps)
|
|
27
|
+
continue; // No package.json found
|
|
28
|
+
for (const imp of imports) {
|
|
29
|
+
if (imp.isTypeOnly)
|
|
30
|
+
continue; // Type-only imports don't need runtime deps
|
|
31
|
+
const resolved = resolveModule(imp.source);
|
|
32
|
+
if (resolved.kind !== 'external')
|
|
33
|
+
continue;
|
|
34
|
+
if (!resolved.packageName)
|
|
35
|
+
continue;
|
|
36
|
+
// Skip workspace packages (handled separately)
|
|
37
|
+
if (resolved.packageName.startsWith('@codeledger/'))
|
|
38
|
+
continue;
|
|
39
|
+
if (!declaredDeps.has(resolved.packageName)) {
|
|
40
|
+
findings.push({
|
|
41
|
+
rule_id: 'RI-UD-001',
|
|
42
|
+
title: 'Undeclared dependency',
|
|
43
|
+
severity: 'P1',
|
|
44
|
+
category: 'build_runtime',
|
|
45
|
+
file: filePath,
|
|
46
|
+
line: imp.line,
|
|
47
|
+
trigger: `import from '${imp.source}'`,
|
|
48
|
+
missing_companions: [`Add '${resolved.packageName}' to package.json dependencies`],
|
|
49
|
+
why_it_matters: `Package '${resolved.packageName}' is imported but not declared in package.json. ` +
|
|
50
|
+
'This may work locally due to hoisting but will fail in Docker builds, ' +
|
|
51
|
+
'CI environments, or after clean installs.',
|
|
52
|
+
confidence: 'high',
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return findings;
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Find the declared dependencies for a file by walking up to the nearest package.json.
|
|
62
|
+
*/
|
|
63
|
+
function findDeclaredDependencies(cwd, filePath, cache) {
|
|
64
|
+
const fullPath = join(cwd, filePath);
|
|
65
|
+
let dir = dirname(fullPath);
|
|
66
|
+
while (dir.startsWith(cwd)) {
|
|
67
|
+
const pkgJsonPath = join(dir, 'package.json');
|
|
68
|
+
const cached = cache.get(pkgJsonPath);
|
|
69
|
+
if (cached)
|
|
70
|
+
return cached;
|
|
71
|
+
if (existsSync(pkgJsonPath)) {
|
|
72
|
+
try {
|
|
73
|
+
const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
|
|
74
|
+
const deps = new Set();
|
|
75
|
+
for (const field of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
|
|
76
|
+
const section = pkg[field];
|
|
77
|
+
if (section && typeof section === 'object') {
|
|
78
|
+
for (const name of Object.keys(section)) {
|
|
79
|
+
deps.add(name);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
cache.set(pkgJsonPath, deps);
|
|
84
|
+
return deps;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const parent = dirname(dir);
|
|
91
|
+
if (parent === dir)
|
|
92
|
+
break;
|
|
93
|
+
dir = parent;
|
|
94
|
+
}
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
function isAnalyzableFile(filePath) {
|
|
98
|
+
return /\.(?:ts|tsx|js|jsx|mts|mjs)$/.test(filePath);
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=undeclared-dependency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undeclared-dependency.js","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/undeclared-dependency.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/** Represents a detected import declaration */
|
|
2
|
+
export interface ImportInfo {
|
|
3
|
+
/** The module specifier (e.g. 'node:fs', './utils.js', 'lodash') */
|
|
4
|
+
source: string;
|
|
5
|
+
/** Named imports (e.g. ['readFileSync', 'writeFileSync']) */
|
|
6
|
+
namedImports: string[];
|
|
7
|
+
/** Default import name, if any */
|
|
8
|
+
defaultImport?: string;
|
|
9
|
+
/** Namespace import name (import * as X), if any */
|
|
10
|
+
namespaceImport?: string;
|
|
11
|
+
/** Whether this is a type-only import */
|
|
12
|
+
isTypeOnly: boolean;
|
|
13
|
+
/** Line number (1-based) */
|
|
14
|
+
line: number;
|
|
15
|
+
/** Whether this is a dynamic import() */
|
|
16
|
+
isDynamic: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** Represents a detected function/method call */
|
|
19
|
+
export interface CallExpressionInfo {
|
|
20
|
+
/** The callee expression (e.g. 'fetch', 'reply.status', 'z.object') */
|
|
21
|
+
callee: string;
|
|
22
|
+
/** The object part if a member expression (e.g. 'reply' from 'reply.status') */
|
|
23
|
+
object?: string;
|
|
24
|
+
/** The method part if a member expression (e.g. 'status' from 'reply.status') */
|
|
25
|
+
method?: string;
|
|
26
|
+
/** Line number (1-based) */
|
|
27
|
+
line: number;
|
|
28
|
+
/** Raw matched text */
|
|
29
|
+
rawText: string;
|
|
30
|
+
/** Whether this call has generic type arguments */
|
|
31
|
+
hasGenerics: boolean;
|
|
32
|
+
}
|
|
33
|
+
/** Represents a detected generic type usage */
|
|
34
|
+
export interface GenericInfo {
|
|
35
|
+
/** The base type/function name */
|
|
36
|
+
name: string;
|
|
37
|
+
/** The generic type arguments as raw text */
|
|
38
|
+
typeArgs: string;
|
|
39
|
+
/** Line number (1-based) */
|
|
40
|
+
line: number;
|
|
41
|
+
}
|
|
42
|
+
/** Represents an exported symbol */
|
|
43
|
+
export interface ExportInfo {
|
|
44
|
+
/** The exported name */
|
|
45
|
+
name: string;
|
|
46
|
+
/** The kind of export */
|
|
47
|
+
kind: 'function' | 'const' | 'class' | 'type' | 'interface' | 'enum' | 'reexport';
|
|
48
|
+
/** Whether it's a default export */
|
|
49
|
+
isDefault: boolean;
|
|
50
|
+
/** Line number (1-based) */
|
|
51
|
+
line: number;
|
|
52
|
+
}
|
|
53
|
+
/** Full AST analysis result for a file */
|
|
54
|
+
export interface FileAnalysis {
|
|
55
|
+
/** All import declarations */
|
|
56
|
+
imports: ImportInfo[];
|
|
57
|
+
/** All call expressions detected */
|
|
58
|
+
calls: CallExpressionInfo[];
|
|
59
|
+
/** All generic type usages */
|
|
60
|
+
generics: GenericInfo[];
|
|
61
|
+
/** All exports */
|
|
62
|
+
exports: ExportInfo[];
|
|
63
|
+
/** Whether the file is analyzable (TS/JS) */
|
|
64
|
+
analyzable: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check if a file path is analyzable by the AST engine.
|
|
68
|
+
*/
|
|
69
|
+
export declare function isAnalyzableFile(filePath: string): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Parse all import declarations from TypeScript/JavaScript source.
|
|
72
|
+
*/
|
|
73
|
+
export declare function parseImports(content: string): ImportInfo[];
|
|
74
|
+
/**
|
|
75
|
+
* Parse call expressions from source code.
|
|
76
|
+
*/
|
|
77
|
+
export declare function parseCallExpressions(content: string): CallExpressionInfo[];
|
|
78
|
+
/**
|
|
79
|
+
* Parse generic type usages from source code.
|
|
80
|
+
*/
|
|
81
|
+
export declare function parseGenerics(content: string): GenericInfo[];
|
|
82
|
+
/**
|
|
83
|
+
* Parse all exports from source code.
|
|
84
|
+
*/
|
|
85
|
+
export declare function parseExports(content: string): ExportInfo[];
|
|
86
|
+
/**
|
|
87
|
+
* Perform full file analysis: imports, calls, generics, exports.
|
|
88
|
+
*/
|
|
89
|
+
export declare function analyzeFile(filePath: string, content: string): FileAnalysis;
|
|
90
|
+
//# sourceMappingURL=ast-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-parser.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/engine/ast-parser.ts"],"names":[],"mappings":"AAWA,+CAA+C;AAC/C,MAAM,WAAW,UAAU;IACzB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kCAAkC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,UAAU,EAAE,OAAO,CAAC;IACpB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,iDAAiD;AACjD,MAAM,WAAW,kBAAkB;IACjC,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,+CAA+C;AAC/C,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oCAAoC;AACpC,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,CAAC;IAClF,oCAAoC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,0CAA0C;AAC1C,MAAM,WAAW,YAAY;IAC3B,8BAA8B;IAC9B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,oCAAoC;IACpC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,8BAA8B;IAC9B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,kBAAkB;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,6CAA6C;IAC7C,UAAU,EAAE,OAAO,CAAC;CACrB;AAID;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAoG1D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAgD1E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CA0B5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAyD1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAkB3E"}
|