@methiu/raigal 0.2.3 → 0.2.5

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/cli.js CHANGED
@@ -13,7 +13,8 @@ import { z } from "zod/v4";
13
13
  import crypto, { createHash, createPublicKey, randomUUID, verify } from "node:crypto";
14
14
  import YAML, { parse } from "yaml";
15
15
  import { confirm, isCancel, multiselect, select, text } from "@clack/prompts";
16
- import readline, * as readline$1 from "node:readline";
16
+ import * as readline$1 from "node:readline";
17
+ import readline from "node:readline";
17
18
  import picomatch from "picomatch";
18
19
  import ts from "typescript";
19
20
  import { parse as parse$1 } from "smol-toml";
@@ -112,8 +113,7 @@ const commandExists = (bin) => {
112
113
  }
113
114
  }
114
115
  }
115
- const command = process.platform === "win32" ? "where.exe" : "which";
116
- const result = spawnSync(command, [bin], {
116
+ const result = spawnSync(process.platform === "win32" ? "where.exe" : "which", [bin], {
117
117
  encoding: "utf-8",
118
118
  timeout: PROVIDER_PROBE_TIMEOUT_MS
119
119
  });
@@ -711,8 +711,7 @@ const stringWidth = (s) => {
711
711
  const bare = stripAnsi$1(s);
712
712
  let total = 0;
713
713
  for (const ch of bare) {
714
- const cp = ch.codePointAt(0) ?? 0;
715
- const w = wcwidth(cp);
714
+ const w = wcwidth(ch.codePointAt(0) ?? 0);
716
715
  total += w > 0 ? w : 1;
717
716
  }
718
717
  return total;
@@ -728,8 +727,7 @@ const truncate = (s, max, ellipsis = "…") => {
728
727
  let out = "";
729
728
  let w = 0;
730
729
  for (const ch of s) {
731
- const cp = ch.codePointAt(0) ?? 0;
732
- const cw = wcwidth(cp);
730
+ const cw = wcwidth(ch.codePointAt(0) ?? 0);
733
731
  if (w + cw > limit) break;
734
732
  out += ch;
735
733
  w += cw;
@@ -739,8 +737,7 @@ const truncate = (s, max, ellipsis = "…") => {
739
737
  //#endregion
740
738
  //#region src/ui/display.ts
741
739
  const renderDisplaySection = (label, deps = {}) => {
742
- const t = deps.theme ?? theme;
743
- return style$1(t, "section", label);
740
+ return style$1(deps.theme ?? theme, "section", label);
744
741
  };
745
742
  const renderDisplayRows = (rows, options = {}) => {
746
743
  if (rows.length === 0) return [];
@@ -901,8 +898,7 @@ const symbols = createSymbols({ plain: isPlain() });
901
898
  */
902
899
  const renderHintLine = (hint, deps = {}) => {
903
900
  const t = deps.theme ?? theme;
904
- const s = deps.symbols ?? symbols;
905
- return ` ${style$1(t, "accent", s.hint)} ${highlightAislop(maskSecrets(hint), t)}\n`;
901
+ return ` ${style$1(t, "accent", (deps.symbols ?? symbols).hint)} ${highlightAislop(maskSecrets(hint), t)}\n`;
906
902
  };
907
903
  const createLogger = (deps = {}) => {
908
904
  const t = deps.theme ?? theme;
@@ -927,7 +923,7 @@ const createLogger = (deps = {}) => {
927
923
  const log = createLogger();
928
924
  //#endregion
929
925
  //#region src/version.ts
930
- const APP_VERSION = "0.2.3";
926
+ const APP_VERSION = "0.2.5";
931
927
  //#endregion
932
928
  //#region src/commands/agent-connect.ts
933
929
  const commandText = (status) => [status.provider.loginCommand.command, ...status.provider.loginCommand.args].join(" ");
@@ -1414,9 +1410,7 @@ const verifyEntitlementJwt = (jwt, options = {}) => {
1414
1410
  if (!header.kid) throw new JwtVerificationError("JWT header missing 'kid'", "unknown_kid");
1415
1411
  const publicKey = getPublicKey(header.kid);
1416
1412
  if (!publicKey) throw new JwtVerificationError(`Unknown or untrusted signing key id (kid: ${header.kid})`, "unknown_kid");
1417
- const signedData = Buffer.from(`${headerB64}.${payloadB64}`, "utf-8");
1418
- const signature = Buffer.from(signatureB64, "base64url");
1419
- if (!verify(null, signedData, publicKey, signature)) throw new JwtVerificationError("Invalid JWT cryptographic signature", "invalid_signature");
1413
+ if (!verify(null, Buffer.from(`${headerB64}.${payloadB64}`, "utf-8"), publicKey, Buffer.from(signatureB64, "base64url"))) throw new JwtVerificationError("Invalid JWT cryptographic signature", "invalid_signature");
1420
1414
  let rawPayload;
1421
1415
  try {
1422
1416
  rawPayload = JSON.parse(Buffer.from(payloadB64, "base64url").toString("utf-8"));
@@ -1428,7 +1422,7 @@ const verifyEntitlementJwt = (jwt, options = {}) => {
1428
1422
  const claims = parsed.data;
1429
1423
  const expectedIssuer = process.env.RAIGAL_ISSUER?.trim() || "https://app.raigal.dev";
1430
1424
  if (claims.iss !== expectedIssuer) throw new JwtVerificationError(`Untrusted issuer: ${claims.iss}`, "invalid_issuer");
1431
- if (!isVersionAtLeast("0.2.3", 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");
1425
+ if (!isVersionAtLeast("0.2.5", 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");
1432
1426
  const now = options.nowSeconds ?? Math.floor(Date.now() / 1e3);
1433
1427
  const grace = options.allowGraceSeconds ?? 0;
1434
1428
  if (now > claims.exp + grace) {
@@ -1462,7 +1456,7 @@ const fetchGitHubOidcToken = async () => {
1462
1456
  };
1463
1457
  //#endregion
1464
1458
  //#region src/cloud/entitlement.ts
1465
- const GRACE_PERIOD_SECONDS = 259200;
1459
+ const GRACE_PERIOD_SECONDS = 4320 * 60;
1466
1460
  var MissingCredentialError = class extends Error {
1467
1461
  constructor(message = "No organization credential found") {
1468
1462
  super(message);
@@ -1587,8 +1581,7 @@ const getEntitlement = async () => {
1587
1581
  }
1588
1582
  } else oidcToken = await fetchGitHubOidcToken();
1589
1583
  try {
1590
- const tokenToPass = activeToken?.token ?? "";
1591
- const response = await fetchEntitlementFromApi(tokenToPass, oidcToken);
1584
+ const response = await fetchEntitlementFromApi(activeToken?.token ?? "", oidcToken);
1592
1585
  const claims = verifyEntitlementJwt(response.entitlement, { nowSeconds: now });
1593
1586
  saveCachedEntitlement(response.entitlement, response.refresh_after);
1594
1587
  return {
@@ -2383,7 +2376,7 @@ var AgentTui = class {
2383
2376
  }
2384
2377
  ensureMounted() {
2385
2378
  if (!this.tty || this.handle) return;
2386
- this.handle = import("./mount-CHGc3gB6.js").then((m) => m.mountAgentTui(this.store));
2379
+ this.handle = import("./mount-DTc8WaIt.js").then((m) => m.mountAgentTui(this.store));
2387
2380
  }
2388
2381
  setActions(actions) {
2389
2382
  this.store.update({ actions: actions.filter((action) => action.trim().length > 0) });
@@ -2478,7 +2471,7 @@ const runSelf = (args, cwd) => {
2478
2471
  AISLOP_NO_UPDATE_NOTIFIER: "1",
2479
2472
  NO_COLOR: "1"
2480
2473
  },
2481
- maxBuffer: 52428800
2474
+ maxBuffer: 50 * 1024 * 1024
2482
2475
  });
2483
2476
  return {
2484
2477
  exitCode: result.status,
@@ -2517,7 +2510,7 @@ const applyDiff = async (root, patch) => {
2517
2510
  cwd: root,
2518
2511
  input: patch,
2519
2512
  encoding: "utf-8",
2520
- maxBuffer: 52428800
2513
+ maxBuffer: 50 * 1024 * 1024
2521
2514
  });
2522
2515
  if (child.status !== 0) throw new Error(child.stderr || child.stdout || "Failed to apply agent diff.");
2523
2516
  };
@@ -2890,7 +2883,7 @@ const detectCiContext = () => {
2890
2883
  };
2891
2884
  //#endregion
2892
2885
  //#region src/cloud/outbox.ts
2893
- const MAX_OUTBOX_BYTES = 5242880;
2886
+ const MAX_OUTBOX_BYTES = 5 * 1024 * 1024;
2894
2887
  const getMaxOutboxBytes = () => {
2895
2888
  const override = process.env.RAIGAL_MAX_OUTBOX_BYTES;
2896
2889
  if (override) {
@@ -3085,8 +3078,7 @@ var CloudRunRecorder = class {
3085
3078
  if (this.finished) return;
3086
3079
  this.finished = true;
3087
3080
  try {
3088
- const run = this.buildRunPayload(exitCode);
3089
- enqueueRun(run);
3081
+ enqueueRun(this.buildRunPayload(exitCode));
3090
3082
  const activeToken = getActiveToken();
3091
3083
  let oidcToken;
3092
3084
  if (!activeToken) oidcToken = await fetchGitHubOidcToken();
@@ -3789,8 +3781,7 @@ const runSafeFixStep = (tui, cwd, options) => {
3789
3781
  };
3790
3782
  const selectFindings = (tui, cwd, limit, pass) => {
3791
3783
  tui.start(`Pass ${pass}: selecting findings`);
3792
- const scan = scanJson(cwd);
3793
- const findings = selectAgentFindings(scan.diagnostics, limit);
3784
+ const findings = selectAgentFindings(scanJson(cwd).diagnostics, limit);
3794
3785
  tui.setMetric("Selected", findings.length);
3795
3786
  tui.complete({
3796
3787
  status: findings.length > 0 ? "done" : "skipped",
@@ -4823,7 +4814,7 @@ const DEFAULT_RULES_YAML = `# Architecture rules (BYO)
4823
4814
  //#endregion
4824
4815
  //#region src/config/extends.ts
4825
4816
  const MAX_DEPTH$1 = 5;
4826
- const MAX_CONFIG_BYTES = 1048576;
4817
+ const MAX_CONFIG_BYTES = 1024 * 1024;
4827
4818
  const isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
4828
4819
  const deepMerge = (...sources) => {
4829
4820
  const result = {};
@@ -5301,8 +5292,7 @@ const loadConfig = (directory) => {
5301
5292
  const configPath = findConfigFile(directory);
5302
5293
  if (!configPath) return DEFAULT_CONFIG;
5303
5294
  try {
5304
- const merged = loadConfigChain(configPath);
5305
- return validateConfig(merged, configPath);
5295
+ return validateConfig(loadConfigChain(configPath), configPath);
5306
5296
  } catch (error) {
5307
5297
  if (error instanceof ConfigError) throw error;
5308
5298
  throw new ConfigError(configPath, `Failed to parse ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
@@ -5577,11 +5567,10 @@ const track = (input) => {
5577
5567
  cachedInstallId = ensured.installId;
5578
5568
  installCreated = ensured.created;
5579
5569
  }
5580
- const merged = {
5570
+ const { clean, dropped } = redactProperties({
5581
5571
  ...baseProperties(cachedInstallId),
5582
5572
  ...input.properties
5583
- };
5584
- const { clean, dropped } = redactProperties(merged);
5573
+ });
5585
5574
  if (isDebug()) {
5586
5575
  const compact = JSON.stringify({
5587
5576
  event: input.event,
@@ -6421,17 +6410,14 @@ const renderRailStep = (step, deps = {}) => {
6421
6410
  * between the last step and the footer.
6422
6411
  */
6423
6412
  const renderRailConnector = (deps = {}) => {
6424
- const t = deps.theme ?? theme;
6425
- const s = deps.symbols ?? symbols;
6426
- return ` ${style$1(t, "accentDim", s.rail)}\n`;
6413
+ return ` ${style$1(deps.theme ?? theme, "accentDim", (deps.symbols ?? symbols).rail)}\n`;
6427
6414
  };
6428
6415
  /**
6429
6416
  * Render the rail-end footer line ("└ <footer text>").
6430
6417
  */
6431
6418
  const renderRailFooter = (footer, deps = {}) => {
6432
6419
  const t = deps.theme ?? theme;
6433
- const s = deps.symbols ?? symbols;
6434
- return ` ${style$1(t, "accentDim", s.railEnd)} ${highlightAislop(footer, t)}\n`;
6420
+ return ` ${style$1(t, "accentDim", (deps.symbols ?? symbols).railEnd)} ${highlightAislop(footer, t)}\n`;
6435
6421
  };
6436
6422
  const renderRail = (input, deps = {}) => {
6437
6423
  const t = deps.theme ?? theme;
@@ -6588,7 +6574,7 @@ const launchMonitorInBackground = async (directory, options) => {
6588
6574
  fs.mkdirSync(logDir, { recursive: true });
6589
6575
  const logPath = path.join(logDir, `${monitorId}.log`);
6590
6576
  const logFd = fs.openSync(logPath, "a");
6591
- const record = {
6577
+ writeAgentMonitorRecord(root, {
6592
6578
  id: monitorId,
6593
6579
  root,
6594
6580
  requestedDirectory: path.resolve(directory),
@@ -6606,8 +6592,7 @@ const launchMonitorInBackground = async (directory, options) => {
6606
6592
  noFix: options.noFix,
6607
6593
  logPath,
6608
6594
  recentCycles: []
6609
- };
6610
- writeAgentMonitorRecord(root, record);
6595
+ });
6611
6596
  const child = spawn(process.execPath, [cliPath(), ...buildBackgroundMonitorArgs(directory, options)], {
6612
6597
  cwd: root,
6613
6598
  detached: true,
@@ -7856,8 +7841,7 @@ const registerPlanSubcommand = (agent) => {
7856
7841
  const plan = agent.command("plan [directory]").description("Preview provider, worktree, findings, and publish actions without editing");
7857
7842
  addAgentOptions(plan);
7858
7843
  plan.action(async (directory = ".", _flags, command) => {
7859
- const flags = command.optsWithGlobals();
7860
- const options = agentOptionsFromFlags(flags, command);
7844
+ const options = agentOptionsFromFlags(command.optsWithGlobals(), command);
7861
7845
  await withAgentLifecycle("agent_plan", directory, agentTelemetryProperties(options), async () => {
7862
7846
  await agentPlanCommand(directory, options);
7863
7847
  });
@@ -7867,8 +7851,7 @@ const registerAgentCommand = (program) => {
7867
7851
  const agent = program.command("agent [directory]").description("Run a local AI slop repair session with Codex, Claude Code, or OpenCode");
7868
7852
  addAgentOptions(agent);
7869
7853
  agent.action(async (directory = ".", _flags, command) => {
7870
- const flags = command.optsWithGlobals();
7871
- const options = agentOptionsFromFlags(flags, command);
7854
+ const options = agentOptionsFromFlags(command.optsWithGlobals(), command);
7872
7855
  await withAgentLifecycle("agent", directory, agentTelemetryProperties(options), async () => {
7873
7856
  return await agentCommand(directory, options);
7874
7857
  });
@@ -8468,7 +8451,7 @@ const filterExcludedDiagnostics = (diagnostics, rootDirectory, excludePatterns)
8468
8451
  };
8469
8452
  //#endregion
8470
8453
  //#region src/utils/project-path-safety.ts
8471
- const MAX_PROJECT_CONFIG_BYTES = 1048576;
8454
+ const MAX_PROJECT_CONFIG_BYTES = 1024 * 1024;
8472
8455
  const isWithinDirectory$3 = (rootDirectory, candidate) => {
8473
8456
  const relative = path.relative(rootDirectory, candidate);
8474
8457
  return relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative);
@@ -8568,7 +8551,7 @@ const isAutoGenerated = (filePath) => {
8568
8551
  };
8569
8552
  //#endregion
8570
8553
  //#region src/utils/git-ignore.ts
8571
- const MAX_BUFFER$2 = 52428800;
8554
+ const MAX_BUFFER$2 = 50 * 1024 * 1024;
8572
8555
  const NOT_IGNORED_ARGUMENTS = [
8573
8556
  "ls-files",
8574
8557
  "--cached",
@@ -8679,7 +8662,7 @@ const dropGitIgnoredPaths = (rootDirectory, absolutePaths) => {
8679
8662
  };
8680
8663
  //#endregion
8681
8664
  //#region src/utils/project-file-list.ts
8682
- const MAX_BUFFER$1 = 52428800;
8665
+ const MAX_BUFFER$1 = 50 * 1024 * 1024;
8683
8666
  const normalizePruneDirectories = (directories) => new Set([...directories].map((directory) => directory.toLowerCase()));
8684
8667
  const isInPrunedDirectory = (filePath, pruneDirectories) => {
8685
8668
  const pathSegments = filePath.split("/");
@@ -13098,8 +13081,7 @@ const isJsRelativeOrAbsolute = (spec) => spec.startsWith(".") || spec.startsWith
13098
13081
  const RUNTIME_BUILTINS = /* @__PURE__ */ new Set(["bun"]);
13099
13082
  const isJsBuiltin = (spec) => {
13100
13083
  if (RUNTIME_BUILTINS.has(spec)) return true;
13101
- const stripped = spec.startsWith("node:") ? spec.slice(5) : spec;
13102
- return isBuiltin(stripped) || isBuiltin(spec);
13084
+ return isBuiltin(spec.startsWith("node:") ? spec.slice(5) : spec) || isBuiltin(spec);
13103
13085
  };
13104
13086
  const VIRTUAL_MODULE_PREFIXES = [
13105
13087
  "astro:",
@@ -13311,8 +13293,7 @@ const isLocalAliasReplacement = (rawValue, configDirectory, rootDirectory) => {
13311
13293
  if (!target) return false;
13312
13294
  if (!target.startsWith(".") && !target.startsWith("/") && !target.startsWith("~/") && !target.startsWith("@/")) return false;
13313
13295
  const normalized = target.startsWith("~/") || target.startsWith("@/") ? target.slice(2) : target;
13314
- const candidate = path.isAbsolute(normalized) ? normalized : path.resolve(configDirectory, normalized);
13315
- return isRootBoundedTarget(candidate, rootDirectory);
13296
+ return isRootBoundedTarget(path.isAbsolute(normalized) ? normalized : path.resolve(configDirectory, normalized), rootDirectory);
13316
13297
  };
13317
13298
  const hasValidPackageImportTarget = (value, packageDirectory, rootDirectory) => {
13318
13299
  if (!isRootBoundedTarget(packageDirectory, rootDirectory)) return false;
@@ -14506,9 +14487,7 @@ const isRustDocCommentLine = (line) => {
14506
14487
  };
14507
14488
  const collectBlocks = (sourceLines, syntax, content, ext) => {
14508
14489
  const blocks = [];
14509
- const actualContent = content ?? sourceLines.join("\n");
14510
- const actualExt = ext ?? (syntax.linePrefixes.includes("//") ? ".ts" : ".py");
14511
- const commentLines = getCommentLines(actualContent, actualExt);
14490
+ const commentLines = getCommentLines(content ?? sourceLines.join("\n"), ext ?? (syntax.linePrefixes.includes("//") ? ".ts" : ".py"));
14512
14491
  let i = 0;
14513
14492
  while (i < sourceLines.length) {
14514
14493
  const line = sourceLines[i];
@@ -14836,8 +14815,7 @@ const detectNarrativeComments = async (context) => {
14836
14815
  } catch {
14837
14816
  continue;
14838
14817
  }
14839
- const lines = content.split("\n");
14840
- const blocks = collectBlocks(lines, syntax, content, ext);
14818
+ const blocks = collectBlocks(content.split("\n"), syntax, content, ext);
14841
14819
  for (const block of blocks) {
14842
14820
  const { matched, reason } = detectNarrativeInBlock(block, ext);
14843
14821
  if (!matched) continue;
@@ -16790,8 +16768,7 @@ const checkFunctionDiagnostics = (relativePath, fn, limits, ext) => {
16790
16768
  const results = [];
16791
16769
  const multiplier = functionLocMultiplier(fn, ext);
16792
16770
  const fnMax = functionLocBudget(fn, ext, limits.maxFunctionLoc);
16793
- const effectiveLineCount = fn.lineCount - fn.templateLines;
16794
- if (exceedsLimit(effectiveLineCount, limits.maxFunctionLoc, multiplier)) results.push({
16771
+ if (exceedsLimit(fn.lineCount - fn.templateLines, limits.maxFunctionLoc, multiplier)) results.push({
16795
16772
  filePath: relativePath,
16796
16773
  engine: "code-quality",
16797
16774
  rule: "complexity/function-too-long",
@@ -16888,7 +16865,7 @@ const isLowSignalMarkupWindow = (lines) => {
16888
16865
  return lines.filter((line) => SVG_MARKUP_RE.test(line)).length >= Math.ceil(WINDOW_SIZE / 2);
16889
16866
  };
16890
16867
  const isLowSignalDataWindow = (lines) => {
16891
- return lines.filter((line) => DATA_LITERAL_RE.test(line)).length >= 9;
16868
+ return lines.filter((line) => DATA_LITERAL_RE.test(line)).length >= WINDOW_SIZE - 1;
16892
16869
  };
16893
16870
  const findSuppressedLines = (lines) => {
16894
16871
  const suppressed = /* @__PURE__ */ new Set();
@@ -16920,7 +16897,7 @@ const collectMeaningfulLines = (content) => {
16920
16897
  if (isLowSignalDataWindow(window)) continue;
16921
16898
  if (window.every(isTrivialLine)) continue;
16922
16899
  const normalised = window.map(normaliseLine);
16923
- if (normalised.filter((n) => n.length > 0 && n !== "}" && n !== "{").length < 9) continue;
16900
+ if (normalised.filter((n) => n.length > 0 && n !== "}" && n !== "{").length < WINDOW_SIZE - 1) continue;
16924
16901
  if (new Set(normalised).size < MIN_DISTINCT_LINES) continue;
16925
16902
  hits.push({
16926
16903
  startLine: i + 1,
@@ -17695,7 +17672,7 @@ const fixClangFormat = async (context) => {
17695
17672
  };
17696
17673
  //#endregion
17697
17674
  //#region src/engines/format/dotnet-format.ts
17698
- const REPORT_FILENAME = ".aislop-dotnet-format.json";
17675
+ const REPORT_FILENAME = ".raigal-dotnet-format.json";
17699
17676
  const parseDotnetFormatReport = (json, rootDirectory) => {
17700
17677
  if (!json) return [];
17701
17678
  let report;
@@ -18136,8 +18113,7 @@ const parseRuffFormatOutput = (output, rootDir) => {
18136
18113
  const fixRuffFormat = async (context) => {
18137
18114
  const targets = context.files ? getPythonTargets(context) : [context.rootDirectory];
18138
18115
  if (context.files && targets.length === 0) return;
18139
- const ruffBinary = resolveToolBinary("ruff");
18140
- const result = await runSubprocess(ruffBinary, ["format", ...targets], {
18116
+ const result = await runSubprocess(resolveToolBinary("ruff"), ["format", ...targets], {
18141
18117
  cwd: context.rootDirectory,
18142
18118
  timeout: 6e4
18143
18119
  });
@@ -18207,8 +18183,7 @@ const parseClangTidyOutput = (output, rootDirectory) => {
18207
18183
  const runClangTidy = async (context) => {
18208
18184
  const compileCommandsDir = findCompileCommandsDir(context);
18209
18185
  if (!compileCommandsDir) return [];
18210
- const implSources = findCppSources(context).filter((f) => CPP_IMPL_EXTENSIONS.has(path.extname(f).toLowerCase()));
18211
- const sources = filterSourcesInDatabase(implSources, readCompileCommandsFiles(compileCommandsDir));
18186
+ const sources = filterSourcesInDatabase(findCppSources(context).filter((f) => CPP_IMPL_EXTENSIONS.has(path.extname(f).toLowerCase())), readCompileCommandsFiles(compileCommandsDir));
18212
18187
  if (sources.length === 0) return [];
18213
18188
  const diagnostics = [];
18214
18189
  for (const chunk of chunkFilePaths(sources, CLANG_TIDY_CHUNK_MAX_FILES)) try {
@@ -19044,8 +19019,7 @@ const processFile = (filePath, fileTargets, result) => {
19044
19019
  });
19045
19020
  continue;
19046
19021
  }
19047
- const shape = classifyIdentifier(best);
19048
- const { edit, skipReason } = computeEdit(sourceFile, shape);
19022
+ const { edit, skipReason } = computeEdit(sourceFile, classifyIdentifier(best));
19049
19023
  if (!edit) {
19050
19024
  pendingSkips.push({
19051
19025
  target,
@@ -19860,8 +19834,7 @@ const ruffLintFixArgs = (context, unsafe) => {
19860
19834
  };
19861
19835
  const fixRuffLint = async (context) => {
19862
19836
  if (context.files && getPythonTargets(context).length === 0) return;
19863
- const ruffBinary = resolveToolBinary("ruff");
19864
- const result = await runSubprocess(ruffBinary, ruffLintFixArgs(context, false), {
19837
+ const result = await runSubprocess(resolveToolBinary("ruff"), ruffLintFixArgs(context, false), {
19865
19838
  cwd: context.rootDirectory,
19866
19839
  timeout: 6e4
19867
19840
  });
@@ -19869,8 +19842,7 @@ const fixRuffLint = async (context) => {
19869
19842
  };
19870
19843
  const fixRuffLintForce = async (context) => {
19871
19844
  if (context.files && getPythonTargets(context).length === 0) return;
19872
- const ruffBinary = resolveToolBinary("ruff");
19873
- const result = await runSubprocess(ruffBinary, ruffLintFixArgs(context, true), {
19845
+ const result = await runSubprocess(resolveToolBinary("ruff"), ruffLintFixArgs(context, true), {
19874
19846
  cwd: context.rootDirectory,
19875
19847
  timeout: 6e4
19876
19848
  });
@@ -19911,8 +19883,7 @@ const resolveTrustedTscPath = () => {
19911
19883
  };
19912
19884
  const isReferenceOnlyConfig = (tsconfigPath) => {
19913
19885
  try {
19914
- const raw = fs.readFileSync(tsconfigPath, "utf-8");
19915
- const parsed = parseJsonc(raw);
19886
+ const parsed = parseJsonc(fs.readFileSync(tsconfigPath, "utf-8"));
19916
19887
  if (!parsed) return false;
19917
19888
  return Array.isArray(parsed.references) && !parsed.files && !parsed.include && !parsed.extends;
19918
19889
  } catch {
@@ -20779,11 +20750,10 @@ const auditSkippedDiagnostic = (source, help) => ({
20779
20750
  });
20780
20751
  const runNpmAudit = async (rootDir, timeout) => {
20781
20752
  try {
20782
- const result = await runSubprocess("npm", ["audit", "--json"], {
20753
+ return parseJsAudit((await runSubprocess("npm", ["audit", "--json"], {
20783
20754
  cwd: rootDir,
20784
20755
  timeout
20785
- });
20786
- return parseJsAudit(result.stdout, "npm audit", readRuntimeDependencies(rootDir));
20756
+ })).stdout, "npm audit", readRuntimeDependencies(rootDir));
20787
20757
  } catch (error) {
20788
20758
  return [auditSkippedDiagnostic("npm audit", `Failed to run npm audit: ${errorMessageOf(error)}`)];
20789
20759
  }
@@ -20804,11 +20774,10 @@ const runBunAudit = async (rootDir, timeout) => {
20804
20774
  const runPnpmAuditWithFallback = async (rootDir, timeout) => {
20805
20775
  const canFallbackToNpm = fs.existsSync(path.join(rootDir, "package-lock.json"));
20806
20776
  try {
20807
- const result = await runSubprocess("pnpm", ["audit", "--json"], {
20777
+ const diagnostics = parseJsAudit((await runSubprocess("pnpm", ["audit", "--json"], {
20808
20778
  cwd: rootDir,
20809
20779
  timeout
20810
- });
20811
- const diagnostics = parseJsAudit(result.stdout, "pnpm audit", readRuntimeDependencies(rootDir));
20780
+ })).stdout, "pnpm audit", readRuntimeDependencies(rootDir));
20812
20781
  if (diagnostics.some((d) => d.rule === "security/dependency-audit-skipped")) {
20813
20782
  if (canFallbackToNpm) return runNpmAudit(rootDir, timeout);
20814
20783
  return diagnostics;
@@ -21542,10 +21511,7 @@ const runEngines = async (context, enabledEngines, onStart, onComplete) => {
21542
21511
  failed: true,
21543
21512
  skipReason: r.reason instanceof Error ? r.reason.message : String(r.reason)
21544
21513
  });
21545
- const stripped = stripSecretDiagnostics(finalResults);
21546
- const csharp = dedupeCSharpAsync(stripped);
21547
- const comments = dedupeOverlappingComments(csharp);
21548
- return dedupeEquivalenceDiagnostics(comments);
21514
+ return dedupeEquivalenceDiagnostics(dedupeOverlappingComments(dedupeCSharpAsync(stripSecretDiagnostics(finalResults))));
21549
21515
  };
21550
21516
  const stripSecretDiagnostics = (results) => {
21551
21517
  for (const result of results) for (const d of result.diagnostics) if (d.redactSource || isSecretClassRule(d.rule)) {
@@ -21770,8 +21736,7 @@ const calculateScore = (diagnostics, weights, thresholds, sourceFileCount, smoot
21770
21736
  const capScale = Math.max(1, fileCount.effectiveSourceFileCount / CAP_REFERENCE_FILES);
21771
21737
  const defaultRuleCap = typeof maxPerRule === "number" && maxPerRule > 0 ? maxPerRule : null;
21772
21738
  const capForRule = (key) => {
21773
- const rule = key.slice(key.indexOf(":") + 1);
21774
- const ruleCap = scoreImpactForRule(rule).cap;
21739
+ const ruleCap = scoreImpactForRule(key.slice(key.indexOf(":") + 1)).cap;
21775
21740
  if (typeof ruleCap === "number") return defaultRuleCap ? Math.min(defaultRuleCap, ruleCap) : ruleCap;
21776
21741
  return defaultRuleCap;
21777
21742
  };
@@ -21884,10 +21849,8 @@ const detectSourceLanguages = (sourceFiles) => {
21884
21849
  const detectLanguages = (directory, sourceFiles) => {
21885
21850
  const languages = new Set(detectSourceLanguages(sourceFiles));
21886
21851
  for (const [file, lang] of Object.entries(LANGUAGE_SIGNALS)) if (fs.existsSync(path.join(directory, file))) languages.add(lang);
21887
- if (readPackageJson(path.join(directory, "package.json"))) {
21888
- if (fs.existsSync(path.join(directory, "tsconfig.json"))) languages.add("typescript");
21889
- else languages.add("javascript");
21890
- }
21852
+ if (readPackageJson(path.join(directory, "package.json"))) if (fs.existsSync(path.join(directory, "tsconfig.json"))) languages.add("typescript");
21853
+ else languages.add("javascript");
21891
21854
  for (const signal of PYTHON_SIGNALS) if (fs.existsSync(path.join(directory, signal))) {
21892
21855
  languages.add("python");
21893
21856
  break;
@@ -22114,7 +22077,7 @@ const runScopedScan = async (cwd, filePaths) => {
22114
22077
  const rulesPath = configDir ? path.join(configDir, RULES_FILE) : void 0;
22115
22078
  const enumeratedPaths = new Set(projectCandidates.map((filePath) => path.resolve(rootDirectory, filePath)));
22116
22079
  const scopedCandidates = filePaths.filter((filePath) => enumeratedPaths.has(path.resolve(rootDirectory, filePath)));
22117
- const context = {
22080
+ const diagnostics = applyRuleSeverities((await runEngines({
22118
22081
  rootDirectory: project.rootDirectory,
22119
22082
  languages: project.languages,
22120
22083
  frameworks: project.frameworks,
@@ -22137,17 +22100,14 @@ const runScopedScan = async (cwd, filePaths) => {
22137
22100
  allowProjectLocalTools: false,
22138
22101
  architectureRulesPath: config.engines.architecture ? rulesPath : void 0
22139
22102
  }
22140
- };
22141
- const enabled = {
22103
+ }, {
22142
22104
  format: false,
22143
22105
  lint: false,
22144
22106
  "code-quality": config.engines["code-quality"],
22145
22107
  "ai-slop": config.engines["ai-slop"],
22146
22108
  architecture: config.engines.architecture,
22147
22109
  security: false
22148
- };
22149
- const results = await runEngines(context, enabled);
22150
- const diagnostics = applyRuleSeverities(results.flatMap((result) => result.diagnostics), config.overrides.length ? {} : config.rules);
22110
+ })).flatMap((result) => result.diagnostics), config.overrides.length ? {} : config.rules);
22151
22111
  const { score } = calculateScore(diagnostics, config.scoring.weights, config.scoring.thresholds, projectSourceFiles.length + projectTestFiles.length, config.scoring.smoothing, config.scoring.maxPerRule);
22152
22112
  return {
22153
22113
  diagnostics,
@@ -22161,7 +22121,7 @@ const atomicWrite = (targetPath, content) => {
22161
22121
  const dir = path.dirname(targetPath);
22162
22122
  fs.mkdirSync(dir, { recursive: true });
22163
22123
  const rand = Math.random().toString(36).slice(2, 10);
22164
- const tmp = path.join(dir, `.aislop-tmp-${process.pid}-${rand}`);
22124
+ const tmp = path.join(dir, `.raigal-tmp-${process.pid}-${rand}`);
22165
22125
  fs.writeFileSync(tmp, content, "utf-8");
22166
22126
  try {
22167
22127
  fs.renameSync(tmp, targetPath);
@@ -22210,14 +22170,18 @@ const baselinePath = (cwd) => {
22210
22170
  if (fs.existsSync(raigalCandidate)) return raigalCandidate;
22211
22171
  const raigalDir = path.join(cwd, ".raigal");
22212
22172
  if (fs.existsSync(raigalDir)) return raigalCandidate;
22213
- return path.join(cwd, ".aislop", "baseline.json");
22173
+ const legacyCandidate = path.join(cwd, ".aislop", "baseline.json");
22174
+ if (fs.existsSync(legacyCandidate)) return legacyCandidate;
22175
+ return raigalCandidate;
22214
22176
  };
22215
22177
  const sessionPath = (cwd) => {
22216
22178
  const raigalCandidate = path.join(cwd, ".raigal", "session.jsonl");
22217
22179
  if (fs.existsSync(raigalCandidate)) return raigalCandidate;
22218
22180
  const raigalDir = path.join(cwd, ".raigal");
22219
22181
  if (fs.existsSync(raigalDir)) return raigalCandidate;
22220
- return path.join(cwd, ".aislop", "session.jsonl");
22182
+ const legacyCandidate = path.join(cwd, ".aislop", "session.jsonl");
22183
+ if (fs.existsSync(legacyCandidate)) return legacyCandidate;
22184
+ return raigalCandidate;
22221
22185
  };
22222
22186
  const readBaseline = (cwd) => {
22223
22187
  const raw = readIfExists(baselinePath(cwd));
@@ -22228,7 +22192,7 @@ const readBaseline = (cwd) => {
22228
22192
  const findingFingerprints = parsed.findingFingerprints ?? [];
22229
22193
  const needsWindowsMigration = parsed.pathFormat !== "posix";
22230
22194
  return {
22231
- schema: "aislop.baseline.v2",
22195
+ schema: "raigal.baseline.v2",
22232
22196
  pathFormat: "posix",
22233
22197
  updatedAt: parsed.updatedAt ?? "",
22234
22198
  score: parsed.score ?? 0,
@@ -22242,7 +22206,7 @@ const readBaseline = (cwd) => {
22242
22206
  }
22243
22207
  };
22244
22208
  const writeBaseline = (cwd, baseline) => {
22245
- const target = baselinePath(cwd);
22209
+ const target = path.join(cwd, ".raigal", "baseline.json");
22246
22210
  atomicWrite(target, `${JSON.stringify({
22247
22211
  ...baseline,
22248
22212
  pathFormat: "posix"
@@ -22256,7 +22220,7 @@ const captureBaseline = async (cwd) => {
22256
22220
  });
22257
22221
  const project = await discoverProject(cwd);
22258
22222
  const config = loadConfig(cwd);
22259
- const context = {
22223
+ const results = await runEngines({
22260
22224
  rootDirectory: project.rootDirectory,
22261
22225
  languages: project.languages,
22262
22226
  frameworks: project.frameworks,
@@ -22275,27 +22239,24 @@ const captureBaseline = async (cwd) => {
22275
22239
  },
22276
22240
  allowProjectLocalTools: false
22277
22241
  }
22278
- };
22279
- const enabled = {
22242
+ }, {
22280
22243
  format: false,
22281
22244
  lint: false,
22282
22245
  "code-quality": config.engines["code-quality"],
22283
22246
  "ai-slop": config.engines["ai-slop"],
22284
22247
  architecture: config.engines.architecture,
22285
22248
  security: false
22286
- };
22287
- const results = await runEngines(context, enabled);
22249
+ });
22288
22250
  const diagnostics = applyRuleSeverities(results.flatMap((r) => r.diagnostics), config.overrides.length ? {} : config.rules);
22289
22251
  const { score } = calculateScore(diagnostics, config.scoring.weights, config.scoring.thresholds, project.sourceFileCount, config.scoring.smoothing, config.scoring.maxPerRule);
22290
22252
  const byEngine = {};
22291
22253
  for (const r of results) {
22292
- const engineDiags = diagnostics.filter((d) => d.engine === r.engine);
22293
- const { score: engineScore } = calculateScore(engineDiags, config.scoring.weights, config.scoring.thresholds, project.sourceFileCount, config.scoring.smoothing, config.scoring.maxPerRule);
22254
+ const { score: engineScore } = calculateScore(diagnostics.filter((d) => d.engine === r.engine), config.scoring.weights, config.scoring.thresholds, project.sourceFileCount, config.scoring.smoothing, config.scoring.maxPerRule);
22294
22255
  byEngine[r.engine] = engineScore;
22295
22256
  }
22296
22257
  const findingFingerprints = diagnostics.filter((d) => d.severity === "error" || d.severity === "warning").map((d) => fingerprintDiagnostic(d, project.rootDirectory));
22297
22258
  const baseline = {
22298
- schema: "aislop.baseline.v2",
22259
+ schema: "raigal.baseline.v2",
22299
22260
  pathFormat: "posix",
22300
22261
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
22301
22262
  score,
@@ -22323,8 +22284,7 @@ const appendSessionFiles = (cwd, files) => {
22323
22284
  } catch {}
22324
22285
  };
22325
22286
  const readSessionFiles = (cwd) => {
22326
- const target = sessionPath(cwd);
22327
- const raw = readIfExists(target);
22287
+ const raw = readIfExists(sessionPath(cwd));
22328
22288
  if (!raw) return [];
22329
22289
  const files = /* @__PURE__ */ new Set();
22330
22290
  for (const line of raw.split("\n")) {
@@ -22714,8 +22674,8 @@ A PostToolUse hook runs \`raigal hook claude\` after every Edit, Write, or Multi
22714
22674
 
22715
22675
  ## Rules
22716
22676
 
22717
- - \`.raigal/config.yaml\` (or \`.aislop/config.yaml\`) - thresholds and engine toggles. Treat as authoritative; don't edit without user consent.
22718
- - \`.raigal/rules.yaml\` (or \`.aislop/rules.yaml\`) - project-specific architecture rules (may be absent). When a finding cites \`architecture/*\`, open this file and follow it.
22677
+ - \`.raigal/config.yaml\` - thresholds and engine toggles. Treat as authoritative; don't edit without user consent.
22678
+ - \`.raigal/rules.yaml\` - project-specific architecture rules (may be absent). When a finding cites \`architecture/*\`, open this file and follow it.
22719
22679
  - Custom rules can change between sessions. Trust what the scan returns, not a cached understanding of what the rules are.
22720
22680
 
22721
22681
  ## Principles
@@ -22797,9 +22757,7 @@ const applyRemoval = (result, opts, target, nextContent) => {
22797
22757
  //#region src/hooks/install/rules-only.ts
22798
22758
  const installRulesOnly = (opts, paths, summary) => {
22799
22759
  const result = emptyResult();
22800
- const existing = readIfExists(paths.rules);
22801
- const hash = sentinelHash(AISLOP_MD_BODY);
22802
- const next = upsertMarkdownFence(existing, AISLOP_MD_BODY, hash).nextContent;
22760
+ const next = upsertMarkdownFence(readIfExists(paths.rules), AISLOP_MD_BODY, sentinelHash(AISLOP_MD_BODY)).nextContent;
22803
22761
  applyContent(result, opts, paths.rules, next, summary);
22804
22762
  if (paths.host && paths.marker) {
22805
22763
  const host = readIfExists(paths.host) ?? "";
@@ -22975,8 +22933,7 @@ const installClaude = (opts) => {
22975
22933
  const nextSettings = renderSettings$1(readIfExists(paths.settings), Boolean(opts.qualityGate));
22976
22934
  applyContent(result, opts, paths.settings, nextSettings, "register PostToolUse + FileChanged hooks");
22977
22935
  const mdHash = sentinelHash(AISLOP_MD_BODY);
22978
- const existingMd = readIfExists(paths.aislopMd);
22979
- const fenced = upsertMarkdownFence(existingMd, AISLOP_MD_BODY, mdHash);
22936
+ const fenced = upsertMarkdownFence(readIfExists(paths.aislopMd), AISLOP_MD_BODY, mdHash);
22980
22937
  applyContent(result, opts, paths.aislopMd, fenced.nextContent, "write AISLOP.md rules");
22981
22938
  const existingClaudeMd = readIfExists(paths.claudeMd) ?? "";
22982
22939
  const marker = "@AISLOP.md";
@@ -23122,9 +23079,7 @@ const installCursor = (opts) => {
23122
23079
  const nextHooks = renderHooksJson(readIfExists(paths.hooks));
23123
23080
  applyContent(result, opts, paths.hooks, nextHooks, "register afterFileEdit hook");
23124
23081
  if (opts.scope === "project") {
23125
- const existingRules = readIfExists(paths.rules);
23126
- const hash = sentinelHash(AISLOP_MD_BODY);
23127
- const rules = upsertMarkdownFence(existingRules, AISLOP_MD_BODY, hash).nextContent;
23082
+ const rules = upsertMarkdownFence(readIfExists(paths.rules), AISLOP_MD_BODY, sentinelHash(AISLOP_MD_BODY)).nextContent;
23128
23083
  applyContent(result, opts, paths.rules, rules, "write .cursor/rules/aislop.mdc");
23129
23084
  }
23130
23085
  return result;
@@ -23197,9 +23152,7 @@ const installGemini = (opts) => {
23197
23152
  const result = emptyResult();
23198
23153
  const next = renderSettings(readIfExists(paths.settings));
23199
23154
  applyContent(result, opts, paths.settings, next, "register AfterTool hook");
23200
- const existingMd = readIfExists(paths.aislopMd);
23201
- const hash = sentinelHash(AISLOP_MD_BODY);
23202
- const fenced = upsertMarkdownFence(existingMd, AISLOP_MD_BODY, hash).nextContent;
23155
+ const fenced = upsertMarkdownFence(readIfExists(paths.aislopMd), AISLOP_MD_BODY, sentinelHash(AISLOP_MD_BODY)).nextContent;
23203
23156
  applyContent(result, opts, paths.aislopMd, fenced, "write AISLOP.md rules");
23204
23157
  const existingGeminiMd = readIfExists(paths.geminiMd) ?? "";
23205
23158
  const marker = "@AISLOP.md";
@@ -23697,10 +23650,8 @@ const runSearchPrompt = async (options) => {
23697
23650
  }
23698
23651
  if (key.name === "space" && options.mode === "multi") {
23699
23652
  const item = filtered[cursor];
23700
- if (item) {
23701
- if (selected.has(item.value)) selected.delete(item.value);
23702
- else selected.add(item.value);
23703
- }
23653
+ if (item) if (selected.has(item.value)) selected.delete(item.value);
23654
+ else selected.add(item.value);
23704
23655
  render();
23705
23656
  return;
23706
23657
  }
@@ -23964,11 +23915,10 @@ const hookRun = async (agent, flags) => {
23964
23915
  process.exit(0);
23965
23916
  }
23966
23917
  let exitCode = 0;
23967
- if (agent === "claude") {
23968
- if (flags?.onFileChanged) exitCode = await runClaudeFileChangedHook();
23969
- else if (flags?.stop) exitCode = await runClaudeStopHook();
23970
- else exitCode = await runClaudeHook();
23971
- } else if (agent === "cursor") exitCode = await runCursorHook();
23918
+ if (agent === "claude") if (flags?.onFileChanged) exitCode = await runClaudeFileChangedHook();
23919
+ else if (flags?.stop) exitCode = await runClaudeStopHook();
23920
+ else exitCode = await runClaudeHook();
23921
+ else if (agent === "cursor") exitCode = await runCursorHook();
23972
23922
  else if (agent === "gemini") exitCode = await runGeminiHook();
23973
23923
  else if (agent === "pi") exitCode = await runPiHook();
23974
23924
  else {
@@ -23979,8 +23929,7 @@ const hookRun = async (agent, flags) => {
23979
23929
  process.exit(exitCode);
23980
23930
  };
23981
23931
  const hookBaseline = async () => {
23982
- const cwd = process.cwd();
23983
- const result = await captureBaseline(cwd);
23932
+ const result = await captureBaseline(process.cwd());
23984
23933
  process.stdout.write(renderHookBaseline({
23985
23934
  score: result.score,
23986
23935
  fileCount: result.fileCount,
@@ -24810,8 +24759,7 @@ const collectRuleEntries = (directory) => {
24810
24759
  for (const { engine, rules } of BUILTIN_RULES) for (const rule of rules) entries.push(toRuleEntry(engine, rule));
24811
24760
  const configDir = findConfigDir(resolvedDir);
24812
24761
  if (configDir) {
24813
- const rulesPath = path.join(configDir, RULES_FILE);
24814
- const archRules = loadArchitectureRules(rulesPath);
24762
+ const archRules = loadArchitectureRules(path.join(configDir, RULES_FILE));
24815
24763
  for (const rule of archRules) entries.push({
24816
24764
  id: `arch/${rule.name}`,
24817
24765
  engine: "architecture",
@@ -25009,7 +24957,7 @@ const trendCommand = async (directory, limit) => {
25009
24957
  //#endregion
25010
24958
  //#region src/update-notifier.ts
25011
24959
  const REGISTRY_URL = "https://registry.npmjs.org/@methiu/raigal/latest";
25012
- const CHECK_INTERVAL_MS = 864e5;
24960
+ const CHECK_INTERVAL_MS = 1440 * 60 * 1e3;
25013
24961
  const REQUEST_TIMEOUT_MS = 2e3;
25014
24962
  const CACHE_BASENAME = "update_check.json";
25015
24963
  const isUpdateNotifierDisabled = (env = process.env) => {
@@ -25082,7 +25030,7 @@ const maybeNotifyUpdate = async (now = Date.now()) => {
25082
25030
  if (!process.stderr.isTTY) return;
25083
25031
  const cachePath = resolveUpdateCachePath();
25084
25032
  const cache = readCache(cachePath);
25085
- if (cache && isOutdated("0.2.3", cache.latest)) process.stderr.write(formatUpdateNotice(APP_VERSION, cache.latest));
25033
+ if (cache && isOutdated("0.2.5", cache.latest)) process.stderr.write(formatUpdateNotice(APP_VERSION, cache.latest));
25086
25034
  if (!cache || now - cache.checkedAt > CHECK_INTERVAL_MS) {
25087
25035
  const latest = await fetchLatestVersion$1();
25088
25036
  if (latest) writeCache(cachePath, {
@@ -25602,7 +25550,7 @@ const renderCommandGroup = (group, commandWidth) => {
25602
25550
  return lines;
25603
25551
  };
25604
25552
  const renderCommandReference = (input = {}) => {
25605
- const version = input.version ?? "0.2.3";
25553
+ const version = input.version ?? "0.2.5";
25606
25554
  const commandWidth = Math.max(...COMMAND_REFERENCE.map((item) => item.command.length));
25607
25555
  const lines = [renderHeader({
25608
25556
  version,
@@ -25824,9 +25772,8 @@ const renderHelpDetails = () => [
25824
25772
  ""
25825
25773
  ].map((line) => highlightRaigal(line, theme)).join("\n");
25826
25774
  const renderHome = (input = {}) => {
25827
- const version = input.version ?? "0.2.3";
25828
25775
  let out = renderHeader({
25829
- version,
25776
+ version: input.version ?? "0.2.5",
25830
25777
  command: "--bare",
25831
25778
  context: []
25832
25779
  });
@@ -26077,8 +26024,7 @@ const saveCachedPolicy = (repoSlug, policy) => {
26077
26024
  };
26078
26025
  const fetchRemotePolicy = async (repoSlug, token) => {
26079
26026
  try {
26080
- const endpoint = `/v1/policy?repo=${encodeURIComponent(repoSlug.toLowerCase())}`;
26081
- const data = await requestApi(endpoint, {
26027
+ const data = await requestApi(`/v1/policy?repo=${encodeURIComponent(repoSlug.toLowerCase())}`, {
26082
26028
  method: "GET",
26083
26029
  token,
26084
26030
  timeoutMs: 4e3
@@ -26483,7 +26429,7 @@ const printEngineStatus = (result) => {
26483
26429
  };
26484
26430
  //#endregion
26485
26431
  //#region src/utils/git.ts
26486
- const MAX_BUFFER = 52428800;
26432
+ const MAX_BUFFER = 50 * 1024 * 1024;
26487
26433
  const baseRefExists = (cwd, ref) => {
26488
26434
  const result = spawnSync("git", [
26489
26435
  "rev-parse",
@@ -27006,8 +26952,7 @@ const renderActionRows = (steps, t) => {
27006
26952
  const renderTextSteps = (steps, t, s) => {
27007
26953
  return steps.filter((step) => step.text).map((step) => {
27008
26954
  const glyph = step.emphasis === "primary" ? s.hint : s.bullet;
27009
- const tokenFor = step.emphasis === "primary" ? "accent" : "muted";
27010
- return ` ${style$1(t, tokenFor, glyph)} ${highlightAislop(step.text ?? "", t)}`;
26955
+ return ` ${style$1(t, step.emphasis === "primary" ? "accent" : "muted", glyph)} ${highlightAislop(step.text ?? "", t)}`;
27011
26956
  });
27012
26957
  };
27013
26958
  const renderSummary = (input, deps = {}) => {
@@ -27064,14 +27009,10 @@ const renderSummary = (input, deps = {}) => {
27064
27009
  return lines.join("\n");
27065
27010
  };
27066
27011
  const renderStarCta = (deps = {}) => {
27067
- const t = deps.theme ?? theme;
27068
- const repository = terminalLink("https://raigal.dev");
27069
- return `\n ${style$1(t, "muted", `★ Found this useful? Consider purchasing this software at ${repository}`)}\n`;
27012
+ return `\n ${style$1(deps.theme ?? theme, "muted", `★ Found this useful? Consider purchasing this software at ${terminalLink("https://raigal.dev")}`)}\n`;
27070
27013
  };
27071
27014
  const renderTeamCta = (deps = {}) => {
27072
- const t = deps.theme ?? theme;
27073
- const href = terminalLink("https://raigal.dev/contact?intent=team-baseline");
27074
- return `\n ${style$1(t, "muted", `→ Using raigal with a team? Get a 14-day team baseline at ${href}`)}\n`;
27015
+ return `\n ${style$1(deps.theme ?? theme, "muted", `→ Using raigal with a team? Get a 14-day team baseline at ${terminalLink("https://raigal.dev/contact?intent=team-baseline")}`)}\n`;
27075
27016
  };
27076
27017
  const renderCleanRun = (input, deps = {}) => {
27077
27018
  const t = deps.theme ?? theme;
@@ -27305,7 +27246,7 @@ const runScanBody = async (resolvedDir, config, options, projectInfo, scanScope,
27305
27246
  architectureRulesPath: config.engines.architecture ? rulesPath : void 0,
27306
27247
  engines: config.engines
27307
27248
  };
27308
- const severityAdjusted = (await runEnginesWithProgress({
27249
+ const { results: unannotated, suppressedCount } = applySuppressions((await runEnginesWithProgress({
27309
27250
  rootDirectory: resolvedDir,
27310
27251
  languages: projectInfo.languages,
27311
27252
  frameworks: projectInfo.frameworks,
@@ -27321,8 +27262,7 @@ const runScanBody = async (resolvedDir, config, options, projectInfo, scanScope,
27321
27262
  }, config.engines, machineOutput)).map((result) => ({
27322
27263
  ...result,
27323
27264
  diagnostics: config.overrides.length ? result.diagnostics : applyRuleSeverities(result.diagnostics, config.rules)
27324
- }));
27325
- const { results: unannotated, suppressedCount } = applySuppressions(severityAdjusted, resolvedDir);
27265
+ })), resolvedDir);
27326
27266
  if (suppressedCount > 0 && !machineOutput) log.muted(`Suppressed ${suppressedCount} finding(s) via raigal-ignore directives`);
27327
27267
  const changeMap = options.changes && !options.staged ? getChangedLineMap(resolvedDir, options.base) : null;
27328
27268
  const results = changeMap ? unannotated.map((result) => ({
@@ -28033,8 +27973,7 @@ const groupByFile = (diagnostics) => {
28033
27973
  });
28034
27974
  };
28035
27975
  const isInstalled = (bin) => {
28036
- const cmd = process.platform === "win32" ? "where" : "which";
28037
- return spawnSync(cmd, [bin], { encoding: "utf-8" }).status === 0;
27976
+ return spawnSync(process.platform === "win32" ? "where" : "which", [bin], { encoding: "utf-8" }).status === 0;
28038
27977
  };
28039
27978
  const copyToClipboard = (text) => {
28040
27979
  const args = {
@@ -28510,8 +28449,7 @@ const fixNarrativeComments = async (context) => {
28510
28449
  for (let i = 0; i < lines.length; i += 1) if (!toRemove.has(i + 1)) kept.push(lines[i]);
28511
28450
  const newContent = kept.join("\n");
28512
28451
  if (newContent !== content) {
28513
- const afterLiterals = extractStringAndTemplateLiterals(newContent, ext);
28514
- if (!areLiteralMultisetsEqual(beforeLiterals, afterLiterals)) continue;
28452
+ if (!areLiteralMultisetsEqual(beforeLiterals, extractStringAndTemplateLiterals(newContent, ext))) continue;
28515
28453
  fs.writeFileSync(filePath, newContent);
28516
28454
  }
28517
28455
  }
@@ -29005,7 +28943,7 @@ const removeUnusedDeclarations = (rootDirectory, declarations) => {
29005
28943
  };
29006
28944
  //#endregion
29007
28945
  //#region src/commands/fix-expo.ts
29008
- const INSTALL_TIMEOUT$1 = 18e5;
28946
+ const INSTALL_TIMEOUT$1 = 1800 * 1e3;
29009
28947
  const fixExpoDependencies = async (context, onProgress) => {
29010
28948
  await removeDisallowedExpoPackages(context.rootDirectory, onProgress);
29011
28949
  onProgress?.("Expo dependency alignment · running expo install --fix (can take a few minutes)");
@@ -29059,8 +28997,8 @@ const removeDisallowedExpoPackages = async (rootDir, onProgress) => {
29059
28997
  };
29060
28998
  //#endregion
29061
28999
  //#region src/commands/fix-force.ts
29062
- const INSTALL_TIMEOUT = 18e5;
29063
- const AUDIT_TIMEOUT = 6e4;
29000
+ const INSTALL_TIMEOUT = 1800 * 1e3;
29001
+ const AUDIT_TIMEOUT = 60 * 1e3;
29064
29002
  const detectPackageManager = (rootDirectory) => {
29065
29003
  if (fs.existsSync(path.join(rootDirectory, "pnpm-lock.yaml"))) return "pnpm";
29066
29004
  if (fs.existsSync(path.join(rootDirectory, "package-lock.json")) || fs.existsSync(path.join(rootDirectory, "package.json"))) return "npm";
@@ -29358,14 +29296,13 @@ const CANNOT_SCOPE_REASON = "cannot honour an explicit file list under --changes
29358
29296
  const MISSING_MANIFEST_REASON = "no manifest or lockfile in the selected scope";
29359
29297
  const fixScopeError = (resolvedDir, flags) => {
29360
29298
  if (flags.changes && flags.staged) return "--changes and --staged cannot be used together.";
29361
- const options = {
29299
+ return scanTargetError(resolvedDir, {
29362
29300
  changes: Boolean(flags.changes),
29363
29301
  staged: Boolean(flags.staged),
29364
29302
  base: flags.base,
29365
29303
  verbose: false,
29366
29304
  json: false
29367
- };
29368
- return scanTargetError(resolvedDir, options);
29305
+ });
29369
29306
  };
29370
29307
  const collectFixFileScope = (rootDirectory, excludePatterns, includePatterns, flags) => {
29371
29308
  const mode = resolveScanScopeMode({
@@ -29424,10 +29361,9 @@ const runFormattingStep = async (deps) => {
29424
29361
  else if (deps.projectInfo.languages.includes("python")) log.warn("Python detected but ruff is not installed; skipping Python formatting fixes.");
29425
29362
  if (deps.projectInfo.languages.includes("go") && deps.projectInfo.installedTools.gofmt) await deps.runStep("Formatting (go)", () => runGofmt(deps.context), () => fixGofmt(deps.context));
29426
29363
  else if (deps.projectInfo.languages.includes("go")) log.warn("Go detected but gofmt is not installed; skipping Go formatting fixes.");
29427
- if (deps.projectInfo.languages.includes("rust") && deps.projectInfo.installedTools.rustfmt) {
29428
- if (isScopedFix(deps.context)) deps.skipStep?.("Formatting (rust)", CANNOT_SCOPE_REASON);
29429
- else await deps.runStep("Formatting (rust)", () => runGenericFormatter(deps.context, "rust"), () => fixGenericFormatter(deps.context, "rust"));
29430
- } else if (deps.projectInfo.languages.includes("rust")) log.warn("Rust detected but rustfmt is not installed; skipping Rust formatting fixes.");
29364
+ if (deps.projectInfo.languages.includes("rust") && deps.projectInfo.installedTools.rustfmt) if (isScopedFix(deps.context)) deps.skipStep?.("Formatting (rust)", CANNOT_SCOPE_REASON);
29365
+ else await deps.runStep("Formatting (rust)", () => runGenericFormatter(deps.context, "rust"), () => fixGenericFormatter(deps.context, "rust"));
29366
+ else if (deps.projectInfo.languages.includes("rust")) log.warn("Rust detected but rustfmt is not installed; skipping Rust formatting fixes.");
29431
29367
  if (deps.projectInfo.languages.includes("ruby") && deps.projectInfo.installedTools.rubocop) {
29432
29368
  if (!skipUnsafeSafeFormatter(deps, "ruby")) await deps.runStep("Formatting (ruby)", () => runGenericFormatter(deps.context, "ruby"), () => fixGenericFormatter(deps.context, "ruby"));
29433
29369
  } else if (deps.projectInfo.languages.includes("ruby")) log.warn("Ruby detected but rubocop is not installed; skipping Ruby formatting fixes.");
@@ -29476,8 +29412,7 @@ const runDeclarationStep = async (deps) => {
29476
29412
  if (!deps.config.engines["code-quality"]) return;
29477
29413
  if (!hasJsOrTs(deps.projectInfo)) return;
29478
29414
  await deps.runStep("Unused declarations", () => detectUnusedDeclarations(deps.context), async () => {
29479
- const diagnostics = await detectUnusedDeclarations(deps.context);
29480
- const declarations = diagnosticsToDeclarations(diagnostics);
29415
+ const declarations = diagnosticsToDeclarations(await detectUnusedDeclarations(deps.context));
29481
29416
  removeUnusedDeclarations(deps.resolvedDir, declarations);
29482
29417
  });
29483
29418
  };
@@ -29508,14 +29443,10 @@ const runForceSteps = async (deps) => {
29508
29443
  return (await runKnipUnusedFiles(deps.resolvedDir)).filter((diagnostic) => isPathInFixScope(deps.context, diagnostic.filePath));
29509
29444
  }, () => fixUnusedFiles(deps.resolvedDir, (filePath) => isPathInFixScope(deps.context, filePath)));
29510
29445
  const railUpdate = (label) => deps.rail.setActiveLabel(label);
29511
- if (deps.config.engines.security) {
29512
- if (!scopeIncludesManifestWrites(deps.context)) deps.skipStep?.("Dependency audit fixes", MISSING_MANIFEST_REASON);
29513
- else await deps.runStep("Dependency audit fixes", () => runDependencyAudit(deps.context), () => fixDependencyAudit(deps.context, railUpdate));
29514
- }
29515
- if (deps.projectInfo.frameworks.includes("expo") && deps.config.lint.expoDoctor) {
29516
- if (!scopeIncludesManifestWrites(deps.context)) deps.skipStep?.("Expo dependency alignment", MISSING_MANIFEST_REASON);
29517
- else await deps.runStep("Expo dependency alignment", () => runExpoDoctor(deps.context), () => fixExpoDependencies(deps.context, railUpdate));
29518
- }
29446
+ if (deps.config.engines.security) if (!scopeIncludesManifestWrites(deps.context)) deps.skipStep?.("Dependency audit fixes", MISSING_MANIFEST_REASON);
29447
+ else await deps.runStep("Dependency audit fixes", () => runDependencyAudit(deps.context), () => fixDependencyAudit(deps.context, railUpdate));
29448
+ if (deps.projectInfo.frameworks.includes("expo") && deps.config.lint.expoDoctor) if (!scopeIncludesManifestWrites(deps.context)) deps.skipStep?.("Expo dependency alignment", MISSING_MANIFEST_REASON);
29449
+ else await deps.runStep("Expo dependency alignment", () => runExpoDoctor(deps.context), () => fixExpoDependencies(deps.context, railUpdate));
29519
29450
  };
29520
29451
  //#endregion
29521
29452
  //#region src/commands/fix-plan.ts
@@ -29811,8 +29742,7 @@ const runFixBody = async (resolvedDir, config, options, projectInfo) => {
29811
29742
  brand: options.printBrand !== false
29812
29743
  }));
29813
29744
  const safe = Boolean(options.safe);
29814
- const excludePatterns = [...config.exclude, ...readAislopIgnorePatterns(resolvedDir)];
29815
- const scope = collectFixFileScope(resolvedDir, excludePatterns, config.include, options);
29745
+ const scope = collectFixFileScope(resolvedDir, [...config.exclude, ...readAislopIgnorePatterns(resolvedDir)], config.include, options);
29816
29746
  const scopedProjectInfo = scope ? {
29817
29747
  ...projectInfo,
29818
29748
  languages: detectSourceLanguages([...scope.files, ...scope.testFiles])
@@ -30162,18 +30092,16 @@ const initCommand = async (directory, options = {}) => {
30162
30092
  status: "done",
30163
30093
  label: `Wrote ${CONFIG_DIR}/${CONFIG_FILE}`
30164
30094
  }];
30165
- if (choices.engines.includes("architecture")) {
30166
- if (!fs.existsSync(rulesPath)) {
30167
- fs.writeFileSync(rulesPath, DEFAULT_RULES_YAML);
30168
- steps.push({
30169
- status: "done",
30170
- label: `Wrote ${CONFIG_DIR}/${RULES_FILE}`
30171
- });
30172
- } else steps.push({
30173
- status: "skipped",
30174
- label: `${CONFIG_DIR}/${RULES_FILE} already exists`
30095
+ if (choices.engines.includes("architecture")) if (!fs.existsSync(rulesPath)) {
30096
+ fs.writeFileSync(rulesPath, DEFAULT_RULES_YAML);
30097
+ steps.push({
30098
+ status: "done",
30099
+ label: `Wrote ${CONFIG_DIR}/${RULES_FILE}`
30175
30100
  });
30176
- }
30101
+ } else steps.push({
30102
+ status: "skipped",
30103
+ label: `${CONFIG_DIR}/${RULES_FILE} already exists`
30104
+ });
30177
30105
  const workflowResult = writeGithubWorkflow(resolvedDir, choices.writeGithubWorkflow);
30178
30106
  if (workflowResult.status === "written") steps.push({
30179
30107
  status: "done",
@@ -30565,13 +30493,11 @@ program.hook("preAction", (_thisCommand, actionCommand) => {
30565
30493
  "hook"
30566
30494
  ].includes(cmdName)) {
30567
30495
  const flagNames = process.argv.slice(2).filter((arg) => arg.startsWith("-")).map((arg) => arg.replace(/^--?/, "").split("=")[0] ?? "");
30568
- const dir = actionCommand.args?.[0] || process.cwd();
30569
- startRunRecorder(cmdName, dir, flagNames);
30496
+ startRunRecorder(cmdName, actionCommand.args?.[0] || process.cwd(), flagNames);
30570
30497
  }
30571
30498
  });
30572
30499
  program.hook("postAction", async () => {
30573
- const code = typeof process.exitCode === "number" ? process.exitCode : 0;
30574
- await finishActiveRecorder(code);
30500
+ await finishActiveRecorder(typeof process.exitCode === "number" ? process.exitCode : 0);
30575
30501
  });
30576
30502
  const main = async () => {
30577
30503
  fireInstalledOnce();