@methiu/raigal 0.2.0 → 0.2.2
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/adapters/astro.d.ts +1 -6
- package/dist/adapters/astro.js +1 -5
- package/dist/adapters/expo.d.ts +2 -6
- package/dist/adapters/expo.js +2 -5
- package/dist/adapters/nuxt.d.ts +1 -6
- package/dist/adapters/nuxt.js +1 -5
- package/dist/adapters/sveltekit.d.ts +1 -6
- package/dist/adapters/sveltekit.js +3 -7
- package/dist/adapters/vite.d.ts +1 -7
- package/dist/adapters/vite.js +1 -6
- package/dist/cli.js +930 -535
- package/dist/index.d.ts +29 -0
- package/dist/index.js +1166 -52
- package/dist/{json-C9fBWj3V.js → json-BaycSoJP.js} +2 -1
- package/dist/{json-C2IwKr9o.js → json-DBoMe4xB.js} +3 -2
- package/dist/mcp.js +205 -27
- package/dist/{sarif-Do8E1xhZ.js → sarif-Ba5D8TPH.js} +1 -1
- package/dist/{version-v4OAaBLZ.js → version-9Cnt1TiK.js} +1 -1
- package/package.json +8 -6
|
@@ -8,7 +8,8 @@ const buildJsonOutput = (results, scoreResult, fileCount, elapsedMs, coverage) =
|
|
|
8
8
|
for (const result of results) engines[result.engine] = {
|
|
9
9
|
issues: result.diagnostics.length,
|
|
10
10
|
skipped: result.skipped,
|
|
11
|
-
elapsed: result.elapsed
|
|
11
|
+
elapsed: result.elapsed,
|
|
12
|
+
...result.failed ? { failed: true } : {}
|
|
12
13
|
};
|
|
13
14
|
return {
|
|
14
15
|
schemaVersion: "1",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as APP_VERSION } from "./version-
|
|
1
|
+
import { t as APP_VERSION } from "./version-9Cnt1TiK.js";
|
|
2
2
|
import { i as ENGINE_INFO, n as withFindingAssessments, t as summarizeFindingAssessments } from "./finding-assessment-M5fUTE-C.js";
|
|
3
3
|
//#region src/output/json.ts
|
|
4
4
|
const buildJsonOutput = (results, scoreResult, fileCount, elapsedMs, coverage) => {
|
|
@@ -8,7 +8,8 @@ const buildJsonOutput = (results, scoreResult, fileCount, elapsedMs, coverage) =
|
|
|
8
8
|
for (const result of results) engines[result.engine] = {
|
|
9
9
|
issues: result.diagnostics.length,
|
|
10
10
|
skipped: result.skipped,
|
|
11
|
-
elapsed: result.elapsed
|
|
11
|
+
elapsed: result.elapsed,
|
|
12
|
+
...result.failed ? { failed: true } : {}
|
|
12
13
|
};
|
|
13
14
|
return {
|
|
14
15
|
schemaVersion: "1",
|
package/dist/mcp.js
CHANGED
|
@@ -12,7 +12,7 @@ import { createPublicKey, randomUUID, verify } from "node:crypto";
|
|
|
12
12
|
import { spawn, spawnSync } from "node:child_process";
|
|
13
13
|
import { z as z$1 } from "zod";
|
|
14
14
|
import YAML, { parse } from "yaml";
|
|
15
|
-
import
|
|
15
|
+
import picomatch from "picomatch";
|
|
16
16
|
import ts from "typescript";
|
|
17
17
|
import { parse as parse$1 } from "smol-toml";
|
|
18
18
|
//#region src/cloud/paths.ts
|
|
@@ -84,7 +84,7 @@ const getActiveToken = () => {
|
|
|
84
84
|
};
|
|
85
85
|
//#endregion
|
|
86
86
|
//#region src/version.ts
|
|
87
|
-
const APP_VERSION = "0.2.
|
|
87
|
+
const APP_VERSION = "0.2.2";
|
|
88
88
|
//#endregion
|
|
89
89
|
//#region src/cloud/contract.ts
|
|
90
90
|
const Severity = z.enum(["error", "warning"]);
|
|
@@ -359,7 +359,7 @@ const verifyEntitlementJwt = (jwt, options = {}) => {
|
|
|
359
359
|
const claims = parsed.data;
|
|
360
360
|
const expectedIssuer = process.env.RAIGAL_ISSUER?.trim() || "https://app.raigal.dev";
|
|
361
361
|
if (claims.iss !== expectedIssuer) throw new JwtVerificationError(`Untrusted issuer: ${claims.iss}`, "invalid_issuer");
|
|
362
|
-
if (!isVersionAtLeast("0.2.
|
|
362
|
+
if (!isVersionAtLeast("0.2.2", claims.min_cli_version)) throw new JwtVerificationError(`CLI version ${APP_VERSION} is below required minimum ${claims.min_cli_version}. Run "raigal update" or "npm install -g @methiu/raigal@latest".`, "cli_version_unsupported");
|
|
363
363
|
const now = options.nowSeconds ?? Math.floor(Date.now() / 1e3);
|
|
364
364
|
const grace = options.allowGraceSeconds ?? 0;
|
|
365
365
|
if (now > claims.exp + grace) {
|
|
@@ -473,6 +473,10 @@ const handleEntitlementFetchError = (err, cached, cachedClaims, now) => {
|
|
|
473
473
|
nowSeconds: now,
|
|
474
474
|
allowGraceSeconds: GRACE_PERIOD_SECONDS
|
|
475
475
|
});
|
|
476
|
+
if (graceClaims.plan === "trial" && graceClaims.trial_ends_at && now > Math.floor(new Date(graceClaims.trial_ends_at).getTime() / 1e3)) {
|
|
477
|
+
clearCachedEntitlement();
|
|
478
|
+
throw new LicenceDeniedError("Organization trial has expired", "trial_expired");
|
|
479
|
+
}
|
|
476
480
|
return {
|
|
477
481
|
jwt: cached.entitlement,
|
|
478
482
|
claims: graceClaims,
|
|
@@ -480,6 +484,7 @@ const handleEntitlementFetchError = (err, cached, cachedClaims, now) => {
|
|
|
480
484
|
grace: now > graceClaims.exp
|
|
481
485
|
};
|
|
482
486
|
} catch (jwtErr) {
|
|
487
|
+
if (jwtErr instanceof LicenceDeniedError) throw jwtErr;
|
|
483
488
|
if (jwtErr instanceof JwtVerificationError && jwtErr.code === "expired_beyond_grace") throw new LicenceUnverifiableError(`Raigal license could not be verified online and the offline grace period expired on ${(/* @__PURE__ */ new Date((cachedClaims?.exp ?? 0) * 1e3)).toISOString()}. Check network connectivity or Raigal Cloud status.`);
|
|
484
489
|
}
|
|
485
490
|
throw new LicenceUnverifiableError(`Raigal license could not be verified online (${err instanceof Error ? err.message : String(err)}). Check network connectivity or Raigal Cloud status.`);
|
|
@@ -494,7 +499,8 @@ const getEntitlement = async () => {
|
|
|
494
499
|
} catch {
|
|
495
500
|
cachedClaims = null;
|
|
496
501
|
}
|
|
497
|
-
|
|
502
|
+
const isTrialExpired = cachedClaims?.plan === "trial" && cachedClaims.trial_ends_at && now > Math.floor(new Date(cachedClaims.trial_ends_at).getTime() / 1e3);
|
|
503
|
+
if (cached && cachedClaims && !isTrialExpired && now < cached.refresh_after) return {
|
|
498
504
|
jwt: cached.entitlement,
|
|
499
505
|
claims: cachedClaims,
|
|
500
506
|
fromCache: true
|
|
@@ -503,7 +509,7 @@ const getEntitlement = async () => {
|
|
|
503
509
|
if (!activeToken) {
|
|
504
510
|
oidcToken = await fetchGitHubOidcToken();
|
|
505
511
|
if (!oidcToken) {
|
|
506
|
-
if (cached && cachedClaims) return {
|
|
512
|
+
if (cached && cachedClaims && !isTrialExpired) return {
|
|
507
513
|
jwt: cached.entitlement,
|
|
508
514
|
claims: cachedClaims,
|
|
509
515
|
fromCache: true
|
|
@@ -664,6 +670,23 @@ const requireEntitlement = async (options = {}) => {
|
|
|
664
670
|
try {
|
|
665
671
|
const entitlement = await getEntitlement();
|
|
666
672
|
const tokenKind = getActiveToken()?.kind ?? "session";
|
|
673
|
+
if (entitlement.claims.plan === "trial" && entitlement.claims.trial_ends_at) {
|
|
674
|
+
const trialEnd = new Date(entitlement.claims.trial_ends_at).getTime();
|
|
675
|
+
if (Date.now() > trialEnd) {
|
|
676
|
+
const message = "Raigal license denied: Organization trial has expired";
|
|
677
|
+
if (mode === "throw") throw new LicenceDeniedError(message, "trial_expired");
|
|
678
|
+
if (mode === "fatal") {
|
|
679
|
+
process.stderr.write(`${message}\n`);
|
|
680
|
+
process.exit(30);
|
|
681
|
+
}
|
|
682
|
+
process.stderr.write(`[raigal] ${message}\n`);
|
|
683
|
+
return {
|
|
684
|
+
ok: false,
|
|
685
|
+
exitCode: 30,
|
|
686
|
+
message
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
}
|
|
667
690
|
const detectedOwner = detectLocalRepoOwner(directory);
|
|
668
691
|
if (options.repoOwner) detectedOwner.owner = options.repoOwner.toLowerCase();
|
|
669
692
|
const ownerCheck = checkOwnerAgainstAllowlist(detectedOwner, entitlement.claims.allowed_owners, tokenKind);
|
|
@@ -784,7 +807,8 @@ const DEFAULT_CONFIG = {
|
|
|
784
807
|
format: "json"
|
|
785
808
|
},
|
|
786
809
|
telemetry: { enabled: true },
|
|
787
|
-
rules: {}
|
|
810
|
+
rules: {},
|
|
811
|
+
overrides: []
|
|
788
812
|
};
|
|
789
813
|
//#endregion
|
|
790
814
|
//#region src/config/extends.ts
|
|
@@ -976,6 +1000,16 @@ const RuleSeverityOverride = z.enum([
|
|
|
976
1000
|
"off"
|
|
977
1001
|
]);
|
|
978
1002
|
const RulesSchema = z.record(z.string(), RuleSeverityOverride).default(() => ({}));
|
|
1003
|
+
const FileOverrideSchema = z.object({
|
|
1004
|
+
files: z.array(z.string().min(1)).min(1),
|
|
1005
|
+
quality: z.object({
|
|
1006
|
+
maxFunctionLoc: QualitySchema.shape.maxFunctionLoc.unwrap().optional(),
|
|
1007
|
+
maxFileLoc: QualitySchema.shape.maxFileLoc.unwrap().optional(),
|
|
1008
|
+
maxNesting: QualitySchema.shape.maxNesting.unwrap().optional(),
|
|
1009
|
+
maxParams: QualitySchema.shape.maxParams.unwrap().optional()
|
|
1010
|
+
}).optional(),
|
|
1011
|
+
rules: z.record(z.string(), RuleSeverityOverride).optional()
|
|
1012
|
+
});
|
|
979
1013
|
const AislopConfigSchema = z.object({
|
|
980
1014
|
version: z.number().default(1),
|
|
981
1015
|
extends: z.union([z.string(), z.array(z.string())]).optional(),
|
|
@@ -1031,6 +1065,7 @@ const AislopConfigSchema = z.object({
|
|
|
1031
1065
|
})),
|
|
1032
1066
|
telemetry: TelemetrySchema.default(() => ({ enabled: true })),
|
|
1033
1067
|
rules: RulesSchema,
|
|
1068
|
+
overrides: z.array(FileOverrideSchema).default(() => []),
|
|
1034
1069
|
exclude: z.array(z.string()).default(() => [
|
|
1035
1070
|
"node_modules",
|
|
1036
1071
|
".git",
|
|
@@ -1249,6 +1284,132 @@ const loadConfig = (directory) => {
|
|
|
1249
1284
|
}
|
|
1250
1285
|
};
|
|
1251
1286
|
//#endregion
|
|
1287
|
+
//#region src/utils/globs.ts
|
|
1288
|
+
const MAX_BRACE_EXPANSIONS = 256;
|
|
1289
|
+
const braceListAt = (pattern, start) => {
|
|
1290
|
+
let depth = 0;
|
|
1291
|
+
const commas = [];
|
|
1292
|
+
for (let i = start; i < pattern.length; i += 1) {
|
|
1293
|
+
const char = pattern[i];
|
|
1294
|
+
if (char === "\\") i += 1;
|
|
1295
|
+
else if (char === "{") depth += 1;
|
|
1296
|
+
else if (char === ",") {
|
|
1297
|
+
if (depth === 1) commas.push(i);
|
|
1298
|
+
} else if (char === "}") {
|
|
1299
|
+
depth -= 1;
|
|
1300
|
+
if (depth === 0) return commas.length > 0 ? {
|
|
1301
|
+
start,
|
|
1302
|
+
end: i,
|
|
1303
|
+
commas
|
|
1304
|
+
} : null;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
return null;
|
|
1308
|
+
};
|
|
1309
|
+
const findBraceList = (pattern) => {
|
|
1310
|
+
for (let start = pattern.indexOf("{"); start !== -1; start = pattern.indexOf("{", start + 1)) {
|
|
1311
|
+
if (start > 0 && pattern[start - 1] === "\\") continue;
|
|
1312
|
+
const list = braceListAt(pattern, start);
|
|
1313
|
+
if (list) return list;
|
|
1314
|
+
}
|
|
1315
|
+
return null;
|
|
1316
|
+
};
|
|
1317
|
+
const expandInto = (pattern, results) => {
|
|
1318
|
+
const list = findBraceList(pattern);
|
|
1319
|
+
if (!list) {
|
|
1320
|
+
results.push(pattern);
|
|
1321
|
+
return results.length <= MAX_BRACE_EXPANSIONS;
|
|
1322
|
+
}
|
|
1323
|
+
const bounds = [
|
|
1324
|
+
list.start,
|
|
1325
|
+
...list.commas,
|
|
1326
|
+
list.end
|
|
1327
|
+
];
|
|
1328
|
+
const prefix = pattern.slice(0, list.start);
|
|
1329
|
+
const suffix = pattern.slice(list.end + 1);
|
|
1330
|
+
for (let i = 0; i < bounds.length - 1; i += 1) {
|
|
1331
|
+
const option = pattern.slice(bounds[i] + 1, bounds[i + 1]);
|
|
1332
|
+
if (!expandInto(`${prefix}${option}${suffix}`, results)) return false;
|
|
1333
|
+
}
|
|
1334
|
+
return true;
|
|
1335
|
+
};
|
|
1336
|
+
const expandBraceLists = (pattern) => {
|
|
1337
|
+
const results = [];
|
|
1338
|
+
return expandInto(pattern, results) ? results : [pattern];
|
|
1339
|
+
};
|
|
1340
|
+
const isNegated = (pattern) => picomatch.scan(pattern).negated;
|
|
1341
|
+
const matchesGlobList = (value, patterns, options = {}) => {
|
|
1342
|
+
const expanded = patterns.flatMap(expandBraceLists);
|
|
1343
|
+
const positives = expanded.filter((pattern) => !isNegated(pattern));
|
|
1344
|
+
const negatives = expanded.filter(isNegated).map((pattern) => pattern.slice(1));
|
|
1345
|
+
const included = positives.length === 0 || picomatch.isMatch(value, positives, options);
|
|
1346
|
+
const excluded = negatives.length > 0 && picomatch.isMatch(value, negatives, options);
|
|
1347
|
+
return included && !excluded;
|
|
1348
|
+
};
|
|
1349
|
+
//#endregion
|
|
1350
|
+
//#region src/scoring/rule-severity.ts
|
|
1351
|
+
/**
|
|
1352
|
+
* Apply per-rule severity overrides from config: "off" drops the diagnostic,
|
|
1353
|
+
* "error"/"warning" rewrite its severity before scoring and rendering.
|
|
1354
|
+
*/
|
|
1355
|
+
const applyRuleSeverities = (diagnostics, overrides) => {
|
|
1356
|
+
if (Object.keys(overrides).length === 0) return diagnostics;
|
|
1357
|
+
const result = [];
|
|
1358
|
+
for (const diagnostic of diagnostics) {
|
|
1359
|
+
const override = overrides[diagnostic.rule];
|
|
1360
|
+
if (!override) {
|
|
1361
|
+
result.push(diagnostic);
|
|
1362
|
+
continue;
|
|
1363
|
+
}
|
|
1364
|
+
if (override === "off") continue;
|
|
1365
|
+
result.push(override === diagnostic.severity ? diagnostic : {
|
|
1366
|
+
...diagnostic,
|
|
1367
|
+
severity: override
|
|
1368
|
+
});
|
|
1369
|
+
}
|
|
1370
|
+
return result;
|
|
1371
|
+
};
|
|
1372
|
+
//#endregion
|
|
1373
|
+
//#region src/config/overrides.ts
|
|
1374
|
+
const overrideRelativePath = (rootDirectory, filePath) => {
|
|
1375
|
+
const paths = path.win32.isAbsolute(rootDirectory) && !path.posix.isAbsolute(rootDirectory) ? path.win32 : path.posix;
|
|
1376
|
+
const root = rootDirectory.replaceAll("\\", "/");
|
|
1377
|
+
const file = filePath.replaceAll("\\", "/");
|
|
1378
|
+
return paths.normalize(paths.isAbsolute(file) ? paths.relative(root, file) : file).replaceAll("\\", "/");
|
|
1379
|
+
};
|
|
1380
|
+
const matchesEntry = (relativePath, patterns) => matchesGlobList(relativePath, patterns, { dot: true });
|
|
1381
|
+
const resolveFilePolicy = (config, relativePath) => {
|
|
1382
|
+
let quality = config.quality;
|
|
1383
|
+
let rules = config.rules ?? {};
|
|
1384
|
+
if (relativePath === ".." || relativePath.startsWith("../") || path.win32.isAbsolute(relativePath)) return {
|
|
1385
|
+
quality,
|
|
1386
|
+
rules
|
|
1387
|
+
};
|
|
1388
|
+
for (const entry of config.overrides ?? []) {
|
|
1389
|
+
if (!matchesEntry(relativePath, entry.files)) continue;
|
|
1390
|
+
if (entry.quality) quality = {
|
|
1391
|
+
...quality,
|
|
1392
|
+
...entry.quality
|
|
1393
|
+
};
|
|
1394
|
+
if (entry.rules) rules = {
|
|
1395
|
+
...rules,
|
|
1396
|
+
...entry.rules
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
return {
|
|
1400
|
+
quality,
|
|
1401
|
+
rules
|
|
1402
|
+
};
|
|
1403
|
+
};
|
|
1404
|
+
const applyFileOverrides = (diagnostics, context) => {
|
|
1405
|
+
if (!context.config.overrides?.length) return diagnostics;
|
|
1406
|
+
return diagnostics.flatMap((diagnostic) => {
|
|
1407
|
+
const relativePath = overrideRelativePath(context.rootDirectory, diagnostic.filePath);
|
|
1408
|
+
const { rules } = resolveFilePolicy(context.config, relativePath);
|
|
1409
|
+
return applyRuleSeverities([diagnostic], rules);
|
|
1410
|
+
});
|
|
1411
|
+
};
|
|
1412
|
+
//#endregion
|
|
1252
1413
|
//#region src/utils/paths.ts
|
|
1253
1414
|
/** Normalize an OS path to forward-slash (POSIX) separators. */
|
|
1254
1415
|
const toPosix = (p) => p.split(path.sep).join("/");
|
|
@@ -1275,13 +1436,13 @@ const normalizeExcludePatterns = (patterns) => patterns.flatMap((pattern) => {
|
|
|
1275
1436
|
const normalized = withoutProjectPrefix.slice(0, end);
|
|
1276
1437
|
if (normalized.length === 0) return [];
|
|
1277
1438
|
if (normalized.length > 256) return [];
|
|
1278
|
-
if (
|
|
1439
|
+
if (picomatch.scan(normalized).isGlob) return [normalized];
|
|
1279
1440
|
if (normalized.startsWith(".") && !normalized.includes("/")) return supportedGlobPatterns([`**/${normalized}`, `**/${normalized}/**`]);
|
|
1280
1441
|
return supportedGlobPatterns([normalized, `${normalized}/**`]);
|
|
1281
1442
|
});
|
|
1282
1443
|
const isPathExcluded = (relativePath, normalizedPatterns) => {
|
|
1283
1444
|
if (normalizedPatterns.length === 0) return false;
|
|
1284
|
-
return
|
|
1445
|
+
return picomatch.isMatch(relativePath, normalizedPatterns, { dot: true });
|
|
1285
1446
|
};
|
|
1286
1447
|
const filterExcludedDiagnostics = (diagnostics, rootDirectory, excludePatterns) => {
|
|
1287
1448
|
if (!excludePatterns || excludePatterns.length === 0) return diagnostics;
|
|
@@ -1703,12 +1864,13 @@ const normalizeIncludePatterns = (patterns) => patterns.flatMap((pattern) => {
|
|
|
1703
1864
|
const normalized = pattern.trim().replace(/^\.\//, "").replace(/\/$/, "");
|
|
1704
1865
|
if (normalized === "" || normalized === ".") return ["**"];
|
|
1705
1866
|
if (normalized.length > 256) return [];
|
|
1706
|
-
if (
|
|
1867
|
+
if (picomatch.scan(normalized).isGlob) return [normalized];
|
|
1707
1868
|
return supportedGlobPatterns([normalized, `${normalized}/**`]);
|
|
1708
1869
|
});
|
|
1709
1870
|
const createPathMatcher = (patterns) => {
|
|
1710
|
-
|
|
1711
|
-
|
|
1871
|
+
if (patterns.length === 0) return () => false;
|
|
1872
|
+
const isMatch = picomatch(patterns, { dot: true });
|
|
1873
|
+
return (filePath) => isMatch(filePath);
|
|
1712
1874
|
};
|
|
1713
1875
|
const filterFiles = (rootDirectory, files, options) => {
|
|
1714
1876
|
const extraExtensions = new Set(options.extraExtensions);
|
|
@@ -9523,10 +9685,10 @@ const checkFileComplexity = (filePath, rootDirectory, limits) => {
|
|
|
9523
9685
|
};
|
|
9524
9686
|
const checkComplexity = async (context) => {
|
|
9525
9687
|
const files = getSourceFiles(context);
|
|
9526
|
-
const limits = context.config.quality;
|
|
9527
9688
|
const diagnostics = [];
|
|
9528
9689
|
for (const filePath of files) {
|
|
9529
9690
|
if (isAutoGenerated(filePath)) continue;
|
|
9691
|
+
const { quality: limits } = resolveFilePolicy(context.config, overrideRelativePath(context.rootDirectory, filePath));
|
|
9530
9692
|
diagnostics.push(...checkFileComplexity(filePath, context.rootDirectory, limits));
|
|
9531
9693
|
}
|
|
9532
9694
|
return diagnostics;
|
|
@@ -10516,13 +10678,23 @@ const withReportPath = async (run) => {
|
|
|
10516
10678
|
};
|
|
10517
10679
|
const UNSUPPORTED_GLOB_SYNTAX = /[?[\]{}!|()\\]/;
|
|
10518
10680
|
const isDotnetFormatPath = (pattern) => !pattern.startsWith("-") && !UNSUPPORTED_GLOB_SYNTAX.test(pattern);
|
|
10681
|
+
const expandBraces = (pattern, depth = 0) => {
|
|
10682
|
+
if (depth > 10) return [pattern];
|
|
10683
|
+
const match = /\{([^{}]+)\}/.exec(pattern);
|
|
10684
|
+
if (!match) return [pattern];
|
|
10685
|
+
const [fullMatch, options] = match;
|
|
10686
|
+
const parts = options.split(",");
|
|
10687
|
+
const prefix = pattern.slice(0, match.index);
|
|
10688
|
+
const suffix = pattern.slice(match.index + fullMatch.length);
|
|
10689
|
+
return parts.flatMap((part) => expandBraces(`${prefix}${part}${suffix}`, depth + 1));
|
|
10690
|
+
};
|
|
10519
10691
|
const buildDotnetFormatExcludeScope = (excludePatterns) => {
|
|
10520
10692
|
const scope = {
|
|
10521
10693
|
excludeArguments: [],
|
|
10522
10694
|
unsupportedPatterns: []
|
|
10523
10695
|
};
|
|
10524
10696
|
for (const pattern of normalizeExcludePatterns(excludePatterns ?? [])) {
|
|
10525
|
-
const expanded =
|
|
10697
|
+
const expanded = expandBraces(pattern);
|
|
10526
10698
|
if (expanded.every(isDotnetFormatPath)) scope.excludeArguments.push(...expanded);
|
|
10527
10699
|
else scope.unsupportedPatterns.push(pattern);
|
|
10528
10700
|
}
|
|
@@ -12107,7 +12279,7 @@ const normalizeEslintIgnorePatterns = (patterns) => patterns.map((pattern) => pa
|
|
|
12107
12279
|
if (!pattern.includes("*") && !path.extname(pattern)) return [`${pattern}/**`];
|
|
12108
12280
|
return [pattern];
|
|
12109
12281
|
});
|
|
12110
|
-
const isEslintIgnored = (relativePath, patterns) => patterns.length > 0 &&
|
|
12282
|
+
const isEslintIgnored = (relativePath, patterns) => patterns.length > 0 && picomatch.isMatch(relativePath, patterns, { dot: true });
|
|
12111
12283
|
const getOxlintTargets = (context) => {
|
|
12112
12284
|
const eslintIgnorePatterns = normalizeEslintIgnorePatterns(collectEslintIgnorePatterns(context.rootDirectory));
|
|
12113
12285
|
return getSourceFiles(context).filter((filePath) => OXLINT_EXTENSIONS.has(path.extname(filePath).toLowerCase())).filter((filePath) => !isAutoGenerated(filePath)).map((filePath) => path.relative(context.rootDirectory, filePath).split(path.sep).join("/")).filter((filePath) => !isEslintIgnored(filePath, eslintIgnorePatterns));
|
|
@@ -12889,7 +13061,8 @@ const readRuntimeDependencies = (rootDir) => {
|
|
|
12889
13061
|
collectRuntimeNames(rootManifest, names);
|
|
12890
13062
|
const globs = [...npmWorkspaceGlobs(rootManifest), ...pnpmWorkspaceGlobs(rootDir)];
|
|
12891
13063
|
if (globs.length === 0) return { runtimeDependencies: names };
|
|
12892
|
-
|
|
13064
|
+
const isMatch = picomatch(globs, { dot: true });
|
|
13065
|
+
for (const relativeDir of listPackageDirectories(rootDir).filter((dir) => isMatch(dir))) {
|
|
12893
13066
|
const memberManifest = readJsonFile(path.join(rootDir, relativeDir, "package.json"));
|
|
12894
13067
|
if (memberManifest) collectRuntimeNames(memberManifest, names);
|
|
12895
13068
|
}
|
|
@@ -13758,6 +13931,7 @@ const runEngines = async (context, enabledEngines, onStart, onComplete) => {
|
|
|
13758
13931
|
const result = await engine.run(context);
|
|
13759
13932
|
result.diagnostics = filterExcludedDiagnostics(result.diagnostics, context.rootDirectory, context.excludePatterns);
|
|
13760
13933
|
result.elapsed = performance.now() - start;
|
|
13934
|
+
result.diagnostics = applyFileOverrides(result.diagnostics, context);
|
|
13761
13935
|
onComplete?.(result);
|
|
13762
13936
|
return result;
|
|
13763
13937
|
} catch (error) {
|
|
@@ -13766,6 +13940,7 @@ const runEngines = async (context, enabledEngines, onStart, onComplete) => {
|
|
|
13766
13940
|
diagnostics: [],
|
|
13767
13941
|
elapsed: performance.now() - start,
|
|
13768
13942
|
skipped: true,
|
|
13943
|
+
failed: true,
|
|
13769
13944
|
skipReason: error instanceof Error ? error.message : String(error)
|
|
13770
13945
|
};
|
|
13771
13946
|
onComplete?.(result);
|
|
@@ -13776,6 +13951,7 @@ const runEngines = async (context, enabledEngines, onStart, onComplete) => {
|
|
|
13776
13951
|
diagnostics: [],
|
|
13777
13952
|
elapsed: 0,
|
|
13778
13953
|
skipped: true,
|
|
13954
|
+
failed: true,
|
|
13779
13955
|
skipReason: r.reason instanceof Error ? r.reason.message : String(r.reason)
|
|
13780
13956
|
});
|
|
13781
13957
|
return dedupeEquivalenceDiagnostics(dedupeOverlappingComments(dedupeCSharpAsync(stripSecretDiagnostics(finalResults))));
|
|
@@ -14449,6 +14625,8 @@ const buildEngineContext = (rootDirectory, project, config) => {
|
|
|
14449
14625
|
frameworks: project.frameworks,
|
|
14450
14626
|
installedTools: project.installedTools,
|
|
14451
14627
|
config: {
|
|
14628
|
+
overrides: config.overrides,
|
|
14629
|
+
rules: config.rules,
|
|
14452
14630
|
quality: config.quality,
|
|
14453
14631
|
security: config.security,
|
|
14454
14632
|
lint: config.lint,
|
|
@@ -14530,7 +14708,6 @@ const handleRaigalScan = async (input) => {
|
|
|
14530
14708
|
...summary
|
|
14531
14709
|
};
|
|
14532
14710
|
};
|
|
14533
|
-
const handleAislopScan = handleRaigalScan;
|
|
14534
14711
|
const aislopFixInputSchema = z$1.object({
|
|
14535
14712
|
path: z$1.string().optional().describe("Project directory to fix, confined to the MCP server's cwd. Defaults to that cwd."),
|
|
14536
14713
|
force: z$1.boolean().optional().describe("Run aggressive fixes (dependency audit overrides, unused-file removal, framework alignment). Off by default; on means writes to package.json and may delete files.")
|
|
@@ -14587,7 +14764,6 @@ const handleRaigalFix = async (input) => {
|
|
|
14587
14764
|
elided: summary.elided
|
|
14588
14765
|
};
|
|
14589
14766
|
};
|
|
14590
|
-
const handleAislopFix = handleRaigalFix;
|
|
14591
14767
|
const aislopWhyInputSchema = z$1.object({ rule_id: z$1.string().describe("Full rule id (e.g. `ai-slop/narrative-comment`, `complexity/function-too-long`, `security/sql-injection`).") });
|
|
14592
14768
|
const aislopWhyTool = {
|
|
14593
14769
|
name: "raigal_why",
|
|
@@ -14606,7 +14782,6 @@ const handleRaigalWhy = (input) => {
|
|
|
14606
14782
|
hint: "Run `raigal rules` for the full list of rules and their auto-fix status. The /patterns page has bad/good code examples for every named ai-slop pattern."
|
|
14607
14783
|
};
|
|
14608
14784
|
};
|
|
14609
|
-
const handleAislopWhy = handleRaigalWhy;
|
|
14610
14785
|
const aislopBaselineInputSchema = z$1.object({ path: z$1.string().optional().describe("Project directory, confined to the MCP server's cwd. Defaults to that cwd.") });
|
|
14611
14786
|
const aislopBaselineTool = {
|
|
14612
14787
|
name: "raigal_baseline",
|
|
@@ -14627,7 +14802,6 @@ const handleRaigalBaseline = (input) => {
|
|
|
14627
14802
|
hint: "Run `raigal hook baseline` to capture a baseline."
|
|
14628
14803
|
};
|
|
14629
14804
|
};
|
|
14630
|
-
const handleAislopBaseline = handleRaigalBaseline;
|
|
14631
14805
|
//#endregion
|
|
14632
14806
|
//#region src/telemetry/env.ts
|
|
14633
14807
|
const ALLOWED_OVERRIDE = /* @__PURE__ */ new Set([
|
|
@@ -14766,6 +14940,10 @@ const SAFE_PROPERTY_NAMES = /* @__PURE__ */ new Set([
|
|
|
14766
14940
|
"exit_code",
|
|
14767
14941
|
"duration_ms",
|
|
14768
14942
|
"error_kind",
|
|
14943
|
+
"error_name",
|
|
14944
|
+
"error_code",
|
|
14945
|
+
"failed_stage",
|
|
14946
|
+
"engines_failed",
|
|
14769
14947
|
"score",
|
|
14770
14948
|
"score_bucket",
|
|
14771
14949
|
"finding_count",
|
|
@@ -14989,35 +15167,35 @@ const buildServer = () => {
|
|
|
14989
15167
|
server.registerTool(aislopScanTool.name, {
|
|
14990
15168
|
description: aislopScanTool.description,
|
|
14991
15169
|
inputSchema: aislopScanInputSchema.shape
|
|
14992
|
-
}, (input) => instrument("aislop_scan", () =>
|
|
15170
|
+
}, (input) => instrument("aislop_scan", () => handleRaigalScan(input)));
|
|
14993
15171
|
server.registerTool(aislopFixTool.name, {
|
|
14994
15172
|
description: aislopFixTool.description,
|
|
14995
15173
|
inputSchema: aislopFixInputSchema.shape
|
|
14996
|
-
}, (input) => instrument("aislop_fix", () =>
|
|
15174
|
+
}, (input) => instrument("aislop_fix", () => handleRaigalFix(input)));
|
|
14997
15175
|
server.registerTool(aislopWhyTool.name, {
|
|
14998
15176
|
description: aislopWhyTool.description,
|
|
14999
15177
|
inputSchema: aislopWhyInputSchema.shape
|
|
15000
|
-
}, (input) => instrument("aislop_why", () =>
|
|
15178
|
+
}, (input) => instrument("aislop_why", () => handleRaigalWhy(input)));
|
|
15001
15179
|
server.registerTool(aislopBaselineTool.name, {
|
|
15002
15180
|
description: aislopBaselineTool.description,
|
|
15003
15181
|
inputSchema: aislopBaselineInputSchema.shape
|
|
15004
|
-
}, (input) => instrument("aislop_baseline", () =>
|
|
15182
|
+
}, (input) => instrument("aislop_baseline", () => handleRaigalBaseline(input)));
|
|
15005
15183
|
server.registerTool("raigal_scan", {
|
|
15006
15184
|
description: aislopScanTool.description,
|
|
15007
15185
|
inputSchema: aislopScanInputSchema.shape
|
|
15008
|
-
}, (input) => instrument("raigal_scan", () =>
|
|
15186
|
+
}, (input) => instrument("raigal_scan", () => handleRaigalScan(input)));
|
|
15009
15187
|
server.registerTool("raigal_fix", {
|
|
15010
15188
|
description: aislopFixTool.description,
|
|
15011
15189
|
inputSchema: aislopFixInputSchema.shape
|
|
15012
|
-
}, (input) => instrument("raigal_fix", () =>
|
|
15190
|
+
}, (input) => instrument("raigal_fix", () => handleRaigalFix(input)));
|
|
15013
15191
|
server.registerTool("raigal_why", {
|
|
15014
15192
|
description: aislopWhyTool.description,
|
|
15015
15193
|
inputSchema: aislopWhyInputSchema.shape
|
|
15016
|
-
}, (input) => instrument("raigal_why", () =>
|
|
15194
|
+
}, (input) => instrument("raigal_why", () => handleRaigalWhy(input)));
|
|
15017
15195
|
server.registerTool("raigal_baseline", {
|
|
15018
15196
|
description: aislopBaselineTool.description,
|
|
15019
15197
|
inputSchema: aislopBaselineInputSchema.shape
|
|
15020
|
-
}, (input) => instrument("raigal_baseline", () =>
|
|
15198
|
+
}, (input) => instrument("raigal_baseline", () => handleRaigalBaseline(input)));
|
|
15021
15199
|
return server;
|
|
15022
15200
|
};
|
|
15023
15201
|
const main = async () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as APP_VERSION } from "./version-
|
|
1
|
+
import { t as APP_VERSION } from "./version-9Cnt1TiK.js";
|
|
2
2
|
import { n as isSecretClassRule, t as FIXED_SECRET_DIAGNOSTIC_MESSAGE } from "./mask-secrets-BXn-ZSEh.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
//#region src/output/sarif.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@methiu/raigal",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -99,24 +99,26 @@
|
|
|
99
99
|
"packageManager": "pnpm@10.28.0",
|
|
100
100
|
"pnpm": {
|
|
101
101
|
"overrides": {
|
|
102
|
-
"fast-uri": ">=3.1.8"
|
|
102
|
+
"fast-uri": ">=3.1.8",
|
|
103
|
+
"source-map-js": ">=1.2.2",
|
|
104
|
+
"proxy-addr": ">=2.0.8"
|
|
103
105
|
}
|
|
104
106
|
},
|
|
105
107
|
"dependencies": {
|
|
106
108
|
"@biomejs/biome": "^2.5.12",
|
|
107
109
|
"@clack/prompts": "^1.7.0",
|
|
108
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
110
|
+
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
109
111
|
"adm-zip": "^0.6.1",
|
|
110
112
|
"commander": "^14.0.3",
|
|
111
113
|
"expo-doctor": "^1.20.4",
|
|
112
114
|
"ink": "^7.1.1",
|
|
113
115
|
"ink-select-input": "^6.2.0",
|
|
114
116
|
"knip": "^6.34.0",
|
|
115
|
-
"micromatch": "^4.0.8",
|
|
116
117
|
"oxlint": "^1.81.0",
|
|
117
118
|
"picocolors": "^1.1.1",
|
|
119
|
+
"picomatch": "^4.0.4",
|
|
118
120
|
"react": "^19.2.8",
|
|
119
|
-
"smol-toml": "^1.
|
|
121
|
+
"smol-toml": "^1.9.0",
|
|
120
122
|
"tar": "^7.5.22",
|
|
121
123
|
"typescript": "^6.0.3",
|
|
122
124
|
"wcwidth": "^1.0.1",
|
|
@@ -124,8 +126,8 @@
|
|
|
124
126
|
"zod": "^4.4.3"
|
|
125
127
|
},
|
|
126
128
|
"devDependencies": {
|
|
127
|
-
"@types/micromatch": "^4.0.10",
|
|
128
129
|
"@types/node": "^26.4.0",
|
|
130
|
+
"@types/picomatch": "^4.0.3",
|
|
129
131
|
"@types/react": "^19.2.18",
|
|
130
132
|
"ink-testing-library": "^4.0.0",
|
|
131
133
|
"tsdown": "^0.22.14",
|