@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.
- package/CHANGELOG.md +27 -0
- package/bin/verity.js +314 -259
- 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.
|
|
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
|
|
33438
|
-
var
|
|
33437
|
+
var import_node_fs56 = require("node:fs");
|
|
33438
|
+
var import_node_path43 = require("node:path");
|
|
33439
33439
|
|
|
33440
|
-
// src/lib/
|
|
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,
|
|
33469
|
-
return ALL.filter((name2) => (0,
|
|
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,
|
|
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
|
|
33506
|
-
const
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
33738
|
-
var
|
|
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
|
|
33742
|
-
var
|
|
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,
|
|
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
|
|
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
|
|
35627
|
+
var import_node_fs61 = require("node:fs");
|
|
35595
35628
|
var import_node_os9 = require("node:os");
|
|
35596
|
-
var
|
|
35629
|
+
var import_node_path47 = require("node:path");
|
|
35597
35630
|
|
|
35598
35631
|
// src/lib/prove/scaffold.ts
|
|
35599
|
-
var
|
|
35600
|
-
var
|
|
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
|
|
35636
|
+
var import_node_fs59 = require("node:fs");
|
|
35604
35637
|
var import_node_crypto15 = require("node:crypto");
|
|
35605
|
-
var
|
|
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 =
|
|
35647
|
+
var FLAGS3 = import_node_fs59.constants;
|
|
35615
35648
|
var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
|
|
35616
35649
|
function assertPlainRelative(rel) {
|
|
35617
|
-
if (!rel || (0,
|
|
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,
|
|
35659
|
+
cur = (0, import_node_path45.join)(cur, part);
|
|
35627
35660
|
let st;
|
|
35628
35661
|
try {
|
|
35629
|
-
st = (0,
|
|
35662
|
+
st = (0, import_node_fs59.lstatSync)(cur);
|
|
35630
35663
|
} catch {
|
|
35631
|
-
(0,
|
|
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,
|
|
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(
|
|
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,
|
|
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,
|
|
35684
|
+
const dir = (0, import_node_path45.dirname)(dest);
|
|
35652
35685
|
try {
|
|
35653
|
-
const st = (0,
|
|
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,
|
|
35694
|
+
realRoot = (0, import_node_fs59.realpathSync)(root);
|
|
35662
35695
|
} catch {
|
|
35663
35696
|
throw new SafeWriteError("unwritable", root);
|
|
35664
35697
|
}
|
|
35665
|
-
const tmp = (0,
|
|
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,
|
|
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,
|
|
35706
|
+
const opened = (0, import_node_fs59.fstatSync)(fd, { bigint: true });
|
|
35674
35707
|
let realTmp;
|
|
35675
35708
|
try {
|
|
35676
|
-
realTmp = (0,
|
|
35709
|
+
realTmp = (0, import_node_fs59.realpathSync)(tmp);
|
|
35677
35710
|
} catch {
|
|
35678
35711
|
throw new SafeWriteError("escaped", tmp);
|
|
35679
35712
|
}
|
|
35680
|
-
const there = (0,
|
|
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,
|
|
35719
|
+
while (off < buf.length) off += (0, import_node_fs59.writeSync)(fd, buf, off, buf.length - off);
|
|
35687
35720
|
} catch (err2) {
|
|
35688
|
-
(0,
|
|
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,
|
|
35725
|
+
(0, import_node_fs59.closeSync)(fd);
|
|
35693
35726
|
try {
|
|
35694
|
-
if (!insideRoot(realRoot, (0,
|
|
35695
|
-
(0,
|
|
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 +
|
|
35742
|
+
cur = cur + import_node_path45.sep + part;
|
|
35710
35743
|
try {
|
|
35711
|
-
if ((0,
|
|
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,
|
|
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,
|
|
36059
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path46.join)(root, rel));
|
|
36027
36060
|
try {
|
|
36028
|
-
(0,
|
|
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,
|
|
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,
|
|
36048
|
-
if (existsNoFollow((0,
|
|
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,
|
|
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,
|
|
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,
|
|
36321
|
-
const elanBin = (0,
|
|
36322
|
-
const elanHas = (0,
|
|
36323
|
-
const userPath = (env.PATH ?? "").split(
|
|
36324
|
-
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
36439
|
-
const asPath = (0,
|
|
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,
|
|
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,
|
|
36448
|
-
if (!(0,
|
|
36449
|
-
return (0,
|
|
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,
|
|
36456
|
-
const rel = (0,
|
|
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,
|
|
36463
|
-
const rel = (0,
|
|
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,
|
|
36505
|
+
const name2 = parsed.header?.model ?? (0, import_node_path47.basename)(modelFile, ".lean");
|
|
36473
36506
|
const report = {
|
|
36474
36507
|
model: name2,
|
|
36475
|
-
file: (0,
|
|
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
|
|
36721
|
-
const empty = { day:
|
|
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 !==
|
|
36728
|
-
return { day:
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
37279
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
37479
|
+
(0, import_node_fs62.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
37426
37480
|
const map = readIterMap();
|
|
37427
37481
|
map[moment] = count;
|
|
37428
|
-
(0,
|
|
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,
|
|
37492
|
+
if ((0, import_node_fs62.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs62.unlinkSync)(GUARD_ITER_FILE);
|
|
37439
37493
|
} else {
|
|
37440
|
-
(0,
|
|
37441
|
-
(0,
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
38536
|
+
const hasConfig = (0, import_node_fs64.existsSync)(projectPath(CODACY_CONFIG_FILE));
|
|
38483
38537
|
const artifacts = {
|
|
38484
|
-
standard: (0,
|
|
38538
|
+
standard: (0, import_node_fs64.existsSync)(projectPath(STANDARD_FILE)),
|
|
38485
38539
|
analysisConfig: hasConfig,
|
|
38486
|
-
verityMd: (0,
|
|
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
|
|
38646
|
-
var
|
|
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,
|
|
38684
|
-
const verityDir = (0,
|
|
38685
|
-
if ((0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
38739
|
-
const verityCreds = (0,
|
|
38740
|
-
if (!(0,
|
|
38741
|
-
if (!(0,
|
|
38742
|
-
(0,
|
|
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,
|
|
38765
|
-
const hadLegacyBlock = (0,
|
|
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,
|
|
38776
|
-
const verityMd = (0,
|
|
38777
|
-
if (!(0,
|
|
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,
|
|
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,
|
|
38794
|
-
if (!(0,
|
|
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,
|
|
38896
|
+
(0, import_node_fs65.writeFileSync)(verityCreds, verityContent + sep6 + toAppend.join("\n") + "\n");
|
|
38843
38897
|
}
|
|
38844
|
-
(0,
|
|
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,
|
|
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,
|
|
38918
|
+
(0, import_node_fs65.renameSync)(from, to);
|
|
38865
38919
|
} catch (err2) {
|
|
38866
38920
|
if (err2.code !== "EXDEV") throw err2;
|
|
38867
|
-
(0,
|
|
38868
|
-
(0,
|
|
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,
|
|
38927
|
+
(0, import_node_fs65.renameSync)(from, to);
|
|
38874
38928
|
} catch (err2) {
|
|
38875
38929
|
if (err2.code !== "EXDEV") throw err2;
|
|
38876
|
-
(0,
|
|
38877
|
-
(0,
|
|
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,
|
|
38884
|
-
for (const entry of (0,
|
|
38885
|
-
const rel = relDir ? (0,
|
|
38886
|
-
const src = (0,
|
|
38887
|
-
const dest = (0,
|
|
38888
|
-
if ((0,
|
|
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,
|
|
38891
|
-
(0,
|
|
38892
|
-
(0,
|
|
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,
|
|
38902
|
-
const verityDir = (0,
|
|
38903
|
-
if ((0,
|
|
38904
|
-
if ((0,
|
|
38905
|
-
if ((0,
|
|
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,
|
|
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,
|
|
38913
|
-
if ((0,
|
|
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,
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
39350
|
-
(0,
|
|
39351
|
-
(0,
|
|
39352
|
-
const zip = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
39376
|
-
(0,
|
|
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,
|
|
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,
|
|
39383
|
-
const top = entries.length === 1 && (0,
|
|
39384
|
-
if (!(0,
|
|
39385
|
-
(0,
|
|
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,
|
|
39389
|
-
(0,
|
|
39390
|
-
(0,
|
|
39391
|
-
(0,
|
|
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
|
|
39450
|
+
var import_node_fs67 = require("node:fs");
|
|
39397
39451
|
var import_promises19 = require("node:fs/promises");
|
|
39398
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
39647
|
+
(0, import_node_path53.join)(__dirname, "..", "data"),
|
|
39594
39648
|
// installed: node_modules/@codacy/verity-cli/data
|
|
39595
|
-
(0,
|
|
39649
|
+
(0, import_node_path53.join)(__dirname, "..", "..", "data"),
|
|
39596
39650
|
// edge case: nested resolution
|
|
39597
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
39631
|
-
const b = await (0, import_promises20.readFile)((0,
|
|
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,
|
|
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,
|
|
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,
|
|
39936
|
-
const dest = (0,
|
|
39937
|
-
if (!(0,
|
|
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,
|
|
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 +
|
|
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,
|
|
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,
|
|
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,
|
|
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.
|
|
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
|
|
40408
|
-
var
|
|
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,
|
|
40418
|
-
if ((0,
|
|
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,
|
|
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,
|
|
40489
|
+
if ((0, import_node_fs69.existsSync)(verityDir)) {
|
|
40436
40490
|
actions.push({
|
|
40437
40491
|
label: `Remove ${VERITY_DIR}/`,
|
|
40438
|
-
apply: () => (0,
|
|
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,
|
|
40497
|
+
if ((0, import_node_fs69.existsSync)(verityMd)) {
|
|
40444
40498
|
actions.push({
|
|
40445
40499
|
label: `Remove ${VERITY_MD_FILE}`,
|
|
40446
|
-
apply: () => (0,
|
|
40500
|
+
apply: () => (0, import_node_fs69.rmSync)(verityMd, { force: true })
|
|
40447
40501
|
});
|
|
40448
40502
|
}
|
|
40449
40503
|
}
|
|
40450
40504
|
const cleanupEmptyDir = (path) => {
|
|
40451
|
-
if ((0,
|
|
40452
|
-
(0,
|
|
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,
|
|
40464
|
-
if (purgeGlobal && (0,
|
|
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,
|
|
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
|
|
40662
|
-
var
|
|
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,
|
|
40700
|
-
for (const entry of (0,
|
|
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,
|
|
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,
|
|
40772
|
+
if ((0, import_node_fs70.existsSync)(file)) {
|
|
40719
40773
|
try {
|
|
40720
|
-
(0,
|
|
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,
|
|
40728
|
-
for (const entry of (0,
|
|
40781
|
+
if ((0, import_node_fs70.existsSync)(logsDir)) {
|
|
40782
|
+
for (const entry of (0, import_node_fs70.readdirSync)(logsDir)) {
|
|
40729
40783
|
try {
|
|
40730
|
-
(0,
|
|
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
|
|
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,
|
|
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
|
|
41271
|
+
var import_node_fs72 = require("node:fs");
|
|
41218
41272
|
async function recordTelemetryChoice(choice) {
|
|
41219
|
-
if (!(0,
|
|
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
|
|
41297
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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 =
|
|
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,
|
|
41718
|
-
const rel = rel0.startsWith("..") || (0,
|
|
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,
|
|
41735
|
-
const digest = rel.startsWith("..") || (0,
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
41898
|
+
if (!(0, import_node_fs74.existsSync)(dir)) {
|
|
41844
41899
|
printInfo("nothing to remove");
|
|
41845
41900
|
return;
|
|
41846
41901
|
}
|
|
41847
|
-
(0,
|
|
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.
|
|
41854
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.
|
|
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();
|