aislop 0.10.1 → 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 +187 -57
- package/dist/cli.js +2748 -989
- package/dist/{expo-doctor-T4DswmX5.js → expo-doctor-BM2JR6f6.js} +1 -1
- package/dist/{expo-doctor-BcIkOte5.js → expo-doctor-BwLKXF__.js} +1 -1
- package/dist/finding-assessment-PCl1fnok.js +149 -0
- package/dist/index.d.ts +20 -3
- package/dist/index.js +3537 -2410
- package/dist/{json-Bqkcl1DF.js → json-0lJPTrwO.js} +10 -6
- package/dist/{json-OIzja7OM.js → json-pHsqtKkz.js} +9 -5
- package/dist/mcp.js +1172 -646
- package/dist/{sarif-C-vh4wcC.js → sarif-BXUicqQU.js} +1 -1
- package/dist/{sarif-CZVuavf_.js → sarif-CjxSBcqx.js} +1 -1
- package/dist/{typecheck-wVSohmOX.js → typecheck-yOGXIIGU.js} +1 -1
- package/dist/version-BJA3AcRM.js +7 -0
- package/package.json +8 -11
- package/dist/engine-info-DCvIfZ0f.js +0 -31
- package/dist/version-rlhQD8Qh.js +0 -5
|
@@ -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",
|
|
@@ -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 };
|
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>;
|
|
@@ -87,6 +88,8 @@ interface RailStep {
|
|
|
87
88
|
interface FixOptions {
|
|
88
89
|
verbose: boolean;
|
|
89
90
|
force?: boolean;
|
|
91
|
+
/** Restrict to reversible fixes only (imports, comment removal, formatting) */
|
|
92
|
+
safe?: boolean;
|
|
90
93
|
/** Agent CLI to launch with remaining issues (e.g. "claude", "codex") */
|
|
91
94
|
agent?: string;
|
|
92
95
|
/** Print the prompt to stdout instead of launching an agent */
|
|
@@ -121,25 +124,38 @@ interface BuildRulesRenderInput {
|
|
|
121
124
|
rules: RuleEntry[];
|
|
122
125
|
invocation?: string;
|
|
123
126
|
printBrand?: boolean;
|
|
127
|
+
includeHeader?: boolean;
|
|
124
128
|
}
|
|
125
129
|
declare const buildRulesRender: (input: BuildRulesRenderInput) => string;
|
|
130
|
+
declare const buildRuleDetailRender: (rule: RuleEntry, input?: {
|
|
131
|
+
printBrand?: boolean;
|
|
132
|
+
includeHeader?: boolean;
|
|
133
|
+
}) => string;
|
|
126
134
|
interface RulesOptions {
|
|
127
135
|
printBrand?: boolean;
|
|
136
|
+
interactive?: boolean;
|
|
128
137
|
}
|
|
129
138
|
declare const rulesCommand: (directory: string, options?: RulesOptions) => Promise<void>;
|
|
130
139
|
//#endregion
|
|
131
140
|
//#region src/utils/discover.d.ts
|
|
132
141
|
type Language = "typescript" | "javascript" | "python" | "go" | "rust" | "java" | "ruby" | "php";
|
|
133
142
|
type Framework = "nextjs" | "react" | "vite" | "remix" | "expo" | "astro" | "django" | "flask" | "fastapi" | "none";
|
|
143
|
+
interface Coverage {
|
|
144
|
+
supportedFiles: number;
|
|
145
|
+
unsupportedFiles: number;
|
|
146
|
+
dominantUnsupported: string | null;
|
|
147
|
+
scoreable: boolean;
|
|
148
|
+
}
|
|
134
149
|
interface ProjectInfo {
|
|
135
150
|
rootDirectory: string;
|
|
136
151
|
projectName: string;
|
|
137
152
|
languages: Language[];
|
|
138
153
|
frameworks: Framework[];
|
|
139
154
|
sourceFileCount: number;
|
|
155
|
+
coverage: Coverage;
|
|
140
156
|
installedTools: Record<string, boolean>;
|
|
141
157
|
}
|
|
142
|
-
declare const discoverProject: (directory: string) => Promise<ProjectInfo>;
|
|
158
|
+
declare const discoverProject: (directory: string, excludePatterns?: string[]) => Promise<ProjectInfo>;
|
|
143
159
|
//#endregion
|
|
144
160
|
//#region src/engines/types.d.ts
|
|
145
161
|
type Severity = "error" | "warning" | "info";
|
|
@@ -169,6 +185,7 @@ interface EngineResult {
|
|
|
169
185
|
interface ScanOptions {
|
|
170
186
|
changes: boolean;
|
|
171
187
|
staged: boolean;
|
|
188
|
+
base?: string;
|
|
172
189
|
verbose: boolean;
|
|
173
190
|
json: boolean;
|
|
174
191
|
sarif?: boolean;
|
|
@@ -191,6 +208,6 @@ interface ScoreResult {
|
|
|
191
208
|
declare const calculateScore: (diagnostics: Diagnostic[], weights: Record<string, number>, thresholds: {
|
|
192
209
|
good: number;
|
|
193
210
|
ok: number;
|
|
194
|
-
}, sourceFileCount?: number, smoothing?: number) => ScoreResult;
|
|
211
|
+
}, sourceFileCount?: number, smoothing?: number, maxPerRule?: number) => ScoreResult;
|
|
195
212
|
//#endregion
|
|
196
|
-
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 };
|