aislop 0.1.2 → 0.1.3
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
CHANGED
|
@@ -217,8 +217,6 @@ Custom import and path rules defined in `.aislop/rules.yml`.
|
|
|
217
217
|
|
|
218
218
|
---
|
|
219
219
|
|
|
220
|
-
## Scoring
|
|
221
|
-
|
|
222
220
|
Every diagnostic contributes a weighted penalty:
|
|
223
221
|
|
|
224
222
|
| Severity | Penalty |
|
|
@@ -227,7 +225,7 @@ Every diagnostic contributes a weighted penalty:
|
|
|
227
225
|
| Warning | 1.0 |
|
|
228
226
|
| Info | 0.25 |
|
|
229
227
|
|
|
230
|
-
Penalties are multiplied by engine weight (configurable, security defaults to 2x). The final score uses logarithmic scaling so a few issues
|
|
228
|
+
Penalties are multiplied by engine weight (configurable, security defaults to 2x). The final score uses logarithmic scaling with issue-density normalization (relative to source file count), so a few issues still matter but a single finding in an otherwise clean project remains proportional.
|
|
231
229
|
|
|
232
230
|
| Score | Label |
|
|
233
231
|
|---|---|
|
|
@@ -356,4 +354,4 @@ See [SECURITY.md](SECURITY.md) for reporting vulnerabilities.
|
|
|
356
354
|
|
|
357
355
|
## License
|
|
358
356
|
|
|
359
|
-
[MIT](LICENSE) -- see the [LICENSE](LICENSE) file.
|
|
357
|
+
[MIT](LICENSE) -- see the [LICENSE](LICENSE) file.
|
package/dist/cli.js
CHANGED
|
@@ -46,7 +46,8 @@ const DEFAULT_CONFIG = {
|
|
|
46
46
|
thresholds: {
|
|
47
47
|
good: 75,
|
|
48
48
|
ok: 50
|
|
49
|
-
}
|
|
49
|
+
},
|
|
50
|
+
smoothing: 10
|
|
50
51
|
},
|
|
51
52
|
ci: {
|
|
52
53
|
failBelow: 0,
|
|
@@ -146,7 +147,8 @@ const ScoringSchema = z.object({
|
|
|
146
147
|
thresholds: ThresholdsSchema.default(() => ({
|
|
147
148
|
good: 75,
|
|
148
149
|
ok: 50
|
|
149
|
-
}))
|
|
150
|
+
})),
|
|
151
|
+
smoothing: z.number().nonnegative().default(10)
|
|
150
152
|
});
|
|
151
153
|
const CiSchema = z.object({
|
|
152
154
|
failBelow: z.number().default(0),
|
|
@@ -178,7 +180,8 @@ const AislopConfigSchema = z.object({
|
|
|
178
180
|
thresholds: {
|
|
179
181
|
good: 75,
|
|
180
182
|
ok: 50
|
|
181
|
-
}
|
|
183
|
+
},
|
|
184
|
+
smoothing: 10
|
|
182
185
|
})),
|
|
183
186
|
ci: CiSchema.default(() => ({
|
|
184
187
|
failBelow: 0,
|
|
@@ -1279,10 +1282,7 @@ const FUNCTION_PATTERNS = [
|
|
|
1279
1282
|
]
|
|
1280
1283
|
}
|
|
1281
1284
|
];
|
|
1282
|
-
const countParams = (
|
|
1283
|
-
if (!paramStr.trim()) return 0;
|
|
1284
|
-
return paramStr.split(",").length;
|
|
1285
|
-
};
|
|
1285
|
+
const countParams = (p) => p.trim() ? p.split(",").length : 0;
|
|
1286
1286
|
const matchFunctionOnLine = (line, ext) => {
|
|
1287
1287
|
for (let i = 0; i < FUNCTION_PATTERNS.length; i++) {
|
|
1288
1288
|
const pattern = FUNCTION_PATTERNS[i];
|
|
@@ -3118,7 +3118,7 @@ const logger = {
|
|
|
3118
3118
|
* Application version — injected at build time by tsdown from package.json.
|
|
3119
3119
|
* The fallback should always match the "version" field in package.json.
|
|
3120
3120
|
*/
|
|
3121
|
-
const APP_VERSION = "0.1.
|
|
3121
|
+
const APP_VERSION = "0.1.3";
|
|
3122
3122
|
|
|
3123
3123
|
//#endregion
|
|
3124
3124
|
//#region src/output/layout.ts
|
|
@@ -3344,7 +3344,12 @@ var ScanProgressRenderer = class {
|
|
|
3344
3344
|
//#endregion
|
|
3345
3345
|
//#region src/scoring/index.ts
|
|
3346
3346
|
const PERFECT_SCORE$1 = 100;
|
|
3347
|
-
const
|
|
3347
|
+
const getEffectiveFileCount = (diagnostics, sourceFileCount) => {
|
|
3348
|
+
if (typeof sourceFileCount === "number" && sourceFileCount > 0) return sourceFileCount;
|
|
3349
|
+
const filesWithDiagnostics = new Set(diagnostics.map((d) => d.filePath)).size;
|
|
3350
|
+
return Math.max(1, filesWithDiagnostics);
|
|
3351
|
+
};
|
|
3352
|
+
const calculateScore = (diagnostics, weights, thresholds, sourceFileCount, smoothing) => {
|
|
3348
3353
|
if (diagnostics.length === 0) return {
|
|
3349
3354
|
score: PERFECT_SCORE$1,
|
|
3350
3355
|
label: "Healthy"
|
|
@@ -3355,7 +3360,11 @@ const calculateScore = (diagnostics, weights, thresholds) => {
|
|
|
3355
3360
|
const severityPenalty = d.severity === "error" ? 3 : d.severity === "warning" ? 1 : .25;
|
|
3356
3361
|
deductions += severityPenalty * engineWeight;
|
|
3357
3362
|
}
|
|
3358
|
-
const
|
|
3363
|
+
const effectiveFileCount = getEffectiveFileCount(diagnostics, sourceFileCount);
|
|
3364
|
+
const smoothingConstant = typeof smoothing === "number" ? smoothing : 10;
|
|
3365
|
+
const issueDensity = Math.min(1, diagnostics.length / (effectiveFileCount + smoothingConstant));
|
|
3366
|
+
const scaledDeductions = deductions * Math.sqrt(issueDensity);
|
|
3367
|
+
const score = Math.max(0, Math.round(PERFECT_SCORE$1 - PERFECT_SCORE$1 * Math.log1p(scaledDeductions) / Math.log1p(PERFECT_SCORE$1 + scaledDeductions)));
|
|
3359
3368
|
return {
|
|
3360
3369
|
score,
|
|
3361
3370
|
label: score >= thresholds.good ? "Healthy" : score >= thresholds.ok ? "Needs Work" : "Critical"
|
|
@@ -3771,7 +3780,7 @@ const scanCommand = async (directory, config, options) => {
|
|
|
3771
3780
|
progressRenderer?.stop();
|
|
3772
3781
|
const allDiagnostics = results.flatMap((r) => r.diagnostics);
|
|
3773
3782
|
const elapsedMs = performance.now() - startTime;
|
|
3774
|
-
const scoreResult = calculateScore(allDiagnostics, config.scoring.weights, config.scoring.thresholds);
|
|
3783
|
+
const scoreResult = calculateScore(allDiagnostics, config.scoring.weights, config.scoring.thresholds, projectInfo.sourceFileCount, config.scoring.smoothing);
|
|
3775
3784
|
const exitCode = allDiagnostics.some((d) => d.severity === "error") || scoreResult.score < config.ci.failBelow ? 1 : 0;
|
|
3776
3785
|
if (!isTelemetryDisabled(config.telemetry?.enabled)) {
|
|
3777
3786
|
const engineIssues = {};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Application version — injected at build time by tsdown from package.json.
|
|
4
4
|
* The fallback should always match the "version" field in package.json.
|
|
5
5
|
*/
|
|
6
|
-
const APP_VERSION = "0.1.
|
|
6
|
+
const APP_VERSION = "0.1.3";
|
|
7
7
|
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/output/engine-info.ts
|
package/dist/index.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ declare const AislopConfigSchema: z.ZodObject<{
|
|
|
30
30
|
good: z.ZodDefault<z.ZodNumber>;
|
|
31
31
|
ok: z.ZodDefault<z.ZodNumber>;
|
|
32
32
|
}, z.core.$strip>>;
|
|
33
|
+
smoothing: z.ZodDefault<z.ZodNumber>;
|
|
33
34
|
}, z.core.$strip>>;
|
|
34
35
|
ci: z.ZodDefault<z.ZodObject<{
|
|
35
36
|
failBelow: z.ZodDefault<z.ZodNumber>;
|
|
@@ -114,6 +115,6 @@ interface ScoreResult {
|
|
|
114
115
|
declare const calculateScore: (diagnostics: Diagnostic[], weights: Record<string, number>, thresholds: {
|
|
115
116
|
good: number;
|
|
116
117
|
ok: number;
|
|
117
|
-
}) => ScoreResult;
|
|
118
|
+
}, sourceFileCount?: number, smoothing?: number) => ScoreResult;
|
|
118
119
|
//#endregion
|
|
119
120
|
export { type AislopConfig, type Diagnostic, type EngineName, type EngineResult, type Framework, type Language, type ProjectInfo, type ScoreResult, type Severity, calculateScore, discoverProject, doctorCommand, fixCommand, initCommand, loadConfig, scanCommand };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as getEngineLabel, r as APP_VERSION, t as ENGINE_INFO } from "./engine-info-
|
|
1
|
+
import { n as getEngineLabel, r as APP_VERSION, t as ENGINE_INFO } from "./engine-info-Bi8pE12U.js";
|
|
2
2
|
import { n as runSubprocess, t as isToolInstalled } from "./subprocess-99puEEGl.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import fs from "node:fs";
|
|
@@ -1273,7 +1273,8 @@ const DEFAULT_CONFIG = {
|
|
|
1273
1273
|
thresholds: {
|
|
1274
1274
|
good: 75,
|
|
1275
1275
|
ok: 50
|
|
1276
|
-
}
|
|
1276
|
+
},
|
|
1277
|
+
smoothing: 10
|
|
1277
1278
|
},
|
|
1278
1279
|
ci: {
|
|
1279
1280
|
failBelow: 0,
|
|
@@ -1373,7 +1374,8 @@ const ScoringSchema = z.object({
|
|
|
1373
1374
|
thresholds: ThresholdsSchema.default(() => ({
|
|
1374
1375
|
good: 75,
|
|
1375
1376
|
ok: 50
|
|
1376
|
-
}))
|
|
1377
|
+
})),
|
|
1378
|
+
smoothing: z.number().nonnegative().default(10)
|
|
1377
1379
|
});
|
|
1378
1380
|
const CiSchema = z.object({
|
|
1379
1381
|
failBelow: z.number().default(0),
|
|
@@ -1405,7 +1407,8 @@ const AislopConfigSchema = z.object({
|
|
|
1405
1407
|
thresholds: {
|
|
1406
1408
|
good: 75,
|
|
1407
1409
|
ok: 50
|
|
1408
|
-
}
|
|
1410
|
+
},
|
|
1411
|
+
smoothing: 10
|
|
1409
1412
|
})),
|
|
1410
1413
|
ci: CiSchema.default(() => ({
|
|
1411
1414
|
failBelow: 0,
|
|
@@ -2392,10 +2395,7 @@ const FUNCTION_PATTERNS = [
|
|
|
2392
2395
|
]
|
|
2393
2396
|
}
|
|
2394
2397
|
];
|
|
2395
|
-
const countParams = (
|
|
2396
|
-
if (!paramStr.trim()) return 0;
|
|
2397
|
-
return paramStr.split(",").length;
|
|
2398
|
-
};
|
|
2398
|
+
const countParams = (p) => p.trim() ? p.split(",").length : 0;
|
|
2399
2399
|
const matchFunctionOnLine = (line, ext) => {
|
|
2400
2400
|
for (let i = 0; i < FUNCTION_PATTERNS.length; i++) {
|
|
2401
2401
|
const pattern = FUNCTION_PATTERNS[i];
|
|
@@ -3776,7 +3776,12 @@ var ScanProgressRenderer = class {
|
|
|
3776
3776
|
//#endregion
|
|
3777
3777
|
//#region src/scoring/index.ts
|
|
3778
3778
|
const PERFECT_SCORE$1 = 100;
|
|
3779
|
-
const
|
|
3779
|
+
const getEffectiveFileCount = (diagnostics, sourceFileCount) => {
|
|
3780
|
+
if (typeof sourceFileCount === "number" && sourceFileCount > 0) return sourceFileCount;
|
|
3781
|
+
const filesWithDiagnostics = new Set(diagnostics.map((d) => d.filePath)).size;
|
|
3782
|
+
return Math.max(1, filesWithDiagnostics);
|
|
3783
|
+
};
|
|
3784
|
+
const calculateScore = (diagnostics, weights, thresholds, sourceFileCount, smoothing) => {
|
|
3780
3785
|
if (diagnostics.length === 0) return {
|
|
3781
3786
|
score: PERFECT_SCORE$1,
|
|
3782
3787
|
label: "Healthy"
|
|
@@ -3787,7 +3792,11 @@ const calculateScore = (diagnostics, weights, thresholds) => {
|
|
|
3787
3792
|
const severityPenalty = d.severity === "error" ? 3 : d.severity === "warning" ? 1 : .25;
|
|
3788
3793
|
deductions += severityPenalty * engineWeight;
|
|
3789
3794
|
}
|
|
3790
|
-
const
|
|
3795
|
+
const effectiveFileCount = getEffectiveFileCount(diagnostics, sourceFileCount);
|
|
3796
|
+
const smoothingConstant = typeof smoothing === "number" ? smoothing : 10;
|
|
3797
|
+
const issueDensity = Math.min(1, diagnostics.length / (effectiveFileCount + smoothingConstant));
|
|
3798
|
+
const scaledDeductions = deductions * Math.sqrt(issueDensity);
|
|
3799
|
+
const score = Math.max(0, Math.round(PERFECT_SCORE$1 - PERFECT_SCORE$1 * Math.log1p(scaledDeductions) / Math.log1p(PERFECT_SCORE$1 + scaledDeductions)));
|
|
3791
3800
|
return {
|
|
3792
3801
|
score,
|
|
3793
3802
|
label: score >= thresholds.good ? "Healthy" : score >= thresholds.ok ? "Needs Work" : "Critical"
|
|
@@ -3971,7 +3980,7 @@ const scanCommand = async (directory, config, options) => {
|
|
|
3971
3980
|
progressRenderer?.stop();
|
|
3972
3981
|
const allDiagnostics = results.flatMap((r) => r.diagnostics);
|
|
3973
3982
|
const elapsedMs = performance.now() - startTime;
|
|
3974
|
-
const scoreResult = calculateScore(allDiagnostics, config.scoring.weights, config.scoring.thresholds);
|
|
3983
|
+
const scoreResult = calculateScore(allDiagnostics, config.scoring.weights, config.scoring.thresholds, projectInfo.sourceFileCount, config.scoring.smoothing);
|
|
3975
3984
|
const exitCode = allDiagnostics.some((d) => d.severity === "error") || scoreResult.score < config.ci.failBelow ? 1 : 0;
|
|
3976
3985
|
if (!isTelemetryDisabled(config.telemetry?.enabled)) {
|
|
3977
3986
|
const engineIssues = {};
|
|
@@ -3991,7 +4000,7 @@ const scanCommand = async (directory, config, options) => {
|
|
|
3991
4000
|
});
|
|
3992
4001
|
}
|
|
3993
4002
|
if (options.json) {
|
|
3994
|
-
const { buildJsonOutput } = await import("./json-
|
|
4003
|
+
const { buildJsonOutput } = await import("./json-66-1kHeg.js");
|
|
3995
4004
|
const jsonOut = buildJsonOutput(results, scoreResult, projectInfo.sourceFileCount, elapsedMs);
|
|
3996
4005
|
console.log(JSON.stringify(jsonOut, null, 2));
|
|
3997
4006
|
return { exitCode };
|