@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.
@@ -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-v4OAaBLZ.js";
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 micromatch from "micromatch";
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.0";
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.0", 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");
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
- if (cached && cachedClaims && now < cached.refresh_after) return {
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 (micromatch.scan(normalized).isGlob) return [normalized];
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 micromatch.isMatch(relativePath, normalizedPatterns, { dot: true });
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 (micromatch.scan(normalized).isGlob) return [normalized];
1867
+ if (picomatch.scan(normalized).isGlob) return [normalized];
1707
1868
  return supportedGlobPatterns([normalized, `${normalized}/**`]);
1708
1869
  });
1709
1870
  const createPathMatcher = (patterns) => {
1710
- const matchers = patterns.map((pattern) => micromatch.matcher(pattern, { dot: true }));
1711
- return (filePath) => matchers.some((matches) => matches(filePath));
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 = micromatch.braces(pattern, { expand: true });
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 && micromatch.isMatch(relativePath, patterns, { dot: true });
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
- for (const relativeDir of micromatch(listPackageDirectories(rootDir), globs)) {
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", () => handleAislopScan(input)));
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", () => handleAislopFix(input)));
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", () => handleAislopWhy(input)));
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", () => handleAislopBaseline(input)));
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", () => handleAislopScan(input)));
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", () => handleAislopFix(input)));
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", () => handleAislopWhy(input)));
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", () => handleAislopBaseline(input)));
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-v4OAaBLZ.js";
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
@@ -1,6 +1,6 @@
1
1
  import "node:fs";
2
2
  import "node:url";
3
3
  //#region src/version.ts
4
- const APP_VERSION = "0.2.0";
4
+ const APP_VERSION = "0.2.2";
5
5
  //#endregion
6
6
  export { APP_VERSION as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@methiu/raigal",
3
- "version": "0.2.0",
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.30.0",
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.8.0",
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",