@codacy/verity-cli 0.35.4 → 0.35.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +22 -10
- package/bin/verity.js +432 -264
- package/package.json +1 -1
package/bin/verity.js
CHANGED
|
@@ -15351,7 +15351,7 @@ function pinRefusalMessage(verdict, targetUrl) {
|
|
|
15351
15351
|
// src/lib/cli-version.ts
|
|
15352
15352
|
function cliVersion() {
|
|
15353
15353
|
try {
|
|
15354
|
-
return true ? "0.35.
|
|
15354
|
+
return true ? "0.35.5" : "dev";
|
|
15355
15355
|
} catch {
|
|
15356
15356
|
return "dev";
|
|
15357
15357
|
}
|
|
@@ -19369,26 +19369,43 @@ function readProjectConfig() {
|
|
|
19369
19369
|
cfg = { ...rest, turn_review_refused: refused2 };
|
|
19370
19370
|
}
|
|
19371
19371
|
}
|
|
19372
|
+
if (cfg.formal === "off" && cfg.path) {
|
|
19373
|
+
const refused2 = repoControlledRefusal(cfg.path);
|
|
19374
|
+
if (refused2 === "unverified") {
|
|
19375
|
+
cfg = { ...cfg, formal_off_unverified: true };
|
|
19376
|
+
} else if (refused2) {
|
|
19377
|
+
const { formal: _dropped, ...rest } = cfg;
|
|
19378
|
+
cfg = { ...rest, formal_off_refused: refused2 };
|
|
19379
|
+
}
|
|
19380
|
+
}
|
|
19372
19381
|
return cfg;
|
|
19373
19382
|
}
|
|
19374
|
-
function
|
|
19383
|
+
function formalOffUnverifiedNote() {
|
|
19384
|
+
return 'off-unverified: .verity/config.json says "off" and git could not confirm that the repository does not control it, so the "off" is kept and the formal check does not run';
|
|
19385
|
+
}
|
|
19386
|
+
function formalOffRefusalMessage(reason) {
|
|
19375
19387
|
switch (reason) {
|
|
19376
19388
|
case "tracked":
|
|
19377
|
-
return '.verity/config.json is tracked in git, so its
|
|
19389
|
+
return '.verity/config.json is tracked in git, so its formal "off" is ignored (a repository cannot switch formal verification off). To make your "off" count, untrack the file: git rm --cached .verity/config.json';
|
|
19378
19390
|
case "symlink":
|
|
19379
|
-
return '.verity/config.json is reached through a symlink, so its
|
|
19380
|
-
case "unverified":
|
|
19381
|
-
return 'could not confirm with git that .verity/config.json is untracked, so its turn_review "off" is ignored';
|
|
19391
|
+
return '.verity/config.json is reached through a symlink, so its formal "off" is ignored';
|
|
19382
19392
|
}
|
|
19383
19393
|
}
|
|
19384
|
-
function
|
|
19394
|
+
function formalSetting(cfg, env = process.env) {
|
|
19395
|
+
const fromEnv = env.VERITY_GIT_MOMENT_FORMAL;
|
|
19396
|
+
if (fromEnv === "off" || fromEnv === "push") return { state: fromEnv, source: "env" };
|
|
19397
|
+
if (cfg.formal === "off") return { state: "off", source: "config" };
|
|
19398
|
+
if (cfg.formal === "push") return { state: "push", source: "config" };
|
|
19399
|
+
return { state: "push", source: "default" };
|
|
19400
|
+
}
|
|
19401
|
+
function turnReviewRefusalMessage(reason) {
|
|
19385
19402
|
switch (reason) {
|
|
19386
19403
|
case "tracked":
|
|
19387
|
-
return
|
|
19404
|
+
return '.verity/config.json is tracked in git, so its turn_review "off" is ignored (a repository cannot switch the review off) \u2014 untrack it with: git rm --cached .verity/config.json';
|
|
19388
19405
|
case "symlink":
|
|
19389
|
-
return
|
|
19406
|
+
return '.verity/config.json is reached through a symlink, so its turn_review "off" is ignored';
|
|
19390
19407
|
case "unverified":
|
|
19391
|
-
return
|
|
19408
|
+
return 'could not confirm with git that .verity/config.json is untracked, so its turn_review "off" is ignored';
|
|
19392
19409
|
}
|
|
19393
19410
|
}
|
|
19394
19411
|
function writeProjectConfig(patch) {
|
|
@@ -26603,11 +26620,15 @@ function registerConfigCommands(program2) {
|
|
|
26603
26620
|
}
|
|
26604
26621
|
printInfo(pluginMode ? "It applies from the next turn." : "It applies from the next Claude Code session (Claude Code reads hooks when a session starts).");
|
|
26605
26622
|
});
|
|
26606
|
-
config.command("formal [state]").description('Get or set formal verification at push: "push" or "off" (needs Lean \u2014 verity lean status)').action((state) => {
|
|
26623
|
+
config.command("formal [state]").description('Get or set formal verification at push: "push" (the default) or "off" (needs Lean \u2014 verity lean status)').action((state) => {
|
|
26607
26624
|
if (state === void 0) {
|
|
26608
26625
|
const cfg = readProjectConfig();
|
|
26609
|
-
|
|
26610
|
-
|
|
26626
|
+
const setting = formalSetting(cfg);
|
|
26627
|
+
process.stdout.write(setting.state + "\n");
|
|
26628
|
+
if (cfg.formal_off_refused && setting.source === "default") printWarn(formalOffRefusalMessage(cfg.formal_off_refused));
|
|
26629
|
+
else if (setting.source === "default") printInfo("On by default. To turn it off for this checkout, run: verity config formal off");
|
|
26630
|
+
if (setting.source === "env") printInfo("Set by VERITY_GIT_MOMENT_FORMAL in this environment");
|
|
26631
|
+
if (cfg.formal_off_unverified && setting.source === "config") printWarn(formalOffUnverifiedNote());
|
|
26611
26632
|
return;
|
|
26612
26633
|
}
|
|
26613
26634
|
if (state !== "push" && state !== "off") {
|
|
@@ -26615,13 +26636,18 @@ function registerConfigCommands(program2) {
|
|
|
26615
26636
|
process.exit(1);
|
|
26616
26637
|
}
|
|
26617
26638
|
writeProjectConfig({ formal: state === "push" ? "push" : "off" });
|
|
26618
|
-
const
|
|
26619
|
-
|
|
26620
|
-
|
|
26639
|
+
const after = readProjectConfig();
|
|
26640
|
+
const offRefused = state === "off" && formalSetting(after).state === "push" ? after.formal_off_refused : void 0;
|
|
26641
|
+
if (offRefused) {
|
|
26642
|
+
printWarn(`Formal verification at push: still on \u2014 ${formalOffRefusalMessage(offRefused)}`);
|
|
26621
26643
|
return;
|
|
26622
26644
|
}
|
|
26623
|
-
printInfo(state === "push" ? "Formal verification at push: on for this checkout (Lean must be installed \u2014 verity lean status)" : "Formal verification at push: off");
|
|
26645
|
+
printInfo(state === "push" ? "Formal verification at push: on for this checkout (Lean must be installed \u2014 verity lean status)" : "Formal verification at push: off for this checkout");
|
|
26624
26646
|
if (state === "push") printInfo("The phase runs with your Verity login (a push without one is skipped and says so: not-logged-in)");
|
|
26647
|
+
const env = process.env.VERITY_GIT_MOMENT_FORMAL;
|
|
26648
|
+
if ((env === "off" || env === "push") && env !== state) {
|
|
26649
|
+
printWarn(`VERITY_GIT_MOMENT_FORMAL=${env} in this environment overrides the file while it is set`);
|
|
26650
|
+
}
|
|
26625
26651
|
});
|
|
26626
26652
|
config.command("verbose [state]").description('Get or set the line Verity prints when a turn has nothing new to review: "on" or "off" (the default)').action((state) => {
|
|
26627
26653
|
if (state === void 0) {
|
|
@@ -29780,11 +29806,11 @@ async function readStopHookStdin() {
|
|
|
29780
29806
|
return new Promise((resolve10) => {
|
|
29781
29807
|
const chunks = [];
|
|
29782
29808
|
let size = 0;
|
|
29783
|
-
let
|
|
29809
|
+
let settled2 = false;
|
|
29784
29810
|
let timer;
|
|
29785
29811
|
const settle = (result) => {
|
|
29786
|
-
if (
|
|
29787
|
-
|
|
29812
|
+
if (settled2) return;
|
|
29813
|
+
settled2 = true;
|
|
29788
29814
|
if (timer) clearTimeout(timer);
|
|
29789
29815
|
process.stdin.off("data", onData);
|
|
29790
29816
|
process.stdin.off("end", onEnd);
|
|
@@ -37129,7 +37155,7 @@ function runAsync(tc, cwd, args2, timeoutMs) {
|
|
|
37129
37155
|
let stdout = "";
|
|
37130
37156
|
let stderr = "";
|
|
37131
37157
|
let timedOut = false;
|
|
37132
|
-
let
|
|
37158
|
+
let settled2 = false;
|
|
37133
37159
|
const kill = () => {
|
|
37134
37160
|
try {
|
|
37135
37161
|
if (posix && child.pid) process.kill(-child.pid, "SIGKILL");
|
|
@@ -37148,8 +37174,8 @@ function runAsync(tc, cwd, args2, timeoutMs) {
|
|
|
37148
37174
|
if (stderr.length < MAX) stderr += d.toString("utf-8");
|
|
37149
37175
|
});
|
|
37150
37176
|
const finish = (ok, message) => {
|
|
37151
|
-
if (
|
|
37152
|
-
|
|
37177
|
+
if (settled2) return;
|
|
37178
|
+
settled2 = true;
|
|
37153
37179
|
clearTimeout(timer);
|
|
37154
37180
|
if (ok) resolve10({ ok: true, stdout, stderr: "", durationMs: Date.now() - started, timedOut: false });
|
|
37155
37181
|
else resolve10({ ok: false, stdout, stderr: stderr || message || "", durationMs: Date.now() - started, timedOut });
|
|
@@ -37658,16 +37684,138 @@ function resumeInterruptedInstall(opts) {
|
|
|
37658
37684
|
return shouldStartBackgroundInstall({ formal: opts.formal, env, free: opts.free }).start && startBackgroundInstall({ cli: opts.cli, env, run: opts.run });
|
|
37659
37685
|
}
|
|
37660
37686
|
|
|
37687
|
+
// src/lib/prove/formal-default.ts
|
|
37688
|
+
var import_node_fs64 = require("node:fs");
|
|
37689
|
+
var import_node_path52 = require("node:path");
|
|
37690
|
+
var NOTICE_MARKER = ".formal-default-notice";
|
|
37691
|
+
var LEAN_MARKER = ".formal-lean-checked";
|
|
37692
|
+
function markerPath3(name2) {
|
|
37693
|
+
return (0, import_node_path52.join)(verityHome(), name2);
|
|
37694
|
+
}
|
|
37695
|
+
function writeMarker(name2, now) {
|
|
37696
|
+
try {
|
|
37697
|
+
(0, import_node_fs64.mkdirSync)(verityHome(), { recursive: true, mode: 448 });
|
|
37698
|
+
(0, import_node_fs64.writeFileSync)(markerPath3(name2), now.toISOString() + "\n");
|
|
37699
|
+
} catch {
|
|
37700
|
+
}
|
|
37701
|
+
}
|
|
37702
|
+
function formalDefaultNoticeDue() {
|
|
37703
|
+
return !(0, import_node_fs64.existsSync)(markerPath3(NOTICE_MARKER));
|
|
37704
|
+
}
|
|
37705
|
+
function recordFormalDefaultNotice(now = /* @__PURE__ */ new Date()) {
|
|
37706
|
+
writeMarker(NOTICE_MARKER, now);
|
|
37707
|
+
}
|
|
37708
|
+
var BLOCKED_LINES = {
|
|
37709
|
+
"opted-out": () => "VERITY_NO_LEAN=1 is set, so Verity does not download Lean 4. Without Lean 4, a push skips the formal check.",
|
|
37710
|
+
ci: () => "This is a CI environment, so Verity does not download Lean 4 (VERITY_LEAN=1 allows it). Without Lean 4, a push skips the formal check.",
|
|
37711
|
+
disk: (detail2) => `Lean 4 needs more disk space${detail2 ? ` (${detail2})` : ""}. Until Lean 4 is installed, a push skips the formal check. Free some space, then run: verity lean install`,
|
|
37712
|
+
"no-release": () => "Lean 4 has no release for this machine, so a push skips the formal check."
|
|
37713
|
+
};
|
|
37714
|
+
function leanLine(lean) {
|
|
37715
|
+
switch (lean.kind) {
|
|
37716
|
+
case "started":
|
|
37717
|
+
return "Lean 4 (about 800 MB) is downloading in the background. To see the progress, run: verity lean status";
|
|
37718
|
+
case "downloading":
|
|
37719
|
+
return "Lean 4 is downloading in the background. To see the progress, run: verity lean status";
|
|
37720
|
+
case "failed":
|
|
37721
|
+
return "The Lean 4 download could not start. Until Lean 4 is installed, a push skips the formal check. To install it, run: verity lean install";
|
|
37722
|
+
case "previous-failed":
|
|
37723
|
+
return "The last Lean 4 download failed. Until Lean 4 is installed, a push skips the formal check. To try again, run: verity lean install";
|
|
37724
|
+
case "blocked":
|
|
37725
|
+
return BLOCKED_LINES[lean.why](lean.detail);
|
|
37726
|
+
case "installed":
|
|
37727
|
+
case "unknown":
|
|
37728
|
+
return null;
|
|
37729
|
+
}
|
|
37730
|
+
}
|
|
37731
|
+
function formalDefaultUserMessage(lean, offRefused) {
|
|
37732
|
+
const aboutLean = leanLine(lean);
|
|
37733
|
+
return [
|
|
37734
|
+
...offRefused ? [`Verity: ${formalOffRefusalMessage(offRefused)}`] : [],
|
|
37735
|
+
"Verity: formal verification at push is now on by default.",
|
|
37736
|
+
"At a push, Verity can check a small Lean model of the riskiest changed function and replay a counterexample on the real code. For the replay, the source of that function goes to the Verity service.",
|
|
37737
|
+
"Only a reproduced bug can block a push.",
|
|
37738
|
+
...aboutLean ? [aboutLean] : [],
|
|
37739
|
+
"To turn it off for this project, run: verity config formal off"
|
|
37740
|
+
].join("\n");
|
|
37741
|
+
}
|
|
37742
|
+
var AGENT_LINE = "Formal verification at push is on by default in this project. At a push, Verity can model one changed function in Lean, so a push can take longer. A block from it means that the counterexample was reproduced on the real code. If the user wants it off, the command is `verity config formal off`.";
|
|
37743
|
+
function settled(lean) {
|
|
37744
|
+
return lean.kind === "installed" || lean.kind === "blocked" && lean.why === "no-release";
|
|
37745
|
+
}
|
|
37746
|
+
var LEAN_RECHECK_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
37747
|
+
function settledRecently(now) {
|
|
37748
|
+
try {
|
|
37749
|
+
const at = Date.parse((0, import_node_fs64.readFileSync)(markerPath3(LEAN_MARKER), "utf-8").trim());
|
|
37750
|
+
return Number.isFinite(at) && now.getTime() - at >= 0 && now.getTime() - at < LEAN_RECHECK_MS;
|
|
37751
|
+
} catch {
|
|
37752
|
+
return false;
|
|
37753
|
+
}
|
|
37754
|
+
}
|
|
37755
|
+
function leanAtStart(opts, now, probeAgain) {
|
|
37756
|
+
const { env } = opts;
|
|
37757
|
+
if (env.VERITY_NO_LEAN === "1") return { kind: "blocked", why: "opted-out" };
|
|
37758
|
+
if (env.CI && env.VERITY_LEAN !== "1") return { kind: "blocked", why: "ci" };
|
|
37759
|
+
const state = readInstallState(env);
|
|
37760
|
+
if (state?.state === "failed") return { kind: "previous-failed" };
|
|
37761
|
+
if (state?.state === "done") return { kind: "installed" };
|
|
37762
|
+
if (state?.state === "running") return installRunning(env) ? { kind: "downloading" } : { kind: "unknown" };
|
|
37763
|
+
if (!probeAgain && settledRecently(now)) return { kind: "unknown" };
|
|
37764
|
+
const lean = probeAndStart(opts);
|
|
37765
|
+
if (settled(lean)) writeMarker(LEAN_MARKER, now);
|
|
37766
|
+
return lean;
|
|
37767
|
+
}
|
|
37768
|
+
function probeAndStart(opts) {
|
|
37769
|
+
const { env } = opts;
|
|
37770
|
+
const d = shouldStartBackgroundInstall({ formal: "push", env, free: opts.free });
|
|
37771
|
+
if (d.start) {
|
|
37772
|
+
const started = startBackgroundInstall({ cli: opts.cli, env, ...opts.run ? { run: opts.run } : {} });
|
|
37773
|
+
return started ? { kind: "started" } : { kind: "failed" };
|
|
37774
|
+
}
|
|
37775
|
+
switch (d.why) {
|
|
37776
|
+
case "installed":
|
|
37777
|
+
return { kind: "installed" };
|
|
37778
|
+
case "running":
|
|
37779
|
+
return { kind: "downloading" };
|
|
37780
|
+
case "opted-out":
|
|
37781
|
+
case "ci":
|
|
37782
|
+
case "no-release":
|
|
37783
|
+
return { kind: "blocked", why: d.why };
|
|
37784
|
+
case "disk":
|
|
37785
|
+
return { kind: "blocked", why: "disk", ...d.detail ? { detail: d.detail } : {} };
|
|
37786
|
+
case "formal-off":
|
|
37787
|
+
return { kind: "unknown" };
|
|
37788
|
+
}
|
|
37789
|
+
}
|
|
37790
|
+
function formalAtSessionStart(opts) {
|
|
37791
|
+
const env = opts.env ?? process.env;
|
|
37792
|
+
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
37793
|
+
const none = { userMsg: null, agentLine: null, leanStarted: false };
|
|
37794
|
+
const setting = formalSetting(opts.cfg, env);
|
|
37795
|
+
if (setting.state !== "push") return none;
|
|
37796
|
+
const noticeDue = setting.source === "default" && formalDefaultNoticeDue();
|
|
37797
|
+
let lean;
|
|
37798
|
+
try {
|
|
37799
|
+
lean = leanAtStart({ cli: opts.cli, env, ...opts.free !== void 0 ? { free: opts.free } : {}, ...opts.run ? { run: opts.run } : {} }, now, noticeDue);
|
|
37800
|
+
} catch (err2) {
|
|
37801
|
+
lean = { kind: "failed" };
|
|
37802
|
+
logEvent("formal_default_lean_failed", { error: String(err2?.message ?? err2).slice(0, 200) });
|
|
37803
|
+
}
|
|
37804
|
+
const leanStarted = lean.kind === "started";
|
|
37805
|
+
if (!noticeDue) return { ...none, leanStarted };
|
|
37806
|
+
return { userMsg: formalDefaultUserMessage(lean, opts.cfg.formal_off_refused), agentLine: AGENT_LINE, leanStarted };
|
|
37807
|
+
}
|
|
37808
|
+
|
|
37661
37809
|
// src/commands/baseline.ts
|
|
37662
|
-
var
|
|
37663
|
-
var
|
|
37810
|
+
var import_node_fs67 = require("node:fs");
|
|
37811
|
+
var import_node_path55 = require("node:path");
|
|
37664
37812
|
|
|
37665
37813
|
// src/lib/skew-notice.ts
|
|
37666
|
-
var
|
|
37667
|
-
var
|
|
37814
|
+
var import_node_fs65 = require("node:fs");
|
|
37815
|
+
var import_node_path53 = require("node:path");
|
|
37668
37816
|
var MARKER2 = ".skew-notice.json";
|
|
37669
|
-
function
|
|
37670
|
-
return (0,
|
|
37817
|
+
function markerPath4() {
|
|
37818
|
+
return (0, import_node_path53.join)(verityHome(), MARKER2);
|
|
37671
37819
|
}
|
|
37672
37820
|
function today(now) {
|
|
37673
37821
|
const y = now.getFullYear();
|
|
@@ -37677,7 +37825,7 @@ function today(now) {
|
|
|
37677
37825
|
}
|
|
37678
37826
|
function skewNoticeDue(skew, now = /* @__PURE__ */ new Date()) {
|
|
37679
37827
|
try {
|
|
37680
|
-
const seen = JSON.parse((0,
|
|
37828
|
+
const seen = JSON.parse((0, import_node_fs65.readFileSync)(markerPath4(), "utf-8"));
|
|
37681
37829
|
return !(seen.global === skew.global && seen.hooks === skew.hooks && seen.day === today(now));
|
|
37682
37830
|
} catch {
|
|
37683
37831
|
return true;
|
|
@@ -37685,15 +37833,15 @@ function skewNoticeDue(skew, now = /* @__PURE__ */ new Date()) {
|
|
|
37685
37833
|
}
|
|
37686
37834
|
function recordSkewNotice(skew, now = /* @__PURE__ */ new Date()) {
|
|
37687
37835
|
try {
|
|
37688
|
-
(0,
|
|
37689
|
-
(0,
|
|
37836
|
+
(0, import_node_fs65.mkdirSync)(verityHome(), { recursive: true, mode: 448 });
|
|
37837
|
+
(0, import_node_fs65.writeFileSync)(markerPath4(), JSON.stringify({ global: skew.global, hooks: skew.hooks, day: today(now) }) + "\n");
|
|
37690
37838
|
} catch {
|
|
37691
37839
|
}
|
|
37692
37840
|
}
|
|
37693
37841
|
|
|
37694
37842
|
// src/lib/project-skills.ts
|
|
37695
|
-
var
|
|
37696
|
-
var
|
|
37843
|
+
var import_node_fs66 = require("node:fs");
|
|
37844
|
+
var import_node_path54 = require("node:path");
|
|
37697
37845
|
var PROJECT_SKILL_NAMES = [
|
|
37698
37846
|
"verity-setup",
|
|
37699
37847
|
"verity-analyze",
|
|
@@ -37719,14 +37867,14 @@ var LEGACY_SKILL_NAMES = [
|
|
|
37719
37867
|
var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
|
|
37720
37868
|
function staleProjectSkills() {
|
|
37721
37869
|
const root = projectPath(".claude/skills");
|
|
37722
|
-
if (!(0,
|
|
37723
|
-
return ALL.filter((name2) => (0,
|
|
37870
|
+
if (!(0, import_node_fs66.existsSync)(root)) return [];
|
|
37871
|
+
return ALL.filter((name2) => (0, import_node_fs66.existsSync)((0, import_node_path54.join)(root, name2)));
|
|
37724
37872
|
}
|
|
37725
37873
|
function removeProjectSkills() {
|
|
37726
37874
|
const root = projectPath(".claude/skills");
|
|
37727
37875
|
const removed = [];
|
|
37728
37876
|
for (const name2 of staleProjectSkills()) {
|
|
37729
|
-
(0,
|
|
37877
|
+
(0, import_node_fs66.rmSync)((0, import_node_path54.join)(root, name2), { recursive: true, force: true });
|
|
37730
37878
|
removed.push(name2);
|
|
37731
37879
|
}
|
|
37732
37880
|
return removed;
|
|
@@ -37761,7 +37909,7 @@ function registerBaselineCommands(program2) {
|
|
|
37761
37909
|
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.";
|
|
37762
37910
|
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}`;
|
|
37763
37911
|
if (!verityConfigured()) {
|
|
37764
|
-
if (isMachineStore((0,
|
|
37912
|
+
if (isMachineStore((0, import_node_path55.join)(repoRoot(), VERITY_DIR))) process.exit(0);
|
|
37765
37913
|
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.";
|
|
37766
37914
|
const lines = [
|
|
37767
37915
|
`Verity is installed but this project is not set up yet, so the quality gate will not review anything here. ${how}`
|
|
@@ -37795,17 +37943,20 @@ function registerBaselineCommands(program2) {
|
|
|
37795
37943
|
let memoryMsg = null;
|
|
37796
37944
|
let memoryAgentLine = null;
|
|
37797
37945
|
const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
|
|
37798
|
-
if (realStart && !(0,
|
|
37946
|
+
if (realStart && !(0, import_node_fs67.existsSync)(memoryNotice)) {
|
|
37799
37947
|
const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
|
|
37800
37948
|
if (trackedGraph > 0) {
|
|
37801
37949
|
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.`;
|
|
37802
37950
|
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.`;
|
|
37803
37951
|
try {
|
|
37804
|
-
(0,
|
|
37952
|
+
(0, import_node_fs67.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
|
|
37805
37953
|
} catch {
|
|
37806
37954
|
}
|
|
37807
37955
|
}
|
|
37808
37956
|
}
|
|
37957
|
+
const formalStart = realStart ? formalAtSessionStart({ cli: process.argv[1], cfg: readProjectConfig() }) : null;
|
|
37958
|
+
const formalMsg = formalStart?.userMsg ?? null;
|
|
37959
|
+
const formalAgentLine = formalStart?.agentLine ?? null;
|
|
37809
37960
|
if (isPluginInvocation() && realStart) {
|
|
37810
37961
|
const installed2 = activePluginVersion();
|
|
37811
37962
|
const state = await readSetupState().catch(() => null);
|
|
@@ -37829,10 +37980,11 @@ function registerBaselineCommands(program2) {
|
|
|
37829
37980
|
}
|
|
37830
37981
|
}
|
|
37831
37982
|
if (memoryAgentLine) notices.push(memoryAgentLine);
|
|
37983
|
+
if (formalAgentLine) notices.push(formalAgentLine);
|
|
37832
37984
|
if (notices.length > 0 || skewMsg) {
|
|
37833
37985
|
process.stdout.write(
|
|
37834
37986
|
JSON.stringify({
|
|
37835
|
-
...userMsg || skewMsg || memoryMsg ? { systemMessage: [skewMsg, userMsg, memoryMsg].filter(Boolean).join("\n") } : {},
|
|
37987
|
+
...userMsg || skewMsg || memoryMsg || formalMsg ? { systemMessage: [skewMsg, userMsg, memoryMsg, formalMsg].filter(Boolean).join("\n") } : {},
|
|
37836
37988
|
hookSpecificOutput: {
|
|
37837
37989
|
hookEventName: "SessionStart",
|
|
37838
37990
|
additionalContext: notices.join("\n")
|
|
@@ -37840,17 +37992,20 @@ function registerBaselineCommands(program2) {
|
|
|
37840
37992
|
}) + "\n"
|
|
37841
37993
|
);
|
|
37842
37994
|
if (skew && skewMsg) recordSkewNotice(skew);
|
|
37995
|
+
if (formalMsg) recordFormalDefaultNotice();
|
|
37843
37996
|
}
|
|
37844
|
-
} else if (memoryMsg) {
|
|
37997
|
+
} else if (memoryMsg || formalMsg) {
|
|
37998
|
+
const agentLines = [memoryAgentLine, formalAgentLine].filter(Boolean).join("\n");
|
|
37845
37999
|
process.stdout.write(
|
|
37846
38000
|
JSON.stringify({
|
|
37847
|
-
systemMessage: memoryMsg,
|
|
38001
|
+
systemMessage: [memoryMsg, formalMsg].filter(Boolean).join("\n"),
|
|
37848
38002
|
hookSpecificOutput: {
|
|
37849
38003
|
hookEventName: "SessionStart",
|
|
37850
|
-
...
|
|
38004
|
+
...agentLines ? { additionalContext: agentLines } : {}
|
|
37851
38005
|
}
|
|
37852
38006
|
}) + "\n"
|
|
37853
38007
|
);
|
|
38008
|
+
if (formalMsg) recordFormalDefaultNotice();
|
|
37854
38009
|
}
|
|
37855
38010
|
if (deferredToPlugin("baseline capture", session ?? null)) {
|
|
37856
38011
|
process.exit(0);
|
|
@@ -37858,7 +38013,7 @@ function registerBaselineCommands(program2) {
|
|
|
37858
38013
|
const authForScope = await resolveToken(program2.opts().token);
|
|
37859
38014
|
const scopeToken = authForScope.ok ? authForScope.data.token : void 0;
|
|
37860
38015
|
if (authForScope.ok && pullsAtSessionStart(authForScope.data, source2)) spawnBackgroundPull();
|
|
37861
|
-
if (source2 !== "compact") resumeInterruptedInstall({ cli: process.argv[1], formal: readProjectConfig().
|
|
38016
|
+
if (source2 !== "compact") resumeInterruptedInstall({ cli: process.argv[1], formal: formalSetting(readProjectConfig()).state });
|
|
37862
38017
|
const scopeSession = session;
|
|
37863
38018
|
const result = captureBaseline({ sessionId: sessionScopeKey(scopeToken, scopeSession), source: source2 });
|
|
37864
38019
|
logEvent("baseline_capture", {
|
|
@@ -37904,31 +38059,31 @@ function hookSource(value) {
|
|
|
37904
38059
|
}
|
|
37905
38060
|
|
|
37906
38061
|
// src/commands/review.ts
|
|
37907
|
-
var
|
|
37908
|
-
var
|
|
38062
|
+
var import_node_fs68 = require("node:fs");
|
|
38063
|
+
var import_node_path56 = require("node:path");
|
|
37909
38064
|
function containReviewPaths(paths, base) {
|
|
37910
38065
|
const kept = [];
|
|
37911
38066
|
const refused2 = [];
|
|
37912
38067
|
for (const raw of paths) {
|
|
37913
|
-
const candidate = (0,
|
|
38068
|
+
const candidate = (0, import_node_path56.isAbsolute)(raw) ? relativeForm(base, raw) : raw;
|
|
37914
38069
|
if (candidate === "" || resolveInside(base, candidate) === null) refused2.push(raw);
|
|
37915
38070
|
else kept.push(candidate);
|
|
37916
38071
|
}
|
|
37917
38072
|
return { kept, refused: refused2 };
|
|
37918
38073
|
}
|
|
37919
38074
|
function relativeForm(base, abs) {
|
|
37920
|
-
const lexical = (0,
|
|
37921
|
-
if (!(lexical === ".." || lexical.startsWith(`..${
|
|
38075
|
+
const lexical = (0, import_node_path56.relative)(base, abs);
|
|
38076
|
+
if (!(lexical === ".." || lexical.startsWith(`..${import_node_path56.sep}`) || (0, import_node_path56.isAbsolute)(lexical))) return lexical;
|
|
37922
38077
|
try {
|
|
37923
|
-
let dir = (0,
|
|
37924
|
-
let rest = (0,
|
|
37925
|
-
while (!(0,
|
|
37926
|
-
const up = (0,
|
|
38078
|
+
let dir = (0, import_node_path56.dirname)(abs);
|
|
38079
|
+
let rest = (0, import_node_path56.basename)(abs);
|
|
38080
|
+
while (!(0, import_node_fs68.existsSync)(dir)) {
|
|
38081
|
+
const up = (0, import_node_path56.dirname)(dir);
|
|
37927
38082
|
if (up === dir) return lexical;
|
|
37928
|
-
rest = (0,
|
|
38083
|
+
rest = (0, import_node_path56.join)((0, import_node_path56.basename)(dir), rest);
|
|
37929
38084
|
dir = up;
|
|
37930
38085
|
}
|
|
37931
|
-
return (0,
|
|
38086
|
+
return (0, import_node_path56.relative)((0, import_node_fs68.realpathSync)(base), (0, import_node_path56.join)((0, import_node_fs68.realpathSync)(dir), rest));
|
|
37932
38087
|
} catch {
|
|
37933
38088
|
return lexical;
|
|
37934
38089
|
}
|
|
@@ -37967,7 +38122,7 @@ async function runReview(opts, globals) {
|
|
|
37967
38122
|
const changedFiles = changed.kept;
|
|
37968
38123
|
const analyzable = filterAnalyzable(allFiles);
|
|
37969
38124
|
const securityFiles = filterSecurity(allFiles);
|
|
37970
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0,
|
|
38125
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs68.existsSync)(f) || resolveFile(f) !== null);
|
|
37971
38126
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
37972
38127
|
const codeDelta = collectCodeDelta(allFiles);
|
|
37973
38128
|
const tokenResult = await resolveToken(globals.token);
|
|
@@ -38038,12 +38193,12 @@ async function runReview(opts, globals) {
|
|
|
38038
38193
|
}
|
|
38039
38194
|
|
|
38040
38195
|
// src/commands/guard.ts
|
|
38041
|
-
var
|
|
38042
|
-
var
|
|
38196
|
+
var import_node_fs70 = require("node:fs");
|
|
38197
|
+
var import_node_path59 = require("node:path");
|
|
38043
38198
|
|
|
38044
38199
|
// src/lib/vendored.ts
|
|
38045
|
-
var
|
|
38046
|
-
var
|
|
38200
|
+
var import_node_fs69 = require("node:fs");
|
|
38201
|
+
var import_node_path57 = require("node:path");
|
|
38047
38202
|
var INSTALLED_SKILL = /^\.claude\/skills\/(verity-[a-z0-9-]+)\/(.+)$/;
|
|
38048
38203
|
function dataDirOrNull() {
|
|
38049
38204
|
try {
|
|
@@ -38058,7 +38213,7 @@ function shippedSkillFile(path, dataDir = dataDirOrNull()) {
|
|
|
38058
38213
|
const [, skill, rel] = m;
|
|
38059
38214
|
if (rel.split("/").some((seg) => seg === ".." || seg === ".")) return null;
|
|
38060
38215
|
try {
|
|
38061
|
-
return (0,
|
|
38216
|
+
return (0, import_node_fs69.readFileSync)((0, import_node_path57.join)(dataDir, "skills", skill, rel), "utf8");
|
|
38062
38217
|
} catch {
|
|
38063
38218
|
return null;
|
|
38064
38219
|
}
|
|
@@ -38097,10 +38252,10 @@ function summarizeFindings(response) {
|
|
|
38097
38252
|
return out2;
|
|
38098
38253
|
});
|
|
38099
38254
|
}
|
|
38100
|
-
function finishOneShot(
|
|
38101
|
-
if (!
|
|
38102
|
-
if (!
|
|
38103
|
-
const r =
|
|
38255
|
+
function finishOneShot(settled2) {
|
|
38256
|
+
if (!settled2) return { status: "pending" };
|
|
38257
|
+
if (!settled2.ok) return { status: "failed" };
|
|
38258
|
+
const r = settled2.response;
|
|
38104
38259
|
return {
|
|
38105
38260
|
status: "arrived",
|
|
38106
38261
|
...typeof r.agent_attestation === "string" ? { attestation: r.agent_attestation } : {},
|
|
@@ -38111,13 +38266,13 @@ function finishOneShot(settled) {
|
|
|
38111
38266
|
async function runAgentReview(options) {
|
|
38112
38267
|
const now = options.now ?? Date.now;
|
|
38113
38268
|
const remaining = () => options.deadlineMs - (now() - options.startedAt);
|
|
38114
|
-
let
|
|
38269
|
+
let settled2 = null;
|
|
38115
38270
|
const oneShotDone = options.oneShot.then(
|
|
38116
38271
|
(outcome) => {
|
|
38117
|
-
|
|
38272
|
+
settled2 = outcome;
|
|
38118
38273
|
},
|
|
38119
38274
|
() => {
|
|
38120
|
-
|
|
38275
|
+
settled2 = { ok: false };
|
|
38121
38276
|
}
|
|
38122
38277
|
);
|
|
38123
38278
|
if (remaining() < MIN_AGENT_START_MS) return { kind: "skipped", reason: "not enough time left after prep" };
|
|
@@ -38139,7 +38294,7 @@ async function runAgentReview(options) {
|
|
|
38139
38294
|
if (turn >= MAX_TURNS || remaining() < MIN_TURN_MS) break;
|
|
38140
38295
|
const results = await options.executeTools(calls);
|
|
38141
38296
|
let oneShot;
|
|
38142
|
-
const current =
|
|
38297
|
+
const current = settled2;
|
|
38143
38298
|
if (current && sentOneShot === "pending") {
|
|
38144
38299
|
oneShot = current.ok ? { status: "arrived", findings: summarizeFindings(current.response) } : { status: "failed" };
|
|
38145
38300
|
sentOneShot = oneShot.status;
|
|
@@ -38154,13 +38309,13 @@ async function runAgentReview(options) {
|
|
|
38154
38309
|
calls = next.data.calls ?? [];
|
|
38155
38310
|
done = next.data.done;
|
|
38156
38311
|
}
|
|
38157
|
-
if (!
|
|
38312
|
+
if (!settled2) {
|
|
38158
38313
|
const wait = Math.max(0, remaining() - FINISH_TIMEOUT_MS);
|
|
38159
38314
|
await Promise.race([oneShotDone, new Promise((resolve10) => setTimeout(resolve10, wait))]);
|
|
38160
38315
|
}
|
|
38161
38316
|
const finished = await options.http.post(
|
|
38162
38317
|
"/agent-review/finish",
|
|
38163
|
-
{ state, session_id: options.sessionId, one_shot: finishOneShot(
|
|
38318
|
+
{ state, session_id: options.sessionId, one_shot: finishOneShot(settled2) },
|
|
38164
38319
|
FINISH_TIMEOUT_MS
|
|
38165
38320
|
);
|
|
38166
38321
|
if (!finished.ok) {
|
|
@@ -38187,7 +38342,7 @@ function effortProfile(root, env = process.env) {
|
|
|
38187
38342
|
}
|
|
38188
38343
|
|
|
38189
38344
|
// src/lib/prove/auto.ts
|
|
38190
|
-
var
|
|
38345
|
+
var import_node_path58 = require("node:path");
|
|
38191
38346
|
var import_node_crypto21 = require("node:crypto");
|
|
38192
38347
|
|
|
38193
38348
|
// src/lib/prove/grounding.ts
|
|
@@ -40415,7 +40570,7 @@ async function runFormalPhase(input) {
|
|
|
40415
40570
|
modelName = gen.name;
|
|
40416
40571
|
const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
|
|
40417
40572
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
40418
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
40573
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path58.join)(root, rel);
|
|
40419
40574
|
progress.model = { name: gen.name, file: rel, rounds: round };
|
|
40420
40575
|
progress.step = "check";
|
|
40421
40576
|
report = await deps.check(root, abs);
|
|
@@ -40564,7 +40719,7 @@ async function runFormalPhase(input) {
|
|
|
40564
40719
|
return done({
|
|
40565
40720
|
status: "checked",
|
|
40566
40721
|
target,
|
|
40567
|
-
model: { name: modelName, file: (0,
|
|
40722
|
+
model: { name: modelName, file: (0, import_node_path58.relative)(root, (0, import_node_path58.join)(root, modelFile)), rounds },
|
|
40568
40723
|
properties: report.properties,
|
|
40569
40724
|
findings
|
|
40570
40725
|
});
|
|
@@ -40641,7 +40796,7 @@ async function generateAndCheck(root, req, opts) {
|
|
|
40641
40796
|
}
|
|
40642
40797
|
const rel = `${dir}/${gen.name}.lean`;
|
|
40643
40798
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
40644
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
40799
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path58.join)(root, rel);
|
|
40645
40800
|
const report = await opts.deps.check(root, abs);
|
|
40646
40801
|
const abstracts = report.header?.abstracts ?? [];
|
|
40647
40802
|
const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
|
|
@@ -41050,7 +41205,7 @@ var WRITERS_BUDGET_MS = 1500;
|
|
|
41050
41205
|
var EXCERPT_MAX_LINES2 = 30;
|
|
41051
41206
|
var VENDORED_READ_MAX_BYTES = 256 * 1024;
|
|
41052
41207
|
var GUARD_BLOCK_CAP = 2;
|
|
41053
|
-
var GUARD_ITER_FILE = (0,
|
|
41208
|
+
var GUARD_ITER_FILE = (0, import_node_path59.join)(VERITY_DIR, ".guard-iteration");
|
|
41054
41209
|
function readPreToolUseStdin() {
|
|
41055
41210
|
const empty = { command: "", cwd: null, sessionId: null };
|
|
41056
41211
|
return new Promise((resolve10) => {
|
|
@@ -41058,11 +41213,11 @@ function readPreToolUseStdin() {
|
|
|
41058
41213
|
if (process.stdin.isTTY) return resolve10(empty);
|
|
41059
41214
|
const chunks = [];
|
|
41060
41215
|
let timer;
|
|
41061
|
-
let
|
|
41216
|
+
let settled2 = false;
|
|
41062
41217
|
const onData = (c) => chunks.push(c);
|
|
41063
41218
|
const settle = (value) => {
|
|
41064
|
-
if (
|
|
41065
|
-
|
|
41219
|
+
if (settled2) return;
|
|
41220
|
+
settled2 = true;
|
|
41066
41221
|
if (timer) clearTimeout(timer);
|
|
41067
41222
|
process.stdin.removeListener("data", onData);
|
|
41068
41223
|
process.stdin.removeListener("end", onEnd);
|
|
@@ -41095,7 +41250,7 @@ function readPreToolUseStdin() {
|
|
|
41095
41250
|
}
|
|
41096
41251
|
function readIterMap() {
|
|
41097
41252
|
try {
|
|
41098
|
-
const raw = JSON.parse((0,
|
|
41253
|
+
const raw = JSON.parse((0, import_node_fs70.readFileSync)(GUARD_ITER_FILE, "utf-8"));
|
|
41099
41254
|
if (raw && typeof raw === "object") {
|
|
41100
41255
|
if (typeof raw.moment === "string" && typeof raw.count === "number") {
|
|
41101
41256
|
return { [raw.moment]: raw.count };
|
|
@@ -41115,10 +41270,10 @@ function readIter(moment) {
|
|
|
41115
41270
|
}
|
|
41116
41271
|
function writeIter(moment, count2) {
|
|
41117
41272
|
try {
|
|
41118
|
-
(0,
|
|
41273
|
+
(0, import_node_fs70.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
41119
41274
|
const map = readIterMap();
|
|
41120
41275
|
map[moment] = count2;
|
|
41121
|
-
(0,
|
|
41276
|
+
(0, import_node_fs70.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
41122
41277
|
} catch {
|
|
41123
41278
|
}
|
|
41124
41279
|
}
|
|
@@ -41128,10 +41283,10 @@ function resetIter(moment) {
|
|
|
41128
41283
|
if (!(moment in map)) return;
|
|
41129
41284
|
delete map[moment];
|
|
41130
41285
|
if (Object.keys(map).length === 0) {
|
|
41131
|
-
if ((0,
|
|
41286
|
+
if ((0, import_node_fs70.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs70.unlinkSync)(GUARD_ITER_FILE);
|
|
41132
41287
|
} else {
|
|
41133
|
-
(0,
|
|
41134
|
-
(0,
|
|
41288
|
+
(0, import_node_fs70.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
41289
|
+
(0, import_node_fs70.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
41135
41290
|
}
|
|
41136
41291
|
} catch {
|
|
41137
41292
|
}
|
|
@@ -41208,7 +41363,7 @@ function ofThisChange(response, sentFiles) {
|
|
|
41208
41363
|
function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
|
|
41209
41364
|
const analyzable = filterAnalyzable(files);
|
|
41210
41365
|
const securityFiles = filterSecurity(files);
|
|
41211
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0,
|
|
41366
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs70.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
|
|
41212
41367
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
41213
41368
|
const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
|
|
41214
41369
|
const requestBody2 = {
|
|
@@ -41381,11 +41536,14 @@ function startAgentReview(input) {
|
|
|
41381
41536
|
};
|
|
41382
41537
|
return run4().catch((err2) => ({ kind: "failed", reason: String(err2?.message ?? err2) }));
|
|
41383
41538
|
}
|
|
41539
|
+
function formalOffUnverifiedLine(moment, config) {
|
|
41540
|
+
if (moment !== "pre-push" || !config.formal_off_unverified) return "";
|
|
41541
|
+
const setting = formalSetting(config);
|
|
41542
|
+
return setting.state === "off" && setting.source === "config" ? `formal: skipped (${formalOffUnverifiedNote()})` : "";
|
|
41543
|
+
}
|
|
41384
41544
|
function startFormalPhase(input) {
|
|
41385
41545
|
if (input.moment !== "pre-push") return null;
|
|
41386
|
-
|
|
41387
|
-
if (env === "off") return null;
|
|
41388
|
-
if (env !== "push" && readProjectConfig().formal !== "push") return null;
|
|
41546
|
+
if (formalSetting(input.config).state !== "push") return null;
|
|
41389
41547
|
const profile = effortProfile(input.root);
|
|
41390
41548
|
const deadlineAt = input.hookStartedAt + profile.pushDeadlineMs - 1e4;
|
|
41391
41549
|
const ig = loadVerityIgnore();
|
|
@@ -41591,7 +41749,8 @@ async function runGuard(opts, globals) {
|
|
|
41591
41749
|
requestBody: requestBody2,
|
|
41592
41750
|
oneShot
|
|
41593
41751
|
});
|
|
41594
|
-
const
|
|
41752
|
+
const projectConfig = moment === "pre-push" ? readProjectConfig() : null;
|
|
41753
|
+
const formal = projectConfig ? startFormalPhase({ moment, files, root: frame.worktreeRoot, hookStartedAt, frame, range, auth: { serviceUrl: urlResult.data, token: tokenResult.data.token }, config: projectConfig }) : null;
|
|
41595
41754
|
const result = await oneShot;
|
|
41596
41755
|
const agentOutcome = agent ? await agent : null;
|
|
41597
41756
|
const formalOutcome = formal ? await formal : null;
|
|
@@ -41643,7 +41802,7 @@ async function runGuard(opts, globals) {
|
|
|
41643
41802
|
const link2 = viewUrl ? ` \u2014 ${viewUrl}` : "";
|
|
41644
41803
|
const covLine = `${coverageSummary(coverage)} in ${reviewSecs}s`;
|
|
41645
41804
|
const agentLine = describeAgentOutcome(agentOutcome);
|
|
41646
|
-
const formalLine = describeFormalOutcome(formalOutcome);
|
|
41805
|
+
const formalLine = describeFormalOutcome(formalOutcome) || (projectConfig ? formalOffUnverifiedLine(moment, projectConfig) : "");
|
|
41647
41806
|
const covDetail = [coverageBlock(coverage), agentLine, formalLine].filter(Boolean).join("\n ");
|
|
41648
41807
|
const witnessed = [...codeDelta.files.map((f) => f.path), ...agentVerdict?.witnessed_files ?? []];
|
|
41649
41808
|
mergeFormalFindings(response, formalOutcome, files);
|
|
@@ -41884,7 +42043,7 @@ function registerIgnoreCommand(program2) {
|
|
|
41884
42043
|
|
|
41885
42044
|
// src/commands/waive.ts
|
|
41886
42045
|
var import_node_crypto23 = require("node:crypto");
|
|
41887
|
-
var
|
|
42046
|
+
var import_node_fs71 = require("node:fs");
|
|
41888
42047
|
function registerWaiveCommand(program2) {
|
|
41889
42048
|
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) => {
|
|
41890
42049
|
const globals = program2.opts();
|
|
@@ -41913,7 +42072,7 @@ function registerWaiveCommand(program2) {
|
|
|
41913
42072
|
if (opts.file) {
|
|
41914
42073
|
body2.file = opts.file;
|
|
41915
42074
|
try {
|
|
41916
|
-
body2.file_sha256 = (0, import_node_crypto23.createHash)("sha256").update((0,
|
|
42075
|
+
body2.file_sha256 = (0, import_node_crypto23.createHash)("sha256").update((0, import_node_fs71.readFileSync)(opts.file)).digest("hex");
|
|
41917
42076
|
} catch {
|
|
41918
42077
|
printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
|
|
41919
42078
|
process.exit(1);
|
|
@@ -41939,15 +42098,15 @@ function registerWaiveCommand(program2) {
|
|
|
41939
42098
|
|
|
41940
42099
|
// src/commands/init/index.ts
|
|
41941
42100
|
var import_node_os15 = require("node:os");
|
|
41942
|
-
var
|
|
42101
|
+
var import_node_fs80 = require("node:fs");
|
|
41943
42102
|
var import_promises17 = require("node:fs/promises");
|
|
41944
|
-
var
|
|
42103
|
+
var import_node_path69 = require("node:path");
|
|
41945
42104
|
|
|
41946
42105
|
// src/lib/init-changes.ts
|
|
41947
42106
|
var import_node_crypto24 = require("node:crypto");
|
|
41948
|
-
var
|
|
42107
|
+
var import_node_fs72 = require("node:fs");
|
|
41949
42108
|
var import_node_os12 = require("node:os");
|
|
41950
|
-
var
|
|
42109
|
+
var import_node_path60 = require("node:path");
|
|
41951
42110
|
var REPO_FILES = [
|
|
41952
42111
|
".gitignore",
|
|
41953
42112
|
"CLAUDE.md",
|
|
@@ -41962,7 +42121,7 @@ var SKILLS_DIR = ".claude/skills";
|
|
|
41962
42121
|
var MAX_HASH_BYTES = 2 * 1024 * 1024;
|
|
41963
42122
|
var MAX_TREE_ENTRIES = 2e3;
|
|
41964
42123
|
function userSettingsDir(env) {
|
|
41965
|
-
return env.CLAUDE_CONFIG_DIR || (0,
|
|
42124
|
+
return env.CLAUDE_CONFIG_DIR || (0, import_node_path60.join)(env.HOME || (0, import_node_os12.homedir)(), ".claude");
|
|
41966
42125
|
}
|
|
41967
42126
|
function fingerprint(root, rel) {
|
|
41968
42127
|
const opened = openRegularInRoot(root, rel);
|
|
@@ -41970,7 +42129,7 @@ function fingerprint(root, rel) {
|
|
|
41970
42129
|
if (opened.reason === "missing") return null;
|
|
41971
42130
|
if (opened.reason === "symlink") {
|
|
41972
42131
|
try {
|
|
41973
|
-
return `link:${(0,
|
|
42132
|
+
return `link:${(0, import_node_fs72.readlinkSync)((0, import_node_path60.join)(root, rel))}`;
|
|
41974
42133
|
} catch {
|
|
41975
42134
|
return "link";
|
|
41976
42135
|
}
|
|
@@ -41989,7 +42148,7 @@ function fingerprint(root, rel) {
|
|
|
41989
42148
|
}
|
|
41990
42149
|
function treeFingerprint(root, dirRel) {
|
|
41991
42150
|
try {
|
|
41992
|
-
if (!(0,
|
|
42151
|
+
if (!(0, import_node_fs72.lstatSync)((0, import_node_path60.join)(root, dirRel)).isDirectory()) return fingerprint(root, dirRel);
|
|
41993
42152
|
} catch {
|
|
41994
42153
|
return null;
|
|
41995
42154
|
}
|
|
@@ -41997,7 +42156,7 @@ function treeFingerprint(root, dirRel) {
|
|
|
41997
42156
|
const walk2 = (rel) => {
|
|
41998
42157
|
let names2;
|
|
41999
42158
|
try {
|
|
42000
|
-
names2 = (0,
|
|
42159
|
+
names2 = (0, import_node_fs72.readdirSync)((0, import_node_path60.join)(root, rel)).sort();
|
|
42001
42160
|
} catch {
|
|
42002
42161
|
return;
|
|
42003
42162
|
}
|
|
@@ -42006,7 +42165,7 @@ function treeFingerprint(root, dirRel) {
|
|
|
42006
42165
|
const relPath = `${rel}/${name2}`;
|
|
42007
42166
|
let st;
|
|
42008
42167
|
try {
|
|
42009
|
-
st = (0,
|
|
42168
|
+
st = (0, import_node_fs72.lstatSync)((0, import_node_path60.join)(root, relPath));
|
|
42010
42169
|
} catch {
|
|
42011
42170
|
continue;
|
|
42012
42171
|
}
|
|
@@ -42030,8 +42189,8 @@ function changedSince(before, after) {
|
|
|
42030
42189
|
|
|
42031
42190
|
// src/lib/init-trace.ts
|
|
42032
42191
|
var import_node_crypto25 = require("node:crypto");
|
|
42033
|
-
var
|
|
42034
|
-
var
|
|
42192
|
+
var import_node_fs73 = require("node:fs");
|
|
42193
|
+
var import_node_path61 = require("node:path");
|
|
42035
42194
|
var INIT_STEPS = [
|
|
42036
42195
|
"started",
|
|
42037
42196
|
"prerequisites",
|
|
@@ -42077,9 +42236,9 @@ function traceDisabled(env = process.env) {
|
|
|
42077
42236
|
}
|
|
42078
42237
|
var PENDING_NAME = "init-trace.json";
|
|
42079
42238
|
var MAX_PENDING_BYTES = 64 * 1024;
|
|
42080
|
-
var verityHome2 = () => (0,
|
|
42239
|
+
var verityHome2 = () => (0, import_node_path61.join)(process.env.HOME ?? "", ".verity");
|
|
42081
42240
|
function pendingTracePath() {
|
|
42082
|
-
return (0,
|
|
42241
|
+
return (0, import_node_path61.join)(verityHome2(), PENDING_NAME);
|
|
42083
42242
|
}
|
|
42084
42243
|
var RUN_ID = /^[0-9a-f]{16}$/;
|
|
42085
42244
|
var CLI_VERSION = /^[0-9A-Za-z.+-]{1,40}$/;
|
|
@@ -42137,10 +42296,10 @@ function writePending(runs) {
|
|
|
42137
42296
|
try {
|
|
42138
42297
|
const kept = runs.filter((r) => r.events.length > 0).slice(-MAX_PENDING_RUNS);
|
|
42139
42298
|
if (kept.length === 0) {
|
|
42140
|
-
(0,
|
|
42299
|
+
(0, import_node_fs73.rmSync)(pendingTracePath(), { force: true });
|
|
42141
42300
|
return;
|
|
42142
42301
|
}
|
|
42143
|
-
(0,
|
|
42302
|
+
(0, import_node_fs73.mkdirSync)(verityHome2(), { recursive: true });
|
|
42144
42303
|
if (!replaceInRoot(verityHome2(), PENDING_NAME, JSON.stringify(kept))) {
|
|
42145
42304
|
logEvent("init_trace_save_refused", {});
|
|
42146
42305
|
}
|
|
@@ -42852,8 +43011,8 @@ var Rail = class {
|
|
|
42852
43011
|
};
|
|
42853
43012
|
|
|
42854
43013
|
// src/commands/init/ui.ts
|
|
42855
|
-
var
|
|
42856
|
-
var
|
|
43014
|
+
var import_node_fs74 = require("node:fs");
|
|
43015
|
+
var import_node_path62 = require("node:path");
|
|
42857
43016
|
var import_node_os13 = require("node:os");
|
|
42858
43017
|
var import_node_child_process18 = require("node:child_process");
|
|
42859
43018
|
function createInitUi(opts) {
|
|
@@ -42873,10 +43032,10 @@ function installInterrupt(ui) {
|
|
|
42873
43032
|
}
|
|
42874
43033
|
var SEEN_FILE = ".init-seen";
|
|
42875
43034
|
function firstInitOnMachine(home = process.env.HOME || (0, import_node_os13.homedir)()) {
|
|
42876
|
-
return !(0,
|
|
43035
|
+
return !(0, import_node_fs74.existsSync)((0, import_node_path62.join)(home, ".verity", SEEN_FILE));
|
|
42877
43036
|
}
|
|
42878
43037
|
function markInitSeen(home = process.env.HOME || (0, import_node_os13.homedir)()) {
|
|
42879
|
-
replaceInRoot((0,
|
|
43038
|
+
replaceInRoot((0, import_node_path62.join)(home, ".verity"), SEEN_FILE, `${(/* @__PURE__ */ new Date()).toISOString()}
|
|
42880
43039
|
`);
|
|
42881
43040
|
}
|
|
42882
43041
|
function repoLabel() {
|
|
@@ -42886,12 +43045,12 @@ function repoLabel() {
|
|
|
42886
43045
|
if (parsed) return terminalText(`${parsed.owner}/${parsed.repo}`, 120);
|
|
42887
43046
|
} catch {
|
|
42888
43047
|
}
|
|
42889
|
-
return terminalText((0,
|
|
43048
|
+
return terminalText((0, import_node_path62.basename)(repoRoot()), 120);
|
|
42890
43049
|
}
|
|
42891
43050
|
|
|
42892
43051
|
// src/lib/prereqs.ts
|
|
42893
43052
|
var import_node_child_process19 = require("node:child_process");
|
|
42894
|
-
var
|
|
43053
|
+
var import_node_fs75 = require("node:fs");
|
|
42895
43054
|
var MIN_NODE_MAJOR = 20;
|
|
42896
43055
|
function which(bin) {
|
|
42897
43056
|
return whichSync(bin, { real: false });
|
|
@@ -42959,7 +43118,7 @@ function checkAnalysisCli(opts = {}) {
|
|
|
42959
43118
|
}
|
|
42960
43119
|
function sameFile(a, b) {
|
|
42961
43120
|
try {
|
|
42962
|
-
return (0,
|
|
43121
|
+
return (0, import_node_fs75.realpathSync)(a) === (0, import_node_fs75.realpathSync)(b);
|
|
42963
43122
|
} catch {
|
|
42964
43123
|
return false;
|
|
42965
43124
|
}
|
|
@@ -43019,12 +43178,12 @@ async function checkPrereqs(opts = {}) {
|
|
|
43019
43178
|
}
|
|
43020
43179
|
|
|
43021
43180
|
// src/lib/telemetry-local.ts
|
|
43022
|
-
var
|
|
43181
|
+
var import_node_path64 = require("node:path");
|
|
43023
43182
|
|
|
43024
43183
|
// src/lib/telemetry-settings.ts
|
|
43025
43184
|
var import_promises14 = require("node:fs/promises");
|
|
43026
43185
|
var import_node_os14 = require("node:os");
|
|
43027
|
-
var
|
|
43186
|
+
var import_node_path63 = require("node:path");
|
|
43028
43187
|
var SETTINGS_LOCAL_FILE2 = ".claude/settings.local.json";
|
|
43029
43188
|
var OTEL_HEADERS_HELPER_CMD = "verity telemetry headers";
|
|
43030
43189
|
var LEGACY_HEADER_KEY = "OTEL_EXPORTER_OTLP_HEADERS";
|
|
@@ -43035,10 +43194,10 @@ var OTLP_ENDPOINT_KEYS = [
|
|
|
43035
43194
|
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT"
|
|
43036
43195
|
];
|
|
43037
43196
|
function claudeConfigDir2() {
|
|
43038
|
-
return process.env.CLAUDE_CONFIG_DIR || (0,
|
|
43197
|
+
return process.env.CLAUDE_CONFIG_DIR || (0, import_node_path63.join)((0, import_node_os14.homedir)(), ".claude");
|
|
43039
43198
|
}
|
|
43040
43199
|
function userSettingsPath() {
|
|
43041
|
-
return (0,
|
|
43200
|
+
return (0, import_node_path63.join)(claudeConfigDir2(), "settings.json");
|
|
43042
43201
|
}
|
|
43043
43202
|
function deriveOtlpEndpoint(serviceUrl) {
|
|
43044
43203
|
return serviceUrl.replace(/\/+$/, "").replace(/\/v1$/, "") + "/v1/otlp";
|
|
@@ -43159,7 +43318,7 @@ async function healLocalTelemetry(root = repoRoot()) {
|
|
|
43159
43318
|
if (settings.env && Object.keys(env).length === 0) delete settings.env;
|
|
43160
43319
|
if (plan.helper) delete settings.otelHeadersHelper;
|
|
43161
43320
|
const next = nextLocalBytes(local.raw, settings);
|
|
43162
|
-
if (next !== null && !replaceInRoot((0,
|
|
43321
|
+
if (next !== null && !replaceInRoot((0, import_node_path64.join)(root, ".claude"), "settings.local.json", next)) {
|
|
43163
43322
|
return { removed: [] };
|
|
43164
43323
|
}
|
|
43165
43324
|
return { removed: [...plan.envKeys, ...plan.helper ? ["otelHeadersHelper"] : []] };
|
|
@@ -43167,8 +43326,8 @@ async function healLocalTelemetry(root = repoRoot()) {
|
|
|
43167
43326
|
|
|
43168
43327
|
// src/lib/telemetry-gate.ts
|
|
43169
43328
|
var import_node_child_process20 = require("node:child_process");
|
|
43170
|
-
var
|
|
43171
|
-
var
|
|
43329
|
+
var import_node_fs76 = require("node:fs");
|
|
43330
|
+
var import_node_path65 = require("node:path");
|
|
43172
43331
|
var PROJECT_MARKERS = ["setup.json", "config.json"];
|
|
43173
43332
|
function writtenOnThisMachine(root, rel) {
|
|
43174
43333
|
const r = (0, import_node_child_process20.spawnSync)("git", hardenedGitArgv(["ls-files", "--error-unmatch", "--", rel]), {
|
|
@@ -43185,10 +43344,10 @@ function writtenOnThisMachine(root, rel) {
|
|
|
43185
43344
|
function isTelemetryProject() {
|
|
43186
43345
|
for (const root of [repoRoot(), mainWorktreeRoot()]) {
|
|
43187
43346
|
if (!root) continue;
|
|
43188
|
-
const dir = (0,
|
|
43347
|
+
const dir = (0, import_node_path65.join)(root, VERITY_DIR);
|
|
43189
43348
|
if (isMachineStore(dir)) continue;
|
|
43190
43349
|
for (const marker of PROJECT_MARKERS) {
|
|
43191
|
-
if ((0,
|
|
43350
|
+
if ((0, import_node_fs76.existsSync)((0, import_node_path65.join)(dir, marker)) && writtenOnThisMachine(root, `${VERITY_DIR}/${marker}`)) return true;
|
|
43192
43351
|
}
|
|
43193
43352
|
}
|
|
43194
43353
|
return false;
|
|
@@ -43453,7 +43612,7 @@ function signInDetail(outcome) {
|
|
|
43453
43612
|
}
|
|
43454
43613
|
function formalDefault(previous, opts = {}) {
|
|
43455
43614
|
const cfg = readProjectConfig();
|
|
43456
|
-
if (previous?.init?.completed_at || opts.setUpBefore || cfg.formal !== void 0 || cfg.formal_refused) return false;
|
|
43615
|
+
if (previous?.init?.completed_at || opts.setUpBefore || cfg.formal !== void 0 || cfg.formal_refused || cfg.formal_off_refused) return false;
|
|
43457
43616
|
writeProjectConfig({ formal: "push" });
|
|
43458
43617
|
return true;
|
|
43459
43618
|
}
|
|
@@ -43464,9 +43623,13 @@ function sayFormalOn(ui) {
|
|
|
43464
43623
|
}
|
|
43465
43624
|
function backgroundStep(ui, opts) {
|
|
43466
43625
|
const { rail } = ui;
|
|
43467
|
-
const
|
|
43468
|
-
const
|
|
43469
|
-
|
|
43626
|
+
const setting = formalSetting(readProjectConfig());
|
|
43627
|
+
const formal = setting.state;
|
|
43628
|
+
const said = formal === "push" && (opts.formalNew === true || setting.source === "default" && formalDefaultNoticeDue());
|
|
43629
|
+
if (said) {
|
|
43630
|
+
sayFormalOn(ui);
|
|
43631
|
+
recordFormalDefaultNotice();
|
|
43632
|
+
}
|
|
43470
43633
|
const lean = shouldStartBackgroundInstall({ formal });
|
|
43471
43634
|
const leanStarted = lean.start && startBackgroundInstall({ cli: opts.cli });
|
|
43472
43635
|
const trivy = startTrivyPrewarm();
|
|
@@ -43597,7 +43760,9 @@ async function scaffoldStep(ui, given = {}) {
|
|
|
43597
43760
|
rail.line(`Could not update CLAUDE.md: ${terminalText(err2.message, 300)}`, "warn");
|
|
43598
43761
|
}
|
|
43599
43762
|
const cfg = readProjectConfig();
|
|
43600
|
-
if (cfg.
|
|
43763
|
+
if (cfg.formal_off_refused && formalSetting(cfg).state === "push") {
|
|
43764
|
+
rail.line(`Formal verification: on \u2014 ${formalOffRefusalMessage(cfg.formal_off_refused)}`, "warn");
|
|
43765
|
+
}
|
|
43601
43766
|
rail.settle();
|
|
43602
43767
|
}
|
|
43603
43768
|
async function askUntrackState(ui, tracked) {
|
|
@@ -43635,9 +43800,9 @@ function retireCodacyConfig(ui) {
|
|
|
43635
43800
|
}
|
|
43636
43801
|
|
|
43637
43802
|
// src/commands/init/wiring.ts
|
|
43638
|
-
var
|
|
43803
|
+
var import_node_fs77 = require("node:fs");
|
|
43639
43804
|
var import_promises16 = require("node:fs/promises");
|
|
43640
|
-
var
|
|
43805
|
+
var import_node_path66 = require("node:path");
|
|
43641
43806
|
var DEFAULT_MOMENTS = ["stop", "pre-commit", "pre-push"];
|
|
43642
43807
|
async function momentsFromInstalledHooks() {
|
|
43643
43808
|
const status = await checkAllVerityHooks();
|
|
@@ -43710,12 +43875,12 @@ var SKILLS = [
|
|
|
43710
43875
|
];
|
|
43711
43876
|
function resolveDataDir2() {
|
|
43712
43877
|
const candidates2 = [
|
|
43713
|
-
(0,
|
|
43714
|
-
(0,
|
|
43715
|
-
(0,
|
|
43878
|
+
(0, import_node_path66.join)(__dirname, "..", "data"),
|
|
43879
|
+
(0, import_node_path66.join)(__dirname, "..", "..", "data"),
|
|
43880
|
+
(0, import_node_path66.join)(process.cwd(), "cli", "data")
|
|
43716
43881
|
];
|
|
43717
43882
|
for (const candidate of candidates2) {
|
|
43718
|
-
if ((0,
|
|
43883
|
+
if ((0, import_node_fs77.existsSync)((0, import_node_path66.join)(candidate, "skills"))) return candidate;
|
|
43719
43884
|
}
|
|
43720
43885
|
throw new Error("Could not find Verity skill data. Reinstall: npm install -g @codacy/verity-cli");
|
|
43721
43886
|
}
|
|
@@ -43723,9 +43888,9 @@ async function skillIsCurrent(src, dest) {
|
|
|
43723
43888
|
const list2 = (dir) => {
|
|
43724
43889
|
const out2 = [];
|
|
43725
43890
|
const walk2 = (d, prefix) => {
|
|
43726
|
-
for (const e of (0,
|
|
43891
|
+
for (const e of (0, import_node_fs77.readdirSync)(d, { withFileTypes: true })) {
|
|
43727
43892
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
43728
|
-
if (e.isDirectory()) walk2((0,
|
|
43893
|
+
if (e.isDirectory()) walk2((0, import_node_path66.join)(d, e.name), rel);
|
|
43729
43894
|
else if (e.isFile()) out2.push(rel);
|
|
43730
43895
|
}
|
|
43731
43896
|
};
|
|
@@ -43736,7 +43901,7 @@ async function skillIsCurrent(src, dest) {
|
|
|
43736
43901
|
const shipped = list2(src);
|
|
43737
43902
|
if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
|
|
43738
43903
|
for (const rel of shipped) {
|
|
43739
|
-
if (await (0, import_promises16.readFile)((0,
|
|
43904
|
+
if (await (0, import_promises16.readFile)((0, import_node_path66.join)(src, rel), "utf-8") !== await (0, import_promises16.readFile)((0, import_node_path66.join)(dest, rel), "utf-8")) return false;
|
|
43740
43905
|
}
|
|
43741
43906
|
return true;
|
|
43742
43907
|
} catch {
|
|
@@ -43744,16 +43909,16 @@ async function skillIsCurrent(src, dest) {
|
|
|
43744
43909
|
}
|
|
43745
43910
|
}
|
|
43746
43911
|
async function installSkills(force) {
|
|
43747
|
-
const source2 = (0,
|
|
43912
|
+
const source2 = (0, import_node_path66.join)(resolveDataDir2(), "skills");
|
|
43748
43913
|
const missing = [];
|
|
43749
43914
|
for (const skill of SKILLS) {
|
|
43750
|
-
const src = (0,
|
|
43751
|
-
const dest = (0,
|
|
43752
|
-
if (!(0,
|
|
43915
|
+
const src = (0, import_node_path66.join)(source2, skill);
|
|
43916
|
+
const dest = (0, import_node_path66.join)(".claude/skills", skill);
|
|
43917
|
+
if (!(0, import_node_fs77.existsSync)(src)) {
|
|
43753
43918
|
missing.push(skill);
|
|
43754
43919
|
continue;
|
|
43755
43920
|
}
|
|
43756
|
-
if ((0,
|
|
43921
|
+
if ((0, import_node_fs77.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) continue;
|
|
43757
43922
|
await (0, import_promises16.mkdir)(dest, { recursive: true });
|
|
43758
43923
|
await (0, import_promises16.cp)(src, dest, { recursive: true, force: true });
|
|
43759
43924
|
}
|
|
@@ -43793,8 +43958,8 @@ async function hooksStep(ui, ctx) {
|
|
|
43793
43958
|
}
|
|
43794
43959
|
|
|
43795
43960
|
// src/commands/init/standard.ts
|
|
43796
|
-
var
|
|
43797
|
-
var
|
|
43961
|
+
var import_node_fs78 = require("node:fs");
|
|
43962
|
+
var import_node_path67 = require("node:path");
|
|
43798
43963
|
var import_yaml10 = __toESM2(require_dist());
|
|
43799
43964
|
|
|
43800
43965
|
// src/lib/catalogue-client.ts
|
|
@@ -43985,9 +44150,9 @@ function localStandard() {
|
|
|
43985
44150
|
function removeLocalStandard() {
|
|
43986
44151
|
const path = projectPath(STANDARD_FILE);
|
|
43987
44152
|
try {
|
|
43988
|
-
const folder = (0,
|
|
44153
|
+
const folder = (0, import_node_fs78.lstatSync)((0, import_node_path67.dirname)(path));
|
|
43989
44154
|
if (!folder.isDirectory() || folder.isSymbolicLink()) return;
|
|
43990
|
-
if ((0,
|
|
44155
|
+
if ((0, import_node_fs78.lstatSync)(path).isFile()) (0, import_node_fs78.unlinkSync)(path);
|
|
43991
44156
|
} catch {
|
|
43992
44157
|
}
|
|
43993
44158
|
}
|
|
@@ -44001,7 +44166,7 @@ function setLocalStandardAside(now = /* @__PURE__ */ new Date(), remove = remove
|
|
|
44001
44166
|
return { ok: false, message: `Could not keep a copy of ${STANDARD_FILE} (${terminalText(err2 instanceof Error ? err2.message : String(err2), 200)}), so it was not set aside.` };
|
|
44002
44167
|
}
|
|
44003
44168
|
remove();
|
|
44004
|
-
if ((0,
|
|
44169
|
+
if ((0, import_node_fs78.existsSync)(projectPath(STANDARD_FILE))) return { ok: false, message: `Could not remove ${STANDARD_FILE} after copying it to ${path}.` };
|
|
44005
44170
|
return { ok: true, path };
|
|
44006
44171
|
}
|
|
44007
44172
|
async function standardStep(ui, ctx) {
|
|
@@ -44063,7 +44228,7 @@ async function standardStep(ui, ctx) {
|
|
|
44063
44228
|
rail.line(team2.status === "none" ? `There is no Standard on the service either, so reviews have no rules. Fix ${STANDARD_FILE}, or delete it, then run verity init again.` : team2.status === "unavailable" ? `The Verity service did not answer (${terminalText(team2.reason, 200)}), so no Standard is confirmed. Fix ${STANDARD_FILE}, then run verity init again.` : team2.status === "denied" && refusalOutcome(team2.code) === "denied" ? `Verity has no access to this repository (${terminalText(team2.reason, 200)}). Fix ${STANDARD_FILE}, give the Verity GitHub App access, then run verity login and verity init.` : team2.status === "denied" ? `The Verity service did not accept your sign-in (${terminalText(team2.reason, 200)}). Fix ${STANDARD_FILE}, then run verity login and verity init.` : `No Standard on the service was looked up. Fix ${STANDARD_FILE}, or sign in, then run verity init again.`);
|
|
44064
44229
|
return end({ source: "none", version: null, profile: notAsked });
|
|
44065
44230
|
};
|
|
44066
|
-
if (ctx.standard === "new" && (0,
|
|
44231
|
+
if (ctx.standard === "new" && (0, import_node_fs78.lstatSync)(projectPath(STANDARD_FILE), { throwIfNoEntry: false })) {
|
|
44067
44232
|
const aside = setLocalStandardAside();
|
|
44068
44233
|
if (!aside.ok) {
|
|
44069
44234
|
rail.warn("Could not set your Standard aside for a new one");
|
|
@@ -44140,7 +44305,7 @@ async function standardStep(ui, ctx) {
|
|
|
44140
44305
|
await keptHints();
|
|
44141
44306
|
return end({ source: "kept", version, profile: notAsked });
|
|
44142
44307
|
};
|
|
44143
|
-
if ((0,
|
|
44308
|
+
if ((0, import_node_fs78.existsSync)(projectPath(STANDARD_FILE))) {
|
|
44144
44309
|
const local = localStandard();
|
|
44145
44310
|
if (!local.ok) return unusableHere(local.problem);
|
|
44146
44311
|
return keptHere(local.content);
|
|
@@ -44266,8 +44431,8 @@ function sayChanged(ui, before) {
|
|
|
44266
44431
|
}
|
|
44267
44432
|
|
|
44268
44433
|
// src/commands/migrate.ts
|
|
44269
|
-
var
|
|
44270
|
-
var
|
|
44434
|
+
var import_node_fs79 = require("node:fs");
|
|
44435
|
+
var import_node_path68 = require("node:path");
|
|
44271
44436
|
var import_node_child_process22 = require("node:child_process");
|
|
44272
44437
|
var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
|
|
44273
44438
|
function defaultNpmRemover(pkg) {
|
|
@@ -44331,12 +44496,12 @@ async function runMigration(opts = {}) {
|
|
|
44331
44496
|
return { actions, migrated: actions.length > 0 };
|
|
44332
44497
|
}
|
|
44333
44498
|
function migrateProjectDir(root, actions) {
|
|
44334
|
-
const gateDir = (0,
|
|
44335
|
-
const verityDir = (0,
|
|
44336
|
-
if ((0,
|
|
44499
|
+
const gateDir = (0, import_node_path68.join)(root, ".gate");
|
|
44500
|
+
const verityDir = (0, import_node_path68.join)(root, ".verity");
|
|
44501
|
+
if ((0, import_node_fs79.existsSync)(gateDir) && !(0, import_node_fs79.existsSync)(verityDir)) {
|
|
44337
44502
|
return migrateProjectDirRename(root, gateDir, verityDir, actions);
|
|
44338
44503
|
}
|
|
44339
|
-
if ((0,
|
|
44504
|
+
if ((0, import_node_fs79.existsSync)(gateDir) && (0, import_node_fs79.existsSync)(verityDir)) {
|
|
44340
44505
|
return migrateProjectDirCarry(gateDir, verityDir, actions);
|
|
44341
44506
|
}
|
|
44342
44507
|
return false;
|
|
@@ -44357,13 +44522,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
|
|
|
44357
44522
|
}
|
|
44358
44523
|
}
|
|
44359
44524
|
if (moved) {
|
|
44360
|
-
if ((0,
|
|
44525
|
+
if ((0, import_node_fs79.existsSync)(gateDir)) {
|
|
44361
44526
|
const carried = carryLegacyContents(gateDir, verityDir);
|
|
44362
44527
|
if (carried > 0) {
|
|
44363
44528
|
actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
|
|
44364
44529
|
}
|
|
44365
44530
|
try {
|
|
44366
|
-
(0,
|
|
44531
|
+
(0, import_node_fs79.rmSync)(gateDir, { recursive: true, force: true });
|
|
44367
44532
|
} catch {
|
|
44368
44533
|
}
|
|
44369
44534
|
}
|
|
@@ -44379,18 +44544,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
|
|
|
44379
44544
|
actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
|
|
44380
44545
|
}
|
|
44381
44546
|
try {
|
|
44382
|
-
(0,
|
|
44547
|
+
(0, import_node_fs79.rmSync)(gateDir, { recursive: true, force: true });
|
|
44383
44548
|
} catch {
|
|
44384
44549
|
}
|
|
44385
44550
|
return carried > 0;
|
|
44386
44551
|
}
|
|
44387
44552
|
function migrateGlobalCredentials(home, actions) {
|
|
44388
44553
|
if (!home) return;
|
|
44389
|
-
const gateCreds = (0,
|
|
44390
|
-
const verityCreds = (0,
|
|
44391
|
-
if (!(0,
|
|
44392
|
-
if (!(0,
|
|
44393
|
-
(0,
|
|
44554
|
+
const gateCreds = (0, import_node_path68.join)(home, ".gate", "credentials");
|
|
44555
|
+
const verityCreds = (0, import_node_path68.join)(home, ".verity", "credentials");
|
|
44556
|
+
if (!(0, import_node_fs79.existsSync)(gateCreds)) return;
|
|
44557
|
+
if (!(0, import_node_fs79.existsSync)(verityCreds)) {
|
|
44558
|
+
(0, import_node_fs79.mkdirSync)((0, import_node_path68.join)(home, ".verity"), { recursive: true });
|
|
44394
44559
|
moveFile(gateCreds, verityCreds);
|
|
44395
44560
|
actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
|
|
44396
44561
|
return;
|
|
@@ -44412,8 +44577,8 @@ async function migrateLegacyHooks(root, actions) {
|
|
|
44412
44577
|
}
|
|
44413
44578
|
}
|
|
44414
44579
|
async function migrateClaudeMd(root, actions) {
|
|
44415
|
-
const claudeMd = (0,
|
|
44416
|
-
const hadLegacyBlock = (0,
|
|
44580
|
+
const claudeMd = (0, import_node_path68.join)(root, "CLAUDE.md");
|
|
44581
|
+
const hadLegacyBlock = (0, import_node_fs79.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
|
|
44417
44582
|
if (!hadLegacyBlock) return;
|
|
44418
44583
|
try {
|
|
44419
44584
|
await ensureClaudeMdPointer(root);
|
|
@@ -44423,9 +44588,9 @@ async function migrateClaudeMd(root, actions) {
|
|
|
44423
44588
|
}
|
|
44424
44589
|
}
|
|
44425
44590
|
function migrateStandardFile(root, actions) {
|
|
44426
|
-
const gateMd = (0,
|
|
44427
|
-
const verityMd = (0,
|
|
44428
|
-
if (!(0,
|
|
44591
|
+
const gateMd = (0, import_node_path68.join)(root, "GATE.md");
|
|
44592
|
+
const verityMd = (0, import_node_path68.join)(root, "VERITY.md");
|
|
44593
|
+
if (!(0, import_node_fs79.existsSync)(gateMd) || (0, import_node_fs79.existsSync)(verityMd)) return;
|
|
44429
44594
|
let moved = false;
|
|
44430
44595
|
if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
|
|
44431
44596
|
try {
|
|
@@ -44437,7 +44602,7 @@ function migrateStandardFile(root, actions) {
|
|
|
44437
44602
|
if (!moved) moveFile(gateMd, verityMd);
|
|
44438
44603
|
const content = readFileSyncSafe(verityMd);
|
|
44439
44604
|
const refreshed = content.split("GATE.md").join("VERITY.md");
|
|
44440
|
-
if (refreshed !== content) (0,
|
|
44605
|
+
if (refreshed !== content) (0, import_node_fs79.writeFileSync)(verityMd, refreshed);
|
|
44441
44606
|
actions.push("Renamed GATE.md \u2192 VERITY.md");
|
|
44442
44607
|
}
|
|
44443
44608
|
async function migrateLocalTelemetry(root, actions) {
|
|
@@ -44481,14 +44646,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
|
|
|
44481
44646
|
}
|
|
44482
44647
|
if (toAppend.length > 0) {
|
|
44483
44648
|
const sep7 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
|
|
44484
|
-
(0,
|
|
44649
|
+
(0, import_node_fs79.writeFileSync)(verityCreds, verityContent + sep7 + toAppend.join("\n") + "\n");
|
|
44485
44650
|
}
|
|
44486
|
-
(0,
|
|
44651
|
+
(0, import_node_fs79.rmSync)(gateCreds, { force: true });
|
|
44487
44652
|
return toAppend.length;
|
|
44488
44653
|
}
|
|
44489
44654
|
function readFileSyncSafe(path) {
|
|
44490
44655
|
try {
|
|
44491
|
-
return (0,
|
|
44656
|
+
return (0, import_node_fs79.readFileSync)(path, "utf-8");
|
|
44492
44657
|
} catch {
|
|
44493
44658
|
return "";
|
|
44494
44659
|
}
|
|
@@ -44503,20 +44668,20 @@ function hasStagedChanges(root) {
|
|
|
44503
44668
|
}
|
|
44504
44669
|
function moveDir(from, to) {
|
|
44505
44670
|
try {
|
|
44506
|
-
(0,
|
|
44671
|
+
(0, import_node_fs79.renameSync)(from, to);
|
|
44507
44672
|
} catch (err2) {
|
|
44508
44673
|
if (err2.code !== "EXDEV") throw err2;
|
|
44509
|
-
(0,
|
|
44510
|
-
(0,
|
|
44674
|
+
(0, import_node_fs79.cpSync)(from, to, { recursive: true });
|
|
44675
|
+
(0, import_node_fs79.rmSync)(from, { recursive: true, force: true });
|
|
44511
44676
|
}
|
|
44512
44677
|
}
|
|
44513
44678
|
function moveFile(from, to) {
|
|
44514
44679
|
try {
|
|
44515
|
-
(0,
|
|
44680
|
+
(0, import_node_fs79.renameSync)(from, to);
|
|
44516
44681
|
} catch (err2) {
|
|
44517
44682
|
if (err2.code !== "EXDEV") throw err2;
|
|
44518
|
-
(0,
|
|
44519
|
-
(0,
|
|
44683
|
+
(0, import_node_fs79.cpSync)(from, to);
|
|
44684
|
+
(0, import_node_fs79.rmSync)(from, { force: true });
|
|
44520
44685
|
}
|
|
44521
44686
|
}
|
|
44522
44687
|
function carryLegacyContents(gateDir, verityDir) {
|
|
@@ -44525,12 +44690,12 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
44525
44690
|
const walk2 = (relDir) => {
|
|
44526
44691
|
let entries;
|
|
44527
44692
|
try {
|
|
44528
|
-
entries = (0,
|
|
44693
|
+
entries = (0, import_node_fs79.readdirSync)((0, import_node_path68.join)(gateDir, relDir), { withFileTypes: true });
|
|
44529
44694
|
} catch {
|
|
44530
44695
|
return;
|
|
44531
44696
|
}
|
|
44532
44697
|
for (const entry of entries) {
|
|
44533
|
-
const rel = relDir ? (0,
|
|
44698
|
+
const rel = relDir ? (0, import_node_path68.join)(relDir, entry.name) : entry.name;
|
|
44534
44699
|
if (entry.isSymbolicLink()) continue;
|
|
44535
44700
|
if (entry.isDirectory()) {
|
|
44536
44701
|
walk2(rel);
|
|
@@ -44540,7 +44705,7 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
44540
44705
|
const opened = openRegularInRoot(gateDir, rel);
|
|
44541
44706
|
if (!opened.ok) continue;
|
|
44542
44707
|
try {
|
|
44543
|
-
(0,
|
|
44708
|
+
(0, import_node_fs79.writeFileSync)((0, import_node_path68.join)(verityDir, rel), readOpened(opened.fd, opened.size), { flag: "wx", mode: 384 });
|
|
44544
44709
|
copied++;
|
|
44545
44710
|
} catch {
|
|
44546
44711
|
}
|
|
@@ -44550,19 +44715,19 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
44550
44715
|
return copied;
|
|
44551
44716
|
}
|
|
44552
44717
|
function hasLegacyStandard(root = repoRoot()) {
|
|
44553
|
-
if (!isRealDir((0,
|
|
44718
|
+
if (!isRealDir((0, import_node_path68.join)(root, ".gate"))) return false;
|
|
44554
44719
|
try {
|
|
44555
|
-
if (!(0,
|
|
44720
|
+
if (!(0, import_node_fs79.lstatSync)((0, import_node_path68.join)(root, ".gate", "standard.yaml")).isFile()) return false;
|
|
44556
44721
|
} catch {
|
|
44557
44722
|
return false;
|
|
44558
44723
|
}
|
|
44559
|
-
const verityDir = (0,
|
|
44724
|
+
const verityDir = (0, import_node_path68.join)(root, ".verity");
|
|
44560
44725
|
if (pathEntryExists(verityDir) && !isRealDir(verityDir)) return false;
|
|
44561
|
-
return !pathEntryExists((0,
|
|
44726
|
+
return !pathEntryExists((0, import_node_path68.join)(verityDir, "standard.yaml"));
|
|
44562
44727
|
}
|
|
44563
44728
|
function pathEntryExists(path) {
|
|
44564
44729
|
try {
|
|
44565
|
-
(0,
|
|
44730
|
+
(0, import_node_fs79.lstatSync)(path);
|
|
44566
44731
|
return true;
|
|
44567
44732
|
} catch {
|
|
44568
44733
|
return false;
|
|
@@ -44570,7 +44735,7 @@ function pathEntryExists(path) {
|
|
|
44570
44735
|
}
|
|
44571
44736
|
function isRealDir(path) {
|
|
44572
44737
|
try {
|
|
44573
|
-
const st = (0,
|
|
44738
|
+
const st = (0, import_node_fs79.lstatSync)(path);
|
|
44574
44739
|
return st.isDirectory() && !st.isSymbolicLink();
|
|
44575
44740
|
} catch {
|
|
44576
44741
|
return false;
|
|
@@ -44579,9 +44744,9 @@ function isRealDir(path) {
|
|
|
44579
44744
|
function ensureRealDirs(root, relDir) {
|
|
44580
44745
|
let current = root;
|
|
44581
44746
|
for (const segment of relDir.split(/[\\/]/).filter(Boolean)) {
|
|
44582
|
-
current = (0,
|
|
44747
|
+
current = (0, import_node_path68.join)(current, segment);
|
|
44583
44748
|
try {
|
|
44584
|
-
(0,
|
|
44749
|
+
(0, import_node_fs79.mkdirSync)(current);
|
|
44585
44750
|
} catch (e) {
|
|
44586
44751
|
if (e.code !== "EEXIST") return false;
|
|
44587
44752
|
}
|
|
@@ -44590,23 +44755,23 @@ function ensureRealDirs(root, relDir) {
|
|
|
44590
44755
|
return true;
|
|
44591
44756
|
}
|
|
44592
44757
|
async function needsMigration(root = repoRoot()) {
|
|
44593
|
-
const gateDir = (0,
|
|
44594
|
-
const verityDir = (0,
|
|
44595
|
-
if ((0,
|
|
44596
|
-
if ((0,
|
|
44597
|
-
if ((0,
|
|
44758
|
+
const gateDir = (0, import_node_path68.join)(root, ".gate");
|
|
44759
|
+
const verityDir = (0, import_node_path68.join)(root, ".verity");
|
|
44760
|
+
if ((0, import_node_fs79.existsSync)(gateDir) && !(0, import_node_fs79.existsSync)(verityDir)) return true;
|
|
44761
|
+
if ((0, import_node_fs79.existsSync)(gateDir) && (0, import_node_fs79.existsSync)(verityDir)) {
|
|
44762
|
+
if ((0, import_node_fs79.existsSync)((0, import_node_path68.join)(gateDir, "credentials")) && !(0, import_node_fs79.existsSync)((0, import_node_path68.join)(verityDir, "credentials"))) {
|
|
44598
44763
|
return true;
|
|
44599
44764
|
}
|
|
44600
|
-
if ((0,
|
|
44765
|
+
if ((0, import_node_fs79.existsSync)((0, import_node_path68.join)(gateDir, "memory")) && !(0, import_node_fs79.existsSync)((0, import_node_path68.join)(verityDir, "memory"))) {
|
|
44601
44766
|
return true;
|
|
44602
44767
|
}
|
|
44603
44768
|
if (hasLegacyStandard(root)) return true;
|
|
44604
44769
|
}
|
|
44605
|
-
const claudeMd = (0,
|
|
44606
|
-
if ((0,
|
|
44770
|
+
const claudeMd = (0, import_node_path68.join)(root, "CLAUDE.md");
|
|
44771
|
+
if ((0, import_node_fs79.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
|
|
44607
44772
|
return true;
|
|
44608
44773
|
}
|
|
44609
|
-
if ((0,
|
|
44774
|
+
if ((0, import_node_fs79.existsSync)((0, import_node_path68.join)(root, "GATE.md")) && !(0, import_node_fs79.existsSync)((0, import_node_path68.join)(root, "VERITY.md"))) {
|
|
44610
44775
|
return true;
|
|
44611
44776
|
}
|
|
44612
44777
|
if (await hasLegacyHooksAt(root)) return true;
|
|
@@ -44846,7 +45011,7 @@ async function recordAnswers(ui, momentIds, telemetry, completed) {
|
|
|
44846
45011
|
moments: momentIds,
|
|
44847
45012
|
...telemetry ? { telemetry } : {},
|
|
44848
45013
|
// A failed run also clears an earlier stamp: "done" describes this checkout now.
|
|
44849
|
-
init: completed ? { completed_at: (/* @__PURE__ */ new Date()).toISOString(), cli_version: true ? "0.35.
|
|
45014
|
+
init: completed ? { completed_at: (/* @__PURE__ */ new Date()).toISOString(), cli_version: true ? "0.35.5" : "dev" } : void 0
|
|
44850
45015
|
});
|
|
44851
45016
|
} catch (err2) {
|
|
44852
45017
|
ui.rail.line(`Could not record the setup answers: ${terminalText(err2.message, 200)}`, "warn");
|
|
@@ -44899,7 +45064,7 @@ async function runInit(program2, opts) {
|
|
|
44899
45064
|
const defaultsOnly = (opts.yes ?? false) || !interactive();
|
|
44900
45065
|
const { givenMoments, givenTelemetry, profileAnswer, standardAnswer } = parseInitFlags(opts);
|
|
44901
45066
|
const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
|
|
44902
|
-
if (!projectMarkers.some((m) => (0,
|
|
45067
|
+
if (!projectMarkers.some((m) => (0, import_node_fs80.existsSync)(m))) {
|
|
44903
45068
|
printError('No project detected in the current directory. Run "verity init" from your project root.');
|
|
44904
45069
|
process.exit(1);
|
|
44905
45070
|
}
|
|
@@ -44927,10 +45092,10 @@ async function runInit(program2, opts) {
|
|
|
44927
45092
|
trace.mark("prerequisites", "ok");
|
|
44928
45093
|
await scaffoldStep(ui, { untrackMemory: opts.untrackMemory === true, untrackStandard: opts.untrackStandard === true, untrackState: opts.untrackState === true });
|
|
44929
45094
|
trace.mark("scaffold", "ok");
|
|
44930
|
-
await (0, import_promises17.mkdir)((0,
|
|
45095
|
+
await (0, import_promises17.mkdir)((0, import_node_path69.join)((0, import_node_os15.homedir)(), ".verity"), { recursive: true });
|
|
44931
45096
|
await repoStep(ui, detectProject());
|
|
44932
45097
|
const previous = await readSetupState();
|
|
44933
|
-
const setUpBefore = (0,
|
|
45098
|
+
const setUpBefore = (0, import_node_fs80.existsSync)(projectPath(STANDARD_FILE));
|
|
44934
45099
|
const answers = await askSetupQuestions(defaultsOnly, previous, { moments: givenMoments, telemetry: givenTelemetry });
|
|
44935
45100
|
trace.mark("questions", "ok", givenMoments || givenTelemetry !== void 0 || profileAnswer || standardAnswer ? "asked" : "defaults");
|
|
44936
45101
|
const plan = planMoments(answers.moments, { given: givenMoments !== void 0, defaultsOnly });
|
|
@@ -44980,7 +45145,7 @@ function registerInitCommand(program2) {
|
|
|
44980
45145
|
}
|
|
44981
45146
|
|
|
44982
45147
|
// src/commands/doctor.ts
|
|
44983
|
-
var
|
|
45148
|
+
var import_node_fs81 = require("node:fs");
|
|
44984
45149
|
var LEGACY_STANDARD_FILE = ".gate/standard.yaml";
|
|
44985
45150
|
async function buildReport() {
|
|
44986
45151
|
const prereqs = await checkPrereqs({ install: false });
|
|
@@ -44990,11 +45155,11 @@ async function buildReport() {
|
|
|
44990
45155
|
const provenance = cliProvenance();
|
|
44991
45156
|
const telemetry = await checkTelemetry();
|
|
44992
45157
|
const artifacts = {
|
|
44993
|
-
standard: (0,
|
|
45158
|
+
standard: (0, import_node_fs81.existsSync)(projectPath(STANDARD_FILE)),
|
|
44994
45159
|
// The migration's own answer, not a bare existsSync: /verity:init skips a
|
|
44995
45160
|
// question on this, so it must be true only when init will carry the file.
|
|
44996
45161
|
legacyStandard: hasLegacyStandard(repoRoot()),
|
|
44997
|
-
verityMd: (0,
|
|
45162
|
+
verityMd: (0, import_node_fs81.existsSync)(projectPath(VERITY_MD_FILE))
|
|
44998
45163
|
};
|
|
44999
45164
|
const next = [];
|
|
45000
45165
|
for (const c of prereqs.checks) {
|
|
@@ -45134,11 +45299,14 @@ function registerDoctorCommand(program2) {
|
|
|
45134
45299
|
printInfo(` Git-moment gate: ${report.hooks.guardOn.length ? report.hooks.guardOn.join(", ") : "off"}`);
|
|
45135
45300
|
{
|
|
45136
45301
|
const cfg = readProjectConfig();
|
|
45137
|
-
const
|
|
45302
|
+
const setting = formalSetting(cfg);
|
|
45303
|
+
const formal = setting.state === "push";
|
|
45138
45304
|
const tc = formal ? findToolchain() : null;
|
|
45139
45305
|
const lean = tc ? "\u2713" : installProgressLine() ?? "MISSING \u2014 verity lean install";
|
|
45140
|
-
|
|
45141
|
-
|
|
45306
|
+
const how = setting.source === "default" ? " by default" : setting.source === "env" ? " (VERITY_GIT_MOMENT_FORMAL)" : "";
|
|
45307
|
+
printInfo(` Formal verification (push): ${formal ? `on${how}, Lean ${lean} (ranking, model writing and replay run on the Verity service with your login)` : `off${how}`}`);
|
|
45308
|
+
if (cfg.formal_off_refused && formal) printWarn(` ${formalOffRefusalMessage(cfg.formal_off_refused)}`);
|
|
45309
|
+
if (cfg.formal_off_unverified && !formal && setting.source === "config") printWarn(` ${formalOffUnverifiedNote()}`);
|
|
45142
45310
|
}
|
|
45143
45311
|
printInfo(` Infra (intent/baseline/compact/session-end): ${[report.hooks.intent, report.hooks.baseline, report.hooks.compact, report.hooks.sessionEnd].filter(Boolean).length}/4`);
|
|
45144
45312
|
printInfo(
|
|
@@ -45164,8 +45332,8 @@ function registerDoctorCommand(program2) {
|
|
|
45164
45332
|
}
|
|
45165
45333
|
|
|
45166
45334
|
// src/commands/uninstall.ts
|
|
45167
|
-
var
|
|
45168
|
-
var
|
|
45335
|
+
var import_node_fs82 = require("node:fs");
|
|
45336
|
+
var import_node_path70 = require("node:path");
|
|
45169
45337
|
function registerUninstallCommand(program2) {
|
|
45170
45338
|
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) => {
|
|
45171
45339
|
const dryRun = opts.dryRun ?? false;
|
|
@@ -45174,11 +45342,11 @@ function registerUninstallCommand(program2) {
|
|
|
45174
45342
|
const actions = [];
|
|
45175
45343
|
const skillsRoot = projectPath(".claude/skills");
|
|
45176
45344
|
for (const name2 of PROJECT_SKILL_NAMES) {
|
|
45177
|
-
const dir = (0,
|
|
45178
|
-
if ((0,
|
|
45345
|
+
const dir = (0, import_node_path70.join)(skillsRoot, name2);
|
|
45346
|
+
if ((0, import_node_fs82.existsSync)(dir)) {
|
|
45179
45347
|
actions.push({
|
|
45180
45348
|
label: `Remove .claude/skills/${name2}/`,
|
|
45181
|
-
apply: () => (0,
|
|
45349
|
+
apply: () => (0, import_node_fs82.rmSync)(dir, { recursive: true, force: true })
|
|
45182
45350
|
});
|
|
45183
45351
|
}
|
|
45184
45352
|
}
|
|
@@ -45192,24 +45360,24 @@ function registerUninstallCommand(program2) {
|
|
|
45192
45360
|
});
|
|
45193
45361
|
}
|
|
45194
45362
|
const verityDir = projectPath(VERITY_DIR);
|
|
45195
|
-
if ((0,
|
|
45363
|
+
if ((0, import_node_fs82.existsSync)(verityDir)) {
|
|
45196
45364
|
actions.push({
|
|
45197
45365
|
label: `Remove ${VERITY_DIR}/`,
|
|
45198
|
-
apply: () => (0,
|
|
45366
|
+
apply: () => (0, import_node_fs82.rmSync)(verityDir, { recursive: true, force: true })
|
|
45199
45367
|
});
|
|
45200
45368
|
}
|
|
45201
45369
|
if (!keepVerityMd) {
|
|
45202
45370
|
const verityMd = projectPath(VERITY_MD_FILE);
|
|
45203
|
-
if ((0,
|
|
45371
|
+
if ((0, import_node_fs82.existsSync)(verityMd)) {
|
|
45204
45372
|
actions.push({
|
|
45205
45373
|
label: `Remove ${VERITY_MD_FILE}`,
|
|
45206
|
-
apply: () => (0,
|
|
45374
|
+
apply: () => (0, import_node_fs82.rmSync)(verityMd, { force: true })
|
|
45207
45375
|
});
|
|
45208
45376
|
}
|
|
45209
45377
|
}
|
|
45210
45378
|
const cleanupEmptyDir = (path) => {
|
|
45211
|
-
if ((0,
|
|
45212
|
-
(0,
|
|
45379
|
+
if ((0, import_node_fs82.existsSync)(path) && (0, import_node_fs82.statSync)(path).isDirectory() && (0, import_node_fs82.readdirSync)(path).length === 0) {
|
|
45380
|
+
(0, import_node_fs82.rmdirSync)(path);
|
|
45213
45381
|
}
|
|
45214
45382
|
};
|
|
45215
45383
|
actions.push({
|
|
@@ -45220,11 +45388,11 @@ function registerUninstallCommand(program2) {
|
|
|
45220
45388
|
}
|
|
45221
45389
|
});
|
|
45222
45390
|
const home = process.env.HOME ?? "";
|
|
45223
|
-
const globalVerityDir = (0,
|
|
45224
|
-
if (purgeGlobal && (0,
|
|
45391
|
+
const globalVerityDir = (0, import_node_path70.join)(home, ".verity");
|
|
45392
|
+
if (purgeGlobal && (0, import_node_fs82.existsSync)(globalVerityDir)) {
|
|
45225
45393
|
actions.push({
|
|
45226
45394
|
label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
|
|
45227
|
-
apply: () => (0,
|
|
45395
|
+
apply: () => (0, import_node_fs82.rmSync)(globalVerityDir, { recursive: true, force: true })
|
|
45228
45396
|
});
|
|
45229
45397
|
}
|
|
45230
45398
|
if (actions.length === 0) {
|
|
@@ -45443,8 +45611,8 @@ function registerTaskCommands(program2) {
|
|
|
45443
45611
|
}
|
|
45444
45612
|
|
|
45445
45613
|
// src/commands/reset.ts
|
|
45446
|
-
var
|
|
45447
|
-
var
|
|
45614
|
+
var import_node_fs83 = require("node:fs");
|
|
45615
|
+
var import_node_path71 = require("node:path");
|
|
45448
45616
|
function registerResetCommand(program2) {
|
|
45449
45617
|
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) => {
|
|
45450
45618
|
const globals = program2.opts();
|
|
@@ -45484,18 +45652,18 @@ function registerResetCommand(program2) {
|
|
|
45484
45652
|
} catch {
|
|
45485
45653
|
}
|
|
45486
45654
|
}
|
|
45487
|
-
const purged = purgeVerityDir((0,
|
|
45655
|
+
const purged = purgeVerityDir((0, import_node_path71.basename)(CACHE_DIR), (name2) => name2.startsWith("pending-"));
|
|
45488
45656
|
if (purged === null) printError(`Did not purge ${CACHE_DIR}: it is not a directory inside ${VERITY_DIR}.`);
|
|
45489
45657
|
const stateDir2 = projectPath(VERITY_DIR);
|
|
45490
45658
|
const filesToClear = [
|
|
45491
|
-
(0,
|
|
45492
|
-
(0,
|
|
45493
|
-
(0,
|
|
45659
|
+
(0, import_node_path71.basename)(INTENT_FILE),
|
|
45660
|
+
(0, import_node_path71.basename)(HASH_FILE),
|
|
45661
|
+
(0, import_node_path71.basename)(BASELINE_SHA_FILE),
|
|
45494
45662
|
".iteration-count",
|
|
45495
45663
|
".last-analysis"
|
|
45496
45664
|
];
|
|
45497
45665
|
for (const name2 of filesToClear) {
|
|
45498
|
-
if (lstatOrNull((0,
|
|
45666
|
+
if (lstatOrNull((0, import_node_path71.join)(stateDir2, name2)) && !replaceInRoot(stateDir2, name2, "")) {
|
|
45499
45667
|
printError(`Did not clear ${VERITY_DIR}/${name2}: it is not a regular file inside ${VERITY_DIR}.`);
|
|
45500
45668
|
}
|
|
45501
45669
|
}
|
|
@@ -45510,29 +45678,29 @@ function registerResetCommand(program2) {
|
|
|
45510
45678
|
}
|
|
45511
45679
|
function lstatOrNull(path) {
|
|
45512
45680
|
try {
|
|
45513
|
-
return (0,
|
|
45681
|
+
return (0, import_node_fs83.lstatSync)(path);
|
|
45514
45682
|
} catch {
|
|
45515
45683
|
return null;
|
|
45516
45684
|
}
|
|
45517
45685
|
}
|
|
45518
45686
|
function purgeVerityDir(child, select) {
|
|
45519
45687
|
const verityDir = projectPath(VERITY_DIR);
|
|
45520
|
-
const dir = (0,
|
|
45688
|
+
const dir = (0, import_node_path71.join)(verityDir, child);
|
|
45521
45689
|
const parent = lstatOrNull(verityDir);
|
|
45522
45690
|
const st = lstatOrNull(dir);
|
|
45523
45691
|
if (!st) return 0;
|
|
45524
45692
|
if (!parent || parent.isSymbolicLink() || !parent.isDirectory()) return null;
|
|
45525
45693
|
if (st.isSymbolicLink() || !st.isDirectory()) return null;
|
|
45526
45694
|
try {
|
|
45527
|
-
if ((0,
|
|
45695
|
+
if ((0, import_node_fs83.realpathSync)(dir) !== (0, import_node_path71.join)((0, import_node_fs83.realpathSync)(verityDir), child)) return null;
|
|
45528
45696
|
} catch {
|
|
45529
45697
|
return null;
|
|
45530
45698
|
}
|
|
45531
45699
|
let removed = 0;
|
|
45532
|
-
for (const entry of (0,
|
|
45700
|
+
for (const entry of (0, import_node_fs83.readdirSync)(dir, { withFileTypes: true })) {
|
|
45533
45701
|
if (entry.isDirectory() || !select(entry.name)) continue;
|
|
45534
45702
|
try {
|
|
45535
|
-
(0,
|
|
45703
|
+
(0, import_node_fs83.unlinkSync)((0, import_node_path71.join)(dir, entry.name));
|
|
45536
45704
|
removed++;
|
|
45537
45705
|
} catch {
|
|
45538
45706
|
}
|
|
@@ -45541,7 +45709,7 @@ function purgeVerityDir(child, select) {
|
|
|
45541
45709
|
}
|
|
45542
45710
|
|
|
45543
45711
|
// src/commands/reflect.ts
|
|
45544
|
-
var
|
|
45712
|
+
var import_node_fs84 = require("node:fs");
|
|
45545
45713
|
|
|
45546
45714
|
// src/lib/reflection-globs.ts
|
|
45547
45715
|
var MAX_GLOBS = 6;
|
|
@@ -45579,7 +45747,7 @@ async function writeNodeToDisk(args2) {
|
|
|
45579
45747
|
{ treePaths: listTrackedFiles(), recordBaseline: false }
|
|
45580
45748
|
);
|
|
45581
45749
|
if (written === 0) return false;
|
|
45582
|
-
return (0,
|
|
45750
|
+
return (0, import_node_fs84.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
|
|
45583
45751
|
} catch {
|
|
45584
45752
|
return false;
|
|
45585
45753
|
}
|
|
@@ -46016,7 +46184,7 @@ function registerRunCommand(program2) {
|
|
|
46016
46184
|
}
|
|
46017
46185
|
|
|
46018
46186
|
// src/commands/telemetry.ts
|
|
46019
|
-
var
|
|
46187
|
+
var import_node_fs85 = require("node:fs");
|
|
46020
46188
|
var SCOPE = "every Claude Code session on this machine";
|
|
46021
46189
|
function declineHeaders(why) {
|
|
46022
46190
|
process.stderr.write(`Verity telemetry is off here: ${why} Nothing is exported from this session.
|
|
@@ -46024,7 +46192,7 @@ function declineHeaders(why) {
|
|
|
46024
46192
|
process.exitCode = 1;
|
|
46025
46193
|
}
|
|
46026
46194
|
async function recordTelemetryChoice(choice) {
|
|
46027
|
-
if (!(0,
|
|
46195
|
+
if (!(0, import_node_fs85.existsSync)(projectPath(SETUP_STATE_FILE))) return;
|
|
46028
46196
|
try {
|
|
46029
46197
|
if ((await readSetupState())?.telemetry === choice) return;
|
|
46030
46198
|
await writeSetupState({ telemetry: choice });
|
|
@@ -46132,12 +46300,12 @@ function registerTelemetryCommands(program2) {
|
|
|
46132
46300
|
}
|
|
46133
46301
|
|
|
46134
46302
|
// src/commands/prove.ts
|
|
46135
|
-
var
|
|
46136
|
-
var
|
|
46303
|
+
var import_node_fs87 = require("node:fs");
|
|
46304
|
+
var import_node_path73 = require("node:path");
|
|
46137
46305
|
|
|
46138
46306
|
// src/lib/prove/on-demand-run.ts
|
|
46139
|
-
var
|
|
46140
|
-
var
|
|
46307
|
+
var import_node_fs86 = require("node:fs");
|
|
46308
|
+
var import_node_path72 = require("node:path");
|
|
46141
46309
|
var ON_DEMAND_RUN = `${PROOFS_DIR}/.results/.formal-run.json`;
|
|
46142
46310
|
var ON_DEMAND_RUN_REUSE_MS = 18 * 6e4;
|
|
46143
46311
|
function isLocalState2(root) {
|
|
@@ -46159,7 +46327,7 @@ function forgetOnDemandRun(root) {
|
|
|
46159
46327
|
setFormalRun(null);
|
|
46160
46328
|
if (!isLocalState2(root)) return;
|
|
46161
46329
|
try {
|
|
46162
|
-
(0,
|
|
46330
|
+
(0, import_node_fs86.unlinkSync)((0, import_node_path72.join)(root, ON_DEMAND_RUN));
|
|
46163
46331
|
} catch {
|
|
46164
46332
|
}
|
|
46165
46333
|
}
|
|
@@ -46336,7 +46504,7 @@ function registerProveCommand(program2) {
|
|
|
46336
46504
|
process.exit(2);
|
|
46337
46505
|
}
|
|
46338
46506
|
const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
|
|
46339
|
-
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0,
|
|
46507
|
+
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path73.relative)(root, (0, import_node_path73.resolve)(p)) || ".") });
|
|
46340
46508
|
if (opts.hint && paths.length === 0) {
|
|
46341
46509
|
const hit = hintMatches(root, opts.hint);
|
|
46342
46510
|
if (hit.files.length > 0) {
|
|
@@ -46390,7 +46558,7 @@ function registerProveCommand(program2) {
|
|
|
46390
46558
|
});
|
|
46391
46559
|
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) => {
|
|
46392
46560
|
const root = repoRoot();
|
|
46393
|
-
if (!(0,
|
|
46561
|
+
if (!(0, import_node_fs87.existsSync)((0, import_node_path73.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
46394
46562
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
46395
46563
|
process.exit(2);
|
|
46396
46564
|
}
|
|
@@ -46414,7 +46582,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
46414
46582
|
const reports = [];
|
|
46415
46583
|
for (const f of files) {
|
|
46416
46584
|
const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
|
|
46417
|
-
report.file = (0,
|
|
46585
|
+
report.file = (0, import_node_path73.relative)(root, f);
|
|
46418
46586
|
reports.push(report);
|
|
46419
46587
|
try {
|
|
46420
46588
|
writeResult(root, report);
|
|
@@ -46452,7 +46620,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
46452
46620
|
printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
|
|
46453
46621
|
process.exit(2);
|
|
46454
46622
|
}
|
|
46455
|
-
if (!(0,
|
|
46623
|
+
if (!(0, import_node_fs87.existsSync)((0, import_node_path73.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
46456
46624
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
46457
46625
|
process.exit(2);
|
|
46458
46626
|
}
|
|
@@ -46491,7 +46659,7 @@ ${report.error ?? ""}`);
|
|
|
46491
46659
|
process.exit(2);
|
|
46492
46660
|
}
|
|
46493
46661
|
}
|
|
46494
|
-
const modelSource = readRegularFileInRoot(root, (0,
|
|
46662
|
+
const modelSource = readRegularFileInRoot(root, (0, import_node_path73.relative)(root, file), 512 * 1024);
|
|
46495
46663
|
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`);
|
|
46496
46664
|
const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
|
|
46497
46665
|
const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
|
|
@@ -46512,7 +46680,7 @@ ${report.error ?? ""}`);
|
|
|
46512
46680
|
});
|
|
46513
46681
|
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) => {
|
|
46514
46682
|
const root = repoRoot();
|
|
46515
|
-
let files = paths.map((p) => (0,
|
|
46683
|
+
let files = paths.map((p) => (0, import_node_path73.relative)(root, (0, import_node_path73.resolve)(p)));
|
|
46516
46684
|
if (files.length === 0) {
|
|
46517
46685
|
const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
|
|
46518
46686
|
const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
|
|
@@ -46586,7 +46754,7 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
46586
46754
|
let revise;
|
|
46587
46755
|
if (opts.revise) {
|
|
46588
46756
|
const existing = resolveModelFile(root, opts.revise);
|
|
46589
|
-
const src = existing ? readRegularFileInRoot(root, (0,
|
|
46757
|
+
const src = existing ? readRegularFileInRoot(root, (0, import_node_path73.relative)(root, existing), 64 * 1024) : null;
|
|
46590
46758
|
if (!src || !src.ok || !opts.note) {
|
|
46591
46759
|
printError("--revise needs an existing model under Models/ and --note - with what the replay showed on stdin");
|
|
46592
46760
|
process.exit(2);
|
|
@@ -46635,8 +46803,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
46635
46803
|
});
|
|
46636
46804
|
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) => {
|
|
46637
46805
|
const root = repoRoot();
|
|
46638
|
-
const rel0 = (0,
|
|
46639
|
-
const rel = rel0.startsWith("..") || (0,
|
|
46806
|
+
const rel0 = (0, import_node_path73.relative)(root, (0, import_node_path73.isAbsolute)(file) ? file : (0, import_node_path73.join)(root, file)).replace(/\\/g, "/");
|
|
46807
|
+
const rel = rel0.startsWith("..") || (0, import_node_path73.isAbsolute)(rel0) ? null : rel0;
|
|
46640
46808
|
if (!rel) {
|
|
46641
46809
|
printError(`${file} is not inside this repository`);
|
|
46642
46810
|
process.exit(2);
|
|
@@ -46652,8 +46820,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
46652
46820
|
});
|
|
46653
46821
|
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) => {
|
|
46654
46822
|
const root = repoRoot();
|
|
46655
|
-
const rel = (0,
|
|
46656
|
-
const digest = rel.startsWith("..") || (0,
|
|
46823
|
+
const rel = (0, import_node_path73.relative)(root, (0, import_node_path73.isAbsolute)(file) ? file : (0, import_node_path73.join)(root, file));
|
|
46824
|
+
const digest = rel.startsWith("..") || (0, import_node_path73.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
|
|
46657
46825
|
if (!digest) {
|
|
46658
46826
|
printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
|
|
46659
46827
|
process.exit(2);
|
|
@@ -46687,10 +46855,10 @@ function refreshScaffold(root) {
|
|
|
46687
46855
|
}
|
|
46688
46856
|
|
|
46689
46857
|
// src/commands/lean.ts
|
|
46690
|
-
var
|
|
46858
|
+
var import_node_fs88 = require("node:fs");
|
|
46691
46859
|
var import_node_child_process24 = require("node:child_process");
|
|
46692
46860
|
var import_node_os16 = require("node:os");
|
|
46693
|
-
var
|
|
46861
|
+
var import_node_path74 = require("node:path");
|
|
46694
46862
|
function registerLeanCommand(program2) {
|
|
46695
46863
|
const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
|
|
46696
46864
|
lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
|
|
@@ -46709,7 +46877,7 @@ function registerLeanCommand(program2) {
|
|
|
46709
46877
|
const bg = readInstallState();
|
|
46710
46878
|
const background = bg ? { ...bg, running: bg.state === "running" && installRunning() } : null;
|
|
46711
46879
|
if (opts.json) {
|
|
46712
|
-
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0,
|
|
46880
|
+
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs88.existsSync)((0, import_node_path74.join)(managed, "bin")), asset: leanAssetName(), background });
|
|
46713
46881
|
return;
|
|
46714
46882
|
}
|
|
46715
46883
|
printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
|
|
@@ -46730,7 +46898,7 @@ function registerLeanCommand(program2) {
|
|
|
46730
46898
|
process.exit(2);
|
|
46731
46899
|
}
|
|
46732
46900
|
const dir = pinnedVersionDir();
|
|
46733
|
-
if ((0,
|
|
46901
|
+
if ((0, import_node_fs88.existsSync)((0, import_node_path74.join)(dir, "bin", "lake")) && !opts.force) {
|
|
46734
46902
|
printInfo(`already installed at ${dir}`);
|
|
46735
46903
|
return;
|
|
46736
46904
|
}
|
|
@@ -46766,20 +46934,20 @@ function registerLeanCommand(program2) {
|
|
|
46766
46934
|
});
|
|
46767
46935
|
lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
|
|
46768
46936
|
const dir = pinnedVersionDir();
|
|
46769
|
-
if (!(0,
|
|
46937
|
+
if (!(0, import_node_fs88.existsSync)(dir)) {
|
|
46770
46938
|
printInfo("nothing to remove");
|
|
46771
46939
|
return;
|
|
46772
46940
|
}
|
|
46773
|
-
(0,
|
|
46941
|
+
(0, import_node_fs88.rmSync)(dir, { recursive: true, force: true });
|
|
46774
46942
|
printInfo(`removed ${dir}`);
|
|
46775
46943
|
});
|
|
46776
46944
|
}
|
|
46777
46945
|
|
|
46778
46946
|
// src/cli.ts
|
|
46779
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.35.
|
|
46947
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.35.5").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) => {
|
|
46780
46948
|
const isTelemetryHelper = actionCommand.name() === "headers" && actionCommand.parent?.name() === "telemetry";
|
|
46781
46949
|
if (!isTelemetryHelper) {
|
|
46782
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.35.
|
|
46950
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.35.5");
|
|
46783
46951
|
}
|
|
46784
46952
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
46785
46953
|
try {
|