@codacy/verity-cli 0.34.0-experimental.ec5aae9 → 0.34.1-experimental.199c728

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/bin/verity.js +314 -259
  3. package/package.json +1 -1
package/bin/verity.js CHANGED
@@ -27257,7 +27257,7 @@ function channelSilence(input) {
27257
27257
  // src/lib/cli-version.ts
27258
27258
  function cliVersion() {
27259
27259
  try {
27260
- return true ? "0.34.0-experimental.ec5aae9" : "dev";
27260
+ return true ? "0.34.1-experimental.199c728" : "dev";
27261
27261
  } catch {
27262
27262
  return "dev";
27263
27263
  }
@@ -33434,12 +33434,41 @@ async function runAnalyze(opts, globals) {
33434
33434
  }
33435
33435
 
33436
33436
  // src/commands/baseline.ts
33437
- var import_node_fs55 = require("node:fs");
33438
- var import_node_path42 = require("node:path");
33437
+ var import_node_fs56 = require("node:fs");
33438
+ var import_node_path43 = require("node:path");
33439
33439
 
33440
- // src/lib/project-skills.ts
33440
+ // src/lib/skew-notice.ts
33441
33441
  var import_node_fs54 = require("node:fs");
33442
33442
  var import_node_path41 = require("node:path");
33443
+ var MARKER = ".skew-notice.json";
33444
+ function markerPath2() {
33445
+ return (0, import_node_path41.join)(verityHome(), MARKER);
33446
+ }
33447
+ function today(now) {
33448
+ const y = now.getFullYear();
33449
+ const m = String(now.getMonth() + 1).padStart(2, "0");
33450
+ const d = String(now.getDate()).padStart(2, "0");
33451
+ return `${y}-${m}-${d}`;
33452
+ }
33453
+ function skewNoticeDue(skew, now = /* @__PURE__ */ new Date()) {
33454
+ try {
33455
+ const seen = JSON.parse((0, import_node_fs54.readFileSync)(markerPath2(), "utf-8"));
33456
+ return !(seen.global === skew.global && seen.hooks === skew.hooks && seen.day === today(now));
33457
+ } catch {
33458
+ return true;
33459
+ }
33460
+ }
33461
+ function recordSkewNotice(skew, now = /* @__PURE__ */ new Date()) {
33462
+ try {
33463
+ (0, import_node_fs54.mkdirSync)(verityHome(), { recursive: true, mode: 448 });
33464
+ (0, import_node_fs54.writeFileSync)(markerPath2(), JSON.stringify({ global: skew.global, hooks: skew.hooks, day: today(now) }) + "\n");
33465
+ } catch {
33466
+ }
33467
+ }
33468
+
33469
+ // src/lib/project-skills.ts
33470
+ var import_node_fs55 = require("node:fs");
33471
+ var import_node_path42 = require("node:path");
33443
33472
  var PROJECT_SKILL_NAMES = [
33444
33473
  "verity-setup",
33445
33474
  "verity-analyze",
@@ -33465,14 +33494,14 @@ var LEGACY_SKILL_NAMES = [
33465
33494
  var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
33466
33495
  function staleProjectSkills() {
33467
33496
  const root = projectPath(".claude/skills");
33468
- if (!(0, import_node_fs54.existsSync)(root)) return [];
33469
- return ALL.filter((name2) => (0, import_node_fs54.existsSync)((0, import_node_path41.join)(root, name2)));
33497
+ if (!(0, import_node_fs55.existsSync)(root)) return [];
33498
+ return ALL.filter((name2) => (0, import_node_fs55.existsSync)((0, import_node_path42.join)(root, name2)));
33470
33499
  }
33471
33500
  function removeProjectSkills() {
33472
33501
  const root = projectPath(".claude/skills");
33473
33502
  const removed = [];
33474
33503
  for (const name2 of staleProjectSkills()) {
33475
- (0, import_node_fs54.rmSync)((0, import_node_path41.join)(root, name2), { recursive: true, force: true });
33504
+ (0, import_node_fs55.rmSync)((0, import_node_path42.join)(root, name2), { recursive: true, force: true });
33476
33505
  removed.push(name2);
33477
33506
  }
33478
33507
  return removed;
@@ -33502,10 +33531,12 @@ function registerBaselineCommands(program2) {
33502
33531
  const skew = cliVersionSkew();
33503
33532
  const why = skew ? `the \`verity\` on PATH is ${skew.global} but the hooks run ${skew.hooks}, so it is not the CLI they use` : verityOnPath() ? "the `verity` on PATH is a separate install whose version could not be read" : "this machine has no `verity` on PATH \u2014 the plugin carries its own copy";
33504
33533
  const cliLine = cli ? `Verity CLI: ${why}. When a Verity skill tells you to run \`verity <args>\`, run \`${cli} <args>\` instead. Everything else about the command is identical.` : null;
33505
- const skewMsg = skew ? `Verity: your global \`verity\` CLI is ${skew.global} but the hooks run ${skew.hooks}. Fix it before using \`verity\` in a terminal: ${skew.remedy}` : null;
33506
- const skewNote = skew ? `Before anything else, including /verity:init's questions, tell the user their global \`verity\` is ${skew.global}, the hooks run ${skew.hooks}, and \`${skew.remedy}\` fixes it. Until they have, do not send them to run \`verity login\` in a terminal: that runs the global one, which can sign this machine in to a different server.` : null;
33534
+ const skewLoud = !!skew && skewNoticeDue(skew);
33535
+ const skewMsg = skew && skewLoud ? `Verity: your global \`verity\` CLI is ${skew.global} but the hooks run ${skew.hooks}. Fix it before using \`verity\` in a terminal: ${skew.remedy}` : null;
33536
+ const loginWarning = "Until they have, do not send them to run `verity login` in a terminal: that runs the global one, which can sign this machine in to a different server.";
33537
+ const skewNote = !skew ? null : skewLoud ? `Before anything else, including /verity:init's questions, tell the user their global \`verity\` is ${skew.global}, the hooks run ${skew.hooks}, and \`${skew.remedy}\` fixes it. ${loginWarning}` : `The user's global \`verity\` is ${skew.global} and the hooks run ${skew.hooks}; \`${skew.remedy}\` fixes it. They were already told today, so do not repeat it unprompted \u2014 mention it only where it matters, such as before suggesting a \`verity\` command for their terminal. ${loginWarning}`;
33507
33538
  if (!verityConfigured()) {
33508
- if (isMachineStore((0, import_node_path42.join)(repoRoot(), VERITY_DIR))) process.exit(0);
33539
+ if (isMachineStore((0, import_node_path43.join)(repoRoot(), VERITY_DIR))) process.exit(0);
33509
33540
  const how = isPluginInvocation() ? "Tell the user to run /verity:init \u2014 they type it; you cannot invoke it." : "Tell the user to run `verity init` in their terminal.";
33510
33541
  const lines = [
33511
33542
  `Verity is installed but this project is not set up yet, so the quality gate will not review anything here. ${how}`
@@ -33532,19 +33563,20 @@ function registerBaselineCommands(program2) {
33532
33563
  }
33533
33564
  }) + "\n"
33534
33565
  );
33566
+ if (skew && skewMsg) recordSkewNotice(skew);
33535
33567
  process.exit(0);
33536
33568
  }
33537
33569
  const realStart = source2 === void 0 || source2 === "startup" || source2 === "clear";
33538
33570
  let memoryMsg = null;
33539
33571
  let memoryAgentLine = null;
33540
33572
  const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
33541
- if (realStart && !(0, import_node_fs55.existsSync)(memoryNotice)) {
33573
+ if (realStart && !(0, import_node_fs56.existsSync)(memoryNotice)) {
33542
33574
  const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
33543
33575
  if (trackedGraph > 0) {
33544
33576
  memoryMsg = `Verity: this project commits its knowledge base (${trackedGraph} files under .verity/memory/), so Verity's generated notes show up in every diff and pull request. Run \`verity memory untrack\` to keep them on disk but out of git, or \`verity memory track\` to keep committing them on purpose.`;
33545
33577
  memoryAgentLine = `This project has ${trackedGraph} knowledge-graph files tracked in git under .verity/memory/. As of Verity 0.32.6 the graph is machine-local by default \u2014 it is rebuilt from the service, and committing it puts generated notes in every pull request. If the user wants that stopped, run \`verity memory untrack\` for them: it keeps every file on disk and stages their removal from the index, so they only need to commit \u2014 and their teammates' working copies will vanish on the next pull and re-sync from the service, which is expected. If they would rather keep committing it, \`verity memory track\` records that and nothing will offer again.`;
33546
33578
  try {
33547
- (0, import_node_fs55.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
33579
+ (0, import_node_fs56.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
33548
33580
  } catch {
33549
33581
  }
33550
33582
  }
@@ -33572,7 +33604,7 @@ function registerBaselineCommands(program2) {
33572
33604
  }
33573
33605
  }
33574
33606
  if (memoryAgentLine) notices.push(memoryAgentLine);
33575
- if (notices.length > 0) {
33607
+ if (notices.length > 0 || skewMsg) {
33576
33608
  process.stdout.write(
33577
33609
  JSON.stringify({
33578
33610
  ...userMsg || skewMsg || memoryMsg ? { systemMessage: [skewMsg, userMsg, memoryMsg].filter(Boolean).join("\n") } : {},
@@ -33582,6 +33614,7 @@ function registerBaselineCommands(program2) {
33582
33614
  }
33583
33615
  }) + "\n"
33584
33616
  );
33617
+ if (skew && skewMsg) recordSkewNotice(skew);
33585
33618
  }
33586
33619
  } else if (memoryMsg) {
33587
33620
  process.stdout.write(
@@ -33645,7 +33678,7 @@ function hookSource(value) {
33645
33678
  }
33646
33679
 
33647
33680
  // src/commands/review.ts
33648
- var import_node_fs56 = require("node:fs");
33681
+ var import_node_fs57 = require("node:fs");
33649
33682
  function registerReviewCommand(program2) {
33650
33683
  program2.command("review").description("Run on-demand Verity analysis (advisory, never blocks)").requiredOption("--files <paths>", "Comma-separated file list").option("--changed <paths>", "Subset of --files that were modified").option("--intent <text>", "User intent description (max 2000 chars); - reads it from stdin, so the words never pass through shell quoting").option("--specs <paths>", "Comma-separated spec file paths").option("--json", "Output raw JSON response").action(async (opts) => {
33651
33684
  const globals = program2.opts();
@@ -33668,7 +33701,7 @@ async function runReview(opts, globals) {
33668
33701
  const changedFiles = opts.changed ? opts.changed.split(",").map((f) => f.trim()).filter(Boolean) : allFiles;
33669
33702
  const analyzable = filterAnalyzable(allFiles);
33670
33703
  const securityFiles = filterSecurity(allFiles);
33671
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs56.existsSync)(f) || resolveFile(f) !== null);
33704
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs57.existsSync)(f) || resolveFile(f) !== null);
33672
33705
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
33673
33706
  const codeDelta = collectCodeDelta(allFiles);
33674
33707
  const tokenResult = await resolveToken(globals.token);
@@ -33734,12 +33767,12 @@ async function runReview(opts, globals) {
33734
33767
  }
33735
33768
 
33736
33769
  // src/commands/guard.ts
33737
- var import_node_fs61 = require("node:fs");
33738
- var import_node_path48 = require("node:path");
33770
+ var import_node_fs62 = require("node:fs");
33771
+ var import_node_path49 = require("node:path");
33739
33772
 
33740
33773
  // src/lib/vendored.ts
33741
- var import_node_fs57 = require("node:fs");
33742
- var import_node_path43 = require("node:path");
33774
+ var import_node_fs58 = require("node:fs");
33775
+ var import_node_path44 = require("node:path");
33743
33776
  var INSTALLED_SKILL = /^\.claude\/skills\/(verity-[a-z0-9-]+)\/(.+)$/;
33744
33777
  function dataDirOrNull() {
33745
33778
  try {
@@ -33754,7 +33787,7 @@ function shippedSkillFile(path, dataDir = dataDirOrNull()) {
33754
33787
  const [, skill, rel] = m;
33755
33788
  if (rel.split("/").some((seg) => seg === ".." || seg === ".")) return null;
33756
33789
  try {
33757
- return (0, import_node_fs57.readFileSync)((0, import_node_path43.join)(dataDir, "skills", skill, rel), "utf8");
33790
+ return (0, import_node_fs58.readFileSync)((0, import_node_path44.join)(dataDir, "skills", skill, rel), "utf8");
33758
33791
  } catch {
33759
33792
  return null;
33760
33793
  }
@@ -33864,7 +33897,7 @@ async function runAgentReview(options) {
33864
33897
  }
33865
33898
 
33866
33899
  // src/lib/prove/auto.ts
33867
- var import_node_path47 = require("node:path");
33900
+ var import_node_path48 = require("node:path");
33868
33901
  var import_node_crypto19 = require("node:crypto");
33869
33902
 
33870
33903
  // src/lib/prove/signals.ts
@@ -35591,18 +35624,18 @@ function renderReplay(model, property, r) {
35591
35624
  // src/lib/prove/runner.ts
35592
35625
  var import_node_child_process15 = require("node:child_process");
35593
35626
  var import_node_os8 = require("node:os");
35594
- var import_node_fs60 = require("node:fs");
35627
+ var import_node_fs61 = require("node:fs");
35595
35628
  var import_node_os9 = require("node:os");
35596
- var import_node_path46 = require("node:path");
35629
+ var import_node_path47 = require("node:path");
35597
35630
 
35598
35631
  // src/lib/prove/scaffold.ts
35599
- var import_node_fs59 = require("node:fs");
35600
- var import_node_path45 = require("node:path");
35632
+ var import_node_fs60 = require("node:fs");
35633
+ var import_node_path46 = require("node:path");
35601
35634
 
35602
35635
  // src/lib/prove/safe-write.ts
35603
- var import_node_fs58 = require("node:fs");
35636
+ var import_node_fs59 = require("node:fs");
35604
35637
  var import_node_crypto15 = require("node:crypto");
35605
- var import_node_path44 = require("node:path");
35638
+ var import_node_path45 = require("node:path");
35606
35639
  var SafeWriteError = class extends Error {
35607
35640
  constructor(reason, path) {
35608
35641
  super(`refusing to write ${path}: ${reason}`);
@@ -35611,10 +35644,10 @@ var SafeWriteError = class extends Error {
35611
35644
  this.name = "SafeWriteError";
35612
35645
  }
35613
35646
  };
35614
- var FLAGS3 = import_node_fs58.constants;
35647
+ var FLAGS3 = import_node_fs59.constants;
35615
35648
  var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
35616
35649
  function assertPlainRelative(rel) {
35617
- if (!rel || (0, import_node_path44.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
35650
+ if (!rel || (0, import_node_path45.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
35618
35651
  for (const part of rel.split(/[\\/]/)) {
35619
35652
  if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
35620
35653
  }
@@ -35623,34 +35656,34 @@ function ensureDirsNoFollow(root, rel) {
35623
35656
  const parts2 = rel.split(/[\\/]/);
35624
35657
  let cur = root;
35625
35658
  for (const part of parts2.slice(0, -1)) {
35626
- cur = (0, import_node_path44.join)(cur, part);
35659
+ cur = (0, import_node_path45.join)(cur, part);
35627
35660
  let st;
35628
35661
  try {
35629
- st = (0, import_node_fs58.lstatSync)(cur);
35662
+ st = (0, import_node_fs59.lstatSync)(cur);
35630
35663
  } catch {
35631
- (0, import_node_fs58.mkdirSync)(cur);
35664
+ (0, import_node_fs59.mkdirSync)(cur);
35632
35665
  continue;
35633
35666
  }
35634
35667
  if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
35635
35668
  if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
35636
35669
  }
35637
- return (0, import_node_path44.join)(root, rel);
35670
+ return (0, import_node_path45.join)(root, rel);
35638
35671
  }
35639
35672
  function insideRoot(realRoot, realPath) {
35640
- return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path44.sep) ? realRoot : realRoot + import_node_path44.sep);
35673
+ return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path45.sep) ? realRoot : realRoot + import_node_path45.sep);
35641
35674
  }
35642
35675
  function removeQuietly(path) {
35643
35676
  try {
35644
- (0, import_node_fs58.unlinkSync)(path);
35677
+ (0, import_node_fs59.unlinkSync)(path);
35645
35678
  } catch {
35646
35679
  }
35647
35680
  }
35648
35681
  function writeFileInRootNoFollow(root, rel, content) {
35649
35682
  assertPlainRelative(rel);
35650
35683
  const dest = ensureDirsNoFollow(root, rel);
35651
- const dir = (0, import_node_path44.dirname)(dest);
35684
+ const dir = (0, import_node_path45.dirname)(dest);
35652
35685
  try {
35653
- const st = (0, import_node_fs58.lstatSync)(dest);
35686
+ const st = (0, import_node_fs59.lstatSync)(dest);
35654
35687
  if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
35655
35688
  if (!st.isFile()) throw new SafeWriteError("not-regular", dest);
35656
35689
  } catch (err2) {
@@ -35658,41 +35691,41 @@ function writeFileInRootNoFollow(root, rel, content) {
35658
35691
  }
35659
35692
  let realRoot;
35660
35693
  try {
35661
- realRoot = (0, import_node_fs58.realpathSync)(root);
35694
+ realRoot = (0, import_node_fs59.realpathSync)(root);
35662
35695
  } catch {
35663
35696
  throw new SafeWriteError("unwritable", root);
35664
35697
  }
35665
- const tmp = (0, import_node_path44.join)(dir, `.${(0, import_node_path44.basename)(dest)}.${(0, import_node_crypto15.randomBytes)(6).toString("hex")}.tmp`);
35698
+ const tmp = (0, import_node_path45.join)(dir, `.${(0, import_node_path45.basename)(dest)}.${(0, import_node_crypto15.randomBytes)(6).toString("hex")}.tmp`);
35666
35699
  let fd;
35667
35700
  try {
35668
- fd = (0, import_node_fs58.openSync)(tmp, import_node_fs58.constants.O_WRONLY | import_node_fs58.constants.O_CREAT | import_node_fs58.constants.O_EXCL | NOFOLLOW2, 420);
35701
+ fd = (0, import_node_fs59.openSync)(tmp, import_node_fs59.constants.O_WRONLY | import_node_fs59.constants.O_CREAT | import_node_fs59.constants.O_EXCL | NOFOLLOW2, 420);
35669
35702
  } catch {
35670
35703
  throw new SafeWriteError("unwritable", tmp);
35671
35704
  }
35672
35705
  try {
35673
- const opened = (0, import_node_fs58.fstatSync)(fd, { bigint: true });
35706
+ const opened = (0, import_node_fs59.fstatSync)(fd, { bigint: true });
35674
35707
  let realTmp;
35675
35708
  try {
35676
- realTmp = (0, import_node_fs58.realpathSync)(tmp);
35709
+ realTmp = (0, import_node_fs59.realpathSync)(tmp);
35677
35710
  } catch {
35678
35711
  throw new SafeWriteError("escaped", tmp);
35679
35712
  }
35680
- const there = (0, import_node_fs58.lstatSync)(realTmp, { bigint: true });
35713
+ const there = (0, import_node_fs59.lstatSync)(realTmp, { bigint: true });
35681
35714
  if (!opened.isFile() || there.ino !== opened.ino || there.dev !== opened.dev || !insideRoot(realRoot, realTmp)) {
35682
35715
  throw new SafeWriteError("escaped", tmp);
35683
35716
  }
35684
35717
  const buf = Buffer.from(content, "utf-8");
35685
35718
  let off = 0;
35686
- while (off < buf.length) off += (0, import_node_fs58.writeSync)(fd, buf, off, buf.length - off);
35719
+ while (off < buf.length) off += (0, import_node_fs59.writeSync)(fd, buf, off, buf.length - off);
35687
35720
  } catch (err2) {
35688
- (0, import_node_fs58.closeSync)(fd);
35721
+ (0, import_node_fs59.closeSync)(fd);
35689
35722
  removeQuietly(tmp);
35690
35723
  throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", tmp);
35691
35724
  }
35692
- (0, import_node_fs58.closeSync)(fd);
35725
+ (0, import_node_fs59.closeSync)(fd);
35693
35726
  try {
35694
- if (!insideRoot(realRoot, (0, import_node_fs58.realpathSync)(dir)) || (0, import_node_fs58.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
35695
- (0, import_node_fs58.renameSync)(tmp, dest);
35727
+ if (!insideRoot(realRoot, (0, import_node_fs59.realpathSync)(dir)) || (0, import_node_fs59.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
35728
+ (0, import_node_fs59.renameSync)(tmp, dest);
35696
35729
  } catch (err2) {
35697
35730
  removeQuietly(tmp);
35698
35731
  throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", dest);
@@ -35706,9 +35739,9 @@ function pathHasNoLink(root, rel) {
35706
35739
  }
35707
35740
  let cur = root;
35708
35741
  for (const part of rel.split(/[\\/]/)) {
35709
- cur = cur + import_node_path44.sep + part;
35742
+ cur = cur + import_node_path45.sep + part;
35710
35743
  try {
35711
- if ((0, import_node_fs58.lstatSync)(cur).isSymbolicLink()) return false;
35744
+ if ((0, import_node_fs59.lstatSync)(cur).isSymbolicLink()) return false;
35712
35745
  } catch {
35713
35746
  return true;
35714
35747
  }
@@ -36018,20 +36051,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
36018
36051
  never committed; what reaches the team is the bug report and the fix.
36019
36052
  `;
36020
36053
  function scaffoldProofs(root) {
36021
- const proofsDir = (0, import_node_path45.join)(root, PROOFS_DIR);
36054
+ const proofsDir = (0, import_node_path46.join)(root, PROOFS_DIR);
36022
36055
  const written = [];
36023
36056
  const kept = [];
36024
36057
  for (const stray of ["lakefile.lean"]) {
36025
36058
  const rel = `${PROOFS_DIR}/${stray}`;
36026
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
36059
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path46.join)(root, rel));
36027
36060
  try {
36028
- (0, import_node_fs59.rmSync)((0, import_node_path45.join)(root, rel), { force: true });
36061
+ (0, import_node_fs60.rmSync)((0, import_node_path46.join)(root, rel), { force: true });
36029
36062
  } catch {
36030
36063
  }
36031
36064
  }
36032
36065
  for (const f of PROOFS_TEMPLATE_FILES) {
36033
36066
  const rel = `${PROOFS_DIR}/${f.path}`;
36034
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
36067
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path46.join)(root, rel));
36035
36068
  const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
36036
36069
  if (current.ok && current.content === f.content) {
36037
36070
  kept.push(rel);
@@ -36044,8 +36077,8 @@ function scaffoldProofs(root) {
36044
36077
  [`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
36045
36078
  [`${MODELS_DIR}/README.md`, MODELS_README]
36046
36079
  ]) {
36047
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
36048
- if (existsNoFollow((0, import_node_path45.join)(root, rel))) {
36080
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path46.join)(root, rel));
36081
+ if (existsNoFollow((0, import_node_path46.join)(root, rel))) {
36049
36082
  kept.push(rel);
36050
36083
  continue;
36051
36084
  }
@@ -36056,7 +36089,7 @@ function scaffoldProofs(root) {
36056
36089
  }
36057
36090
  function existsNoFollow(abs) {
36058
36091
  try {
36059
- (0, import_node_fs59.lstatSync)(abs);
36092
+ (0, import_node_fs60.lstatSync)(abs);
36060
36093
  return true;
36061
36094
  } catch {
36062
36095
  return false;
@@ -36314,17 +36347,17 @@ function renderReport(r) {
36314
36347
 
36315
36348
  // src/lib/prove/runner.ts
36316
36349
  function verityLeanHome(env = process.env) {
36317
- return env.VERITY_LEAN_HOME ?? (0, import_node_path46.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
36350
+ return env.VERITY_LEAN_HOME ?? (0, import_node_path47.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
36318
36351
  }
36319
36352
  function findToolchain(env = process.env) {
36320
- const managedBin = (0, import_node_path46.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
36321
- const elanBin = (0, import_node_path46.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
36322
- const elanHas = (0, import_node_fs60.existsSync)((0, import_node_path46.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
36323
- const userPath = (env.PATH ?? "").split(import_node_path46.delimiter).filter((d) => d && (elanHas || (0, import_node_path46.resolve)(d) !== (0, import_node_path46.resolve)(elanBin)));
36324
- const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path46.delimiter);
36353
+ const managedBin = (0, import_node_path47.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
36354
+ const elanBin = (0, import_node_path47.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
36355
+ const elanHas = (0, import_node_fs61.existsSync)((0, import_node_path47.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
36356
+ const userPath = (env.PATH ?? "").split(import_node_path47.delimiter).filter((d) => d && (elanHas || (0, import_node_path47.resolve)(d) !== (0, import_node_path47.resolve)(elanBin)));
36357
+ const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path47.delimiter);
36325
36358
  const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
36326
36359
  const exe = process.platform === "win32" ? "lake.exe" : "lake";
36327
- const candidates2 = [(0, import_node_path46.join)(managedBin, exe), ...elanHas ? [(0, import_node_path46.join)(elanBin, exe)] : [], exe];
36360
+ const candidates2 = [(0, import_node_path47.join)(managedBin, exe), ...elanHas ? [(0, import_node_path47.join)(elanBin, exe)] : [], exe];
36328
36361
  for (const candidate of candidates2) {
36329
36362
  try {
36330
36363
  (0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
@@ -36403,7 +36436,7 @@ function proofsWorkspaceProblem(root) {
36403
36436
  for (const rel of [".verity", PROOFS_DIR, `${PROOFS_DIR}/.lake`]) {
36404
36437
  let st;
36405
36438
  try {
36406
- st = (0, import_node_fs60.lstatSync)((0, import_node_path46.join)(root, rel));
36439
+ st = (0, import_node_fs61.lstatSync)((0, import_node_path47.join)(root, rel));
36407
36440
  } catch {
36408
36441
  break;
36409
36442
  }
@@ -36423,44 +36456,44 @@ function refused(problem) {
36423
36456
  function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
36424
36457
  const problem = proofsWorkspaceProblem(root);
36425
36458
  if (problem) return refused(problem);
36426
- return run2(tc, (0, import_node_path46.join)(root, PROOFS_DIR), ["build"], timeoutMs);
36459
+ return run2(tc, (0, import_node_path47.join)(root, PROOFS_DIR), ["build"], timeoutMs);
36427
36460
  }
36428
36461
  async function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
36429
36462
  const problem = proofsWorkspaceProblem(root);
36430
36463
  if (problem) return refused(problem);
36431
- return runAsync(tc, (0, import_node_path46.join)(root, PROOFS_DIR), ["build"], timeoutMs);
36464
+ return runAsync(tc, (0, import_node_path47.join)(root, PROOFS_DIR), ["build"], timeoutMs);
36432
36465
  }
36433
36466
  function isModelInRoot(modelsAbs, rel) {
36434
- if (!rel.endsWith(".lean") || (0, import_node_path46.isAbsolute)(rel) || rel.startsWith("..")) return false;
36467
+ if (!rel.endsWith(".lean") || (0, import_node_path47.isAbsolute)(rel) || rel.startsWith("..")) return false;
36435
36468
  return statRegularInRoot(modelsAbs, rel).ok;
36436
36469
  }
36437
36470
  function resolveModelFile(root, arg) {
36438
- const modelsAbs = (0, import_node_path46.join)(root, MODELS_DIR);
36439
- const asPath = (0, import_node_path46.relative)(modelsAbs, (0, import_node_path46.isAbsolute)(arg) ? arg : (0, import_node_path46.resolve)(root, arg));
36471
+ const modelsAbs = (0, import_node_path47.join)(root, MODELS_DIR);
36472
+ const asPath = (0, import_node_path47.relative)(modelsAbs, (0, import_node_path47.isAbsolute)(arg) ? arg : (0, import_node_path47.resolve)(root, arg));
36440
36473
  const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
36441
36474
  for (const rel of candidates2) {
36442
- if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path46.join)(modelsAbs, rel);
36475
+ if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path47.join)(modelsAbs, rel);
36443
36476
  }
36444
36477
  return null;
36445
36478
  }
36446
36479
  function listModelFiles(root) {
36447
- const modelsAbs = (0, import_node_path46.join)(root, MODELS_DIR);
36448
- if (!(0, import_node_fs60.existsSync)(modelsAbs)) return [];
36449
- return (0, import_node_fs60.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path46.join)(modelsAbs, f));
36480
+ const modelsAbs = (0, import_node_path47.join)(root, MODELS_DIR);
36481
+ if (!(0, import_node_fs61.existsSync)(modelsAbs)) return [];
36482
+ return (0, import_node_fs61.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path47.join)(modelsAbs, f));
36450
36483
  }
36451
36484
  function trimDiagnostics(text) {
36452
36485
  return text.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
36453
36486
  }
36454
36487
  function checkModel(tc, root, modelFile, opts = {}) {
36455
- const proofsAbs = (0, import_node_path46.join)(root, PROOFS_DIR);
36456
- const rel = (0, import_node_path46.relative)(proofsAbs, modelFile);
36488
+ const proofsAbs = (0, import_node_path47.join)(root, PROOFS_DIR);
36489
+ const rel = (0, import_node_path47.relative)(proofsAbs, modelFile);
36457
36490
  const problem = proofsWorkspaceProblem(root);
36458
36491
  const res = problem ? refused(problem) : run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
36459
36492
  return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
36460
36493
  }
36461
36494
  async function checkModelAsync(tc, root, modelFile, opts = {}) {
36462
- const proofsAbs = (0, import_node_path46.join)(root, PROOFS_DIR);
36463
- const rel = (0, import_node_path46.relative)(proofsAbs, modelFile);
36495
+ const proofsAbs = (0, import_node_path47.join)(root, PROOFS_DIR);
36496
+ const rel = (0, import_node_path47.relative)(proofsAbs, modelFile);
36464
36497
  const problem = proofsWorkspaceProblem(root);
36465
36498
  const res = problem ? refused(problem) : await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
36466
36499
  return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
@@ -36469,10 +36502,10 @@ function toReport(res, root, modelFile, timeoutMs) {
36469
36502
  const parsed = parseVerityLines(res.stdout);
36470
36503
  const combined = `${res.stdout}
36471
36504
  ${res.stderr}`;
36472
- const name2 = parsed.header?.model ?? (0, import_node_path46.basename)(modelFile, ".lean");
36505
+ const name2 = parsed.header?.model ?? (0, import_node_path47.basename)(modelFile, ".lean");
36473
36506
  const report = {
36474
36507
  model: name2,
36475
- file: (0, import_node_path46.relative)(root, modelFile),
36508
+ file: (0, import_node_path47.relative)(root, modelFile),
36476
36509
  ok: res.ok,
36477
36510
  header: parsed.header,
36478
36511
  properties: parsed.properties,
@@ -36717,15 +36750,15 @@ function nonNegative(v) {
36717
36750
  return typeof v === "number" && Number.isFinite(v) && v > 0 ? v : 0;
36718
36751
  }
36719
36752
  function readLedger(root) {
36720
- const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
36721
- const empty = { day: today, models: 0, costUsd: 0 };
36753
+ const today2 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
36754
+ const empty = { day: today2, models: 0, costUsd: 0 };
36722
36755
  if (!isLocalState(root, AUTO_LEDGER)) return empty;
36723
36756
  const read2 = readRegularFileInRoot(root, AUTO_LEDGER, 4096);
36724
36757
  if (!read2.ok) return empty;
36725
36758
  try {
36726
36759
  const o = JSON.parse(read2.content);
36727
- if (o.day !== today || typeof o.models !== "number") return empty;
36728
- return { day: today, models: nonNegative(o.models), costUsd: nonNegative(o.costUsd) };
36760
+ if (o.day !== today2 || typeof o.models !== "number") return empty;
36761
+ return { day: today2, models: nonNegative(o.models), costUsd: nonNegative(o.costUsd) };
36729
36762
  } catch {
36730
36763
  return empty;
36731
36764
  }
@@ -37042,7 +37075,7 @@ async function runFormalPhase(input) {
37042
37075
  modelName = gen.name;
37043
37076
  const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
37044
37077
  writeFileInRootNoFollow(root, rel, gen.source);
37045
- const abs = resolveModelFile(root, rel) ?? (0, import_node_path47.join)(root, rel);
37078
+ const abs = resolveModelFile(root, rel) ?? (0, import_node_path48.join)(root, rel);
37046
37079
  progress.model = { name: gen.name, file: rel, rounds: round };
37047
37080
  progress.step = "check";
37048
37081
  report = await deps.check(root, abs);
@@ -37164,7 +37197,7 @@ async function runFormalPhase(input) {
37164
37197
  return done({
37165
37198
  status: "checked",
37166
37199
  target,
37167
- model: { name: modelName, file: (0, import_node_path47.relative)(root, (0, import_node_path47.join)(root, modelFile)), rounds },
37200
+ model: { name: modelName, file: (0, import_node_path48.relative)(root, (0, import_node_path48.join)(root, modelFile)), rounds },
37168
37201
  properties: report.properties,
37169
37202
  findings
37170
37203
  });
@@ -37197,7 +37230,19 @@ async function generateAndCheck(root, req, opts) {
37197
37230
  const read2 = readSrc(req.file, 96 * 1024);
37198
37231
  if (!read2.ok) return { ok: false, error: `${req.file}: ${read2.reason}`, rounds: 0, costUsd: 0 };
37199
37232
  const sha2562 = sha256Of(read2.content);
37200
- const { lines, numbered: numbered2 } = describeTarget(read2.content, req.symbol, req.file, req.lines, { codeMap: opts.deps.codeMap });
37233
+ const { lines, numbered: numbered2, extent } = describeTarget(read2.content, req.symbol, req.file, req.lines, { codeMap: opts.deps.codeMap });
37234
+ let warning;
37235
+ if (!lines) {
37236
+ const outline = extent === "fallback:not-found" ? opts.deps.codeMap?.outline(req.file, read2.content) : void 0;
37237
+ if (outline?.source === "tree-sitter") {
37238
+ const names2 = [...new Set(outline.value.filter((f) => f.name && f.kind !== "lambda").map((f) => f.qualified))];
37239
+ const last = (req.symbol.split(/[.#:]/).pop() ?? req.symbol).toLowerCase();
37240
+ const close = names2.filter((n) => n.toLowerCase().includes(last));
37241
+ const shown = (close.length > 0 ? close : names2).slice(0, 12);
37242
+ return { ok: false, error: `no function \`${req.symbol}\` in ${req.file}${shown.length ? ` (it has: ${shown.join(", ")})` : ""}. Name one as ${req.file}#<name>, or pass --lines a-b`, rounds: 0, costUsd: 0 };
37243
+ }
37244
+ warning = `could not find the lines of \`${req.symbol}\` in ${req.file} (${extent}): the model is written from the start of the file, and a replay must copy half of the whole file. Pass --lines a-b to name the code.`;
37245
+ }
37201
37246
  const target = {
37202
37247
  file: req.file,
37203
37248
  symbol: req.symbol,
@@ -37205,7 +37250,9 @@ async function generateAndCheck(root, req, opts) {
37205
37250
  sha256: sha2562,
37206
37251
  numbered: numbered2,
37207
37252
  reasons: req.hint ? [`the user's worry, in their words: ${req.hint.slice(0, 280)}`] : [],
37208
- properties: []
37253
+ properties: [],
37254
+ // The run row records which extractor answered, as at push.
37255
+ extentSource: extent
37209
37256
  };
37210
37257
  const context = opts.deps.codeMap && !req.lines ? targetContext({ codeMap: opts.deps.codeMap, codeSource: opts.deps.codeSource, readSource: readSrc, file: req.file, content: read2.content, symbol: req.symbol }) : null;
37211
37258
  Object.assign(target, context?.fields ?? {});
@@ -37227,7 +37274,7 @@ async function generateAndCheck(root, req, opts) {
37227
37274
  }
37228
37275
  const rel = `${dir}/${gen.name}.lean`;
37229
37276
  writeFileInRootNoFollow(root, rel, gen.source);
37230
- const abs = resolveModelFile(root, rel) ?? (0, import_node_path47.join)(root, rel);
37277
+ const abs = resolveModelFile(root, rel) ?? (0, import_node_path48.join)(root, rel);
37231
37278
  const report = await opts.deps.check(root, abs);
37232
37279
  const abstracts = report.header?.abstracts ?? [];
37233
37280
  const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
@@ -37241,14 +37288,14 @@ async function generateAndCheck(root, req, opts) {
37241
37288
  const g = basisOf(p.source, files);
37242
37289
  return g.ok ? [] : [`${p.id}: ${g.why}`];
37243
37290
  });
37244
- if (bad.length === 0) return { ok: true, name: gen.name, file: rel, report, rounds: round, costUsd };
37291
+ if (bad.length === 0) return { ok: true, name: gen.name, file: rel, report, rounds: round, costUsd, ...warning ? { warning } : {} };
37245
37292
  lastError = ungroundedMessage(bad.join("; "));
37246
37293
  if (round < maxRounds) {
37247
37294
  previous = { source: gen.source, error: lastError };
37248
37295
  continue;
37249
37296
  }
37250
37297
  const grounded = report.properties.filter((p) => basisOf(p.source, files).ok);
37251
- if (grounded.length > 0) return { ok: true, name: gen.name, file: rel, report: { ...report, properties: grounded }, rounds: round, costUsd };
37298
+ if (grounded.length > 0) return { ok: true, name: gen.name, file: rel, report: { ...report, properties: grounded }, rounds: round, costUsd, ...warning ? { warning } : {} };
37252
37299
  break;
37253
37300
  }
37254
37301
  lastError = stray ? `the model abstracts ${stray.file}, not ${req.file}` : report.error ?? (report.malformed ? "the model printed malformed VERITY lines" : "the model reported no property");
@@ -37274,9 +37321,16 @@ async function prepareFormalPhase(root, env = process.env, auth2, readSource, co
37274
37321
  }
37275
37322
  const build = await buildLibraryAsync(toolchain, root, 9e4);
37276
37323
  if (!build.ok) return { ok: false, skip: "library-build-failed", detail: build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).join(" ").slice(0, 200) };
37324
+ const code = await loadCodeContext(root, env, codeSource);
37325
+ return { ok: true, deps: { ...defaultDeps({ auth: auth2, apiKey, env, toolchain, readSource, ...code }), codeSource: code.codeSource } };
37326
+ }
37327
+ async function loadCodeContext(root, env = process.env, codeSource) {
37277
37328
  const loaded = await loadCodeMap(env);
37278
- const source2 = codeSource ?? withoutPaths(worktreeSource(root), isDeniedPath);
37279
- return { ok: true, deps: { ...defaultDeps({ auth: auth2, apiKey, env, toolchain, readSource, codeMap: loaded.ok ? loaded.map : null, codeSource: source2 }), codeSource: source2 } };
37329
+ return { codeMap: loaded.ok ? loaded.map : null, codeSource: codeSource ?? withoutPaths(worktreeSource(root), isDeniedPath) };
37330
+ }
37331
+ async function onDemandDeps(root, opts) {
37332
+ const code = await loadCodeContext(root, opts.env);
37333
+ return { ...defaultDeps({ ...opts, tier: "deep", ...code }), codeSource: code.codeSource };
37280
37334
  }
37281
37335
  function changedFunction(codeMap, file, content, changed) {
37282
37336
  const outline = codeMap.outline(file, content);
@@ -37357,7 +37411,7 @@ var WRITERS_BUDGET_MS = 1500;
37357
37411
  var EXCERPT_MAX_LINES2 = 30;
37358
37412
  var VENDORED_READ_MAX_BYTES = 256 * 1024;
37359
37413
  var GUARD_BLOCK_CAP = 2;
37360
- var GUARD_ITER_FILE = (0, import_node_path48.join)(VERITY_DIR, ".guard-iteration");
37414
+ var GUARD_ITER_FILE = (0, import_node_path49.join)(VERITY_DIR, ".guard-iteration");
37361
37415
  function readPreToolUseStdin() {
37362
37416
  const empty = { command: "", cwd: null, sessionId: null };
37363
37417
  return new Promise((resolve9) => {
@@ -37402,7 +37456,7 @@ function readPreToolUseStdin() {
37402
37456
  }
37403
37457
  function readIterMap() {
37404
37458
  try {
37405
- const raw = JSON.parse((0, import_node_fs61.readFileSync)(GUARD_ITER_FILE, "utf-8"));
37459
+ const raw = JSON.parse((0, import_node_fs62.readFileSync)(GUARD_ITER_FILE, "utf-8"));
37406
37460
  if (raw && typeof raw === "object") {
37407
37461
  if (typeof raw.moment === "string" && typeof raw.count === "number") {
37408
37462
  return { [raw.moment]: raw.count };
@@ -37422,10 +37476,10 @@ function readIter(moment) {
37422
37476
  }
37423
37477
  function writeIter(moment, count) {
37424
37478
  try {
37425
- (0, import_node_fs61.mkdirSync)(VERITY_DIR, { recursive: true });
37479
+ (0, import_node_fs62.mkdirSync)(VERITY_DIR, { recursive: true });
37426
37480
  const map = readIterMap();
37427
37481
  map[moment] = count;
37428
- (0, import_node_fs61.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
37482
+ (0, import_node_fs62.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
37429
37483
  } catch {
37430
37484
  }
37431
37485
  }
@@ -37435,10 +37489,10 @@ function resetIter(moment) {
37435
37489
  if (!(moment in map)) return;
37436
37490
  delete map[moment];
37437
37491
  if (Object.keys(map).length === 0) {
37438
- if ((0, import_node_fs61.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs61.unlinkSync)(GUARD_ITER_FILE);
37492
+ if ((0, import_node_fs62.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs62.unlinkSync)(GUARD_ITER_FILE);
37439
37493
  } else {
37440
- (0, import_node_fs61.mkdirSync)(VERITY_DIR, { recursive: true });
37441
- (0, import_node_fs61.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
37494
+ (0, import_node_fs62.mkdirSync)(VERITY_DIR, { recursive: true });
37495
+ (0, import_node_fs62.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
37442
37496
  }
37443
37497
  } catch {
37444
37498
  }
@@ -37508,7 +37562,7 @@ function hasBlockingFinding(response, sentFiles) {
37508
37562
  function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
37509
37563
  const analyzable = filterAnalyzable(files);
37510
37564
  const securityFiles = filterSecurity(files);
37511
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs61.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
37565
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs62.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
37512
37566
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
37513
37567
  const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
37514
37568
  const requestBody = {
@@ -38134,7 +38188,7 @@ function registerIgnoreCommand(program2) {
38134
38188
 
38135
38189
  // src/commands/waive.ts
38136
38190
  var import_node_crypto20 = require("node:crypto");
38137
- var import_node_fs62 = require("node:fs");
38191
+ var import_node_fs63 = require("node:fs");
38138
38192
  function registerWaiveCommand(program2) {
38139
38193
  program2.command("waive <pattern-id>").description("Record an accepted-risk disposition for an open finding (voids when the file changes)").option("--file <path>", "File the finding is anchored to, REPO-RELATIVE (recommended \u2014 narrows the waive)").requiredOption("--reason <text>", "The human disposition this records (reviewer finding, ADR, \u2026)").action(async (patternId, opts) => {
38140
38194
  const globals = program2.opts();
@@ -38163,7 +38217,7 @@ function registerWaiveCommand(program2) {
38163
38217
  if (opts.file) {
38164
38218
  body2.file = opts.file;
38165
38219
  try {
38166
- body2.file_sha256 = (0, import_node_crypto20.createHash)("sha256").update((0, import_node_fs62.readFileSync)(opts.file)).digest("hex");
38220
+ body2.file_sha256 = (0, import_node_crypto20.createHash)("sha256").update((0, import_node_fs63.readFileSync)(opts.file)).digest("hex");
38167
38221
  } catch {
38168
38222
  printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
38169
38223
  process.exit(1);
@@ -38188,10 +38242,10 @@ function registerWaiveCommand(program2) {
38188
38242
  }
38189
38243
 
38190
38244
  // src/commands/init.ts
38191
- var import_node_fs67 = require("node:fs");
38245
+ var import_node_fs68 = require("node:fs");
38192
38246
  var import_promises20 = require("node:fs/promises");
38193
38247
  var import_yaml6 = __toESM2(require_dist());
38194
- var import_node_path52 = require("node:path");
38248
+ var import_node_path53 = require("node:path");
38195
38249
  var import_node_os11 = require("node:os");
38196
38250
  var import_node_child_process19 = require("node:child_process");
38197
38251
 
@@ -38271,7 +38325,7 @@ function printPhase(n, of, title, subtitle) {
38271
38325
  }
38272
38326
 
38273
38327
  // src/commands/doctor.ts
38274
- var import_node_fs63 = require("node:fs");
38328
+ var import_node_fs64 = require("node:fs");
38275
38329
 
38276
38330
  // src/lib/prereqs.ts
38277
38331
  var import_node_child_process16 = require("node:child_process");
@@ -38479,11 +38533,11 @@ async function buildReport() {
38479
38533
  const hooks = wiring.status;
38480
38534
  const provenance = cliProvenance();
38481
38535
  const telemetry = await checkTelemetry();
38482
- const hasConfig = (0, import_node_fs63.existsSync)(projectPath(CODACY_CONFIG_FILE));
38536
+ const hasConfig = (0, import_node_fs64.existsSync)(projectPath(CODACY_CONFIG_FILE));
38483
38537
  const artifacts = {
38484
- standard: (0, import_node_fs63.existsSync)(projectPath(STANDARD_FILE)),
38538
+ standard: (0, import_node_fs64.existsSync)(projectPath(STANDARD_FILE)),
38485
38539
  analysisConfig: hasConfig,
38486
- verityMd: (0, import_node_fs63.existsSync)(projectPath(VERITY_MD_FILE)),
38540
+ verityMd: (0, import_node_fs64.existsSync)(projectPath(VERITY_MD_FILE)),
38487
38541
  analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
38488
38542
  };
38489
38543
  const next = [];
@@ -38642,8 +38696,8 @@ function registerDoctorCommand(program2) {
38642
38696
  }
38643
38697
 
38644
38698
  // src/commands/migrate.ts
38645
- var import_node_fs64 = require("node:fs");
38646
- var import_node_path49 = require("node:path");
38699
+ var import_node_fs65 = require("node:fs");
38700
+ var import_node_path50 = require("node:path");
38647
38701
  var import_node_child_process17 = require("node:child_process");
38648
38702
  var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
38649
38703
  function defaultNpmRemover(pkg) {
@@ -38680,12 +38734,12 @@ async function runMigration(opts = {}) {
38680
38734
  return { actions, migrated: actions.length > 0 };
38681
38735
  }
38682
38736
  function migrateProjectDir(root, actions) {
38683
- const gateDir = (0, import_node_path49.join)(root, ".gate");
38684
- const verityDir = (0, import_node_path49.join)(root, ".verity");
38685
- if ((0, import_node_fs64.existsSync)(gateDir) && !(0, import_node_fs64.existsSync)(verityDir)) {
38737
+ const gateDir = (0, import_node_path50.join)(root, ".gate");
38738
+ const verityDir = (0, import_node_path50.join)(root, ".verity");
38739
+ if ((0, import_node_fs65.existsSync)(gateDir) && !(0, import_node_fs65.existsSync)(verityDir)) {
38686
38740
  return migrateProjectDirRename(root, gateDir, verityDir, actions);
38687
38741
  }
38688
- if ((0, import_node_fs64.existsSync)(gateDir) && (0, import_node_fs64.existsSync)(verityDir)) {
38742
+ if ((0, import_node_fs65.existsSync)(gateDir) && (0, import_node_fs65.existsSync)(verityDir)) {
38689
38743
  return migrateProjectDirCarry(gateDir, verityDir, actions);
38690
38744
  }
38691
38745
  return false;
@@ -38706,13 +38760,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
38706
38760
  }
38707
38761
  }
38708
38762
  if (moved) {
38709
- if ((0, import_node_fs64.existsSync)(gateDir)) {
38763
+ if ((0, import_node_fs65.existsSync)(gateDir)) {
38710
38764
  const carried = carryLegacyContents(gateDir, verityDir);
38711
38765
  if (carried > 0) {
38712
38766
  actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
38713
38767
  }
38714
38768
  try {
38715
- (0, import_node_fs64.rmSync)(gateDir, { recursive: true, force: true });
38769
+ (0, import_node_fs65.rmSync)(gateDir, { recursive: true, force: true });
38716
38770
  } catch {
38717
38771
  }
38718
38772
  }
@@ -38728,18 +38782,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
38728
38782
  actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
38729
38783
  }
38730
38784
  try {
38731
- (0, import_node_fs64.rmSync)(gateDir, { recursive: true, force: true });
38785
+ (0, import_node_fs65.rmSync)(gateDir, { recursive: true, force: true });
38732
38786
  } catch {
38733
38787
  }
38734
38788
  return carried > 0;
38735
38789
  }
38736
38790
  function migrateGlobalCredentials(home, actions) {
38737
38791
  if (!home) return;
38738
- const gateCreds = (0, import_node_path49.join)(home, ".gate", "credentials");
38739
- const verityCreds = (0, import_node_path49.join)(home, ".verity", "credentials");
38740
- if (!(0, import_node_fs64.existsSync)(gateCreds)) return;
38741
- if (!(0, import_node_fs64.existsSync)(verityCreds)) {
38742
- (0, import_node_fs64.mkdirSync)((0, import_node_path49.join)(home, ".verity"), { recursive: true });
38792
+ const gateCreds = (0, import_node_path50.join)(home, ".gate", "credentials");
38793
+ const verityCreds = (0, import_node_path50.join)(home, ".verity", "credentials");
38794
+ if (!(0, import_node_fs65.existsSync)(gateCreds)) return;
38795
+ if (!(0, import_node_fs65.existsSync)(verityCreds)) {
38796
+ (0, import_node_fs65.mkdirSync)((0, import_node_path50.join)(home, ".verity"), { recursive: true });
38743
38797
  moveFile(gateCreds, verityCreds);
38744
38798
  actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
38745
38799
  return;
@@ -38761,8 +38815,8 @@ async function migrateLegacyHooks(root, actions) {
38761
38815
  }
38762
38816
  }
38763
38817
  async function migrateClaudeMd(root, actions) {
38764
- const claudeMd = (0, import_node_path49.join)(root, "CLAUDE.md");
38765
- const hadLegacyBlock = (0, import_node_fs64.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
38818
+ const claudeMd = (0, import_node_path50.join)(root, "CLAUDE.md");
38819
+ const hadLegacyBlock = (0, import_node_fs65.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
38766
38820
  if (!hadLegacyBlock) return;
38767
38821
  try {
38768
38822
  await ensureClaudeMdPointer(root);
@@ -38772,9 +38826,9 @@ async function migrateClaudeMd(root, actions) {
38772
38826
  }
38773
38827
  }
38774
38828
  function migrateStandardFile(root, actions) {
38775
- const gateMd = (0, import_node_path49.join)(root, "GATE.md");
38776
- const verityMd = (0, import_node_path49.join)(root, "VERITY.md");
38777
- if (!(0, import_node_fs64.existsSync)(gateMd) || (0, import_node_fs64.existsSync)(verityMd)) return;
38829
+ const gateMd = (0, import_node_path50.join)(root, "GATE.md");
38830
+ const verityMd = (0, import_node_path50.join)(root, "VERITY.md");
38831
+ if (!(0, import_node_fs65.existsSync)(gateMd) || (0, import_node_fs65.existsSync)(verityMd)) return;
38778
38832
  let moved = false;
38779
38833
  if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
38780
38834
  try {
@@ -38786,12 +38840,12 @@ function migrateStandardFile(root, actions) {
38786
38840
  if (!moved) moveFile(gateMd, verityMd);
38787
38841
  const content = readFileSyncSafe(verityMd);
38788
38842
  const refreshed = content.split("GATE.md").join("VERITY.md");
38789
- if (refreshed !== content) (0, import_node_fs64.writeFileSync)(verityMd, refreshed);
38843
+ if (refreshed !== content) (0, import_node_fs65.writeFileSync)(verityMd, refreshed);
38790
38844
  actions.push("Renamed GATE.md \u2192 VERITY.md");
38791
38845
  }
38792
38846
  async function migrateTelemetryHeaders(root, actions) {
38793
- const file = (0, import_node_path49.join)(root, ".claude", "settings.local.json");
38794
- if (!(0, import_node_fs64.existsSync)(file)) return;
38847
+ const file = (0, import_node_path50.join)(root, ".claude", "settings.local.json");
38848
+ if (!(0, import_node_fs65.existsSync)(file)) return;
38795
38849
  let settings;
38796
38850
  try {
38797
38851
  settings = JSON.parse(readFileSyncSafe(file) || "{}");
@@ -38839,14 +38893,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
38839
38893
  }
38840
38894
  if (toAppend.length > 0) {
38841
38895
  const sep6 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
38842
- (0, import_node_fs64.writeFileSync)(verityCreds, verityContent + sep6 + toAppend.join("\n") + "\n");
38896
+ (0, import_node_fs65.writeFileSync)(verityCreds, verityContent + sep6 + toAppend.join("\n") + "\n");
38843
38897
  }
38844
- (0, import_node_fs64.rmSync)(gateCreds, { force: true });
38898
+ (0, import_node_fs65.rmSync)(gateCreds, { force: true });
38845
38899
  return toAppend.length;
38846
38900
  }
38847
38901
  function readFileSyncSafe(path) {
38848
38902
  try {
38849
- return (0, import_node_fs64.readFileSync)(path, "utf-8");
38903
+ return (0, import_node_fs65.readFileSync)(path, "utf-8");
38850
38904
  } catch {
38851
38905
  return "";
38852
38906
  }
@@ -38861,35 +38915,35 @@ function hasStagedChanges(root) {
38861
38915
  }
38862
38916
  function moveDir(from, to) {
38863
38917
  try {
38864
- (0, import_node_fs64.renameSync)(from, to);
38918
+ (0, import_node_fs65.renameSync)(from, to);
38865
38919
  } catch (err2) {
38866
38920
  if (err2.code !== "EXDEV") throw err2;
38867
- (0, import_node_fs64.cpSync)(from, to, { recursive: true });
38868
- (0, import_node_fs64.rmSync)(from, { recursive: true, force: true });
38921
+ (0, import_node_fs65.cpSync)(from, to, { recursive: true });
38922
+ (0, import_node_fs65.rmSync)(from, { recursive: true, force: true });
38869
38923
  }
38870
38924
  }
38871
38925
  function moveFile(from, to) {
38872
38926
  try {
38873
- (0, import_node_fs64.renameSync)(from, to);
38927
+ (0, import_node_fs65.renameSync)(from, to);
38874
38928
  } catch (err2) {
38875
38929
  if (err2.code !== "EXDEV") throw err2;
38876
- (0, import_node_fs64.cpSync)(from, to);
38877
- (0, import_node_fs64.rmSync)(from, { force: true });
38930
+ (0, import_node_fs65.cpSync)(from, to);
38931
+ (0, import_node_fs65.rmSync)(from, { force: true });
38878
38932
  }
38879
38933
  }
38880
38934
  function carryLegacyContents(gateDir, verityDir) {
38881
38935
  let copied = 0;
38882
38936
  const walk2 = (relDir) => {
38883
- const srcDir = (0, import_node_path49.join)(gateDir, relDir);
38884
- for (const entry of (0, import_node_fs64.readdirSync)(srcDir)) {
38885
- const rel = relDir ? (0, import_node_path49.join)(relDir, entry) : entry;
38886
- const src = (0, import_node_path49.join)(gateDir, rel);
38887
- const dest = (0, import_node_path49.join)(verityDir, rel);
38888
- if ((0, import_node_fs64.statSync)(src).isDirectory()) {
38937
+ const srcDir = (0, import_node_path50.join)(gateDir, relDir);
38938
+ for (const entry of (0, import_node_fs65.readdirSync)(srcDir)) {
38939
+ const rel = relDir ? (0, import_node_path50.join)(relDir, entry) : entry;
38940
+ const src = (0, import_node_path50.join)(gateDir, rel);
38941
+ const dest = (0, import_node_path50.join)(verityDir, rel);
38942
+ if ((0, import_node_fs65.statSync)(src).isDirectory()) {
38889
38943
  walk2(rel);
38890
- } else if (!(0, import_node_fs64.existsSync)(dest)) {
38891
- (0, import_node_fs64.mkdirSync)((0, import_node_path49.dirname)(dest), { recursive: true });
38892
- (0, import_node_fs64.cpSync)(src, dest);
38944
+ } else if (!(0, import_node_fs65.existsSync)(dest)) {
38945
+ (0, import_node_fs65.mkdirSync)((0, import_node_path50.dirname)(dest), { recursive: true });
38946
+ (0, import_node_fs65.cpSync)(src, dest);
38893
38947
  copied++;
38894
38948
  }
38895
38949
  }
@@ -38898,22 +38952,22 @@ function carryLegacyContents(gateDir, verityDir) {
38898
38952
  return copied;
38899
38953
  }
38900
38954
  async function needsMigration(root = repoRoot()) {
38901
- const gateDir = (0, import_node_path49.join)(root, ".gate");
38902
- const verityDir = (0, import_node_path49.join)(root, ".verity");
38903
- if ((0, import_node_fs64.existsSync)(gateDir) && !(0, import_node_fs64.existsSync)(verityDir)) return true;
38904
- if ((0, import_node_fs64.existsSync)(gateDir) && (0, import_node_fs64.existsSync)(verityDir)) {
38905
- if ((0, import_node_fs64.existsSync)((0, import_node_path49.join)(gateDir, "credentials")) && !(0, import_node_fs64.existsSync)((0, import_node_path49.join)(verityDir, "credentials"))) {
38955
+ const gateDir = (0, import_node_path50.join)(root, ".gate");
38956
+ const verityDir = (0, import_node_path50.join)(root, ".verity");
38957
+ if ((0, import_node_fs65.existsSync)(gateDir) && !(0, import_node_fs65.existsSync)(verityDir)) return true;
38958
+ if ((0, import_node_fs65.existsSync)(gateDir) && (0, import_node_fs65.existsSync)(verityDir)) {
38959
+ if ((0, import_node_fs65.existsSync)((0, import_node_path50.join)(gateDir, "credentials")) && !(0, import_node_fs65.existsSync)((0, import_node_path50.join)(verityDir, "credentials"))) {
38906
38960
  return true;
38907
38961
  }
38908
- if ((0, import_node_fs64.existsSync)((0, import_node_path49.join)(gateDir, "memory")) && !(0, import_node_fs64.existsSync)((0, import_node_path49.join)(verityDir, "memory"))) {
38962
+ if ((0, import_node_fs65.existsSync)((0, import_node_path50.join)(gateDir, "memory")) && !(0, import_node_fs65.existsSync)((0, import_node_path50.join)(verityDir, "memory"))) {
38909
38963
  return true;
38910
38964
  }
38911
38965
  }
38912
- const claudeMd = (0, import_node_path49.join)(root, "CLAUDE.md");
38913
- if ((0, import_node_fs64.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
38966
+ const claudeMd = (0, import_node_path50.join)(root, "CLAUDE.md");
38967
+ if ((0, import_node_fs65.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
38914
38968
  return true;
38915
38969
  }
38916
- if ((0, import_node_fs64.existsSync)((0, import_node_path49.join)(root, "GATE.md")) && !(0, import_node_fs64.existsSync)((0, import_node_path49.join)(root, "VERITY.md"))) {
38970
+ if ((0, import_node_fs65.existsSync)((0, import_node_path50.join)(root, "GATE.md")) && !(0, import_node_fs65.existsSync)((0, import_node_path50.join)(root, "VERITY.md"))) {
38917
38971
  return true;
38918
38972
  }
38919
38973
  if (await hasLegacyHooksAt(root)) return true;
@@ -39194,11 +39248,11 @@ async function promptMultiSelect(question, choices, fallback) {
39194
39248
  }
39195
39249
 
39196
39250
  // src/lib/prove/lean-install.ts
39197
- var import_node_fs65 = require("node:fs");
39251
+ var import_node_fs66 = require("node:fs");
39198
39252
  var import_node_crypto21 = require("node:crypto");
39199
39253
  var import_node_child_process18 = require("node:child_process");
39200
39254
  var import_node_os10 = require("node:os");
39201
- var import_node_path50 = require("node:path");
39255
+ var import_node_path51 = require("node:path");
39202
39256
  var import_promises18 = require("node:stream/promises");
39203
39257
  var import_node_stream = require("node:stream");
39204
39258
  var RELEASES = "https://releases.lean-lang.org/lean4";
@@ -39209,10 +39263,10 @@ function freeBytes(dir) {
39209
39263
  let d = dir;
39210
39264
  for (let i2 = 0; i2 < 64; i2++) {
39211
39265
  try {
39212
- const st = (0, import_node_fs65.statfsSync)(d);
39266
+ const st = (0, import_node_fs66.statfsSync)(d);
39213
39267
  return Number(st.bavail) * Number(st.bsize);
39214
39268
  } catch {
39215
- const up = (0, import_node_path50.join)(d, "..");
39269
+ const up = (0, import_node_path51.join)(d, "..");
39216
39270
  if (up === d) return null;
39217
39271
  d = up;
39218
39272
  }
@@ -39234,7 +39288,7 @@ function expectedSha256(asset, version = pinnedVersion()) {
39234
39288
  function sha256File(path) {
39235
39289
  return new Promise((resolve9, reject) => {
39236
39290
  const hash = (0, import_node_crypto21.createHash)("sha256");
39237
- (0, import_node_fs65.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve9(hash.digest("hex"))).on("error", reject);
39291
+ (0, import_node_fs66.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve9(hash.digest("hex"))).on("error", reject);
39238
39292
  });
39239
39293
  }
39240
39294
  async function verifyDownload(zip, asset, version = pinnedVersion()) {
@@ -39254,7 +39308,7 @@ function leanAssetName(version = pinnedVersion()) {
39254
39308
  return suffix ? `lean-${v}-${suffix}.zip` : null;
39255
39309
  }
39256
39310
  function pinnedVersionDir(env = process.env) {
39257
- return (0, import_node_path50.join)(verityLeanHome(env), pinnedVersion());
39311
+ return (0, import_node_path51.join)(verityLeanHome(env), pinnedVersion());
39258
39312
  }
39259
39313
  function lakeBinary() {
39260
39314
  return (0, import_node_os10.platform)() === "win32" ? "lake.exe" : "lake";
@@ -39265,12 +39319,12 @@ function unzip(zip, dest) {
39265
39319
  for (const [cmd, args2] of attempts) {
39266
39320
  try {
39267
39321
  (0, import_node_child_process18.execFileSync)(cmd, args2, { stdio: ["ignore", "ignore", "pipe"], timeout: 15 * 6e4 });
39268
- if ((0, import_node_fs65.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
39322
+ if ((0, import_node_fs66.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
39269
39323
  errors.push(`${cmd}: produced nothing`);
39270
39324
  } catch (err2) {
39271
39325
  errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
39272
39326
  try {
39273
- for (const e of (0, import_node_fs65.readdirSync)(dest)) (0, import_node_fs65.rmSync)((0, import_node_path50.join)(dest, e), { recursive: true, force: true });
39327
+ for (const e of (0, import_node_fs66.readdirSync)(dest)) (0, import_node_fs66.rmSync)((0, import_node_path51.join)(dest, e), { recursive: true, force: true });
39274
39328
  } catch {
39275
39329
  }
39276
39330
  }
@@ -39296,7 +39350,7 @@ async function download(url, dest, onProgress, stallMs = DOWNLOAD_STALL_MS) {
39296
39350
  seen += chunk.length;
39297
39351
  onProgress(seen, total);
39298
39352
  });
39299
- await (0, import_promises18.pipeline)(stream, (0, import_node_fs65.createWriteStream)(dest), { signal: ctrl.signal });
39353
+ await (0, import_promises18.pipeline)(stream, (0, import_node_fs66.createWriteStream)(dest), { signal: ctrl.signal });
39300
39354
  } catch (err2) {
39301
39355
  if (ctrl.signal.aborted) throw new Error(`download stalled: nothing received for ${Math.round(stallMs / 1e3)} s`);
39302
39356
  throw err2;
@@ -39346,10 +39400,10 @@ async function installLean(opts = {}) {
39346
39400
  const gb = (n) => (n / 1024 ** 3).toFixed(1);
39347
39401
  return { ok: false, error: `not enough disk space for Lean: ${gb(free)} GB free where ${home} lives, needs about ${gb(needed)} GB` };
39348
39402
  }
39349
- const tmp = (0, import_node_path50.join)(home, ".tmp");
39350
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39351
- (0, import_node_fs65.mkdirSync)(tmp, { recursive: true });
39352
- const zip = (0, import_node_path50.join)(tmp, asset);
39403
+ const tmp = (0, import_node_path51.join)(home, ".tmp");
39404
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39405
+ (0, import_node_fs66.mkdirSync)(tmp, { recursive: true });
39406
+ const zip = (0, import_node_path51.join)(tmp, asset);
39353
39407
  say(`downloading ${url}`);
39354
39408
  let lastPct = -1;
39355
39409
  try {
@@ -39362,40 +39416,40 @@ async function installLean(opts = {}) {
39362
39416
  }
39363
39417
  });
39364
39418
  } catch (err2) {
39365
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39419
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39366
39420
  return { ok: false, error: err2.message };
39367
39421
  }
39368
39422
  say("verifying checksum");
39369
39423
  const verified = await verifyDownload(zip, asset);
39370
39424
  if (!verified.ok) {
39371
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39425
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39372
39426
  return { ok: false, error: verified.error };
39373
39427
  }
39374
39428
  say("unpacking (this takes a minute)");
39375
- const unpack = (0, import_node_path50.join)(tmp, "unpack");
39376
- (0, import_node_fs65.mkdirSync)(unpack);
39429
+ const unpack = (0, import_node_path51.join)(tmp, "unpack");
39430
+ (0, import_node_fs66.mkdirSync)(unpack);
39377
39431
  const unpacked = unzip(zip, unpack);
39378
39432
  if (!unpacked.ok) {
39379
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39433
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39380
39434
  return { ok: false, error: `unpack failed: ${unpacked.error}` };
39381
39435
  }
39382
- const entries = (0, import_node_fs65.readdirSync)(unpack);
39383
- const top = entries.length === 1 && (0, import_node_fs65.statSync)((0, import_node_path50.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path50.join)(unpack, entries[0]) : unpack;
39384
- if (!(0, import_node_fs65.existsSync)((0, import_node_path50.join)(top, "bin", lakeBinary()))) {
39385
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39436
+ const entries = (0, import_node_fs66.readdirSync)(unpack);
39437
+ const top = entries.length === 1 && (0, import_node_fs66.statSync)((0, import_node_path51.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path51.join)(unpack, entries[0]) : unpack;
39438
+ if (!(0, import_node_fs66.existsSync)((0, import_node_path51.join)(top, "bin", lakeBinary()))) {
39439
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39386
39440
  return { ok: false, error: "the archive did not contain bin/lake" };
39387
39441
  }
39388
- (0, import_node_fs65.rmSync)(dir, { recursive: true, force: true });
39389
- (0, import_node_fs65.mkdirSync)(home, { recursive: true });
39390
- (0, import_node_fs65.renameSync)(top, dir);
39391
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39442
+ (0, import_node_fs66.rmSync)(dir, { recursive: true, force: true });
39443
+ (0, import_node_fs66.mkdirSync)(home, { recursive: true });
39444
+ (0, import_node_fs66.renameSync)(top, dir);
39445
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39392
39446
  return { ok: true, dir };
39393
39447
  }
39394
39448
 
39395
39449
  // src/lib/remote-config.ts
39396
- var import_node_fs66 = require("node:fs");
39450
+ var import_node_fs67 = require("node:fs");
39397
39451
  var import_promises19 = require("node:fs/promises");
39398
- var import_node_path51 = require("node:path");
39452
+ var import_node_path52 = require("node:path");
39399
39453
  var import_yaml5 = __toESM2(require_dist());
39400
39454
  var IGNORE_RIDER = "verityignore";
39401
39455
  async function fetchRemoteSetup(opts) {
@@ -39440,7 +39494,7 @@ async function adoptRemoteSetup(found, opts) {
39440
39494
  written.push(STANDARD_FILE);
39441
39495
  if (rider !== null) {
39442
39496
  const localIgnore = projectPath(VERITYIGNORE_FILE);
39443
- if (!(0, import_node_fs66.existsSync)(localIgnore)) {
39497
+ if (!(0, import_node_fs67.existsSync)(localIgnore)) {
39444
39498
  await writeOut(VERITYIGNORE_FILE, rider);
39445
39499
  written.push(VERITYIGNORE_FILE);
39446
39500
  } else {
@@ -39473,7 +39527,7 @@ async function adoptRemoteSetup(found, opts) {
39473
39527
  }
39474
39528
  async function writeOut(relative6, body2) {
39475
39529
  const target = projectPath(relative6);
39476
- await (0, import_promises19.mkdir)((0, import_node_path51.dirname)(target), { recursive: true });
39530
+ await (0, import_promises19.mkdir)((0, import_node_path52.dirname)(target), { recursive: true });
39477
39531
  await (0, import_promises19.writeFile)(target, body2);
39478
39532
  }
39479
39533
  function describeRemote(found) {
@@ -39590,15 +39644,15 @@ async function runOptionalAuth(resolution, opts = {}) {
39590
39644
  }
39591
39645
  function resolveDataDir2() {
39592
39646
  const candidates2 = [
39593
- (0, import_node_path52.join)(__dirname, "..", "data"),
39647
+ (0, import_node_path53.join)(__dirname, "..", "data"),
39594
39648
  // installed: node_modules/@codacy/verity-cli/data
39595
- (0, import_node_path52.join)(__dirname, "..", "..", "data"),
39649
+ (0, import_node_path53.join)(__dirname, "..", "..", "data"),
39596
39650
  // edge case: nested resolution
39597
- (0, import_node_path52.join)(process.cwd(), "cli", "data")
39651
+ (0, import_node_path53.join)(process.cwd(), "cli", "data")
39598
39652
  // local dev: running from repo root
39599
39653
  ];
39600
39654
  for (const candidate of candidates2) {
39601
- if ((0, import_node_fs67.existsSync)((0, import_node_path52.join)(candidate, "skills"))) {
39655
+ if ((0, import_node_fs68.existsSync)((0, import_node_path53.join)(candidate, "skills"))) {
39602
39656
  return candidate;
39603
39657
  }
39604
39658
  }
@@ -39614,9 +39668,9 @@ async function skillIsCurrent(src, dest) {
39614
39668
  const list2 = (dir) => {
39615
39669
  const out2 = [];
39616
39670
  const walk2 = (d, prefix) => {
39617
- for (const e of (0, import_node_fs67.readdirSync)(d, { withFileTypes: true })) {
39671
+ for (const e of (0, import_node_fs68.readdirSync)(d, { withFileTypes: true })) {
39618
39672
  const rel = prefix ? `${prefix}/${e.name}` : e.name;
39619
- if (e.isDirectory()) walk2((0, import_node_path52.join)(d, e.name), rel);
39673
+ if (e.isDirectory()) walk2((0, import_node_path53.join)(d, e.name), rel);
39620
39674
  else if (e.isFile()) out2.push(rel);
39621
39675
  }
39622
39676
  };
@@ -39627,8 +39681,8 @@ async function skillIsCurrent(src, dest) {
39627
39681
  const shipped = list2(src);
39628
39682
  if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
39629
39683
  for (const rel of shipped) {
39630
- const a = await (0, import_promises20.readFile)((0, import_node_path52.join)(src, rel), "utf-8");
39631
- const b = await (0, import_promises20.readFile)((0, import_node_path52.join)(dest, rel), "utf-8");
39684
+ const a = await (0, import_promises20.readFile)((0, import_node_path53.join)(src, rel), "utf-8");
39685
+ const b = await (0, import_promises20.readFile)((0, import_node_path53.join)(dest, rel), "utf-8");
39632
39686
  if (a !== b) return false;
39633
39687
  }
39634
39688
  return true;
@@ -39831,7 +39885,7 @@ async function synthesizeLocally(opts) {
39831
39885
  async function healStaleAnalysisConfig(globals) {
39832
39886
  const configPath = projectPath(CODACY_CONFIG_FILE);
39833
39887
  const standardPath = projectPath(STANDARD_FILE);
39834
- if (!(0, import_node_fs67.existsSync)(configPath) || !(0, import_node_fs67.existsSync)(standardPath)) return;
39888
+ if (!(0, import_node_fs68.existsSync)(configPath) || !(0, import_node_fs68.existsSync)(standardPath)) return;
39835
39889
  const validation = validatePatternIds();
39836
39890
  if (validation.status !== "invalid") return;
39837
39891
  printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
@@ -39928,17 +39982,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
39928
39982
  async function installSkills(force, step) {
39929
39983
  step("Installing skills");
39930
39984
  const dataDir = resolveDataDir2();
39931
- const skillsSource = (0, import_node_path52.join)(dataDir, "skills");
39985
+ const skillsSource = (0, import_node_path53.join)(dataDir, "skills");
39932
39986
  const skillsDest = ".claude/skills";
39933
39987
  let skillsInstalled = 0;
39934
39988
  for (const skill of SKILLS) {
39935
- const src = (0, import_node_path52.join)(skillsSource, skill);
39936
- const dest = (0, import_node_path52.join)(skillsDest, skill);
39937
- if (!(0, import_node_fs67.existsSync)(src)) {
39989
+ const src = (0, import_node_path53.join)(skillsSource, skill);
39990
+ const dest = (0, import_node_path53.join)(skillsDest, skill);
39991
+ if (!(0, import_node_fs68.existsSync)(src)) {
39938
39992
  printWarn(` Skill data not found: ${skill}`);
39939
39993
  continue;
39940
39994
  }
39941
- if ((0, import_node_fs67.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
39995
+ if ((0, import_node_fs68.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
39942
39996
  skillsInstalled++;
39943
39997
  continue;
39944
39998
  }
@@ -40087,7 +40141,7 @@ async function offerFormalVerification(defaultsOnly, pluginMode) {
40087
40141
  if (!toolchain) {
40088
40142
  const dir = pinnedVersionDir();
40089
40143
  const home = (0, import_node_os11.homedir)();
40090
- const shown = dir.startsWith(home + import_node_path52.sep) ? `~${dir.slice(home.length)}` : dir;
40144
+ const shown = dir.startsWith(home + import_node_path53.sep) ? `~${dir.slice(home.length)}` : dir;
40091
40145
  console.log("");
40092
40146
  console.log(` "yes" installs Lean 4 (${LEAN_DOWNLOAD_SIZE}) into ${shown}`);
40093
40147
  }
@@ -40146,7 +40200,7 @@ function registerInitCommand(program2) {
40146
40200
  const staleMarker = clearStalePluginMarker();
40147
40201
  const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
40148
40202
  const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
40149
- const isProject = projectMarkers.some((m) => (0, import_node_fs67.existsSync)(m));
40203
+ const isProject = projectMarkers.some((m) => (0, import_node_fs68.existsSync)(m));
40150
40204
  if (!isProject) {
40151
40205
  printError("No project detected in the current directory.");
40152
40206
  printInfo('Run "verity init" from your project root.');
@@ -40249,7 +40303,7 @@ function registerInitCommand(program2) {
40249
40303
  untrackMemory: opts.untrackMemory === true,
40250
40304
  untrackState: opts.untrackState === true
40251
40305
  });
40252
- const globalVerityDir = (0, import_node_path52.join)(process.env.HOME ?? "", ".verity");
40306
+ const globalVerityDir = (0, import_node_path53.join)(process.env.HOME ?? "", ".verity");
40253
40307
  await (0, import_promises20.mkdir)(globalVerityDir, { recursive: true });
40254
40308
  console.log("");
40255
40309
  step("Wiring Claude Code hooks");
@@ -40324,7 +40378,7 @@ function registerInitCommand(program2) {
40324
40378
  }
40325
40379
  step("Your project's Standard");
40326
40380
  let haveStandard = false;
40327
- if ((0, import_node_fs67.existsSync)(projectPath(STANDARD_FILE))) {
40381
+ if ((0, import_node_fs68.existsSync)(projectPath(STANDARD_FILE))) {
40328
40382
  printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
40329
40383
  haveStandard = true;
40330
40384
  } else {
@@ -40354,7 +40408,7 @@ function registerInitCommand(program2) {
40354
40408
  ...telemetryChoice ? { telemetry: telemetryChoice } : {},
40355
40409
  init: {
40356
40410
  completed_at: (/* @__PURE__ */ new Date()).toISOString(),
40357
- cli_version: true ? "0.34.0-experimental.ec5aae9" : "dev"
40411
+ cli_version: true ? "0.34.1-experimental.199c728" : "dev"
40358
40412
  }
40359
40413
  });
40360
40414
  } catch (err2) {
@@ -40404,8 +40458,8 @@ function registerInitCommand(program2) {
40404
40458
  }
40405
40459
 
40406
40460
  // src/commands/uninstall.ts
40407
- var import_node_fs68 = require("node:fs");
40408
- var import_node_path53 = require("node:path");
40461
+ var import_node_fs69 = require("node:fs");
40462
+ var import_node_path54 = require("node:path");
40409
40463
  function registerUninstallCommand(program2) {
40410
40464
  program2.command("uninstall").description("Remove Verity from this project (skills, hooks, .verity/, VERITY.md)").option("--dry-run", "Show what would be removed without doing it").option("--purge-global", "Also remove ~/.verity/ (deletes saved tokens \u2014 reconnect requires re-registration)").option("--keep-verity-md", "Keep the project root VERITY.md file").action(async (opts) => {
40411
40465
  const dryRun = opts.dryRun ?? false;
@@ -40414,11 +40468,11 @@ function registerUninstallCommand(program2) {
40414
40468
  const actions = [];
40415
40469
  const skillsRoot = projectPath(".claude/skills");
40416
40470
  for (const name2 of PROJECT_SKILL_NAMES) {
40417
- const dir = (0, import_node_path53.join)(skillsRoot, name2);
40418
- if ((0, import_node_fs68.existsSync)(dir)) {
40471
+ const dir = (0, import_node_path54.join)(skillsRoot, name2);
40472
+ if ((0, import_node_fs69.existsSync)(dir)) {
40419
40473
  actions.push({
40420
40474
  label: `Remove .claude/skills/${name2}/`,
40421
- apply: () => (0, import_node_fs68.rmSync)(dir, { recursive: true, force: true })
40475
+ apply: () => (0, import_node_fs69.rmSync)(dir, { recursive: true, force: true })
40422
40476
  });
40423
40477
  }
40424
40478
  }
@@ -40432,24 +40486,24 @@ function registerUninstallCommand(program2) {
40432
40486
  });
40433
40487
  }
40434
40488
  const verityDir = projectPath(VERITY_DIR);
40435
- if ((0, import_node_fs68.existsSync)(verityDir)) {
40489
+ if ((0, import_node_fs69.existsSync)(verityDir)) {
40436
40490
  actions.push({
40437
40491
  label: `Remove ${VERITY_DIR}/`,
40438
- apply: () => (0, import_node_fs68.rmSync)(verityDir, { recursive: true, force: true })
40492
+ apply: () => (0, import_node_fs69.rmSync)(verityDir, { recursive: true, force: true })
40439
40493
  });
40440
40494
  }
40441
40495
  if (!keepVerityMd) {
40442
40496
  const verityMd = projectPath(VERITY_MD_FILE);
40443
- if ((0, import_node_fs68.existsSync)(verityMd)) {
40497
+ if ((0, import_node_fs69.existsSync)(verityMd)) {
40444
40498
  actions.push({
40445
40499
  label: `Remove ${VERITY_MD_FILE}`,
40446
- apply: () => (0, import_node_fs68.rmSync)(verityMd, { force: true })
40500
+ apply: () => (0, import_node_fs69.rmSync)(verityMd, { force: true })
40447
40501
  });
40448
40502
  }
40449
40503
  }
40450
40504
  const cleanupEmptyDir = (path) => {
40451
- if ((0, import_node_fs68.existsSync)(path) && (0, import_node_fs68.statSync)(path).isDirectory() && (0, import_node_fs68.readdirSync)(path).length === 0) {
40452
- (0, import_node_fs68.rmdirSync)(path);
40505
+ if ((0, import_node_fs69.existsSync)(path) && (0, import_node_fs69.statSync)(path).isDirectory() && (0, import_node_fs69.readdirSync)(path).length === 0) {
40506
+ (0, import_node_fs69.rmdirSync)(path);
40453
40507
  }
40454
40508
  };
40455
40509
  actions.push({
@@ -40460,11 +40514,11 @@ function registerUninstallCommand(program2) {
40460
40514
  }
40461
40515
  });
40462
40516
  const home = process.env.HOME ?? "";
40463
- const globalVerityDir = (0, import_node_path53.join)(home, ".verity");
40464
- if (purgeGlobal && (0, import_node_fs68.existsSync)(globalVerityDir)) {
40517
+ const globalVerityDir = (0, import_node_path54.join)(home, ".verity");
40518
+ if (purgeGlobal && (0, import_node_fs69.existsSync)(globalVerityDir)) {
40465
40519
  actions.push({
40466
40520
  label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
40467
- apply: () => (0, import_node_fs68.rmSync)(globalVerityDir, { recursive: true, force: true })
40521
+ apply: () => (0, import_node_fs69.rmSync)(globalVerityDir, { recursive: true, force: true })
40468
40522
  });
40469
40523
  }
40470
40524
  if (actions.length === 0) {
@@ -40658,8 +40712,8 @@ function registerTaskCommands(program2) {
40658
40712
  }
40659
40713
 
40660
40714
  // src/commands/reset.ts
40661
- var import_node_fs69 = require("node:fs");
40662
- var import_node_path54 = require("node:path");
40715
+ var import_node_fs70 = require("node:fs");
40716
+ var import_node_path55 = require("node:path");
40663
40717
  function registerResetCommand(program2) {
40664
40718
  program2.command("reset").description("Close the current task and clear transient state").option("--keep-task", "Only purge caches; leave the current task open").option("--all", "Also purge diagnostic logs (.verity/.logs/)").action(async (opts) => {
40665
40719
  const globals = program2.opts();
@@ -40696,11 +40750,11 @@ function registerResetCommand(program2) {
40696
40750
  }
40697
40751
  const cacheDir = projectPath(CACHE_DIR);
40698
40752
  let purged = 0;
40699
- if ((0, import_node_fs69.existsSync)(cacheDir)) {
40700
- for (const entry of (0, import_node_fs69.readdirSync)(cacheDir)) {
40753
+ if ((0, import_node_fs70.existsSync)(cacheDir)) {
40754
+ for (const entry of (0, import_node_fs70.readdirSync)(cacheDir)) {
40701
40755
  if (entry.startsWith("pending-")) {
40702
40756
  try {
40703
- (0, import_node_fs69.unlinkSync)((0, import_node_path54.join)(cacheDir, entry));
40757
+ (0, import_node_fs70.unlinkSync)((0, import_node_path55.join)(cacheDir, entry));
40704
40758
  purged++;
40705
40759
  } catch {
40706
40760
  }
@@ -40715,19 +40769,19 @@ function registerResetCommand(program2) {
40715
40769
  projectPath(`${VERITY_DIR}/.last-analysis`)
40716
40770
  ];
40717
40771
  for (const file of filesToClear) {
40718
- if ((0, import_node_fs69.existsSync)(file)) {
40772
+ if ((0, import_node_fs70.existsSync)(file)) {
40719
40773
  try {
40720
- (0, import_node_fs69.writeFileSync)(file, "");
40774
+ (0, import_node_fs70.writeFileSync)(file, "");
40721
40775
  } catch {
40722
40776
  }
40723
40777
  }
40724
40778
  }
40725
40779
  if (opts.all) {
40726
40780
  const logsDir = projectPath(`${VERITY_DIR}/.logs`);
40727
- if ((0, import_node_fs69.existsSync)(logsDir)) {
40728
- for (const entry of (0, import_node_fs69.readdirSync)(logsDir)) {
40781
+ if ((0, import_node_fs70.existsSync)(logsDir)) {
40782
+ for (const entry of (0, import_node_fs70.readdirSync)(logsDir)) {
40729
40783
  try {
40730
- (0, import_node_fs69.unlinkSync)((0, import_node_path54.join)(logsDir, entry));
40784
+ (0, import_node_fs70.unlinkSync)((0, import_node_path55.join)(logsDir, entry));
40731
40785
  } catch {
40732
40786
  }
40733
40787
  }
@@ -40739,7 +40793,7 @@ function registerResetCommand(program2) {
40739
40793
  }
40740
40794
 
40741
40795
  // src/commands/reflect.ts
40742
- var import_node_fs70 = require("node:fs");
40796
+ var import_node_fs71 = require("node:fs");
40743
40797
 
40744
40798
  // src/lib/reflection-globs.ts
40745
40799
  var MAX_GLOBS = 6;
@@ -40777,7 +40831,7 @@ async function writeNodeToDisk(args2) {
40777
40831
  { treePaths: listTrackedFiles(), recordBaseline: false }
40778
40832
  );
40779
40833
  if (written === 0) return false;
40780
- return (0, import_node_fs70.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
40834
+ return (0, import_node_fs71.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
40781
40835
  } catch {
40782
40836
  return false;
40783
40837
  }
@@ -41214,9 +41268,9 @@ function registerRunCommand(program2) {
41214
41268
  }
41215
41269
 
41216
41270
  // src/commands/telemetry.ts
41217
- var import_node_fs71 = require("node:fs");
41271
+ var import_node_fs72 = require("node:fs");
41218
41272
  async function recordTelemetryChoice(choice) {
41219
- if (!(0, import_node_fs71.existsSync)(projectPath(SETUP_STATE_FILE))) return;
41273
+ if (!(0, import_node_fs72.existsSync)(projectPath(SETUP_STATE_FILE))) return;
41220
41274
  try {
41221
41275
  if ((await readSetupState())?.telemetry === choice) return;
41222
41276
  await writeSetupState({ telemetry: choice });
@@ -41293,8 +41347,8 @@ function registerTelemetryCommands(program2) {
41293
41347
  }
41294
41348
 
41295
41349
  // src/commands/prove.ts
41296
- var import_node_fs72 = require("node:fs");
41297
- var import_node_path55 = require("node:path");
41350
+ var import_node_fs73 = require("node:fs");
41351
+ var import_node_path56 = require("node:path");
41298
41352
 
41299
41353
  // src/lib/prove/hint-pool.ts
41300
41354
  var STOP2 = /* @__PURE__ */ new Set([
@@ -41436,7 +41490,7 @@ function registerProveCommand(program2) {
41436
41490
  process.exit(2);
41437
41491
  }
41438
41492
  const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
41439
- let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path55.relative)(root, (0, import_node_path55.resolve)(p)) || ".") });
41493
+ let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path56.relative)(root, (0, import_node_path56.resolve)(p)) || ".") });
41440
41494
  if (opts.hint && paths.length === 0) {
41441
41495
  const hit = hintMatches(root, opts.hint);
41442
41496
  if (hit.files.length > 0) {
@@ -41490,7 +41544,7 @@ function registerProveCommand(program2) {
41490
41544
  });
41491
41545
  prove.command("check [model]").description("Elaborate a model (or every model) with the local Lean toolchain and report each property").option("--timeout <ms>", "Per-model timeout in ms", "120000").option("--json", "Machine-readable output").action((model, opts) => {
41492
41546
  const root = repoRoot();
41493
- if (!(0, import_node_fs72.existsSync)((0, import_node_path55.join)(root, PROOFS_DIR, "lakefile.toml"))) {
41547
+ if (!(0, import_node_fs73.existsSync)((0, import_node_path56.join)(root, PROOFS_DIR, "lakefile.toml"))) {
41494
41548
  printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
41495
41549
  process.exit(2);
41496
41550
  }
@@ -41514,7 +41568,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
41514
41568
  const reports = [];
41515
41569
  for (const f of files) {
41516
41570
  const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
41517
- report.file = (0, import_node_path55.relative)(root, f);
41571
+ report.file = (0, import_node_path56.relative)(root, f);
41518
41572
  reports.push(report);
41519
41573
  try {
41520
41574
  writeResult(root, report);
@@ -41552,7 +41606,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
41552
41606
  printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
41553
41607
  process.exit(2);
41554
41608
  }
41555
- if (!(0, import_node_fs72.existsSync)((0, import_node_path55.join)(root, PROOFS_DIR, "lakefile.toml"))) {
41609
+ if (!(0, import_node_fs73.existsSync)((0, import_node_path56.join)(root, PROOFS_DIR, "lakefile.toml"))) {
41556
41610
  printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
41557
41611
  process.exit(2);
41558
41612
  }
@@ -41583,7 +41637,7 @@ ${report.error ?? ""}`);
41583
41637
  printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
41584
41638
  return;
41585
41639
  }
41586
- const modelSource = readRegularFileInRoot(root, (0, import_node_path55.relative)(root, file), 512 * 1024);
41640
+ const modelSource = readRegularFileInRoot(root, (0, import_node_path56.relative)(root, file), 512 * 1024);
41587
41641
  if (!opts.json) printInfo(`replaying ${targets.length} counterexample(s) of ${model} in network-less containers (${Math.min(targets.length, REPLAY_CONCURRENCY)} at a time)\u2026`);
41588
41642
  const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
41589
41643
  const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
@@ -41603,7 +41657,7 @@ ${report.error ?? ""}`);
41603
41657
  });
41604
41658
  prove.command("auto [files...]").description("The formal phase the pre-push guard runs: select one risky symbol among changed files, generate a model, check it, replay counterexamples (default files: the commits ahead of upstream)").option("--deadline <ms>", "Budget for the whole phase", "170000").option("--json", "Machine-readable output").action(async (paths, opts) => {
41605
41659
  const root = repoRoot();
41606
- let files = paths.map((p) => (0, import_node_path55.relative)(root, (0, import_node_path55.resolve)(p)));
41660
+ let files = paths.map((p) => (0, import_node_path56.relative)(root, (0, import_node_path56.resolve)(p)));
41607
41661
  if (files.length === 0) {
41608
41662
  const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
41609
41663
  const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
@@ -41675,7 +41729,7 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
41675
41729
  let revise;
41676
41730
  if (opts.revise) {
41677
41731
  const existing = resolveModelFile(root, opts.revise);
41678
- const src = existing ? readRegularFileInRoot(root, (0, import_node_path55.relative)(root, existing), 64 * 1024) : null;
41732
+ const src = existing ? readRegularFileInRoot(root, (0, import_node_path56.relative)(root, existing), 64 * 1024) : null;
41679
41733
  if (!src || !src.ok || !opts.note) {
41680
41734
  printError("--revise needs an existing model under Models/ and --note - with what the replay showed on stdin");
41681
41735
  process.exit(2);
@@ -41688,21 +41742,22 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
41688
41742
  printError("Verity library did not build");
41689
41743
  process.exit(2);
41690
41744
  }
41691
- const deps = defaultDeps({ auth: auth2 ?? void 0, apiKey: process.env.VERITY_PROVE_DIRECT === "1" ? process.env.OPENAI_API_KEY : void 0, toolchain: tc, tier: "deep" });
41745
+ const deps = await onDemandDeps(root, { auth: auth2 ?? void 0, apiKey: process.env.VERITY_PROVE_DIRECT === "1" ? process.env.OPENAI_API_KEY : void 0, toolchain: tc });
41692
41746
  if (!opts.json) printInfo(`asking the Verity service for a model of ${symbol || `${file}:${opts.lines}`} \u2026`);
41693
41747
  const out2 = await generateAndCheck(root, { file, symbol: symbol || `${file}:${opts.lines}`, lines, hint: opts.hint, revise }, { deps, maxRounds: 3 });
41694
41748
  if (!out2.ok) {
41695
41749
  if (opts.json) printJson(out2);
41696
- else printError(`${out2.error} (${out2.rounds} round(s)${out2.costUsd ? `, $${out2.costUsd.toFixed(2)}` : ""}) \u2014 write the model by hand (Models/README.md) or narrow the target`);
41750
+ else printError(out2.rounds === 0 ? out2.error : `${out2.error} (${out2.rounds} round(s)${out2.costUsd ? `, $${out2.costUsd.toFixed(2)}` : ""}) \u2014 write the model by hand (Models/README.md) or narrow the target`);
41697
41751
  process.exit(2);
41698
41752
  }
41753
+ if (out2.warning && !opts.json) printWarn(out2.warning);
41699
41754
  try {
41700
41755
  writeResult(root, out2.report);
41701
41756
  } catch (err2) {
41702
41757
  if (!(err2 instanceof SafeWriteError)) throw err2;
41703
41758
  }
41704
41759
  if (opts.json) {
41705
- printJson({ name: out2.name, file: out2.file, rounds: out2.rounds, cost_usd: out2.costUsd, report: { ...out2.report, passes: reportPasses(out2.report), summary: summarize(out2.report) } });
41760
+ printJson({ name: out2.name, file: out2.file, rounds: out2.rounds, cost_usd: out2.costUsd, ...out2.warning ? { warning: out2.warning } : {}, report: { ...out2.report, passes: reportPasses(out2.report), summary: summarize(out2.report) } });
41706
41761
  return;
41707
41762
  }
41708
41763
  printInfo(`wrote ${out2.file} (${out2.rounds} round(s)${out2.costUsd ? `, $${out2.costUsd.toFixed(2)}` : ""})`);
@@ -41714,8 +41769,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
41714
41769
  });
41715
41770
  prove.command("waive <file>").description("Dismiss the remembered formal finding(s) on a file for its current bytes \u2014 the accepted-risk path for a formal block").requiredOption("--reason <text>", "The human disposition this records (reviewer finding, ADR, \u2026)").action((file, opts) => {
41716
41771
  const root = repoRoot();
41717
- const rel0 = (0, import_node_path55.relative)(root, (0, import_node_path55.isAbsolute)(file) ? file : (0, import_node_path55.join)(root, file)).replace(/\\/g, "/");
41718
- const rel = rel0.startsWith("..") || (0, import_node_path55.isAbsolute)(rel0) ? null : rel0;
41772
+ const rel0 = (0, import_node_path56.relative)(root, (0, import_node_path56.isAbsolute)(file) ? file : (0, import_node_path56.join)(root, file)).replace(/\\/g, "/");
41773
+ const rel = rel0.startsWith("..") || (0, import_node_path56.isAbsolute)(rel0) ? null : rel0;
41719
41774
  if (!rel) {
41720
41775
  printError(`${file} is not inside this repository`);
41721
41776
  process.exit(2);
@@ -41731,8 +41786,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
41731
41786
  });
41732
41787
  prove.command("hash <file>").description("Print the sha256 of a file, for a model header (Verity.model \u2026 sha256). Path is REPO-relative, as in the header").action((file) => {
41733
41788
  const root = repoRoot();
41734
- const rel = (0, import_node_path55.relative)(root, (0, import_node_path55.isAbsolute)(file) ? file : (0, import_node_path55.join)(root, file));
41735
- const digest = rel.startsWith("..") || (0, import_node_path55.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
41789
+ const rel = (0, import_node_path56.relative)(root, (0, import_node_path56.isAbsolute)(file) ? file : (0, import_node_path56.join)(root, file));
41790
+ const digest = rel.startsWith("..") || (0, import_node_path56.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
41736
41791
  if (!digest) {
41737
41792
  printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
41738
41793
  process.exit(2);
@@ -41766,10 +41821,10 @@ function refreshScaffold(root) {
41766
41821
  }
41767
41822
 
41768
41823
  // src/commands/lean.ts
41769
- var import_node_fs73 = require("node:fs");
41824
+ var import_node_fs74 = require("node:fs");
41770
41825
  var import_node_child_process20 = require("node:child_process");
41771
41826
  var import_node_os12 = require("node:os");
41772
- var import_node_path56 = require("node:path");
41827
+ var import_node_path57 = require("node:path");
41773
41828
  function registerLeanCommand(program2) {
41774
41829
  const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
41775
41830
  lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
@@ -41786,7 +41841,7 @@ function registerLeanCommand(program2) {
41786
41841
  const managed = pinnedVersionDir();
41787
41842
  const matches = version ? version.includes(pin) : false;
41788
41843
  if (opts.json) {
41789
- printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs73.existsSync)((0, import_node_path56.join)(managed, "bin")), asset: leanAssetName() });
41844
+ printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs74.existsSync)((0, import_node_path57.join)(managed, "bin")), asset: leanAssetName() });
41790
41845
  return;
41791
41846
  }
41792
41847
  printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
@@ -41804,7 +41859,7 @@ function registerLeanCommand(program2) {
41804
41859
  process.exit(2);
41805
41860
  }
41806
41861
  const dir = pinnedVersionDir();
41807
- if ((0, import_node_fs73.existsSync)((0, import_node_path56.join)(dir, "bin", "lake")) && !opts.force) {
41862
+ if ((0, import_node_fs74.existsSync)((0, import_node_path57.join)(dir, "bin", "lake")) && !opts.force) {
41808
41863
  printInfo(`already installed at ${dir}`);
41809
41864
  return;
41810
41865
  }
@@ -41840,18 +41895,18 @@ function registerLeanCommand(program2) {
41840
41895
  });
41841
41896
  lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
41842
41897
  const dir = pinnedVersionDir();
41843
- if (!(0, import_node_fs73.existsSync)(dir)) {
41898
+ if (!(0, import_node_fs74.existsSync)(dir)) {
41844
41899
  printInfo("nothing to remove");
41845
41900
  return;
41846
41901
  }
41847
- (0, import_node_fs73.rmSync)(dir, { recursive: true, force: true });
41902
+ (0, import_node_fs74.rmSync)(dir, { recursive: true, force: true });
41848
41903
  printInfo(`removed ${dir}`);
41849
41904
  });
41850
41905
  }
41851
41906
 
41852
41907
  // src/cli.ts
41853
- program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.ec5aae9").option("--token <token>", "Override authentication token").option("--service-url <url>", "Override service URL").option("--verbose", "Log HTTP requests/responses to stderr").hook("preAction", async (_thisCommand, actionCommand) => {
41854
- installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.ec5aae9");
41908
+ program.name("verity").description("CLI for Verity quality gate service").version("0.34.1-experimental.199c728").option("--token <token>", "Override authentication token").option("--service-url <url>", "Override service URL").option("--verbose", "Log HTTP requests/responses to stderr").hook("preAction", async (_thisCommand, actionCommand) => {
41909
+ installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.1-experimental.199c728");
41855
41910
  setUserNamedServiceUrl(program.opts().serviceUrl);
41856
41911
  try {
41857
41912
  await foldLegacyLocalCredential();