aislop 0.10.2 → 0.11.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.
- package/README.md +151 -69
- package/dist/cli.js +1803 -374
- package/dist/{expo-doctor-T4DswmX5.js → expo-doctor-BM2JR6f6.js} +1 -1
- package/dist/{expo-doctor-c-jE6pR2.js → expo-doctor-BwLKXF__.js} +2 -2
- package/dist/finding-assessment-PCl1fnok.js +149 -0
- package/dist/{generic-BsQa13CS.js → generic-D_T4cUaC.js} +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.js +1015 -215
- package/dist/{json-B01i-GOz.js → json-0lJPTrwO.js} +5 -3
- package/dist/{json-CXV4D0Ib.js → json-pHsqtKkz.js} +4 -2
- package/dist/mcp.js +540 -97
- package/dist/{sarif-cy5SiDDq.js → sarif-BXUicqQU.js} +1 -1
- package/dist/{sarif-CZVuavf_.js → sarif-CjxSBcqx.js} +1 -1
- package/dist/{typecheck-BdQ7uFyK.js → typecheck-DQSzG8fX.js} +1 -1
- package/dist/{typecheck-wVSohmOX.js → typecheck-yOGXIIGU.js} +1 -1
- package/dist/version-BJA3AcRM.js +7 -0
- package/package.json +2 -2
- package/dist/engine-info-Cpt36DqZ.js +0 -31
- package/dist/version-BfJVwhN2.js +0 -5
- /package/dist/{subprocess-0uXz8HdE.js → subprocess-CQUJDGgn.js} +0 -0
|
@@ -123,7 +123,7 @@ const runExpoDoctor = async (context) => {
|
|
|
123
123
|
rule: "expo-doctor/config-error",
|
|
124
124
|
severity: "warning",
|
|
125
125
|
message: configError,
|
|
126
|
-
help: "Install project dependencies, then re-run `
|
|
126
|
+
help: "Install project dependencies, then re-run `aislop scan`.",
|
|
127
127
|
line: 0,
|
|
128
128
|
column: 0,
|
|
129
129
|
category: "Expo",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
|
|
2
|
-
import { n as runSubprocess } from "./subprocess-
|
|
2
|
+
import { n as runSubprocess } from "./subprocess-CQUJDGgn.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
@@ -124,7 +124,7 @@ const runExpoDoctor = async (context) => {
|
|
|
124
124
|
rule: "expo-doctor/config-error",
|
|
125
125
|
severity: "warning",
|
|
126
126
|
message: configError,
|
|
127
|
-
help: "Install project dependencies, then re-run `
|
|
127
|
+
help: "Install project dependencies, then re-run `aislop scan`.",
|
|
128
128
|
line: 0,
|
|
129
129
|
column: 0,
|
|
130
130
|
category: "Expo",
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
//#region src/output/engine-info.ts
|
|
2
|
+
const ENGINE_INFO = {
|
|
3
|
+
format: {
|
|
4
|
+
label: "Formatting",
|
|
5
|
+
description: "Whitespace, indentation, line wrapping, and import ordering"
|
|
6
|
+
},
|
|
7
|
+
lint: {
|
|
8
|
+
label: "Linting",
|
|
9
|
+
description: "Static analysis for likely bugs and bad patterns"
|
|
10
|
+
},
|
|
11
|
+
"code-quality": {
|
|
12
|
+
label: "Code Quality",
|
|
13
|
+
description: "Complexity limits, dead code detection, and duplication checks"
|
|
14
|
+
},
|
|
15
|
+
"ai-slop": {
|
|
16
|
+
label: "AI Slop",
|
|
17
|
+
description: "Narrative comments, dead patterns, unsafe type casts, TODO stubs, generic names"
|
|
18
|
+
},
|
|
19
|
+
architecture: {
|
|
20
|
+
label: "Architecture",
|
|
21
|
+
description: "Project-specific import and layering rules"
|
|
22
|
+
},
|
|
23
|
+
security: {
|
|
24
|
+
label: "Security",
|
|
25
|
+
description: "Secret leaks, risky APIs, and dependency vulnerabilities"
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const getEngineLabel = (engine) => ENGINE_INFO[engine].label;
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/output/finding-assessment.ts
|
|
32
|
+
const KNIP_FORCE_RULES = new Set([
|
|
33
|
+
"knip/files",
|
|
34
|
+
"knip/dependencies",
|
|
35
|
+
"knip/devDependencies"
|
|
36
|
+
]);
|
|
37
|
+
const isForceFixable = (diagnostic) => {
|
|
38
|
+
if (diagnostic.fixable) return false;
|
|
39
|
+
if (KNIP_FORCE_RULES.has(diagnostic.rule)) return true;
|
|
40
|
+
if (diagnostic.rule === "security/vulnerable-dependency") return diagnostic.detail === "npm" || diagnostic.detail === "pnpm";
|
|
41
|
+
if (diagnostic.rule.startsWith("expo-doctor/")) return diagnostic.rule !== "expo-doctor/config-error";
|
|
42
|
+
return false;
|
|
43
|
+
};
|
|
44
|
+
const FINDING_KIND_LABELS = {
|
|
45
|
+
"confirmed-defect": "confirmed defects",
|
|
46
|
+
"conservative-security": "conservative security",
|
|
47
|
+
"style-policy": "style/policy",
|
|
48
|
+
"ai-slop-indicator": "AI-slop indicators"
|
|
49
|
+
};
|
|
50
|
+
const STYLE_POLICY_RULES = new Set([
|
|
51
|
+
"ai-slop/trivial-comment",
|
|
52
|
+
"ai-slop/narrative-comment",
|
|
53
|
+
"ai-slop/meta-comment",
|
|
54
|
+
"ai-slop/console-leftover",
|
|
55
|
+
"ai-slop/ts-directive",
|
|
56
|
+
"complexity/file-too-large",
|
|
57
|
+
"complexity/function-too-long",
|
|
58
|
+
"complexity/deep-nesting",
|
|
59
|
+
"complexity/too-many-params",
|
|
60
|
+
"code-quality/duplicate-block",
|
|
61
|
+
"eslint/no-empty",
|
|
62
|
+
"eslint/no-unused-vars",
|
|
63
|
+
"eslint/no-useless-escape",
|
|
64
|
+
"eslint/no-unused-expressions",
|
|
65
|
+
"unicorn/no-useless-fallback-in-spread",
|
|
66
|
+
"unicorn/prefer-string-starts-ends-with",
|
|
67
|
+
"unicorn/no-new-array",
|
|
68
|
+
"unicorn/no-useless-spread"
|
|
69
|
+
]);
|
|
70
|
+
const CONFIRMED_DEFECT_RULES = new Set([
|
|
71
|
+
"ai-slop/hallucinated-import",
|
|
72
|
+
"eslint/no-undef",
|
|
73
|
+
"eslint/no-unreachable",
|
|
74
|
+
"security/vulnerable-dependency"
|
|
75
|
+
]);
|
|
76
|
+
const LOW_CONFIDENCE_SECURITY_RULES = new Set(["security/innerhtml", "security/dangerously-set-innerhtml"]);
|
|
77
|
+
const confidenceFor = (diagnostic, kind) => {
|
|
78
|
+
if (kind === "confirmed-defect") return "high";
|
|
79
|
+
if (kind === "style-policy") return "medium";
|
|
80
|
+
if (kind === "conservative-security") {
|
|
81
|
+
if (LOW_CONFIDENCE_SECURITY_RULES.has(diagnostic.rule)) return "medium";
|
|
82
|
+
return diagnostic.severity === "error" ? "high" : "medium";
|
|
83
|
+
}
|
|
84
|
+
return diagnostic.severity === "error" ? "high" : "medium";
|
|
85
|
+
};
|
|
86
|
+
const classifyKind = (diagnostic) => {
|
|
87
|
+
if (CONFIRMED_DEFECT_RULES.has(diagnostic.rule)) return "confirmed-defect";
|
|
88
|
+
if (diagnostic.engine === "security") return "conservative-security";
|
|
89
|
+
if (STYLE_POLICY_RULES.has(diagnostic.rule)) return "style-policy";
|
|
90
|
+
if (diagnostic.engine === "format" || diagnostic.engine === "code-quality") return "style-policy";
|
|
91
|
+
if (diagnostic.engine === "ai-slop") return "ai-slop-indicator";
|
|
92
|
+
if (diagnostic.severity === "error") return "confirmed-defect";
|
|
93
|
+
return "style-policy";
|
|
94
|
+
};
|
|
95
|
+
const assessDiagnostic = (diagnostic) => {
|
|
96
|
+
const kind = classifyKind(diagnostic);
|
|
97
|
+
return {
|
|
98
|
+
kind,
|
|
99
|
+
confidence: confidenceFor(diagnostic, kind),
|
|
100
|
+
label: FINDING_KIND_LABELS[kind]
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
const withFindingAssessments = (diagnostics) => diagnostics.map((diagnostic) => ({
|
|
104
|
+
...diagnostic,
|
|
105
|
+
assessment: assessDiagnostic(diagnostic),
|
|
106
|
+
forceFixable: isForceFixable(diagnostic)
|
|
107
|
+
}));
|
|
108
|
+
const summarizeFindingAssessments = (diagnostics) => {
|
|
109
|
+
const byKind = {
|
|
110
|
+
"confirmed-defect": 0,
|
|
111
|
+
"conservative-security": 0,
|
|
112
|
+
"style-policy": 0,
|
|
113
|
+
"ai-slop-indicator": 0
|
|
114
|
+
};
|
|
115
|
+
const byConfidence = {
|
|
116
|
+
high: 0,
|
|
117
|
+
medium: 0,
|
|
118
|
+
low: 0
|
|
119
|
+
};
|
|
120
|
+
const rows = /* @__PURE__ */ new Map();
|
|
121
|
+
for (const diagnostic of diagnostics) {
|
|
122
|
+
const assessment = assessDiagnostic(diagnostic);
|
|
123
|
+
byKind[assessment.kind]++;
|
|
124
|
+
byConfidence[assessment.confidence]++;
|
|
125
|
+
const row = rows.get(assessment.kind) ?? {
|
|
126
|
+
kind: assessment.kind,
|
|
127
|
+
label: assessment.label,
|
|
128
|
+
count: 0,
|
|
129
|
+
errors: 0,
|
|
130
|
+
warnings: 0,
|
|
131
|
+
info: 0,
|
|
132
|
+
fixable: 0
|
|
133
|
+
};
|
|
134
|
+
row.count++;
|
|
135
|
+
if (diagnostic.severity === "error") row.errors++;
|
|
136
|
+
else if (diagnostic.severity === "warning") row.warnings++;
|
|
137
|
+
else row.info++;
|
|
138
|
+
if (diagnostic.fixable) row.fixable++;
|
|
139
|
+
rows.set(assessment.kind, row);
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
rows: [...rows.values()].sort((a, b) => b.count - a.count),
|
|
143
|
+
byKind,
|
|
144
|
+
byConfidence
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
//#endregion
|
|
149
|
+
export { getEngineLabel as i, withFindingAssessments as n, ENGINE_INFO as r, summarizeFindingAssessments as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
|
|
2
|
-
import { n as runSubprocess } from "./subprocess-
|
|
2
|
+
import { n as runSubprocess } from "./subprocess-CQUJDGgn.js";
|
|
3
3
|
|
|
4
4
|
//#region src/engines/lint/generic.ts
|
|
5
5
|
var generic_exports = /* @__PURE__ */ __exportAll({
|
package/dist/index.d.ts
CHANGED
|
@@ -52,6 +52,7 @@ declare const AislopConfigSchema: z.ZodObject<{
|
|
|
52
52
|
ok: z.ZodDefault<z.ZodNumber>;
|
|
53
53
|
}, z.core.$strip>>;
|
|
54
54
|
smoothing: z.ZodDefault<z.ZodNumber>;
|
|
55
|
+
maxPerRule: z.ZodDefault<z.ZodNumber>;
|
|
55
56
|
}, z.core.$strip>>;
|
|
56
57
|
ci: z.ZodDefault<z.ZodObject<{
|
|
57
58
|
failBelow: z.ZodDefault<z.ZodNumber>;
|
|
@@ -123,10 +124,16 @@ interface BuildRulesRenderInput {
|
|
|
123
124
|
rules: RuleEntry[];
|
|
124
125
|
invocation?: string;
|
|
125
126
|
printBrand?: boolean;
|
|
127
|
+
includeHeader?: boolean;
|
|
126
128
|
}
|
|
127
129
|
declare const buildRulesRender: (input: BuildRulesRenderInput) => string;
|
|
130
|
+
declare const buildRuleDetailRender: (rule: RuleEntry, input?: {
|
|
131
|
+
printBrand?: boolean;
|
|
132
|
+
includeHeader?: boolean;
|
|
133
|
+
}) => string;
|
|
128
134
|
interface RulesOptions {
|
|
129
135
|
printBrand?: boolean;
|
|
136
|
+
interactive?: boolean;
|
|
130
137
|
}
|
|
131
138
|
declare const rulesCommand: (directory: string, options?: RulesOptions) => Promise<void>;
|
|
132
139
|
//#endregion
|
|
@@ -178,6 +185,7 @@ interface EngineResult {
|
|
|
178
185
|
interface ScanOptions {
|
|
179
186
|
changes: boolean;
|
|
180
187
|
staged: boolean;
|
|
188
|
+
base?: string;
|
|
181
189
|
verbose: boolean;
|
|
182
190
|
json: boolean;
|
|
183
191
|
sarif?: boolean;
|
|
@@ -200,6 +208,6 @@ interface ScoreResult {
|
|
|
200
208
|
declare const calculateScore: (diagnostics: Diagnostic[], weights: Record<string, number>, thresholds: {
|
|
201
209
|
good: number;
|
|
202
210
|
ok: number;
|
|
203
|
-
}, sourceFileCount?: number, smoothing?: number) => ScoreResult;
|
|
211
|
+
}, sourceFileCount?: number, smoothing?: number, maxPerRule?: number) => ScoreResult;
|
|
204
212
|
//#endregion
|
|
205
|
-
export { type AislopConfig, type Diagnostic, type EngineName, type EngineResult, type Framework, type Language, type ProjectInfo, type ScoreResult, type Severity, buildDoctorRender, buildInitSuccessRender, buildRulesRender, calculateScore, discoverProject, doctorCommand, fixCommand, initCommand, loadConfig, rulesCommand, scanCommand };
|
|
213
|
+
export { type AislopConfig, type Diagnostic, type EngineName, type EngineResult, type Framework, type Language, type ProjectInfo, type ScoreResult, type Severity, buildDoctorRender, buildInitSuccessRender, buildRuleDetailRender, buildRulesRender, calculateScore, discoverProject, doctorCommand, fixCommand, initCommand, loadConfig, rulesCommand, scanCommand };
|