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.
@@ -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 `npx aislop scan`.",
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-0uXz8HdE.js";
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 `npx aislop scan`.",
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-0uXz8HdE.js";
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 };