@codacy/verity-cli 0.35.0-experimental.3211f79 → 0.35.0-experimental.7c5e75b
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/bin/verity.js +896 -496
- package/package.json +2 -9
package/bin/verity.js
CHANGED
|
@@ -10192,14 +10192,14 @@ var require_public_api = __commonJS2({
|
|
|
10192
10192
|
const { lineCounter: lineCounter2, prettyErrors } = parseOptions(options);
|
|
10193
10193
|
const parser$1 = new parser.Parser(lineCounter2?.addNewLine);
|
|
10194
10194
|
const composer$1 = new composer.Composer(options);
|
|
10195
|
-
const
|
|
10195
|
+
const docs = Array.from(composer$1.compose(parser$1.parse(source2)));
|
|
10196
10196
|
if (prettyErrors && lineCounter2)
|
|
10197
|
-
for (const doc of
|
|
10197
|
+
for (const doc of docs) {
|
|
10198
10198
|
doc.errors.forEach(errors.prettifyError(source2, lineCounter2));
|
|
10199
10199
|
doc.warnings.forEach(errors.prettifyError(source2, lineCounter2));
|
|
10200
10200
|
}
|
|
10201
|
-
if (
|
|
10202
|
-
return
|
|
10201
|
+
if (docs.length > 0)
|
|
10202
|
+
return docs;
|
|
10203
10203
|
return Object.assign([], { empty: true }, composer$1.streamInfo());
|
|
10204
10204
|
}
|
|
10205
10205
|
function parseDocument(source2, options = {}) {
|
|
@@ -24520,36 +24520,8 @@ function collectRiskSignals(root, opts = {}) {
|
|
|
24520
24520
|
return out2.slice(0, opts.limit ?? 10);
|
|
24521
24521
|
}
|
|
24522
24522
|
|
|
24523
|
-
// src/lib/
|
|
24524
|
-
var
|
|
24525
|
-
var PROFILE_FILE = ".verity/repo-profile.json";
|
|
24526
|
-
var LIMITS = {
|
|
24527
|
-
languages: 20,
|
|
24528
|
-
frameworks: 50,
|
|
24529
|
-
dependencies: 300,
|
|
24530
|
-
folders: 300,
|
|
24531
|
-
commits: 500,
|
|
24532
|
-
// The server allows 20; 10 keeps a full profile well under its body cap.
|
|
24533
|
-
pathsPerCommit: 10,
|
|
24534
|
-
docs: 8,
|
|
24535
|
-
// A long doc is cut by section (fitDoc), so these bound how much of the
|
|
24536
|
-
// team's conventions reach the writer, not where a doc is cut.
|
|
24537
|
-
docBytes: 12288,
|
|
24538
|
-
nestedDocBytes: 6144,
|
|
24539
|
-
contributorDocBytes: 4096,
|
|
24540
|
-
docsTotalBytes: 32768,
|
|
24541
|
-
subject: 120,
|
|
24542
|
-
path: 200,
|
|
24543
|
-
name: 100
|
|
24544
|
-
};
|
|
24545
|
-
var WINDOW_DAYS = 180;
|
|
24546
|
-
var MAX_PROFILE_BYTES = 120 * 1024;
|
|
24547
|
-
var ROOT_DOCS = ["CLAUDE.md", "AGENTS.md", ".cursorrules", ".github/copilot-instructions.md"];
|
|
24548
|
-
var CONTRIBUTOR_DOCS = ["CONTRIBUTING.md", "ARCHITECTURE.md"];
|
|
24549
|
-
var README = "README.md";
|
|
24550
|
-
var README_BYTES = 3072;
|
|
24551
|
-
var NESTED_DOC = /^(?:[^./][^/]*\/){1,4}(?:AGENTS|CLAUDE)\.md$/;
|
|
24552
|
-
var NOT_THE_TEAMS = /(?:^|\/)(?:examples?|samples?|templates?|[\w-]*-template|fixtures?|tests?|__tests__|vendor|third_party|node_modules)\//i;
|
|
24523
|
+
// src/lib/profile-text.ts
|
|
24524
|
+
var PATH_MAX = 200;
|
|
24553
24525
|
var SECRET_PATTERNS = [
|
|
24554
24526
|
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}\b/g,
|
|
24555
24527
|
/\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,
|
|
@@ -24576,63 +24548,77 @@ function redact(text2) {
|
|
|
24576
24548
|
function oneLine(text2, max) {
|
|
24577
24549
|
return redact(text2.replace(/[\r\n\t]+/g, " ")).trim().slice(0, max);
|
|
24578
24550
|
}
|
|
24579
|
-
var DEP = /^[A-Za-z0-9@][A-Za-z0-9@._/:+-]*$/;
|
|
24580
|
-
function dependencies(root, files) {
|
|
24581
|
-
const seen = /* @__PURE__ */ new Set();
|
|
24582
|
-
for (const name2 of declaredDependencies(root, files)) {
|
|
24583
|
-
if (name2.length <= LIMITS.name && DEP.test(name2)) seen.add(name2);
|
|
24584
|
-
if (seen.size >= LIMITS.dependencies) break;
|
|
24585
|
-
}
|
|
24586
|
-
return [...seen];
|
|
24587
|
-
}
|
|
24588
24551
|
function safePath(p) {
|
|
24589
|
-
if (!p || p.length >
|
|
24552
|
+
if (!p || p.length > PATH_MAX || p.startsWith("/") || p.includes("\\")) return null;
|
|
24590
24553
|
if (p.split("/").some((seg) => seg === "" || seg === "..")) return null;
|
|
24591
24554
|
if (/[\u0000-\u001f\u007f]/.test(p)) return null;
|
|
24592
24555
|
return p;
|
|
24593
24556
|
}
|
|
24594
|
-
|
|
24595
|
-
|
|
24596
|
-
|
|
24597
|
-
|
|
24598
|
-
|
|
24599
|
-
|
|
24600
|
-
|
|
24601
|
-
|
|
24557
|
+
|
|
24558
|
+
// src/lib/profile-docs.ts
|
|
24559
|
+
var DOC_LIMITS = {
|
|
24560
|
+
docs: 8,
|
|
24561
|
+
// A long doc is cut by section (fitDoc), so these bound how much of the
|
|
24562
|
+
// team's conventions reach the writer, not where a doc is cut.
|
|
24563
|
+
docBytes: 12288,
|
|
24564
|
+
nestedDocBytes: 6144,
|
|
24565
|
+
contributorDocBytes: 4096,
|
|
24566
|
+
docsTotalBytes: 32768
|
|
24567
|
+
};
|
|
24568
|
+
var ROOT_DOCS = ["CLAUDE.md", "AGENTS.md", ".cursorrules", ".github/copilot-instructions.md"];
|
|
24569
|
+
var CONTRIBUTOR_DOCS = ["CONTRIBUTING.md", "ARCHITECTURE.md"];
|
|
24570
|
+
var README = "README.md";
|
|
24571
|
+
var README_BYTES = 3072;
|
|
24572
|
+
var NESTED_DOC = /^(?:[^./][^/]*\/){1,4}(?:AGENTS|CLAUDE)\.md$/;
|
|
24573
|
+
var NOT_THE_TEAMS = /(?:^|\/)(?:examples?|samples?|templates?|[\w-]*-template|fixtures?|tests?|__tests__|vendor|third_party|node_modules)\//i;
|
|
24574
|
+
var MANAGED_START = "<!-- verity-memory:start -->";
|
|
24575
|
+
var MANAGED_END = "<!-- verity-memory:end -->";
|
|
24576
|
+
var PRESERVE_START2 = "<!-- verity-memory:preserve -->";
|
|
24577
|
+
var PRESERVE_END2 = "<!-- /verity-memory:preserve -->";
|
|
24578
|
+
var FENCE_OPEN = /^[ \t]*(?:(?:[-*+]|\d+[.)])[ \t]+)*(`{3,}|~{3,})/;
|
|
24579
|
+
var FENCE_CLOSE = /^[ \t]*(`{3,}|~{3,})[ \t]*$/;
|
|
24580
|
+
var QUOTE = /^(?:[ \t]*>)+ ?/;
|
|
24581
|
+
var LIST_ITEM = /^[ \t]*(?:[-*+]|\d+[.)])[ \t]/;
|
|
24582
|
+
function indentWidth(line2) {
|
|
24583
|
+
let w = 0;
|
|
24584
|
+
for (const ch of line2) {
|
|
24585
|
+
if (ch === " ") w++;
|
|
24586
|
+
else if (ch === " ") w += 4;
|
|
24587
|
+
else break;
|
|
24602
24588
|
}
|
|
24603
|
-
return
|
|
24589
|
+
return w;
|
|
24604
24590
|
}
|
|
24605
|
-
function
|
|
24606
|
-
const
|
|
24607
|
-
|
|
24608
|
-
|
|
24609
|
-
|
|
24610
|
-
|
|
24611
|
-
|
|
24612
|
-
|
|
24613
|
-
|
|
24614
|
-
"--"
|
|
24615
|
-
], { timeoutMs: 3e4 });
|
|
24616
|
-
const commits = [];
|
|
24617
|
-
if (!res.ok) return { window_days: WINDOW_DAYS, commits };
|
|
24618
|
-
let current = null;
|
|
24619
|
-
for (const line2 of res.stdout.split("\n")) {
|
|
24620
|
-
if (line2.startsWith("@@")) {
|
|
24621
|
-
if (current && current.subject) commits.push(current);
|
|
24622
|
-
const raw = line2.slice(3);
|
|
24623
|
-
current = { subject: oneLine(raw, LIMITS.subject), paths: [], fix: FIX_SUBJECT.test(raw) };
|
|
24591
|
+
function stripCode(text2) {
|
|
24592
|
+
const out2 = [];
|
|
24593
|
+
let fence = null;
|
|
24594
|
+
let underItem = false;
|
|
24595
|
+
for (const line2 of text2.split("\n")) {
|
|
24596
|
+
const body2 = line2.replace(QUOTE, "");
|
|
24597
|
+
if (fence) {
|
|
24598
|
+
const close = FENCE_CLOSE.exec(body2);
|
|
24599
|
+
if (close && close[1][0] === fence[0] && close[1].length >= fence.length) fence = null;
|
|
24624
24600
|
continue;
|
|
24625
24601
|
}
|
|
24626
|
-
const
|
|
24627
|
-
if (
|
|
24602
|
+
const open = FENCE_OPEN.exec(body2);
|
|
24603
|
+
if (open) {
|
|
24604
|
+
fence = open[1];
|
|
24605
|
+
underItem = false;
|
|
24606
|
+
continue;
|
|
24607
|
+
}
|
|
24608
|
+
if (body2.trim() === "") {
|
|
24609
|
+
out2.push(line2);
|
|
24610
|
+
underItem = false;
|
|
24611
|
+
continue;
|
|
24612
|
+
}
|
|
24613
|
+
if (indentWidth(body2) >= 4) {
|
|
24614
|
+
if (underItem && LIST_ITEM.test(body2)) out2.push(line2);
|
|
24615
|
+
continue;
|
|
24616
|
+
}
|
|
24617
|
+
out2.push(line2);
|
|
24618
|
+
underItem = LIST_ITEM.test(body2);
|
|
24628
24619
|
}
|
|
24629
|
-
|
|
24630
|
-
return { window_days: WINDOW_DAYS, commits: commits.slice(0, LIMITS.commits) };
|
|
24620
|
+
return out2.join("\n");
|
|
24631
24621
|
}
|
|
24632
|
-
var MANAGED_START = "<!-- verity-memory:start -->";
|
|
24633
|
-
var MANAGED_END = "<!-- verity-memory:end -->";
|
|
24634
|
-
var PRESERVE_START2 = "<!-- verity-memory:preserve -->";
|
|
24635
|
-
var PRESERVE_END2 = "<!-- /verity-memory:preserve -->";
|
|
24636
24622
|
function docText(raw) {
|
|
24637
24623
|
let text2 = raw;
|
|
24638
24624
|
const start2 = text2.indexOf(MANAGED_START);
|
|
@@ -24644,7 +24630,7 @@ function docText(raw) {
|
|
|
24644
24630
|
const kept = ps >= 0 && pe > ps ? block.slice(ps + PRESERVE_START2.length, pe) : "";
|
|
24645
24631
|
text2 = text2.slice(0, start2) + kept + text2.slice(end + MANAGED_END.length);
|
|
24646
24632
|
}
|
|
24647
|
-
text2 = text2.replace(
|
|
24633
|
+
text2 = stripCode(text2.replace(/<!--[\s\S]*?-->/g, "").replace(/<!--[\s\S]*$/, "")).replace(/\n{3,}/g, "\n\n");
|
|
24648
24634
|
return redact(text2).trim();
|
|
24649
24635
|
}
|
|
24650
24636
|
var RULE_TITLE = /convention|pattern|rule|gotcha|footgun|pitfall|best practice|guideline|principle|standard|style|architecture|design|security|database|migration|schema|\bapi\b|error|state|naming|structure|i18n|internationali[sz]|translation|important|critical|warning|do not|don't|never|must|avoid/i;
|
|
@@ -24677,18 +24663,23 @@ function sectionRank(s) {
|
|
|
24677
24663
|
return title * 1e3 + Math.min(999, s.lines.filter((l) => NORMATIVE.test(l)).length);
|
|
24678
24664
|
}
|
|
24679
24665
|
function fitDoc(text2, budget) {
|
|
24680
|
-
if (text2
|
|
24666
|
+
if (utf8(text2) <= budget) return text2;
|
|
24681
24667
|
const all = docSections(text2);
|
|
24682
|
-
const
|
|
24668
|
+
const lineBytes = (line2) => utf8(line2) + 1;
|
|
24669
|
+
const GAP = lineBytes("\u2026");
|
|
24683
24670
|
const chosen = /* @__PURE__ */ new Map();
|
|
24671
|
+
const headingsCounted = /* @__PURE__ */ new Set();
|
|
24684
24672
|
let used2 = 0;
|
|
24685
24673
|
for (const s of [...all].sort((a, b) => sectionRank(b) - sectionRank(a) || a.order - b.order)) {
|
|
24686
24674
|
if (!s.lines.some((l) => l.trim())) continue;
|
|
24675
|
+
const parents = s.parents.filter((p) => !headingsCounted.has(p) && !chosen.has(p));
|
|
24676
|
+
const parentBytes = parents.reduce((n2, p) => n2 + lineBytes(all[p].heading ?? ""), 0);
|
|
24687
24677
|
const lean = s.lines.filter((l) => NORMATIVE.test(l));
|
|
24688
24678
|
for (const lines of [s.lines, lean]) {
|
|
24689
|
-
const n2 =
|
|
24679
|
+
const n2 = (s.heading ? lineBytes(s.heading) : 0) + lines.reduce((m, l) => m + lineBytes(l), 0) + parentBytes + GAP;
|
|
24690
24680
|
if (lines.length && used2 + n2 <= budget) {
|
|
24691
24681
|
chosen.set(s.order, lines);
|
|
24682
|
+
for (const p of parents) headingsCounted.add(p);
|
|
24692
24683
|
used2 += n2;
|
|
24693
24684
|
break;
|
|
24694
24685
|
}
|
|
@@ -24712,23 +24703,38 @@ function fitDoc(text2, budget) {
|
|
|
24712
24703
|
if (s.heading) out2.push(s.heading);
|
|
24713
24704
|
out2.push(...lines);
|
|
24714
24705
|
}
|
|
24715
|
-
return out2.join("\n").replace(/\n{3,}/g, "\n\n").trim()
|
|
24706
|
+
return cutToBytes(out2.join("\n").replace(/\n{3,}/g, "\n\n").trim(), budget);
|
|
24707
|
+
}
|
|
24708
|
+
function utf8(text2) {
|
|
24709
|
+
return Buffer.byteLength(text2, "utf8");
|
|
24710
|
+
}
|
|
24711
|
+
function cutToBytes(text2, max) {
|
|
24712
|
+
if (utf8(text2) <= max) return text2;
|
|
24713
|
+
let out2 = "";
|
|
24714
|
+
let n2 = 0;
|
|
24715
|
+
for (const ch of text2) {
|
|
24716
|
+
const b = utf8(ch);
|
|
24717
|
+
if (n2 + b > max) break;
|
|
24718
|
+
out2 += ch;
|
|
24719
|
+
n2 += b;
|
|
24720
|
+
}
|
|
24721
|
+
return out2;
|
|
24716
24722
|
}
|
|
24717
24723
|
var normal = (line2) => line2.trim().toLowerCase().replace(/\s+/g, " ");
|
|
24718
|
-
function
|
|
24724
|
+
function readDocs(root, files) {
|
|
24719
24725
|
const nested = files.filter((f) => NESTED_DOC.test(f) && !NOT_THE_TEAMS.test(f) && safePath(f) !== null).sort((a, b) => a.split("/").length - b.split("/").length || a.localeCompare(b));
|
|
24720
24726
|
const plan = [
|
|
24721
|
-
...ROOT_DOCS.map((n2) => [n2,
|
|
24722
|
-
...nested.map((n2) => [n2,
|
|
24723
|
-
...CONTRIBUTOR_DOCS.map((n2) => [n2,
|
|
24727
|
+
...ROOT_DOCS.map((n2) => [n2, DOC_LIMITS.docBytes]),
|
|
24728
|
+
...nested.map((n2) => [n2, DOC_LIMITS.nestedDocBytes]),
|
|
24729
|
+
...CONTRIBUTOR_DOCS.map((n2) => [n2, DOC_LIMITS.contributorDocBytes]),
|
|
24724
24730
|
[README, README_BYTES]
|
|
24725
24731
|
];
|
|
24726
24732
|
const out2 = [];
|
|
24727
24733
|
const sent = /* @__PURE__ */ new Set();
|
|
24728
24734
|
let total = 0;
|
|
24729
24735
|
for (const [name2, cap2] of plan) {
|
|
24730
|
-
const room = Math.min(cap2,
|
|
24731
|
-
if (out2.length >=
|
|
24736
|
+
const room = Math.min(cap2, DOC_LIMITS.docsTotalBytes - total);
|
|
24737
|
+
if (out2.length >= DOC_LIMITS.docs || room < 200) break;
|
|
24732
24738
|
if (name2 === README && out2.some((d) => ROOT_DOCS.includes(d.name))) continue;
|
|
24733
24739
|
const read2 = readRegularFileInRoot(root, name2, 256 * 1024);
|
|
24734
24740
|
if (!read2.ok) continue;
|
|
@@ -24736,13 +24742,78 @@ function docs(root, files) {
|
|
|
24736
24742
|
const text2 = fitDoc(fresh, room);
|
|
24737
24743
|
if (!text2) continue;
|
|
24738
24744
|
for (const l of text2.split("\n")) if (normal(l).length >= 25) sent.add(normal(l));
|
|
24739
|
-
total += text2
|
|
24745
|
+
total += utf8(text2);
|
|
24740
24746
|
out2.push({ name: name2, text: text2 });
|
|
24741
24747
|
}
|
|
24742
24748
|
return out2;
|
|
24743
24749
|
}
|
|
24750
|
+
|
|
24751
|
+
// src/lib/repo-profile.ts
|
|
24752
|
+
var PROFILE_SCHEMA = "repo-profile/v1";
|
|
24753
|
+
var PROFILE_FILE = ".verity/repo-profile.json";
|
|
24754
|
+
var LIMITS = {
|
|
24755
|
+
languages: 20,
|
|
24756
|
+
frameworks: 50,
|
|
24757
|
+
dependencies: 300,
|
|
24758
|
+
folders: 300,
|
|
24759
|
+
commits: 500,
|
|
24760
|
+
// The server allows 20; 10 keeps a full profile well under its body cap.
|
|
24761
|
+
pathsPerCommit: 10,
|
|
24762
|
+
subject: 120,
|
|
24763
|
+
path: 200,
|
|
24764
|
+
name: 100
|
|
24765
|
+
};
|
|
24766
|
+
var WINDOW_DAYS = 180;
|
|
24767
|
+
var MAX_PROFILE_BYTES = 120 * 1024;
|
|
24768
|
+
var DEP = /^[A-Za-z0-9@][A-Za-z0-9@._/:+-]*$/;
|
|
24769
|
+
function dependencies(root, files) {
|
|
24770
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24771
|
+
for (const name2 of declaredDependencies(root, files)) {
|
|
24772
|
+
if (name2.length <= LIMITS.name && DEP.test(name2)) seen.add(name2);
|
|
24773
|
+
if (seen.size >= LIMITS.dependencies) break;
|
|
24774
|
+
}
|
|
24775
|
+
return [...seen];
|
|
24776
|
+
}
|
|
24777
|
+
function tree(files) {
|
|
24778
|
+
const counts = /* @__PURE__ */ new Map();
|
|
24779
|
+
for (const file of files) {
|
|
24780
|
+
const parts2 = file.split("/");
|
|
24781
|
+
for (let depth = 1; depth <= Math.min(3, parts2.length - 1); depth++) {
|
|
24782
|
+
const folder = parts2.slice(0, depth).join("/");
|
|
24783
|
+
counts.set(folder, (counts.get(folder) ?? 0) + 1);
|
|
24784
|
+
}
|
|
24785
|
+
}
|
|
24786
|
+
return [...counts.entries()].filter(([path]) => safePath(path) !== null).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, LIMITS.folders).map(([path, n2]) => ({ path, files: n2 })).sort((a, b) => a.path.localeCompare(b.path));
|
|
24787
|
+
}
|
|
24788
|
+
function history(root) {
|
|
24789
|
+
const res = runGitSync(root, [
|
|
24790
|
+
"log",
|
|
24791
|
+
`--since=${WINDOW_DAYS} days ago`,
|
|
24792
|
+
"-n",
|
|
24793
|
+
String(LIMITS.commits),
|
|
24794
|
+
"--no-merges",
|
|
24795
|
+
"--format=@@%x1f%s",
|
|
24796
|
+
"--name-only",
|
|
24797
|
+
"--"
|
|
24798
|
+
], { timeoutMs: 3e4 });
|
|
24799
|
+
const commits = [];
|
|
24800
|
+
if (!res.ok) return { window_days: WINDOW_DAYS, commits };
|
|
24801
|
+
let current = null;
|
|
24802
|
+
for (const line2 of res.stdout.split("\n")) {
|
|
24803
|
+
if (line2.startsWith("@@")) {
|
|
24804
|
+
if (current && current.subject) commits.push(current);
|
|
24805
|
+
const raw = line2.slice(3);
|
|
24806
|
+
current = { subject: oneLine(raw, LIMITS.subject), paths: [], fix: FIX_SUBJECT.test(raw) };
|
|
24807
|
+
continue;
|
|
24808
|
+
}
|
|
24809
|
+
const path = safePath(line2.trim());
|
|
24810
|
+
if (current && path && current.paths.length < LIMITS.pathsPerCommit) current.paths.push(path);
|
|
24811
|
+
}
|
|
24812
|
+
if (current && current.subject) commits.push(current);
|
|
24813
|
+
return { window_days: WINDOW_DAYS, commits: commits.slice(0, LIMITS.commits) };
|
|
24814
|
+
}
|
|
24744
24815
|
function fitProfile(p) {
|
|
24745
|
-
const size = () => JSON.stringify(p)
|
|
24816
|
+
const size = () => Buffer.byteLength(JSON.stringify(p), "utf8");
|
|
24746
24817
|
if (size() <= MAX_PROFILE_BYTES) return p;
|
|
24747
24818
|
const commits = p.history.commits;
|
|
24748
24819
|
for (const wantFix of [false, true]) {
|
|
@@ -24750,6 +24821,9 @@ function fitProfile(p) {
|
|
|
24750
24821
|
if (commits[i2].fix === wantFix) commits.splice(i2, 1);
|
|
24751
24822
|
}
|
|
24752
24823
|
}
|
|
24824
|
+
while (size() > MAX_PROFILE_BYTES && p.docs.length > 0) p.docs.pop();
|
|
24825
|
+
while (size() > MAX_PROFILE_BYTES && p.tree.length > 0) p.tree.pop();
|
|
24826
|
+
while (size() > MAX_PROFILE_BYTES && p.dependencies.length > 0) p.dependencies.pop();
|
|
24753
24827
|
return p;
|
|
24754
24828
|
}
|
|
24755
24829
|
function buildRepoProfile(root = repoRoot()) {
|
|
@@ -24771,7 +24845,7 @@ function buildRepoProfile(root = repoRoot()) {
|
|
|
24771
24845
|
dependencies: dependencies(root, files),
|
|
24772
24846
|
tree: tree(files),
|
|
24773
24847
|
history: history(root),
|
|
24774
|
-
docs:
|
|
24848
|
+
docs: readDocs(root, files)
|
|
24775
24849
|
});
|
|
24776
24850
|
}
|
|
24777
24851
|
function describeProfile(p) {
|
|
@@ -25163,11 +25237,11 @@ async function currentReviewMoments(pluginMode) {
|
|
|
25163
25237
|
const cfg = readProjectConfig();
|
|
25164
25238
|
const hooks = await checkAllVerityHooks();
|
|
25165
25239
|
const turn = cfg.turn_review !== "off" && (pluginMode || hooks.stop);
|
|
25166
|
-
const
|
|
25240
|
+
const git3 = pluginMode ? cfg.git_moments : hooks.guard ? hooks.guardOn.length > 0 ? hooks.guardOn : cfg.git_moments : [];
|
|
25167
25241
|
return [
|
|
25168
25242
|
...turn ? ["stop"] : [],
|
|
25169
|
-
...
|
|
25170
|
-
...
|
|
25243
|
+
...git3.includes("commit") ? ["pre-commit"] : [],
|
|
25244
|
+
...git3.includes("push") ? ["pre-push"] : []
|
|
25171
25245
|
];
|
|
25172
25246
|
}
|
|
25173
25247
|
async function setReviewMoments(moments, pluginMode) {
|
|
@@ -26120,7 +26194,7 @@ function createRun(opts, globals) {
|
|
|
26120
26194
|
|
|
26121
26195
|
// src/commands/analyze/index.ts
|
|
26122
26196
|
var import_node_fs55 = require("node:fs");
|
|
26123
|
-
var
|
|
26197
|
+
var import_node_path43 = require("node:path");
|
|
26124
26198
|
|
|
26125
26199
|
// src/lib/repo-context.ts
|
|
26126
26200
|
var import_node_child_process11 = require("node:child_process");
|
|
@@ -28244,7 +28318,7 @@ function channelSilence(input) {
|
|
|
28244
28318
|
// src/lib/cli-version.ts
|
|
28245
28319
|
function cliVersion() {
|
|
28246
28320
|
try {
|
|
28247
|
-
return true ? "0.35.0-experimental.
|
|
28321
|
+
return true ? "0.35.0-experimental.7c5e75b" : "dev";
|
|
28248
28322
|
} catch {
|
|
28249
28323
|
return "dev";
|
|
28250
28324
|
}
|
|
@@ -28285,6 +28359,8 @@ async function sendSkipBeacon(ctx, reason) {
|
|
|
28285
28359
|
|
|
28286
28360
|
// src/lib/static-analysis.ts
|
|
28287
28361
|
var import_node_child_process12 = require("node:child_process");
|
|
28362
|
+
var import_node_module = require("node:module");
|
|
28363
|
+
var import_node_path34 = require("node:path");
|
|
28288
28364
|
var import_node_fs44 = require("node:fs");
|
|
28289
28365
|
|
|
28290
28366
|
// src/lib/static-config.ts
|
|
@@ -28331,19 +28407,44 @@ var SEVERITY_ORDER = {
|
|
|
28331
28407
|
Low: 3
|
|
28332
28408
|
};
|
|
28333
28409
|
function isCodacyAvailable() {
|
|
28334
|
-
return
|
|
28410
|
+
return resolveAnalyzer() !== null;
|
|
28411
|
+
}
|
|
28412
|
+
var NO_BUNDLED_ANALYZER_ENV = "VERITY_NO_BUNDLED_ANALYZER";
|
|
28413
|
+
function bundledAnalyzer(from = __filename) {
|
|
28414
|
+
try {
|
|
28415
|
+
const pkgPath = (0, import_node_module.createRequire)(from).resolve("@codacy/analysis-cli/package.json");
|
|
28416
|
+
const pkg = JSON.parse((0, import_node_fs44.readFileSync)(pkgPath, "utf-8"));
|
|
28417
|
+
const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.["codacy-analysis"];
|
|
28418
|
+
if (typeof bin !== "string" || bin === "") return null;
|
|
28419
|
+
const entry = (0, import_node_path34.join)((0, import_node_path34.dirname)(pkgPath), bin);
|
|
28420
|
+
if (!(0, import_node_fs44.statSync)(entry).isFile()) return null;
|
|
28421
|
+
return { path: entry, version: typeof pkg.version === "string" ? pkg.version : "unknown" };
|
|
28422
|
+
} catch {
|
|
28423
|
+
return null;
|
|
28424
|
+
}
|
|
28335
28425
|
}
|
|
28336
|
-
function
|
|
28337
|
-
|
|
28426
|
+
function resolveAnalyzer(opts = {}) {
|
|
28427
|
+
const env = opts.env ?? process.env;
|
|
28428
|
+
if (env[NO_BUNDLED_ANALYZER_ENV] !== "1") {
|
|
28429
|
+
const bundled = (opts.bundled ?? bundledAnalyzer)();
|
|
28430
|
+
if (bundled) return { source: "bundled", path: bundled.path, version: bundled.version };
|
|
28431
|
+
}
|
|
28432
|
+
const onPath = (opts.onPath ?? (() => whichSync("codacy-analysis")))();
|
|
28433
|
+
return onPath ? { source: "path", path: onPath } : null;
|
|
28434
|
+
}
|
|
28435
|
+
function analyzerCommand(analyzer, argv, execPath = process.execPath) {
|
|
28436
|
+
if (analyzer.source === "bundled") return { command: execPath, args: [analyzer.path, ...argv] };
|
|
28437
|
+
return { command: analyzer.path, args: argv };
|
|
28338
28438
|
}
|
|
28339
28439
|
function startTrivyPrewarm(opts = {}) {
|
|
28340
28440
|
if ((opts.platform ?? process.platform) === "win32") return false;
|
|
28341
28441
|
if ((opts.env ?? process.env).CI) return false;
|
|
28342
|
-
const analyzer =
|
|
28442
|
+
const analyzer = (opts.resolve ?? resolveAnalyzer)();
|
|
28343
28443
|
const config = ensureStaticConfig();
|
|
28344
28444
|
if (!analyzer || !config) return false;
|
|
28345
28445
|
try {
|
|
28346
|
-
const
|
|
28446
|
+
const { command, args: args2 } = analyzerCommand(analyzer, buildAnalyzerArgv([STATIC_ANALYSIS_CONFIG_FILE], config));
|
|
28447
|
+
const child = (opts.run ?? import_node_child_process12.spawn)(command, args2, {
|
|
28347
28448
|
cwd: repoRoot(),
|
|
28348
28449
|
detached: true,
|
|
28349
28450
|
stdio: "ignore"
|
|
@@ -28390,7 +28491,7 @@ function runCodacyAnalysisIfAvailable(files) {
|
|
|
28390
28491
|
if (!isCodacyAvailable()) {
|
|
28391
28492
|
return withFailure(
|
|
28392
28493
|
"analyzer_unavailable",
|
|
28393
|
-
"@codacy/analysis-cli was not found on PATH \u2014 no static analysis ran"
|
|
28494
|
+
"@codacy/analysis-cli was not bundled with this Verity install and was not found on PATH \u2014 no static analysis ran. Reinstall Verity: npm install -g @codacy/verity-cli"
|
|
28394
28495
|
);
|
|
28395
28496
|
}
|
|
28396
28497
|
return runCodacyAnalysis(files);
|
|
@@ -28413,8 +28514,10 @@ function runCodacyAnalysis(files) {
|
|
|
28413
28514
|
"Could not write .verity/static-analysis.json \u2014 no static analysis ran"
|
|
28414
28515
|
);
|
|
28415
28516
|
}
|
|
28416
|
-
const
|
|
28417
|
-
const
|
|
28517
|
+
const argv = buildAnalyzerArgv(existingFiles, configPath);
|
|
28518
|
+
const resolved = resolveAnalyzer();
|
|
28519
|
+
const { command, args: args2 } = resolved ? analyzerCommand(resolved, argv) : { command: "codacy-analysis", args: argv };
|
|
28520
|
+
const proc = (0, import_node_child_process12.spawnSync)(command, args2, {
|
|
28418
28521
|
encoding: "utf-8",
|
|
28419
28522
|
maxBuffer: 10 * 1024 * 1024
|
|
28420
28523
|
});
|
|
@@ -28678,7 +28781,7 @@ async function scope(run4) {
|
|
|
28678
28781
|
|
|
28679
28782
|
// src/lib/specs.ts
|
|
28680
28783
|
var import_node_fs45 = require("node:fs");
|
|
28681
|
-
var
|
|
28784
|
+
var import_node_path35 = require("node:path");
|
|
28682
28785
|
var SPEC_CANDIDATES = [
|
|
28683
28786
|
"CLAUDE.md",
|
|
28684
28787
|
"AGENTS.md",
|
|
@@ -28700,7 +28803,7 @@ var UNCONSULTED_TOTAL_BYTES = 30720;
|
|
|
28700
28803
|
function readSpecFiles(specsOpt, root) {
|
|
28701
28804
|
const out2 = [];
|
|
28702
28805
|
for (const raw of specsOpt.split(",").map((f) => f.trim()).filter(Boolean)) {
|
|
28703
|
-
const candidate = (0,
|
|
28806
|
+
const candidate = (0, import_node_path35.isAbsolute)(raw) ? (0, import_node_path35.relative)(root, raw) : raw;
|
|
28704
28807
|
const content = readFileInside(root, candidate, MAX_EXPLICIT_SPEC_FILE_BYTES);
|
|
28705
28808
|
if (content === null) continue;
|
|
28706
28809
|
out2.push({ path: raw, content });
|
|
@@ -28759,7 +28862,7 @@ function findMdFiles(dir, maxDepth, depth = 0) {
|
|
|
28759
28862
|
try {
|
|
28760
28863
|
const entries = (0, import_node_fs45.readdirSync)(dir, { withFileTypes: true });
|
|
28761
28864
|
for (const entry of entries) {
|
|
28762
|
-
const fullPath = (0,
|
|
28865
|
+
const fullPath = (0, import_node_path35.join)(dir, entry.name);
|
|
28763
28866
|
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
28764
28867
|
result.push(fullPath);
|
|
28765
28868
|
} else if (entry.isDirectory() && depth < maxDepth - 1) {
|
|
@@ -28772,10 +28875,10 @@ function findMdFiles(dir, maxDepth, depth = 0) {
|
|
|
28772
28875
|
}
|
|
28773
28876
|
function discoverPlans() {
|
|
28774
28877
|
const home = process.env.HOME ?? "";
|
|
28775
|
-
const homePlansDir = (0,
|
|
28878
|
+
const homePlansDir = (0, import_node_path35.join)(home, ".claude", "plans");
|
|
28776
28879
|
const sources = [];
|
|
28777
28880
|
if (isRealDirectoryChain(process.cwd(), [".claude", "plans"])) {
|
|
28778
|
-
sources.push({ root: process.cwd(), prefix: (0,
|
|
28881
|
+
sources.push({ root: process.cwd(), prefix: (0, import_node_path35.join)(".claude", "plans") });
|
|
28779
28882
|
}
|
|
28780
28883
|
if (home && (0, import_node_fs45.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
|
|
28781
28884
|
const candidates2 = [];
|
|
@@ -28783,14 +28886,14 @@ function discoverPlans() {
|
|
|
28783
28886
|
for (const source2 of sources) {
|
|
28784
28887
|
let names2;
|
|
28785
28888
|
try {
|
|
28786
|
-
names2 = (0, import_node_fs45.readdirSync)(source2.prefix ? (0,
|
|
28889
|
+
names2 = (0, import_node_fs45.readdirSync)(source2.prefix ? (0, import_node_path35.join)(source2.root, source2.prefix) : source2.root);
|
|
28787
28890
|
} catch {
|
|
28788
28891
|
continue;
|
|
28789
28892
|
}
|
|
28790
28893
|
for (const f of names2) {
|
|
28791
28894
|
if (!f.endsWith(".md") || seen.has(f)) continue;
|
|
28792
28895
|
seen.add(f);
|
|
28793
|
-
const relPath = source2.prefix ? (0,
|
|
28896
|
+
const relPath = source2.prefix ? (0, import_node_path35.join)(source2.prefix, f) : f;
|
|
28794
28897
|
const stat3 = statRegularInRoot(source2.root, relPath);
|
|
28795
28898
|
if (!stat3.ok) continue;
|
|
28796
28899
|
candidates2.push({ name: f, root: source2.root, relPath, mtime: stat3.mtimeMs, size: stat3.size });
|
|
@@ -28808,7 +28911,7 @@ function discoverPlans() {
|
|
|
28808
28911
|
function isRealDirectoryChain(root, parts2) {
|
|
28809
28912
|
let current = root;
|
|
28810
28913
|
for (const part of parts2) {
|
|
28811
|
-
current = (0,
|
|
28914
|
+
current = (0, import_node_path35.join)(current, part);
|
|
28812
28915
|
try {
|
|
28813
28916
|
if (!(0, import_node_fs45.lstatSync)(current).isDirectory()) return false;
|
|
28814
28917
|
} catch {
|
|
@@ -29012,7 +29115,7 @@ async function mode(run4) {
|
|
|
29012
29115
|
|
|
29013
29116
|
// src/lib/fold.ts
|
|
29014
29117
|
var import_node_fs46 = require("node:fs");
|
|
29015
|
-
var
|
|
29118
|
+
var import_node_path36 = require("node:path");
|
|
29016
29119
|
var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
|
|
29017
29120
|
"user",
|
|
29018
29121
|
"assistant",
|
|
@@ -29244,9 +29347,9 @@ function fold(transcriptPath, opts = {}) {
|
|
|
29244
29347
|
return result;
|
|
29245
29348
|
}
|
|
29246
29349
|
try {
|
|
29247
|
-
const sidecarDir = (0,
|
|
29248
|
-
(0,
|
|
29249
|
-
(0,
|
|
29350
|
+
const sidecarDir = (0, import_node_path36.join)(
|
|
29351
|
+
(0, import_node_path36.dirname)(transcriptPath),
|
|
29352
|
+
(0, import_node_path36.basename)(transcriptPath).replace(/\.jsonl$/, ""),
|
|
29250
29353
|
"subagents"
|
|
29251
29354
|
);
|
|
29252
29355
|
if ((0, import_node_fs46.existsSync)(sidecarDir)) {
|
|
@@ -29256,7 +29359,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
29256
29359
|
const walk2 = (d, depth) => {
|
|
29257
29360
|
if (depth > 4) return;
|
|
29258
29361
|
for (const e of (0, import_node_fs46.readdirSync)(d, { withFileTypes: true })) {
|
|
29259
|
-
const p = (0,
|
|
29362
|
+
const p = (0, import_node_path36.join)(d, e.name);
|
|
29260
29363
|
if (e.isDirectory()) {
|
|
29261
29364
|
walk2(p, depth + 1);
|
|
29262
29365
|
} else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
|
|
@@ -29629,7 +29732,7 @@ async function evidence(run4) {
|
|
|
29629
29732
|
|
|
29630
29733
|
// src/lib/cache-cleanup.ts
|
|
29631
29734
|
var import_node_fs47 = require("node:fs");
|
|
29632
|
-
var
|
|
29735
|
+
var import_node_path37 = require("node:path");
|
|
29633
29736
|
var CACHE_TTL_DAYS = 7;
|
|
29634
29737
|
function pruneStaleCache() {
|
|
29635
29738
|
try {
|
|
@@ -29637,7 +29740,7 @@ function pruneStaleCache() {
|
|
|
29637
29740
|
const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
|
|
29638
29741
|
for (const entry of (0, import_node_fs47.readdirSync)(dir)) {
|
|
29639
29742
|
if (!entry.startsWith("pending-")) continue;
|
|
29640
|
-
const path = (0,
|
|
29743
|
+
const path = (0, import_node_path37.join)(dir, entry);
|
|
29641
29744
|
try {
|
|
29642
29745
|
const stat3 = (0, import_node_fs47.statSync)(path);
|
|
29643
29746
|
if (stat3.mtimeMs < cutoff) {
|
|
@@ -29872,7 +29975,7 @@ function languageOf2(path) {
|
|
|
29872
29975
|
|
|
29873
29976
|
// src/lib/code/runtime.ts
|
|
29874
29977
|
var import_node_fs49 = require("node:fs");
|
|
29875
|
-
var
|
|
29978
|
+
var import_node_path38 = require("node:path");
|
|
29876
29979
|
var import_web_tree_sitter2 = __toESM2(require_web_tree_sitter2());
|
|
29877
29980
|
|
|
29878
29981
|
// src/lib/code/grammars.json
|
|
@@ -29932,12 +30035,12 @@ var grammars_default = {
|
|
|
29932
30035
|
var MAX_PARSE_BYTES = 512 * 1024;
|
|
29933
30036
|
function grammarCandidates(file, pkg, env = process.env) {
|
|
29934
30037
|
return [
|
|
29935
|
-
...env.VERITY_GRAMMAR_DIR ? [(0,
|
|
29936
|
-
(0,
|
|
30038
|
+
...env.VERITY_GRAMMAR_DIR ? [(0, import_node_path38.join)(env.VERITY_GRAMMAR_DIR, file)] : [],
|
|
30039
|
+
(0, import_node_path38.join)(__dirname, "..", "data", "grammars", file),
|
|
29937
30040
|
// bundled: cli/bin/ → cli/data/grammars/
|
|
29938
|
-
(0,
|
|
30041
|
+
(0, import_node_path38.join)(__dirname, "..", "..", "..", "data", "grammars", file),
|
|
29939
30042
|
// tsx: cli/src/lib/code/ → cli/data/grammars/
|
|
29940
|
-
(0,
|
|
30043
|
+
(0, import_node_path38.join)(__dirname, "..", "..", "..", "node_modules", pkg, file)
|
|
29941
30044
|
// tsx, before a build: the pinned devDependency
|
|
29942
30045
|
];
|
|
29943
30046
|
}
|
|
@@ -30673,14 +30776,14 @@ function accessMap(input) {
|
|
|
30673
30776
|
const targetWrites = (r) => effects.some((e) => e.op === "write" && sameResource(r, e.resource));
|
|
30674
30777
|
const excluded = /* @__PURE__ */ new Set([target, ...helpers, ...fileFns.filter((f) => inside(f, target))]);
|
|
30675
30778
|
const accessors = [];
|
|
30676
|
-
const consider = (fns, p,
|
|
30779
|
+
const consider = (fns, p, sameFile2, fileState) => {
|
|
30677
30780
|
for (const f of fns) {
|
|
30678
|
-
if (
|
|
30679
|
-
if (
|
|
30680
|
-
const theirs = effectsWithHelpers(f, fns, lang, 2, fileState).filter((e) => !(
|
|
30781
|
+
if (sameFile2 && excluded.has(f)) continue;
|
|
30782
|
+
if (sameFile2 && inside(target, f)) continue;
|
|
30783
|
+
const theirs = effectsWithHelpers(f, fns, lang, 2, fileState).filter((e) => !(sameFile2 && e.via.includes(target.name)) && searchable.some((r) => sameResource(r, e.resource) && (e.op === "write" || targetWrites(r))));
|
|
30681
30784
|
if (theirs.length === 0) continue;
|
|
30682
|
-
if (
|
|
30683
|
-
accessors.push({ fn: f, effects: theirs, writes: theirs.some((e) => e.op === "write"), sameFile });
|
|
30785
|
+
if (sameFile2 && [...helperNames].includes(f.name)) continue;
|
|
30786
|
+
accessors.push({ fn: f, effects: theirs, writes: theirs.some((e) => e.op === "write"), sameFile: sameFile2 });
|
|
30684
30787
|
}
|
|
30685
30788
|
};
|
|
30686
30789
|
consider(fileFns, path, true, state);
|
|
@@ -31070,7 +31173,7 @@ var MAX_CALLERS = 30;
|
|
|
31070
31173
|
var MAX_READ_BYTES4 = 512 * 1024;
|
|
31071
31174
|
var IDENT = /^[A-Za-z_$][\w$]*$/;
|
|
31072
31175
|
var TEST_OR_TOOLING = /(^|\/)(tests?|__tests__|spec|specs|fixtures?|e2e|testdata|experiments|scripts)\/|\.(test|spec)\.[cm]?[jt]sx?$|_test\.(py|go)$|(^|\/)test_[^/]+\.py$/;
|
|
31073
|
-
var
|
|
31176
|
+
var dirname19 = (p) => p.includes("/") ? p.slice(0, p.lastIndexOf("/")) : "";
|
|
31074
31177
|
function joinPath(dir, rel) {
|
|
31075
31178
|
const out2 = dir ? dir.split("/") : [];
|
|
31076
31179
|
for (const part of rel.split("/")) {
|
|
@@ -31195,7 +31298,7 @@ function parseJsonc(text2) {
|
|
|
31195
31298
|
return JSON.parse(out2.replace(/,(\s*[}\]])/g, "$1"));
|
|
31196
31299
|
}
|
|
31197
31300
|
function tsconfigFor(source2, fromPath, cache) {
|
|
31198
|
-
for (let dir =
|
|
31301
|
+
for (let dir = dirname19(fromPath); ; dir = dirname19(dir)) {
|
|
31199
31302
|
const file = dir ? `${dir}/tsconfig.json` : "tsconfig.json";
|
|
31200
31303
|
if (!cache.has(file)) {
|
|
31201
31304
|
const read2 = source2.read(file, 256 * 1024);
|
|
@@ -31219,7 +31322,7 @@ function tsconfigFor(source2, fromPath, cache) {
|
|
|
31219
31322
|
function tsCandidates(spec, fromPath, cfg) {
|
|
31220
31323
|
const bases = [];
|
|
31221
31324
|
if (spec.startsWith(".")) {
|
|
31222
|
-
const b = joinPath(
|
|
31325
|
+
const b = joinPath(dirname19(fromPath), spec);
|
|
31223
31326
|
if (b !== null) bases.push(b);
|
|
31224
31327
|
} else if (cfg) {
|
|
31225
31328
|
const root = cfg.baseUrl !== null ? joinPath(cfg.dir, cfg.baseUrl) : cfg.dir;
|
|
@@ -31251,8 +31354,8 @@ function pyCandidates(spec, fromPath) {
|
|
|
31251
31354
|
const mod = spec.slice(dots).replace(/\./g, "/");
|
|
31252
31355
|
const out2 = [];
|
|
31253
31356
|
if (dots > 0) {
|
|
31254
|
-
let dir =
|
|
31255
|
-
for (let i2 = 1; i2 < dots; i2++) dir =
|
|
31357
|
+
let dir = dirname19(fromPath);
|
|
31358
|
+
for (let i2 = 1; i2 < dots; i2++) dir = dirname19(dir);
|
|
31256
31359
|
const b = mod ? joinPath(dir, mod) : dir;
|
|
31257
31360
|
if (b !== null) out2.push(`${b}.py`, `${b}/__init__.py`);
|
|
31258
31361
|
} else {
|
|
@@ -31279,7 +31382,7 @@ function moduleFiles(source2, spec, fromPath, lang, cache = /* @__PURE__ */ new
|
|
|
31279
31382
|
const module2 = mod.ok ? /^\s*module\s+(\S+)/m.exec(mod.content)?.[1] : void 0;
|
|
31280
31383
|
if (!module2 || !(spec === module2 || spec.startsWith(`${module2}/`))) return [];
|
|
31281
31384
|
const dir = spec.slice(module2.length + 1);
|
|
31282
|
-
return source2.list(dir || void 0).filter((p) =>
|
|
31385
|
+
return source2.list(dir || void 0).filter((p) => dirname19(p) === dir && p.endsWith(".go") && !p.endsWith("_test.go"));
|
|
31283
31386
|
}
|
|
31284
31387
|
if (lang === "java") {
|
|
31285
31388
|
const suffix = `${spec.replace(/\./g, "/")}.java`;
|
|
@@ -31330,7 +31433,7 @@ function definitionOf(input) {
|
|
|
31330
31433
|
if (type?.startsWith(RESULT_OF)) {
|
|
31331
31434
|
const [fnName, idx] = type.slice(RESULT_OF.length).split("#");
|
|
31332
31435
|
type = null;
|
|
31333
|
-
const others = lang === "go" ? source2.list(
|
|
31436
|
+
const others = lang === "go" ? source2.list(dirname19(path) || void 0).filter((p) => dirname19(p) === dirname19(path) && p.endsWith(".go") && p !== path) : (() => {
|
|
31334
31437
|
const imp = importOf(content, lang, fnName, null);
|
|
31335
31438
|
return imp ? moduleFiles(source2, imp.spec, path, lang, tsCache) : [];
|
|
31336
31439
|
})();
|
|
@@ -31377,7 +31480,7 @@ function definitionOf(input) {
|
|
|
31377
31480
|
}
|
|
31378
31481
|
}
|
|
31379
31482
|
if (out2.length === 0 && lang === "go" && !receiver) {
|
|
31380
|
-
for (const f of source2.list(
|
|
31483
|
+
for (const f of source2.list(dirname19(path) || void 0).filter((p) => dirname19(p) === dirname19(path) && p.endsWith(".go") && p !== path)) {
|
|
31381
31484
|
add(functionsNamed(outlineOf2(f), name2), "package");
|
|
31382
31485
|
if (Date.now() > input.deadlineAt) break;
|
|
31383
31486
|
}
|
|
@@ -32273,7 +32376,7 @@ async function repoContext(run4) {
|
|
|
32273
32376
|
// src/lib/seed-runner.ts
|
|
32274
32377
|
var import_promises13 = require("node:fs/promises");
|
|
32275
32378
|
var import_node_fs50 = require("node:fs");
|
|
32276
|
-
var
|
|
32379
|
+
var import_node_path39 = require("node:path");
|
|
32277
32380
|
var import_yaml6 = __toESM2(require_dist());
|
|
32278
32381
|
|
|
32279
32382
|
// src/lib/seed.ts
|
|
@@ -32496,7 +32599,7 @@ function normalizeTitle(title) {
|
|
|
32496
32599
|
async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
|
|
32497
32600
|
const titles = /* @__PURE__ */ new Set();
|
|
32498
32601
|
for (const dir of NODE_DIRS) {
|
|
32499
|
-
const full = (0,
|
|
32602
|
+
const full = (0, import_node_path39.join)(memoryDir3, dir);
|
|
32500
32603
|
if (!(0, import_node_fs50.existsSync)(full)) continue;
|
|
32501
32604
|
let files;
|
|
32502
32605
|
try {
|
|
@@ -32508,7 +32611,7 @@ async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
|
|
|
32508
32611
|
if (!file.endsWith(".md")) continue;
|
|
32509
32612
|
let content;
|
|
32510
32613
|
try {
|
|
32511
|
-
content = await (0, import_promises13.readFile)((0,
|
|
32614
|
+
content = await (0, import_promises13.readFile)((0, import_node_path39.join)(full, file), "utf-8");
|
|
32512
32615
|
} catch {
|
|
32513
32616
|
continue;
|
|
32514
32617
|
}
|
|
@@ -32685,7 +32788,7 @@ async function runSeed(opts) {
|
|
|
32685
32788
|
}
|
|
32686
32789
|
const content = typeof res.data.content === "string" && res.data.content.length > 0 ? res.data.content : renderNodeMarkdown(c, nodeId, createdAt);
|
|
32687
32790
|
try {
|
|
32688
|
-
await (0, import_promises13.mkdir)((0,
|
|
32791
|
+
await (0, import_promises13.mkdir)((0, import_node_path39.dirname)(targetPath), { recursive: true });
|
|
32689
32792
|
await (0, import_promises13.writeFile)(targetPath, content);
|
|
32690
32793
|
if (deduplicated) existing++;
|
|
32691
32794
|
else {
|
|
@@ -32702,7 +32805,7 @@ async function runSeed(opts) {
|
|
|
32702
32805
|
|
|
32703
32806
|
// src/commands/analyze/phases/08-memory-manifest.ts
|
|
32704
32807
|
var import_node_fs51 = require("node:fs");
|
|
32705
|
-
var
|
|
32808
|
+
var import_node_path40 = require("node:path");
|
|
32706
32809
|
async function memoryManifest(run4) {
|
|
32707
32810
|
const { globals } = run4;
|
|
32708
32811
|
const { serviceUrl, token } = run4;
|
|
@@ -32712,7 +32815,7 @@ async function memoryManifest(run4) {
|
|
|
32712
32815
|
let autoSeedNotice = null;
|
|
32713
32816
|
try {
|
|
32714
32817
|
await ensureMemoryDir();
|
|
32715
|
-
const seedMarker = (0,
|
|
32818
|
+
const seedMarker = (0, import_node_path40.join)(VERITY_DIR, ".seeded");
|
|
32716
32819
|
const hasStandard = (0, import_node_fs51.existsSync)(STANDARD_FILE);
|
|
32717
32820
|
const alreadyTried = (0, import_node_fs51.existsSync)(seedMarker);
|
|
32718
32821
|
if (hasStandard && !alreadyTried) {
|
|
@@ -32833,7 +32936,7 @@ function computeIncrement(reviewedPaths, hashOf, priorAuthored) {
|
|
|
32833
32936
|
}
|
|
32834
32937
|
|
|
32835
32938
|
// src/commands/analyze/phases/10-working-memory.ts
|
|
32836
|
-
var
|
|
32939
|
+
var import_node_path41 = require("node:path");
|
|
32837
32940
|
async function workingMemory(run4) {
|
|
32838
32941
|
const { opts } = run4;
|
|
32839
32942
|
const { allForReview, baseline, conversation, foldResult, sessionId, token, transcriptPath } = run4;
|
|
@@ -32845,7 +32948,7 @@ async function workingMemory(run4) {
|
|
|
32845
32948
|
const priorState = foldForMarks(memorySession.d);
|
|
32846
32949
|
incrementReport = computeIncrement(
|
|
32847
32950
|
allForReview,
|
|
32848
|
-
(p) => fileHash((0,
|
|
32951
|
+
(p) => fileHash((0, import_node_path41.join)(repoRoot(), p)),
|
|
32849
32952
|
priorState.authored_all.map((a) => ({
|
|
32850
32953
|
path: a.path,
|
|
32851
32954
|
hash_at_last_verdict: a.hash_at_last_verdict
|
|
@@ -33474,7 +33577,7 @@ async function transmit(run4) {
|
|
|
33474
33577
|
|
|
33475
33578
|
// src/commands/analyze/phases/13-reconcile.ts
|
|
33476
33579
|
var import_node_fs54 = require("node:fs");
|
|
33477
|
-
var
|
|
33580
|
+
var import_node_path42 = require("node:path");
|
|
33478
33581
|
async function reconcile(run4) {
|
|
33479
33582
|
const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory: memory2, memorySession, response, reviewable, securityFiles, turnId } = run4;
|
|
33480
33583
|
const sentPaths = codeDelta.files.map((f) => f.path);
|
|
@@ -33503,7 +33606,7 @@ async function reconcile(run4) {
|
|
|
33503
33606
|
const st = foldDossier(memorySession.d);
|
|
33504
33607
|
openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line2) => {
|
|
33505
33608
|
try {
|
|
33506
|
-
const src = (0, import_node_fs54.readFileSync)((0,
|
|
33609
|
+
const src = (0, import_node_fs54.readFileSync)((0, import_node_path42.join)(repoRoot(), file), "utf8").split("\n");
|
|
33507
33610
|
const at = src[line2 - 1];
|
|
33508
33611
|
return at === void 0 ? null : lineSha(at);
|
|
33509
33612
|
} catch {
|
|
@@ -34325,7 +34428,7 @@ function registerAnalyzeCommand(program2) {
|
|
|
34325
34428
|
var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
|
|
34326
34429
|
async function runAnalyze(opts, globals) {
|
|
34327
34430
|
if (!verityConfigured()) {
|
|
34328
|
-
(0, import_node_fs55.writeSync)(2, isMachineStore((0,
|
|
34431
|
+
(0, import_node_fs55.writeSync)(2, isMachineStore((0, import_node_path43.join)(repoRoot(), VERITY_DIR)) ? "[verity] nothing to review in your home directory \u2014 run Verity inside a project.\n" : '[verity] not set up in this project \u2014 run "verity init" first.\n');
|
|
34329
34432
|
process.exit(0);
|
|
34330
34433
|
}
|
|
34331
34434
|
const run4 = createRun(opts, globals);
|
|
@@ -34349,23 +34452,23 @@ async function runAnalyze(opts, globals) {
|
|
|
34349
34452
|
var import_node_fs60 = require("node:fs");
|
|
34350
34453
|
var import_node_child_process17 = require("node:child_process");
|
|
34351
34454
|
var import_node_crypto18 = require("node:crypto");
|
|
34352
|
-
var
|
|
34455
|
+
var import_node_path48 = require("node:path");
|
|
34353
34456
|
|
|
34354
34457
|
// src/lib/prove/runner.ts
|
|
34355
34458
|
var import_node_child_process15 = require("node:child_process");
|
|
34356
34459
|
var import_node_os9 = require("node:os");
|
|
34357
34460
|
var import_node_fs58 = require("node:fs");
|
|
34358
34461
|
var import_node_os10 = require("node:os");
|
|
34359
|
-
var
|
|
34462
|
+
var import_node_path46 = require("node:path");
|
|
34360
34463
|
|
|
34361
34464
|
// src/lib/prove/scaffold.ts
|
|
34362
34465
|
var import_node_fs57 = require("node:fs");
|
|
34363
|
-
var
|
|
34466
|
+
var import_node_path45 = require("node:path");
|
|
34364
34467
|
|
|
34365
34468
|
// src/lib/prove/safe-write.ts
|
|
34366
34469
|
var import_node_fs56 = require("node:fs");
|
|
34367
34470
|
var import_node_crypto15 = require("node:crypto");
|
|
34368
|
-
var
|
|
34471
|
+
var import_node_path44 = require("node:path");
|
|
34369
34472
|
var SafeWriteError = class extends Error {
|
|
34370
34473
|
constructor(reason, path) {
|
|
34371
34474
|
super(`refusing to write ${path}: ${reason}`);
|
|
@@ -34377,7 +34480,7 @@ var SafeWriteError = class extends Error {
|
|
|
34377
34480
|
var FLAGS3 = import_node_fs56.constants;
|
|
34378
34481
|
var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
|
|
34379
34482
|
function assertPlainRelative(rel) {
|
|
34380
|
-
if (!rel || (0,
|
|
34483
|
+
if (!rel || (0, import_node_path44.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
|
|
34381
34484
|
for (const part of rel.split(/[\\/]/)) {
|
|
34382
34485
|
if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
|
|
34383
34486
|
}
|
|
@@ -34386,7 +34489,7 @@ function ensureDirsNoFollow(root, rel) {
|
|
|
34386
34489
|
const parts2 = rel.split(/[\\/]/);
|
|
34387
34490
|
let cur = root;
|
|
34388
34491
|
for (const part of parts2.slice(0, -1)) {
|
|
34389
|
-
cur = (0,
|
|
34492
|
+
cur = (0, import_node_path44.join)(cur, part);
|
|
34390
34493
|
let st;
|
|
34391
34494
|
try {
|
|
34392
34495
|
st = (0, import_node_fs56.lstatSync)(cur);
|
|
@@ -34397,10 +34500,10 @@ function ensureDirsNoFollow(root, rel) {
|
|
|
34397
34500
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
|
|
34398
34501
|
if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
|
|
34399
34502
|
}
|
|
34400
|
-
return (0,
|
|
34503
|
+
return (0, import_node_path44.join)(root, rel);
|
|
34401
34504
|
}
|
|
34402
34505
|
function insideRoot(realRoot, realPath) {
|
|
34403
|
-
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(
|
|
34506
|
+
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path44.sep) ? realRoot : realRoot + import_node_path44.sep);
|
|
34404
34507
|
}
|
|
34405
34508
|
function removeQuietly(path) {
|
|
34406
34509
|
try {
|
|
@@ -34411,7 +34514,7 @@ function removeQuietly(path) {
|
|
|
34411
34514
|
function writeFileInRootNoFollow(root, rel, content) {
|
|
34412
34515
|
assertPlainRelative(rel);
|
|
34413
34516
|
const dest = ensureDirsNoFollow(root, rel);
|
|
34414
|
-
const dir = (0,
|
|
34517
|
+
const dir = (0, import_node_path44.dirname)(dest);
|
|
34415
34518
|
try {
|
|
34416
34519
|
const st = (0, import_node_fs56.lstatSync)(dest);
|
|
34417
34520
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
|
|
@@ -34425,7 +34528,7 @@ function writeFileInRootNoFollow(root, rel, content) {
|
|
|
34425
34528
|
} catch {
|
|
34426
34529
|
throw new SafeWriteError("unwritable", root);
|
|
34427
34530
|
}
|
|
34428
|
-
const tmp = (0,
|
|
34531
|
+
const tmp = (0, import_node_path44.join)(dir, `.${(0, import_node_path44.basename)(dest)}.${(0, import_node_crypto15.randomBytes)(6).toString("hex")}.tmp`);
|
|
34429
34532
|
let fd;
|
|
34430
34533
|
try {
|
|
34431
34534
|
fd = (0, import_node_fs56.openSync)(tmp, import_node_fs56.constants.O_WRONLY | import_node_fs56.constants.O_CREAT | import_node_fs56.constants.O_EXCL | NOFOLLOW2, 420);
|
|
@@ -34469,7 +34572,7 @@ function pathHasNoLink(root, rel) {
|
|
|
34469
34572
|
}
|
|
34470
34573
|
let cur = root;
|
|
34471
34574
|
for (const part of rel.split(/[\\/]/)) {
|
|
34472
|
-
cur = cur +
|
|
34575
|
+
cur = cur + import_node_path44.sep + part;
|
|
34473
34576
|
try {
|
|
34474
34577
|
if ((0, import_node_fs56.lstatSync)(cur).isSymbolicLink()) return false;
|
|
34475
34578
|
} catch {
|
|
@@ -34781,20 +34884,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
|
|
|
34781
34884
|
never committed; what reaches the team is the bug report and the fix.
|
|
34782
34885
|
`;
|
|
34783
34886
|
function scaffoldProofs(root) {
|
|
34784
|
-
const proofsDir = (0,
|
|
34887
|
+
const proofsDir = (0, import_node_path45.join)(root, PROOFS_DIR);
|
|
34785
34888
|
const written = [];
|
|
34786
34889
|
const kept = [];
|
|
34787
34890
|
for (const stray of ["lakefile.lean"]) {
|
|
34788
34891
|
const rel = `${PROOFS_DIR}/${stray}`;
|
|
34789
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
34892
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
|
|
34790
34893
|
try {
|
|
34791
|
-
(0, import_node_fs57.rmSync)((0,
|
|
34894
|
+
(0, import_node_fs57.rmSync)((0, import_node_path45.join)(root, rel), { force: true });
|
|
34792
34895
|
} catch {
|
|
34793
34896
|
}
|
|
34794
34897
|
}
|
|
34795
34898
|
for (const f of PROOFS_TEMPLATE_FILES) {
|
|
34796
34899
|
const rel = `${PROOFS_DIR}/${f.path}`;
|
|
34797
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
34900
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
|
|
34798
34901
|
const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
|
|
34799
34902
|
if (current.ok && current.content === f.content) {
|
|
34800
34903
|
kept.push(rel);
|
|
@@ -34807,8 +34910,8 @@ function scaffoldProofs(root) {
|
|
|
34807
34910
|
[`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
|
|
34808
34911
|
[`${MODELS_DIR}/README.md`, MODELS_README]
|
|
34809
34912
|
]) {
|
|
34810
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
34811
|
-
if (existsNoFollow((0,
|
|
34913
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
|
|
34914
|
+
if (existsNoFollow((0, import_node_path45.join)(root, rel))) {
|
|
34812
34915
|
kept.push(rel);
|
|
34813
34916
|
continue;
|
|
34814
34917
|
}
|
|
@@ -35077,17 +35180,17 @@ function renderReport(r) {
|
|
|
35077
35180
|
|
|
35078
35181
|
// src/lib/prove/runner.ts
|
|
35079
35182
|
function verityLeanHome(env = process.env) {
|
|
35080
|
-
return env.VERITY_LEAN_HOME ?? (0,
|
|
35183
|
+
return env.VERITY_LEAN_HOME ?? (0, import_node_path46.join)(env.HOME ?? (0, import_node_os10.homedir)(), ".verity", "lean");
|
|
35081
35184
|
}
|
|
35082
35185
|
function findToolchain(env = process.env) {
|
|
35083
|
-
const managedBin = (0,
|
|
35084
|
-
const elanBin = (0,
|
|
35085
|
-
const elanHas = (0, import_node_fs58.existsSync)((0,
|
|
35086
|
-
const userPath = (env.PATH ?? "").split(
|
|
35087
|
-
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(
|
|
35186
|
+
const managedBin = (0, import_node_path46.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
|
|
35187
|
+
const elanBin = (0, import_node_path46.join)(env.HOME ?? (0, import_node_os10.homedir)(), ".elan", "bin");
|
|
35188
|
+
const elanHas = (0, import_node_fs58.existsSync)((0, import_node_path46.join)(env.HOME ?? (0, import_node_os10.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
|
|
35189
|
+
const userPath = (env.PATH ?? "").split(import_node_path46.delimiter).filter((d) => d && (elanHas || (0, import_node_path46.resolve)(d) !== (0, import_node_path46.resolve)(elanBin)));
|
|
35190
|
+
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path46.delimiter);
|
|
35088
35191
|
const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
|
|
35089
35192
|
const exe = process.platform === "win32" ? "lake.exe" : "lake";
|
|
35090
|
-
const candidates2 = [(0,
|
|
35193
|
+
const candidates2 = [(0, import_node_path46.join)(managedBin, exe), ...elanHas ? [(0, import_node_path46.join)(elanBin, exe)] : [], exe];
|
|
35091
35194
|
for (const candidate of candidates2) {
|
|
35092
35195
|
try {
|
|
35093
35196
|
(0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
|
|
@@ -35166,7 +35269,7 @@ function proofsWorkspaceProblem(root) {
|
|
|
35166
35269
|
for (const rel of [".verity", PROOFS_DIR, `${PROOFS_DIR}/.lake`]) {
|
|
35167
35270
|
let st;
|
|
35168
35271
|
try {
|
|
35169
|
-
st = (0, import_node_fs58.lstatSync)((0,
|
|
35272
|
+
st = (0, import_node_fs58.lstatSync)((0, import_node_path46.join)(root, rel));
|
|
35170
35273
|
} catch {
|
|
35171
35274
|
break;
|
|
35172
35275
|
}
|
|
@@ -35186,44 +35289,44 @@ function refused(problem) {
|
|
|
35186
35289
|
function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
35187
35290
|
const problem = proofsWorkspaceProblem(root);
|
|
35188
35291
|
if (problem) return refused(problem);
|
|
35189
|
-
return run2(tc, (0,
|
|
35292
|
+
return run2(tc, (0, import_node_path46.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
35190
35293
|
}
|
|
35191
35294
|
async function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
35192
35295
|
const problem = proofsWorkspaceProblem(root);
|
|
35193
35296
|
if (problem) return refused(problem);
|
|
35194
|
-
return runAsync(tc, (0,
|
|
35297
|
+
return runAsync(tc, (0, import_node_path46.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
35195
35298
|
}
|
|
35196
35299
|
function isModelInRoot(modelsAbs, rel) {
|
|
35197
|
-
if (!rel.endsWith(".lean") || (0,
|
|
35300
|
+
if (!rel.endsWith(".lean") || (0, import_node_path46.isAbsolute)(rel) || rel.startsWith("..")) return false;
|
|
35198
35301
|
return statRegularInRoot(modelsAbs, rel).ok;
|
|
35199
35302
|
}
|
|
35200
35303
|
function resolveModelFile(root, arg) {
|
|
35201
|
-
const modelsAbs = (0,
|
|
35202
|
-
const asPath = (0,
|
|
35304
|
+
const modelsAbs = (0, import_node_path46.join)(root, MODELS_DIR);
|
|
35305
|
+
const asPath = (0, import_node_path46.relative)(modelsAbs, (0, import_node_path46.isAbsolute)(arg) ? arg : (0, import_node_path46.resolve)(root, arg));
|
|
35203
35306
|
const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
|
|
35204
35307
|
for (const rel of candidates2) {
|
|
35205
|
-
if (isModelInRoot(modelsAbs, rel)) return (0,
|
|
35308
|
+
if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path46.join)(modelsAbs, rel);
|
|
35206
35309
|
}
|
|
35207
35310
|
return null;
|
|
35208
35311
|
}
|
|
35209
35312
|
function listModelFiles(root) {
|
|
35210
|
-
const modelsAbs = (0,
|
|
35313
|
+
const modelsAbs = (0, import_node_path46.join)(root, MODELS_DIR);
|
|
35211
35314
|
if (!(0, import_node_fs58.existsSync)(modelsAbs)) return [];
|
|
35212
|
-
return (0, import_node_fs58.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0,
|
|
35315
|
+
return (0, import_node_fs58.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path46.join)(modelsAbs, f));
|
|
35213
35316
|
}
|
|
35214
35317
|
function trimDiagnostics(text2) {
|
|
35215
35318
|
return text2.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
|
|
35216
35319
|
}
|
|
35217
35320
|
function checkModel(tc, root, modelFile, opts = {}) {
|
|
35218
|
-
const proofsAbs = (0,
|
|
35219
|
-
const rel = (0,
|
|
35321
|
+
const proofsAbs = (0, import_node_path46.join)(root, PROOFS_DIR);
|
|
35322
|
+
const rel = (0, import_node_path46.relative)(proofsAbs, modelFile);
|
|
35220
35323
|
const problem = proofsWorkspaceProblem(root);
|
|
35221
35324
|
const res = problem ? refused(problem) : run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
35222
35325
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
35223
35326
|
}
|
|
35224
35327
|
async function checkModelAsync(tc, root, modelFile, opts = {}) {
|
|
35225
|
-
const proofsAbs = (0,
|
|
35226
|
-
const rel = (0,
|
|
35328
|
+
const proofsAbs = (0, import_node_path46.join)(root, PROOFS_DIR);
|
|
35329
|
+
const rel = (0, import_node_path46.relative)(proofsAbs, modelFile);
|
|
35227
35330
|
const problem = proofsWorkspaceProblem(root);
|
|
35228
35331
|
const res = problem ? refused(problem) : await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
35229
35332
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
@@ -35232,10 +35335,10 @@ function toReport(res, root, modelFile, timeoutMs) {
|
|
|
35232
35335
|
const parsed = parseVerityLines(res.stdout);
|
|
35233
35336
|
const combined = `${res.stdout}
|
|
35234
35337
|
${res.stderr}`;
|
|
35235
|
-
const name2 = parsed.header?.model ?? (0,
|
|
35338
|
+
const name2 = parsed.header?.model ?? (0, import_node_path46.basename)(modelFile, ".lean");
|
|
35236
35339
|
const report = {
|
|
35237
35340
|
model: name2,
|
|
35238
|
-
file: (0,
|
|
35341
|
+
file: (0, import_node_path46.relative)(root, modelFile),
|
|
35239
35342
|
ok: res.ok,
|
|
35240
35343
|
header: parsed.header,
|
|
35241
35344
|
properties: parsed.properties,
|
|
@@ -35281,7 +35384,7 @@ var import_node_fs59 = require("node:fs");
|
|
|
35281
35384
|
var import_node_crypto17 = require("node:crypto");
|
|
35282
35385
|
var import_node_child_process16 = require("node:child_process");
|
|
35283
35386
|
var import_node_os11 = require("node:os");
|
|
35284
|
-
var
|
|
35387
|
+
var import_node_path47 = require("node:path");
|
|
35285
35388
|
var import_promises15 = require("node:stream/promises");
|
|
35286
35389
|
var import_node_stream = require("node:stream");
|
|
35287
35390
|
var RELEASES = "https://releases.lean-lang.org/lean4";
|
|
@@ -35295,7 +35398,7 @@ function freeBytes(dir) {
|
|
|
35295
35398
|
const st = (0, import_node_fs59.statfsSync)(d);
|
|
35296
35399
|
return Number(st.bavail) * Number(st.bsize);
|
|
35297
35400
|
} catch {
|
|
35298
|
-
const up = (0,
|
|
35401
|
+
const up = (0, import_node_path47.join)(d, "..");
|
|
35299
35402
|
if (up === d) return null;
|
|
35300
35403
|
d = up;
|
|
35301
35404
|
}
|
|
@@ -35337,13 +35440,13 @@ function leanAssetName(version = pinnedVersion()) {
|
|
|
35337
35440
|
return suffix ? `lean-${v}-${suffix}.zip` : null;
|
|
35338
35441
|
}
|
|
35339
35442
|
function pinnedVersionDir(env = process.env) {
|
|
35340
|
-
return (0,
|
|
35443
|
+
return (0, import_node_path47.join)(verityLeanHome(env), pinnedVersion());
|
|
35341
35444
|
}
|
|
35342
35445
|
function lakeBinary() {
|
|
35343
35446
|
return (0, import_node_os11.platform)() === "win32" ? "lake.exe" : "lake";
|
|
35344
35447
|
}
|
|
35345
35448
|
function managedInstalled(env = process.env) {
|
|
35346
|
-
return (0, import_node_fs59.existsSync)((0,
|
|
35449
|
+
return (0, import_node_fs59.existsSync)((0, import_node_path47.join)(pinnedVersionDir(env), "bin", lakeBinary()));
|
|
35347
35450
|
}
|
|
35348
35451
|
function unzip(zip, dest) {
|
|
35349
35452
|
const attempts = (0, import_node_os11.platform)() === "linux" ? [["unzip", ["-q", zip, "-d", dest]], ["python3", ["-m", "zipfile", "-e", zip, dest]], ["tar", ["-xf", zip, "-C", dest]]] : [["tar", ["-xf", zip, "-C", dest]], ["unzip", ["-q", zip, "-d", dest]], ["python3", ["-m", "zipfile", "-e", zip, dest]]];
|
|
@@ -35356,7 +35459,7 @@ function unzip(zip, dest) {
|
|
|
35356
35459
|
} catch (err2) {
|
|
35357
35460
|
errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
|
|
35358
35461
|
try {
|
|
35359
|
-
for (const e of (0, import_node_fs59.readdirSync)(dest)) (0, import_node_fs59.rmSync)((0,
|
|
35462
|
+
for (const e of (0, import_node_fs59.readdirSync)(dest)) (0, import_node_fs59.rmSync)((0, import_node_path47.join)(dest, e), { recursive: true, force: true });
|
|
35360
35463
|
} catch {
|
|
35361
35464
|
}
|
|
35362
35465
|
}
|
|
@@ -35432,10 +35535,10 @@ async function installLean(opts = {}) {
|
|
|
35432
35535
|
const gb = (n2) => (n2 / 1024 ** 3).toFixed(1);
|
|
35433
35536
|
return { ok: false, error: `not enough disk space for Lean: ${gb(free)} GB free where ${home} lives, needs about ${gb(needed)} GB` };
|
|
35434
35537
|
}
|
|
35435
|
-
const tmp = (0,
|
|
35538
|
+
const tmp = (0, import_node_path47.join)(home, ".tmp");
|
|
35436
35539
|
(0, import_node_fs59.rmSync)(tmp, { recursive: true, force: true });
|
|
35437
35540
|
(0, import_node_fs59.mkdirSync)(tmp, { recursive: true });
|
|
35438
|
-
const zip = (0,
|
|
35541
|
+
const zip = (0, import_node_path47.join)(tmp, asset);
|
|
35439
35542
|
say(`downloading ${url}`);
|
|
35440
35543
|
let lastPct = -1;
|
|
35441
35544
|
try {
|
|
@@ -35458,7 +35561,7 @@ async function installLean(opts = {}) {
|
|
|
35458
35561
|
return { ok: false, error: verified.error };
|
|
35459
35562
|
}
|
|
35460
35563
|
say("unpacking (this takes a minute)");
|
|
35461
|
-
const unpack = (0,
|
|
35564
|
+
const unpack = (0, import_node_path47.join)(tmp, "unpack");
|
|
35462
35565
|
(0, import_node_fs59.mkdirSync)(unpack);
|
|
35463
35566
|
const unpacked = unzip(zip, unpack);
|
|
35464
35567
|
if (!unpacked.ok) {
|
|
@@ -35466,8 +35569,8 @@ async function installLean(opts = {}) {
|
|
|
35466
35569
|
return { ok: false, error: `unpack failed: ${unpacked.error}` };
|
|
35467
35570
|
}
|
|
35468
35571
|
const entries = (0, import_node_fs59.readdirSync)(unpack);
|
|
35469
|
-
const top = entries.length === 1 && (0, import_node_fs59.statSync)((0,
|
|
35470
|
-
if (!(0, import_node_fs59.existsSync)((0,
|
|
35572
|
+
const top = entries.length === 1 && (0, import_node_fs59.statSync)((0, import_node_path47.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path47.join)(unpack, entries[0]) : unpack;
|
|
35573
|
+
if (!(0, import_node_fs59.existsSync)((0, import_node_path47.join)(top, "bin", lakeBinary()))) {
|
|
35471
35574
|
(0, import_node_fs59.rmSync)(tmp, { recursive: true, force: true });
|
|
35472
35575
|
return { ok: false, error: "the archive did not contain bin/lake" };
|
|
35473
35576
|
}
|
|
@@ -35551,7 +35654,7 @@ function startBackgroundInstall(opts) {
|
|
|
35551
35654
|
const home = verityLeanHome(env);
|
|
35552
35655
|
try {
|
|
35553
35656
|
(0, import_node_fs60.mkdirSync)(home, { recursive: true });
|
|
35554
|
-
const log = (0, import_node_fs60.openSync)((0,
|
|
35657
|
+
const log = (0, import_node_fs60.openSync)((0, import_node_path48.join)(home, LOG_FILE), import_node_fs60.constants.O_WRONLY | import_node_fs60.constants.O_APPEND | import_node_fs60.constants.O_CREAT | (import_node_fs60.constants.O_NOFOLLOW ?? 0), 384);
|
|
35555
35658
|
try {
|
|
35556
35659
|
const child = (opts.run ?? import_node_child_process17.spawn)(process.execPath, [opts.cli, "lean", "install", "--yes", "--background"], {
|
|
35557
35660
|
detached: true,
|
|
@@ -35583,7 +35686,7 @@ function lockToken(env) {
|
|
|
35583
35686
|
function acquireInstallLock(env = process.env, now = Date.now()) {
|
|
35584
35687
|
const home = verityLeanHome(env);
|
|
35585
35688
|
(0, import_node_fs60.mkdirSync)(home, { recursive: true });
|
|
35586
|
-
const lock = (0,
|
|
35689
|
+
const lock = (0, import_node_path48.join)(home, LOCK_FILE);
|
|
35587
35690
|
if ((0, import_node_fs60.existsSync)(lock) && !installRunning(env, now)) (0, import_node_fs60.rmSync)(lock, { force: true });
|
|
35588
35691
|
const token = (0, import_node_crypto18.randomBytes)(16).toString("hex");
|
|
35589
35692
|
try {
|
|
@@ -35599,7 +35702,7 @@ function acquireInstallLock(env = process.env, now = Date.now()) {
|
|
|
35599
35702
|
function refreshInstallLock(env = process.env, now = Date.now()) {
|
|
35600
35703
|
if (!heldToken || lockToken(env) !== heldToken) return;
|
|
35601
35704
|
try {
|
|
35602
|
-
const fd = (0, import_node_fs60.openSync)((0,
|
|
35705
|
+
const fd = (0, import_node_fs60.openSync)((0, import_node_path48.join)(verityLeanHome(env), LOCK_FILE), import_node_fs60.constants.O_WRONLY | import_node_fs60.constants.O_TRUNC | (import_node_fs60.constants.O_NOFOLLOW ?? 0));
|
|
35603
35706
|
try {
|
|
35604
35707
|
(0, import_node_fs60.writeFileSync)(fd, JSON.stringify({ pid: process.pid, at: now, token: heldToken }));
|
|
35605
35708
|
} finally {
|
|
@@ -35609,7 +35712,7 @@ function refreshInstallLock(env = process.env, now = Date.now()) {
|
|
|
35609
35712
|
}
|
|
35610
35713
|
}
|
|
35611
35714
|
function releaseInstallLock(env = process.env) {
|
|
35612
|
-
if (heldToken && lockToken(env) === heldToken) (0, import_node_fs60.rmSync)((0,
|
|
35715
|
+
if (heldToken && lockToken(env) === heldToken) (0, import_node_fs60.rmSync)((0, import_node_path48.join)(verityLeanHome(env), LOCK_FILE), { force: true });
|
|
35613
35716
|
heldToken = null;
|
|
35614
35717
|
}
|
|
35615
35718
|
function writeInstallState(state, env = process.env) {
|
|
@@ -35662,14 +35765,14 @@ function resumeInterruptedInstall(opts) {
|
|
|
35662
35765
|
|
|
35663
35766
|
// src/commands/baseline.ts
|
|
35664
35767
|
var import_node_fs63 = require("node:fs");
|
|
35665
|
-
var
|
|
35768
|
+
var import_node_path51 = require("node:path");
|
|
35666
35769
|
|
|
35667
35770
|
// src/lib/skew-notice.ts
|
|
35668
35771
|
var import_node_fs61 = require("node:fs");
|
|
35669
|
-
var
|
|
35772
|
+
var import_node_path49 = require("node:path");
|
|
35670
35773
|
var MARKER = ".skew-notice.json";
|
|
35671
35774
|
function markerPath2() {
|
|
35672
|
-
return (0,
|
|
35775
|
+
return (0, import_node_path49.join)(verityHome(), MARKER);
|
|
35673
35776
|
}
|
|
35674
35777
|
function today(now) {
|
|
35675
35778
|
const y = now.getFullYear();
|
|
@@ -35695,7 +35798,7 @@ function recordSkewNotice(skew, now = /* @__PURE__ */ new Date()) {
|
|
|
35695
35798
|
|
|
35696
35799
|
// src/lib/project-skills.ts
|
|
35697
35800
|
var import_node_fs62 = require("node:fs");
|
|
35698
|
-
var
|
|
35801
|
+
var import_node_path50 = require("node:path");
|
|
35699
35802
|
var PROJECT_SKILL_NAMES = [
|
|
35700
35803
|
"verity-setup",
|
|
35701
35804
|
"verity-analyze",
|
|
@@ -35722,13 +35825,13 @@ var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
|
|
|
35722
35825
|
function staleProjectSkills() {
|
|
35723
35826
|
const root = projectPath(".claude/skills");
|
|
35724
35827
|
if (!(0, import_node_fs62.existsSync)(root)) return [];
|
|
35725
|
-
return ALL.filter((name2) => (0, import_node_fs62.existsSync)((0,
|
|
35828
|
+
return ALL.filter((name2) => (0, import_node_fs62.existsSync)((0, import_node_path50.join)(root, name2)));
|
|
35726
35829
|
}
|
|
35727
35830
|
function removeProjectSkills() {
|
|
35728
35831
|
const root = projectPath(".claude/skills");
|
|
35729
35832
|
const removed = [];
|
|
35730
35833
|
for (const name2 of staleProjectSkills()) {
|
|
35731
|
-
(0, import_node_fs62.rmSync)((0,
|
|
35834
|
+
(0, import_node_fs62.rmSync)((0, import_node_path50.join)(root, name2), { recursive: true, force: true });
|
|
35732
35835
|
removed.push(name2);
|
|
35733
35836
|
}
|
|
35734
35837
|
return removed;
|
|
@@ -35763,7 +35866,7 @@ function registerBaselineCommands(program2) {
|
|
|
35763
35866
|
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.";
|
|
35764
35867
|
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}`;
|
|
35765
35868
|
if (!verityConfigured()) {
|
|
35766
|
-
if (isMachineStore((0,
|
|
35869
|
+
if (isMachineStore((0, import_node_path51.join)(repoRoot(), VERITY_DIR))) process.exit(0);
|
|
35767
35870
|
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.";
|
|
35768
35871
|
const lines = [
|
|
35769
35872
|
`Verity is installed but this project is not set up yet, so the quality gate will not review anything here. ${how}`
|
|
@@ -35907,30 +36010,30 @@ function hookSource(value) {
|
|
|
35907
36010
|
|
|
35908
36011
|
// src/commands/review.ts
|
|
35909
36012
|
var import_node_fs64 = require("node:fs");
|
|
35910
|
-
var
|
|
36013
|
+
var import_node_path52 = require("node:path");
|
|
35911
36014
|
function containReviewPaths(paths, base) {
|
|
35912
36015
|
const kept = [];
|
|
35913
36016
|
const refused2 = [];
|
|
35914
36017
|
for (const raw of paths) {
|
|
35915
|
-
const candidate = (0,
|
|
36018
|
+
const candidate = (0, import_node_path52.isAbsolute)(raw) ? relativeForm(base, raw) : raw;
|
|
35916
36019
|
if (candidate === "" || resolveInside(base, candidate) === null) refused2.push(raw);
|
|
35917
36020
|
else kept.push(candidate);
|
|
35918
36021
|
}
|
|
35919
36022
|
return { kept, refused: refused2 };
|
|
35920
36023
|
}
|
|
35921
36024
|
function relativeForm(base, abs) {
|
|
35922
|
-
const lexical = (0,
|
|
35923
|
-
if (!(lexical === ".." || lexical.startsWith(`..${
|
|
36025
|
+
const lexical = (0, import_node_path52.relative)(base, abs);
|
|
36026
|
+
if (!(lexical === ".." || lexical.startsWith(`..${import_node_path52.sep}`) || (0, import_node_path52.isAbsolute)(lexical))) return lexical;
|
|
35924
36027
|
try {
|
|
35925
|
-
let dir = (0,
|
|
35926
|
-
let rest = (0,
|
|
36028
|
+
let dir = (0, import_node_path52.dirname)(abs);
|
|
36029
|
+
let rest = (0, import_node_path52.basename)(abs);
|
|
35927
36030
|
while (!(0, import_node_fs64.existsSync)(dir)) {
|
|
35928
|
-
const up = (0,
|
|
36031
|
+
const up = (0, import_node_path52.dirname)(dir);
|
|
35929
36032
|
if (up === dir) return lexical;
|
|
35930
|
-
rest = (0,
|
|
36033
|
+
rest = (0, import_node_path52.join)((0, import_node_path52.basename)(dir), rest);
|
|
35931
36034
|
dir = up;
|
|
35932
36035
|
}
|
|
35933
|
-
return (0,
|
|
36036
|
+
return (0, import_node_path52.relative)((0, import_node_fs64.realpathSync)(base), (0, import_node_path52.join)((0, import_node_fs64.realpathSync)(dir), rest));
|
|
35934
36037
|
} catch {
|
|
35935
36038
|
return lexical;
|
|
35936
36039
|
}
|
|
@@ -36036,11 +36139,11 @@ async function runReview(opts, globals) {
|
|
|
36036
36139
|
|
|
36037
36140
|
// src/commands/guard.ts
|
|
36038
36141
|
var import_node_fs67 = require("node:fs");
|
|
36039
|
-
var
|
|
36142
|
+
var import_node_path56 = require("node:path");
|
|
36040
36143
|
|
|
36041
36144
|
// src/lib/vendored.ts
|
|
36042
36145
|
var import_node_fs65 = require("node:fs");
|
|
36043
|
-
var
|
|
36146
|
+
var import_node_path53 = require("node:path");
|
|
36044
36147
|
var INSTALLED_SKILL = /^\.claude\/skills\/(verity-[a-z0-9-]+)\/(.+)$/;
|
|
36045
36148
|
function dataDirOrNull() {
|
|
36046
36149
|
try {
|
|
@@ -36055,7 +36158,7 @@ function shippedSkillFile(path, dataDir = dataDirOrNull()) {
|
|
|
36055
36158
|
const [, skill, rel] = m;
|
|
36056
36159
|
if (rel.split("/").some((seg) => seg === ".." || seg === ".")) return null;
|
|
36057
36160
|
try {
|
|
36058
|
-
return (0, import_node_fs65.readFileSync)((0,
|
|
36161
|
+
return (0, import_node_fs65.readFileSync)((0, import_node_path53.join)(dataDir, "skills", skill, rel), "utf8");
|
|
36059
36162
|
} catch {
|
|
36060
36163
|
return null;
|
|
36061
36164
|
}
|
|
@@ -36166,7 +36269,7 @@ async function runAgentReview(options) {
|
|
|
36166
36269
|
|
|
36167
36270
|
// src/lib/effort.ts
|
|
36168
36271
|
var import_node_fs66 = require("node:fs");
|
|
36169
|
-
var
|
|
36272
|
+
var import_node_path54 = require("node:path");
|
|
36170
36273
|
var import_yaml7 = __toESM2(require_dist());
|
|
36171
36274
|
var EFFORT_PROFILES = {
|
|
36172
36275
|
default: { pushDeadlineMs: 18e4, formal: { tier: "fast", maxRounds: 2, minScore: 0.7, costCapUsd: 1, maxTargets: 1, relaxedGates: false, dailyModels: 5, dailyCostUsd: 5 } },
|
|
@@ -36179,7 +36282,7 @@ function asEffort(value) {
|
|
|
36179
36282
|
function resolveEffort(root, env = process.env) {
|
|
36180
36283
|
if (env.VERITY_EFFORT) return asEffort(env.VERITY_EFFORT);
|
|
36181
36284
|
try {
|
|
36182
|
-
const standard = (0, import_yaml7.parse)((0, import_node_fs66.readFileSync)((0,
|
|
36285
|
+
const standard = (0, import_yaml7.parse)((0, import_node_fs66.readFileSync)((0, import_node_path54.join)(root, STANDARD_FILE), "utf8"));
|
|
36183
36286
|
return asEffort(standard?.process_constraints?.git_moment_effort);
|
|
36184
36287
|
} catch {
|
|
36185
36288
|
return "default";
|
|
@@ -36190,7 +36293,7 @@ function effortProfile(root, env = process.env) {
|
|
|
36190
36293
|
}
|
|
36191
36294
|
|
|
36192
36295
|
// src/lib/prove/auto.ts
|
|
36193
|
-
var
|
|
36296
|
+
var import_node_path55 = require("node:path");
|
|
36194
36297
|
var import_node_crypto21 = require("node:crypto");
|
|
36195
36298
|
|
|
36196
36299
|
// src/lib/prove/grounding.ts
|
|
@@ -38344,7 +38447,7 @@ async function runFormalPhase(input) {
|
|
|
38344
38447
|
modelName = gen.name;
|
|
38345
38448
|
const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
|
|
38346
38449
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
38347
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
38450
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path55.join)(root, rel);
|
|
38348
38451
|
progress.model = { name: gen.name, file: rel, rounds: round };
|
|
38349
38452
|
progress.step = "check";
|
|
38350
38453
|
report = await deps.check(root, abs);
|
|
@@ -38493,7 +38596,7 @@ async function runFormalPhase(input) {
|
|
|
38493
38596
|
return done({
|
|
38494
38597
|
status: "checked",
|
|
38495
38598
|
target,
|
|
38496
|
-
model: { name: modelName, file: (0,
|
|
38599
|
+
model: { name: modelName, file: (0, import_node_path55.relative)(root, (0, import_node_path55.join)(root, modelFile)), rounds },
|
|
38497
38600
|
properties: report.properties,
|
|
38498
38601
|
findings
|
|
38499
38602
|
});
|
|
@@ -38570,7 +38673,7 @@ async function generateAndCheck(root, req, opts) {
|
|
|
38570
38673
|
}
|
|
38571
38674
|
const rel = `${dir}/${gen.name}.lean`;
|
|
38572
38675
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
38573
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
38676
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path55.join)(root, rel);
|
|
38574
38677
|
const report = await opts.deps.check(root, abs);
|
|
38575
38678
|
const abstracts = report.header?.abstracts ?? [];
|
|
38576
38679
|
const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
|
|
@@ -38960,7 +39063,7 @@ var WRITERS_BUDGET_MS = 1500;
|
|
|
38960
39063
|
var EXCERPT_MAX_LINES2 = 30;
|
|
38961
39064
|
var VENDORED_READ_MAX_BYTES = 256 * 1024;
|
|
38962
39065
|
var GUARD_BLOCK_CAP = 2;
|
|
38963
|
-
var GUARD_ITER_FILE = (0,
|
|
39066
|
+
var GUARD_ITER_FILE = (0, import_node_path56.join)(VERITY_DIR, ".guard-iteration");
|
|
38964
39067
|
function readPreToolUseStdin() {
|
|
38965
39068
|
const empty = { command: "", cwd: null, sessionId: null };
|
|
38966
39069
|
return new Promise((resolve9) => {
|
|
@@ -39130,11 +39233,11 @@ function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedInte
|
|
|
39130
39233
|
}
|
|
39131
39234
|
};
|
|
39132
39235
|
if (coverageTelemetry) requestBody2.coverage_telemetry = coverageTelemetry;
|
|
39133
|
-
const
|
|
39134
|
-
if (
|
|
39236
|
+
const docs = discoverGuardDocs(files);
|
|
39237
|
+
if (docs.length > 0 || statedIntent) {
|
|
39135
39238
|
const intentContext = {};
|
|
39136
39239
|
if (statedIntent) intentContext.user_prompt = statedIntent;
|
|
39137
|
-
if (
|
|
39240
|
+
if (docs.length > 0) intentContext.plans = docs;
|
|
39138
39241
|
requestBody2.intent_context = intentContext;
|
|
39139
39242
|
}
|
|
39140
39243
|
return requestBody2;
|
|
@@ -39819,14 +39922,14 @@ function registerWaiveCommand(program2) {
|
|
|
39819
39922
|
}
|
|
39820
39923
|
|
|
39821
39924
|
// src/commands/init/index.ts
|
|
39822
|
-
var
|
|
39925
|
+
var import_node_fs76 = require("node:fs");
|
|
39823
39926
|
var import_promises19 = require("node:fs/promises");
|
|
39824
|
-
var
|
|
39927
|
+
var import_node_path64 = require("node:path");
|
|
39825
39928
|
|
|
39826
39929
|
// src/lib/init-trace.ts
|
|
39827
39930
|
var import_node_crypto23 = require("node:crypto");
|
|
39828
39931
|
var import_node_fs69 = require("node:fs");
|
|
39829
|
-
var
|
|
39932
|
+
var import_node_path57 = require("node:path");
|
|
39830
39933
|
var INIT_STEPS = [
|
|
39831
39934
|
"started",
|
|
39832
39935
|
"prerequisites",
|
|
@@ -39872,9 +39975,9 @@ function traceDisabled(env = process.env) {
|
|
|
39872
39975
|
}
|
|
39873
39976
|
var PENDING_NAME = "init-trace.json";
|
|
39874
39977
|
var MAX_PENDING_BYTES = 64 * 1024;
|
|
39875
|
-
var verityHome2 = () => (0,
|
|
39978
|
+
var verityHome2 = () => (0, import_node_path57.join)(process.env.HOME ?? "", ".verity");
|
|
39876
39979
|
function pendingTracePath() {
|
|
39877
|
-
return (0,
|
|
39980
|
+
return (0, import_node_path57.join)(verityHome2(), PENDING_NAME);
|
|
39878
39981
|
}
|
|
39879
39982
|
var RUN_ID = /^[0-9a-f]{16}$/;
|
|
39880
39983
|
var CLI_VERSION = /^[0-9A-Za-z.+-]{1,40}$/;
|
|
@@ -40629,20 +40732,201 @@ var Rail = class {
|
|
|
40629
40732
|
};
|
|
40630
40733
|
|
|
40631
40734
|
// src/commands/migrate.ts
|
|
40632
|
-
var
|
|
40633
|
-
var
|
|
40634
|
-
var
|
|
40735
|
+
var import_node_fs71 = require("node:fs");
|
|
40736
|
+
var import_node_path61 = require("node:path");
|
|
40737
|
+
var import_node_child_process19 = require("node:child_process");
|
|
40635
40738
|
|
|
40636
|
-
// src/lib/telemetry.ts
|
|
40739
|
+
// src/lib/telemetry-local.ts
|
|
40740
|
+
var import_node_path59 = require("node:path");
|
|
40741
|
+
|
|
40742
|
+
// src/lib/telemetry-settings.ts
|
|
40637
40743
|
var import_promises16 = require("node:fs/promises");
|
|
40744
|
+
var import_node_os12 = require("node:os");
|
|
40745
|
+
var import_node_path58 = require("node:path");
|
|
40638
40746
|
var SETTINGS_LOCAL_FILE2 = ".claude/settings.local.json";
|
|
40639
|
-
var GITIGNORE_FILE = ".gitignore";
|
|
40640
|
-
var GITIGNORE_ENTRY = SETTINGS_LOCAL_IGNORE_ENTRY;
|
|
40641
40747
|
var OTEL_HEADERS_HELPER_CMD = "verity telemetry headers";
|
|
40642
|
-
var
|
|
40748
|
+
var LEGACY_HEADER_KEY = "OTEL_EXPORTER_OTLP_HEADERS";
|
|
40749
|
+
var OTLP_ENDPOINT_KEYS = [
|
|
40750
|
+
"OTEL_EXPORTER_OTLP_ENDPOINT",
|
|
40751
|
+
"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT",
|
|
40752
|
+
"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
|
|
40753
|
+
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT"
|
|
40754
|
+
];
|
|
40755
|
+
function claudeConfigDir2() {
|
|
40756
|
+
return process.env.CLAUDE_CONFIG_DIR || (0, import_node_path58.join)((0, import_node_os12.homedir)(), ".claude");
|
|
40757
|
+
}
|
|
40758
|
+
function userSettingsPath() {
|
|
40759
|
+
return (0, import_node_path58.join)(claudeConfigDir2(), "settings.json");
|
|
40760
|
+
}
|
|
40643
40761
|
function deriveOtlpEndpoint(serviceUrl) {
|
|
40644
40762
|
return serviceUrl.replace(/\/+$/, "").replace(/\/v1$/, "") + "/v1/otlp";
|
|
40645
40763
|
}
|
|
40764
|
+
function isVerityOtlpEndpoint(value, also) {
|
|
40765
|
+
if (typeof value !== "string" || value.trim() === "") return false;
|
|
40766
|
+
if (also && value.replace(/\/+$/, "") === also.replace(/\/+$/, "")) return true;
|
|
40767
|
+
try {
|
|
40768
|
+
return /\/functions\/v1\/otlp\/?$/.test(new URL(value).pathname);
|
|
40769
|
+
} catch {
|
|
40770
|
+
return false;
|
|
40771
|
+
}
|
|
40772
|
+
}
|
|
40773
|
+
function sameUrl(a, b) {
|
|
40774
|
+
const norm3 = (raw) => {
|
|
40775
|
+
const trimmed = raw.trim().replace(/\/+$/, "");
|
|
40776
|
+
try {
|
|
40777
|
+
const u = new URL(trimmed);
|
|
40778
|
+
return `${u.protocol}//${u.host.toLowerCase()}${u.pathname.replace(/\/+$/, "")}`;
|
|
40779
|
+
} catch {
|
|
40780
|
+
return trimmed.toLowerCase();
|
|
40781
|
+
}
|
|
40782
|
+
};
|
|
40783
|
+
return norm3(a) === norm3(b);
|
|
40784
|
+
}
|
|
40785
|
+
function envOf(settings) {
|
|
40786
|
+
const env = settings.env;
|
|
40787
|
+
return env && typeof env === "object" && !Array.isArray(env) ? env : {};
|
|
40788
|
+
}
|
|
40789
|
+
function displayPath(path) {
|
|
40790
|
+
const home = (0, import_node_os12.homedir)();
|
|
40791
|
+
return home && path.startsWith(home + "/") ? "~" + path.slice(home.length) : path;
|
|
40792
|
+
}
|
|
40793
|
+
async function readSettingsFile(path) {
|
|
40794
|
+
let raw;
|
|
40795
|
+
try {
|
|
40796
|
+
raw = await (0, import_promises16.readFile)(path, "utf-8");
|
|
40797
|
+
} catch (err2) {
|
|
40798
|
+
if (err2.code === "ENOENT") return { ok: true, settings: {}, exists: false };
|
|
40799
|
+
return { ok: false, error: `Could not read ${displayPath(path)}: ${err2.message}` };
|
|
40800
|
+
}
|
|
40801
|
+
try {
|
|
40802
|
+
const parsed = raw.trim() === "" ? {} : JSON.parse(raw);
|
|
40803
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
40804
|
+
return { ok: false, error: `${displayPath(path)} is not a JSON object. Fix it, then run the command again. Nothing was changed.` };
|
|
40805
|
+
}
|
|
40806
|
+
return { ok: true, settings: parsed, exists: true };
|
|
40807
|
+
} catch {
|
|
40808
|
+
return { ok: false, error: `${displayPath(path)} is not valid JSON. Fix it, then run the command again. Nothing was changed.` };
|
|
40809
|
+
}
|
|
40810
|
+
}
|
|
40811
|
+
|
|
40812
|
+
// src/lib/telemetry-local.ts
|
|
40813
|
+
var MAX_LOCAL_SETTINGS_BYTES = 1024 * 1024;
|
|
40814
|
+
function nextLocalBytes(raw, value) {
|
|
40815
|
+
try {
|
|
40816
|
+
if (jsonSemanticEqual(JSON.parse(raw), value)) return null;
|
|
40817
|
+
} catch {
|
|
40818
|
+
}
|
|
40819
|
+
const next = JSON.stringify(value, null, detectJsonIndent(raw)) + "\n";
|
|
40820
|
+
return next === raw ? null : next;
|
|
40821
|
+
}
|
|
40822
|
+
var OLD_LOCAL_WRITER_VALUES = {
|
|
40823
|
+
CLAUDE_CODE_ENABLE_TELEMETRY: "1",
|
|
40824
|
+
OTEL_METRICS_EXPORTER: "otlp",
|
|
40825
|
+
OTEL_TRACES_EXPORTER: "otlp",
|
|
40826
|
+
CLAUDE_CODE_ENHANCED_TELEMETRY_BETA: "1",
|
|
40827
|
+
OTEL_EXPORTER_OTLP_PROTOCOL: "http/json",
|
|
40828
|
+
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE: "delta",
|
|
40829
|
+
OTEL_LOG_USER_PROMPTS: "0",
|
|
40830
|
+
OTEL_LOG_TOOL_DETAILS: "0",
|
|
40831
|
+
OTEL_LOG_TOOL_CONTENT: "0",
|
|
40832
|
+
OTEL_METRICS_INCLUDE_SESSION_ID: "true",
|
|
40833
|
+
OTEL_METRICS_INCLUDE_ACCOUNT_UUID: "false",
|
|
40834
|
+
OTEL_METRICS_INCLUDE_VERSION: "false",
|
|
40835
|
+
OTEL_METRIC_EXPORT_INTERVAL: "60000"
|
|
40836
|
+
};
|
|
40837
|
+
var LEGACY_VERITY_HEADER = /^Authorization=Bearer (?:verity|gate)_/;
|
|
40838
|
+
function planLocalHeal(settings) {
|
|
40839
|
+
const env = envOf(settings);
|
|
40840
|
+
const envKeys = [];
|
|
40841
|
+
if (typeof env[LEGACY_HEADER_KEY] === "string" && LEGACY_VERITY_HEADER.test(env[LEGACY_HEADER_KEY])) {
|
|
40842
|
+
envKeys.push(LEGACY_HEADER_KEY);
|
|
40843
|
+
}
|
|
40844
|
+
if (isVerityOtlpEndpoint(env.OTEL_EXPORTER_OTLP_ENDPOINT)) {
|
|
40845
|
+
envKeys.push("OTEL_EXPORTER_OTLP_ENDPOINT");
|
|
40846
|
+
for (const [key, value] of Object.entries(OLD_LOCAL_WRITER_VALUES)) {
|
|
40847
|
+
if (env[key] === value) envKeys.push(key);
|
|
40848
|
+
}
|
|
40849
|
+
}
|
|
40850
|
+
return { envKeys, helper: settings.otelHeadersHelper === OTEL_HEADERS_HELPER_CMD };
|
|
40851
|
+
}
|
|
40852
|
+
function readLocalSettings(root) {
|
|
40853
|
+
const read2 = readRegularFileInRoot(root, SETTINGS_LOCAL_FILE2, MAX_LOCAL_SETTINGS_BYTES);
|
|
40854
|
+
if (!read2.ok) return null;
|
|
40855
|
+
try {
|
|
40856
|
+
const parsed = JSON.parse(read2.content);
|
|
40857
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
40858
|
+
return { raw: read2.content, settings: parsed };
|
|
40859
|
+
} catch {
|
|
40860
|
+
return null;
|
|
40861
|
+
}
|
|
40862
|
+
}
|
|
40863
|
+
function localTelemetryLeftovers(root = repoRoot()) {
|
|
40864
|
+
const local = readLocalSettings(root);
|
|
40865
|
+
if (!local) return [];
|
|
40866
|
+
const plan = planLocalHeal(local.settings);
|
|
40867
|
+
return [...plan.envKeys, ...plan.helper ? ["otelHeadersHelper"] : []];
|
|
40868
|
+
}
|
|
40869
|
+
async function healLocalTelemetry(root = repoRoot()) {
|
|
40870
|
+
const local = readLocalSettings(root);
|
|
40871
|
+
if (!local) return { removed: [] };
|
|
40872
|
+
const settings = local.settings;
|
|
40873
|
+
const plan = planLocalHeal(settings);
|
|
40874
|
+
if (plan.envKeys.length === 0 && !plan.helper) return { removed: [] };
|
|
40875
|
+
const env = envOf(settings);
|
|
40876
|
+
for (const key of plan.envKeys) delete env[key];
|
|
40877
|
+
if (settings.env && Object.keys(env).length === 0) delete settings.env;
|
|
40878
|
+
if (plan.helper) delete settings.otelHeadersHelper;
|
|
40879
|
+
const next = nextLocalBytes(local.raw, settings);
|
|
40880
|
+
if (next !== null && !replaceInRoot((0, import_node_path59.join)(root, ".claude"), "settings.local.json", next)) {
|
|
40881
|
+
return { removed: [] };
|
|
40882
|
+
}
|
|
40883
|
+
return { removed: [...plan.envKeys, ...plan.helper ? ["otelHeadersHelper"] : []] };
|
|
40884
|
+
}
|
|
40885
|
+
|
|
40886
|
+
// src/lib/telemetry-gate.ts
|
|
40887
|
+
var import_node_child_process18 = require("node:child_process");
|
|
40888
|
+
var import_node_fs70 = require("node:fs");
|
|
40889
|
+
var import_node_path60 = require("node:path");
|
|
40890
|
+
var PROJECT_MARKERS = ["setup.json", "config.json"];
|
|
40891
|
+
function writtenOnThisMachine(root, rel) {
|
|
40892
|
+
const r = (0, import_node_child_process18.spawnSync)("git", hardenedGitArgv(["ls-files", "--error-unmatch", "--", rel]), {
|
|
40893
|
+
cwd: root,
|
|
40894
|
+
env: hardenedGitEnv(),
|
|
40895
|
+
encoding: "utf-8",
|
|
40896
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
40897
|
+
timeout: 5e3
|
|
40898
|
+
});
|
|
40899
|
+
if (r.status === 1) return true;
|
|
40900
|
+
if (r.status === 128 && /not a git repository/i.test(r.stderr ?? "")) return true;
|
|
40901
|
+
return false;
|
|
40902
|
+
}
|
|
40903
|
+
function isTelemetryProject() {
|
|
40904
|
+
for (const root of [repoRoot(), mainWorktreeRoot()]) {
|
|
40905
|
+
if (!root) continue;
|
|
40906
|
+
const dir = (0, import_node_path60.join)(root, VERITY_DIR);
|
|
40907
|
+
if (isMachineStore(dir)) continue;
|
|
40908
|
+
for (const marker of PROJECT_MARKERS) {
|
|
40909
|
+
if ((0, import_node_fs70.existsSync)((0, import_node_path60.join)(dir, marker)) && writtenOnThisMachine(root, `${VERITY_DIR}/${marker}`)) return true;
|
|
40910
|
+
}
|
|
40911
|
+
}
|
|
40912
|
+
return false;
|
|
40913
|
+
}
|
|
40914
|
+
async function telemetryPinRefusal(token, endpoint) {
|
|
40915
|
+
const serviceUrl = endpoint.trim().replace(/\/+$/, "").replace(/\/otlp$/, "");
|
|
40916
|
+
const pin = await checkTokenPin(token, serviceUrl);
|
|
40917
|
+
if (pin.attach) return null;
|
|
40918
|
+
if (pin.reason === "mismatch" && sameUrl(deriveOtlpEndpoint(pin.mintedFor), endpoint)) return null;
|
|
40919
|
+
return pinRefusalMessage(pin, serviceUrl);
|
|
40920
|
+
}
|
|
40921
|
+
async function sessionExportEndpoints() {
|
|
40922
|
+
const pick = (env) => OTLP_ENDPOINT_KEYS.map((key) => env[key]).filter((v) => typeof v === "string" && v.trim() !== "");
|
|
40923
|
+
const fromEnv = pick(process.env);
|
|
40924
|
+
if (fromEnv.length > 0) return fromEnv;
|
|
40925
|
+
const read2 = await readSettingsFile(userSettingsPath());
|
|
40926
|
+
return read2.ok ? pick(envOf(read2.settings)) : [];
|
|
40927
|
+
}
|
|
40928
|
+
|
|
40929
|
+
// src/lib/telemetry.ts
|
|
40646
40930
|
function buildTelemetryEnv(serviceUrl) {
|
|
40647
40931
|
return {
|
|
40648
40932
|
CLAUDE_CODE_ENABLE_TELEMETRY: "1",
|
|
@@ -40658,79 +40942,110 @@ function buildTelemetryEnv(serviceUrl) {
|
|
|
40658
40942
|
OTEL_METRICS_INCLUDE_SESSION_ID: "true",
|
|
40659
40943
|
OTEL_METRICS_INCLUDE_ACCOUNT_UUID: "false",
|
|
40660
40944
|
OTEL_METRICS_INCLUDE_VERSION: "false",
|
|
40945
|
+
OTEL_METRICS_INCLUDE_REPOSITORY: "true",
|
|
40661
40946
|
OTEL_METRIC_EXPORT_INTERVAL: "60000"
|
|
40662
40947
|
};
|
|
40663
40948
|
}
|
|
40664
40949
|
var VERITY_TELEMETRY_KEYS = Object.keys(buildTelemetryEnv(""));
|
|
40665
|
-
|
|
40666
|
-
|
|
40667
|
-
|
|
40668
|
-
|
|
40669
|
-
return
|
|
40950
|
+
var EXPORTER_KEYS = ["OTEL_METRICS_EXPORTER", "OTEL_TRACES_EXPORTER"];
|
|
40951
|
+
function foreignExportKey(settings, endpoint) {
|
|
40952
|
+
const helper = settings.otelHeadersHelper;
|
|
40953
|
+
if (typeof helper === "string" && helper.trim() !== "" && helper !== OTEL_HEADERS_HELPER_CMD) {
|
|
40954
|
+
return "otelHeadersHelper";
|
|
40955
|
+
}
|
|
40956
|
+
const env = envOf(settings);
|
|
40957
|
+
for (const key of OTLP_ENDPOINT_KEYS) {
|
|
40958
|
+
const value = env[key];
|
|
40959
|
+
if (value !== void 0 && value !== "" && !isVerityOtlpEndpoint(value, endpoint)) return key;
|
|
40960
|
+
}
|
|
40961
|
+
if (env[LEGACY_HEADER_KEY] !== void 0 && env[LEGACY_HEADER_KEY] !== "") return LEGACY_HEADER_KEY;
|
|
40962
|
+
for (const key of EXPORTER_KEYS) {
|
|
40963
|
+
const value = env[key];
|
|
40964
|
+
if (value !== void 0 && value !== "" && value !== "otlp") return key;
|
|
40670
40965
|
}
|
|
40966
|
+
return null;
|
|
40671
40967
|
}
|
|
40672
|
-
async function
|
|
40673
|
-
|
|
40674
|
-
|
|
40675
|
-
|
|
40676
|
-
const
|
|
40677
|
-
|
|
40678
|
-
|
|
40679
|
-
|
|
40680
|
-
|
|
40968
|
+
async function installTelemetry(serviceUrl, opts = {}) {
|
|
40969
|
+
const path = userSettingsPath();
|
|
40970
|
+
const read2 = await readSettingsFile(path);
|
|
40971
|
+
if (!read2.ok) return { ok: false, error: read2.error };
|
|
40972
|
+
const settings = read2.settings;
|
|
40973
|
+
const env = buildTelemetryEnv(serviceUrl);
|
|
40974
|
+
const foreign = foreignExportKey(settings, env.OTEL_EXPORTER_OTLP_ENDPOINT);
|
|
40975
|
+
if (foreign) {
|
|
40976
|
+
return {
|
|
40977
|
+
ok: false,
|
|
40978
|
+
error: `Telemetry not installed: ${displayPath(path)} already sets ${foreign}, so you export somewhere else already. Nothing was changed.`
|
|
40979
|
+
};
|
|
40681
40980
|
}
|
|
40682
|
-
|
|
40683
|
-
if (
|
|
40684
|
-
|
|
40981
|
+
let token = opts.token;
|
|
40982
|
+
if (!token) {
|
|
40983
|
+
const resolved = await resolveToken();
|
|
40984
|
+
if (!resolved.ok) {
|
|
40985
|
+
return { ok: false, error: 'Telemetry not installed: no Verity token on this machine. Run "verity login". Nothing was changed.' };
|
|
40986
|
+
}
|
|
40987
|
+
token = resolved.data.token;
|
|
40685
40988
|
}
|
|
40686
|
-
const
|
|
40687
|
-
|
|
40688
|
-
|
|
40689
|
-
}
|
|
40690
|
-
|
|
40691
|
-
const env = buildTelemetryEnv(serviceUrl);
|
|
40692
|
-
const settings = await readSettingsLocal();
|
|
40693
|
-
settings.env = { ...settings.env ?? {}, ...env };
|
|
40694
|
-
for (const key of LEGACY_TELEMETRY_ENV_KEYS) delete settings.env[key];
|
|
40989
|
+
const refusal = await telemetryPinRefusal(token, env.OTEL_EXPORTER_OTLP_ENDPOINT);
|
|
40990
|
+
if (refusal) {
|
|
40991
|
+
return { ok: false, error: `Telemetry not installed: ${refusal} Nothing was changed.` };
|
|
40992
|
+
}
|
|
40993
|
+
settings.env = { ...envOf(settings), ...env };
|
|
40695
40994
|
settings.otelHeadersHelper = OTEL_HEADERS_HELPER_CMD;
|
|
40696
|
-
await
|
|
40697
|
-
await
|
|
40698
|
-
return {
|
|
40995
|
+
await writeJsonFilePreservingStyle(path, settings);
|
|
40996
|
+
const healed = await healLocalTelemetry();
|
|
40997
|
+
return {
|
|
40998
|
+
ok: true,
|
|
40999
|
+
data: { endpoint: env.OTEL_EXPORTER_OTLP_ENDPOINT, settingsPath: path, healedLocalKeys: healed.removed }
|
|
41000
|
+
};
|
|
40699
41001
|
}
|
|
40700
41002
|
async function checkTelemetry() {
|
|
40701
|
-
const
|
|
40702
|
-
const
|
|
40703
|
-
|
|
41003
|
+
const path = userSettingsPath();
|
|
41004
|
+
const read2 = await readSettingsFile(path);
|
|
41005
|
+
const settings = read2.ok ? read2.settings : {};
|
|
41006
|
+
const env = envOf(settings);
|
|
41007
|
+
const endpoint = env.OTEL_EXPORTER_OTLP_ENDPOINT || null;
|
|
41008
|
+
const enabled = env.CLAUDE_CODE_ENABLE_TELEMETRY === "1" && !!endpoint && settings.otelHeadersHelper === OTEL_HEADERS_HELPER_CMD;
|
|
41009
|
+
return { enabled, endpoint, settingsPath: path, staleLocalKeys: localTelemetryLeftovers() };
|
|
40704
41010
|
}
|
|
40705
41011
|
async function uninstallTelemetry() {
|
|
40706
|
-
const
|
|
40707
|
-
const
|
|
40708
|
-
if (
|
|
40709
|
-
|
|
40710
|
-
|
|
40711
|
-
return { ok: true, data: { removed: 0 } };
|
|
40712
|
-
}
|
|
41012
|
+
const path = userSettingsPath();
|
|
41013
|
+
const read2 = await readSettingsFile(path);
|
|
41014
|
+
if (!read2.ok) return { ok: false, error: read2.error };
|
|
41015
|
+
const settings = read2.settings;
|
|
41016
|
+
const env = envOf(settings);
|
|
40713
41017
|
let removed = 0;
|
|
40714
|
-
|
|
40715
|
-
|
|
40716
|
-
|
|
40717
|
-
|
|
41018
|
+
const endpoint = env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
41019
|
+
const foreignEndpoint = endpoint !== void 0 && endpoint !== "" && !isVerityOtlpEndpoint(endpoint);
|
|
41020
|
+
if (isVerityOtlpEndpoint(endpoint)) {
|
|
41021
|
+
const verityValues = buildTelemetryEnv("");
|
|
41022
|
+
for (const key of VERITY_TELEMETRY_KEYS) {
|
|
41023
|
+
if (key === "OTEL_EXPORTER_OTLP_ENDPOINT" || env[key] === verityValues[key]) {
|
|
41024
|
+
if (key in env) {
|
|
41025
|
+
delete env[key];
|
|
41026
|
+
removed++;
|
|
41027
|
+
}
|
|
41028
|
+
}
|
|
40718
41029
|
}
|
|
41030
|
+
if (settings.otelHeadersHelper === OTEL_HEADERS_HELPER_CMD) delete settings.otelHeadersHelper;
|
|
41031
|
+
if (settings.env && Object.keys(env).length === 0) delete settings.env;
|
|
41032
|
+
await writeJsonFilePreservingStyle(path, settings);
|
|
40719
41033
|
}
|
|
40720
|
-
|
|
40721
|
-
|
|
40722
|
-
await writeSettingsLocal(settings);
|
|
40723
|
-
return { ok: true, data: { removed } };
|
|
41034
|
+
const healed = await healLocalTelemetry();
|
|
41035
|
+
return { ok: true, data: { removed, settingsPath: path, foreignEndpoint, healedLocalKeys: healed.removed } };
|
|
40724
41036
|
}
|
|
40725
41037
|
|
|
40726
41038
|
// src/commands/migrate.ts
|
|
40727
41039
|
var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
|
|
40728
41040
|
function defaultNpmRemover(pkg) {
|
|
40729
|
-
(0,
|
|
41041
|
+
(0, import_node_child_process19.execSync)(`npm rm -g ${pkg}`, { stdio: "pipe", timeout: 12e4 });
|
|
41042
|
+
}
|
|
41043
|
+
function git2(cwd, args2) {
|
|
41044
|
+
(0, import_node_child_process19.execFileSync)("git", hardenedGitArgv(args2), { cwd, stdio: "pipe", env: hardenedGitEnv() });
|
|
40730
41045
|
}
|
|
40731
41046
|
function isGitTracked(cwd, relPath) {
|
|
40732
41047
|
try {
|
|
40733
|
-
(
|
|
41048
|
+
git2(cwd, ["ls-files", "--error-unmatch", "--", relPath]);
|
|
40734
41049
|
return true;
|
|
40735
41050
|
} catch {
|
|
40736
41051
|
return false;
|
|
@@ -40738,7 +41053,7 @@ function isGitTracked(cwd, relPath) {
|
|
|
40738
41053
|
}
|
|
40739
41054
|
function isGitRepo(cwd) {
|
|
40740
41055
|
try {
|
|
40741
|
-
(
|
|
41056
|
+
git2(cwd, ["rev-parse", "--is-inside-work-tree"]);
|
|
40742
41057
|
return true;
|
|
40743
41058
|
} catch {
|
|
40744
41059
|
return false;
|
|
@@ -40754,17 +41069,17 @@ async function runMigration(opts = {}) {
|
|
|
40754
41069
|
await migrateLegacyHooks(root, actions);
|
|
40755
41070
|
await migrateClaudeMd(root, actions);
|
|
40756
41071
|
migrateStandardFile(root, actions);
|
|
40757
|
-
await
|
|
41072
|
+
await migrateLocalTelemetry(root, actions);
|
|
40758
41073
|
removeLegacyPackage(movedProjectDir, npmRemover, actions);
|
|
40759
41074
|
return { actions, migrated: actions.length > 0 };
|
|
40760
41075
|
}
|
|
40761
41076
|
function migrateProjectDir(root, actions) {
|
|
40762
|
-
const gateDir = (0,
|
|
40763
|
-
const verityDir = (0,
|
|
40764
|
-
if ((0,
|
|
41077
|
+
const gateDir = (0, import_node_path61.join)(root, ".gate");
|
|
41078
|
+
const verityDir = (0, import_node_path61.join)(root, ".verity");
|
|
41079
|
+
if ((0, import_node_fs71.existsSync)(gateDir) && !(0, import_node_fs71.existsSync)(verityDir)) {
|
|
40765
41080
|
return migrateProjectDirRename(root, gateDir, verityDir, actions);
|
|
40766
41081
|
}
|
|
40767
|
-
if ((0,
|
|
41082
|
+
if ((0, import_node_fs71.existsSync)(gateDir) && (0, import_node_fs71.existsSync)(verityDir)) {
|
|
40768
41083
|
return migrateProjectDirCarry(gateDir, verityDir, actions);
|
|
40769
41084
|
}
|
|
40770
41085
|
return false;
|
|
@@ -40778,20 +41093,20 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
|
|
|
40778
41093
|
);
|
|
40779
41094
|
}
|
|
40780
41095
|
try {
|
|
40781
|
-
(
|
|
41096
|
+
git2(root, ["mv", "--", ".gate", ".verity"]);
|
|
40782
41097
|
actions.push("Moved .gate/ \u2192 .verity/ (git mv, staged)");
|
|
40783
41098
|
moved = true;
|
|
40784
41099
|
} catch {
|
|
40785
41100
|
}
|
|
40786
41101
|
}
|
|
40787
41102
|
if (moved) {
|
|
40788
|
-
if ((0,
|
|
41103
|
+
if ((0, import_node_fs71.existsSync)(gateDir)) {
|
|
40789
41104
|
const carried = carryLegacyContents(gateDir, verityDir);
|
|
40790
41105
|
if (carried > 0) {
|
|
40791
41106
|
actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
|
|
40792
41107
|
}
|
|
40793
41108
|
try {
|
|
40794
|
-
(0,
|
|
41109
|
+
(0, import_node_fs71.rmSync)(gateDir, { recursive: true, force: true });
|
|
40795
41110
|
} catch {
|
|
40796
41111
|
}
|
|
40797
41112
|
}
|
|
@@ -40807,18 +41122,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
|
|
|
40807
41122
|
actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
|
|
40808
41123
|
}
|
|
40809
41124
|
try {
|
|
40810
|
-
(0,
|
|
41125
|
+
(0, import_node_fs71.rmSync)(gateDir, { recursive: true, force: true });
|
|
40811
41126
|
} catch {
|
|
40812
41127
|
}
|
|
40813
41128
|
return carried > 0;
|
|
40814
41129
|
}
|
|
40815
41130
|
function migrateGlobalCredentials(home, actions) {
|
|
40816
41131
|
if (!home) return;
|
|
40817
|
-
const gateCreds = (0,
|
|
40818
|
-
const verityCreds = (0,
|
|
40819
|
-
if (!(0,
|
|
40820
|
-
if (!(0,
|
|
40821
|
-
(0,
|
|
41132
|
+
const gateCreds = (0, import_node_path61.join)(home, ".gate", "credentials");
|
|
41133
|
+
const verityCreds = (0, import_node_path61.join)(home, ".verity", "credentials");
|
|
41134
|
+
if (!(0, import_node_fs71.existsSync)(gateCreds)) return;
|
|
41135
|
+
if (!(0, import_node_fs71.existsSync)(verityCreds)) {
|
|
41136
|
+
(0, import_node_fs71.mkdirSync)((0, import_node_path61.join)(home, ".verity"), { recursive: true });
|
|
40822
41137
|
moveFile(gateCreds, verityCreds);
|
|
40823
41138
|
actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
|
|
40824
41139
|
return;
|
|
@@ -40840,8 +41155,8 @@ async function migrateLegacyHooks(root, actions) {
|
|
|
40840
41155
|
}
|
|
40841
41156
|
}
|
|
40842
41157
|
async function migrateClaudeMd(root, actions) {
|
|
40843
|
-
const claudeMd = (0,
|
|
40844
|
-
const hadLegacyBlock = (0,
|
|
41158
|
+
const claudeMd = (0, import_node_path61.join)(root, "CLAUDE.md");
|
|
41159
|
+
const hadLegacyBlock = (0, import_node_fs71.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
|
|
40845
41160
|
if (!hadLegacyBlock) return;
|
|
40846
41161
|
try {
|
|
40847
41162
|
await ensureClaudeMdPointer(root);
|
|
@@ -40851,13 +41166,13 @@ async function migrateClaudeMd(root, actions) {
|
|
|
40851
41166
|
}
|
|
40852
41167
|
}
|
|
40853
41168
|
function migrateStandardFile(root, actions) {
|
|
40854
|
-
const gateMd = (0,
|
|
40855
|
-
const verityMd = (0,
|
|
40856
|
-
if (!(0,
|
|
41169
|
+
const gateMd = (0, import_node_path61.join)(root, "GATE.md");
|
|
41170
|
+
const verityMd = (0, import_node_path61.join)(root, "VERITY.md");
|
|
41171
|
+
if (!(0, import_node_fs71.existsSync)(gateMd) || (0, import_node_fs71.existsSync)(verityMd)) return;
|
|
40857
41172
|
let moved = false;
|
|
40858
41173
|
if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
|
|
40859
41174
|
try {
|
|
40860
|
-
(
|
|
41175
|
+
git2(root, ["mv", "--", "GATE.md", "VERITY.md"]);
|
|
40861
41176
|
moved = true;
|
|
40862
41177
|
} catch {
|
|
40863
41178
|
}
|
|
@@ -40865,27 +41180,15 @@ function migrateStandardFile(root, actions) {
|
|
|
40865
41180
|
if (!moved) moveFile(gateMd, verityMd);
|
|
40866
41181
|
const content = readFileSyncSafe(verityMd);
|
|
40867
41182
|
const refreshed = content.split("GATE.md").join("VERITY.md");
|
|
40868
|
-
if (refreshed !== content) (0,
|
|
41183
|
+
if (refreshed !== content) (0, import_node_fs71.writeFileSync)(verityMd, refreshed);
|
|
40869
41184
|
actions.push("Renamed GATE.md \u2192 VERITY.md");
|
|
40870
41185
|
}
|
|
40871
|
-
async function
|
|
40872
|
-
const
|
|
40873
|
-
if (
|
|
40874
|
-
|
|
40875
|
-
|
|
40876
|
-
|
|
40877
|
-
} catch {
|
|
40878
|
-
return;
|
|
40879
|
-
}
|
|
40880
|
-
const env = settings.env;
|
|
40881
|
-
const hasInlineHeader = !!env && "OTEL_EXPORTER_OTLP_HEADERS" in env;
|
|
40882
|
-
const telemetryEnabled = env?.CLAUDE_CODE_ENABLE_TELEMETRY === "1";
|
|
40883
|
-
const needsHelper = telemetryEnabled && settings.otelHeadersHelper !== OTEL_HEADERS_HELPER_CMD;
|
|
40884
|
-
if (!hasInlineHeader && !needsHelper) return;
|
|
40885
|
-
if (hasInlineHeader && env) delete env["OTEL_EXPORTER_OTLP_HEADERS"];
|
|
40886
|
-
if (telemetryEnabled) settings.otelHeadersHelper = OTEL_HEADERS_HELPER_CMD;
|
|
40887
|
-
await writeJsonFilePreservingStyle(file, settings);
|
|
40888
|
-
actions.push("Moved the telemetry token out of .claude/settings.local.json (now resolved at runtime)");
|
|
41186
|
+
async function migrateLocalTelemetry(root, actions) {
|
|
41187
|
+
const { removed } = await healLocalTelemetry(root);
|
|
41188
|
+
if (removed.length === 0) return;
|
|
41189
|
+
actions.push(
|
|
41190
|
+
`Removed ${removed.length} old Verity telemetry key(s) from ${SETTINGS_LOCAL_FILE2} (Claude Code ignores them there). Run "verity telemetry install" to export from this machine.`
|
|
41191
|
+
);
|
|
40889
41192
|
}
|
|
40890
41193
|
function removeLegacyPackage(movedProjectDir, npmRemover, actions) {
|
|
40891
41194
|
if (!movedProjectDir) return;
|
|
@@ -40918,21 +41221,21 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
|
|
|
40918
41221
|
}
|
|
40919
41222
|
if (toAppend.length > 0) {
|
|
40920
41223
|
const sep7 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
|
|
40921
|
-
(0,
|
|
41224
|
+
(0, import_node_fs71.writeFileSync)(verityCreds, verityContent + sep7 + toAppend.join("\n") + "\n");
|
|
40922
41225
|
}
|
|
40923
|
-
(0,
|
|
41226
|
+
(0, import_node_fs71.rmSync)(gateCreds, { force: true });
|
|
40924
41227
|
return toAppend.length;
|
|
40925
41228
|
}
|
|
40926
41229
|
function readFileSyncSafe(path) {
|
|
40927
41230
|
try {
|
|
40928
|
-
return (0,
|
|
41231
|
+
return (0, import_node_fs71.readFileSync)(path, "utf-8");
|
|
40929
41232
|
} catch {
|
|
40930
41233
|
return "";
|
|
40931
41234
|
}
|
|
40932
41235
|
}
|
|
40933
41236
|
function hasStagedChanges(root) {
|
|
40934
41237
|
try {
|
|
40935
|
-
(
|
|
41238
|
+
git2(root, ["diff", "--cached", "--quiet", ...DIFF_READ_FLAGS]);
|
|
40936
41239
|
return false;
|
|
40937
41240
|
} catch {
|
|
40938
41241
|
return true;
|
|
@@ -40940,59 +41243,90 @@ function hasStagedChanges(root) {
|
|
|
40940
41243
|
}
|
|
40941
41244
|
function moveDir(from, to) {
|
|
40942
41245
|
try {
|
|
40943
|
-
(0,
|
|
41246
|
+
(0, import_node_fs71.renameSync)(from, to);
|
|
40944
41247
|
} catch (err2) {
|
|
40945
41248
|
if (err2.code !== "EXDEV") throw err2;
|
|
40946
|
-
(0,
|
|
40947
|
-
(0,
|
|
41249
|
+
(0, import_node_fs71.cpSync)(from, to, { recursive: true });
|
|
41250
|
+
(0, import_node_fs71.rmSync)(from, { recursive: true, force: true });
|
|
40948
41251
|
}
|
|
40949
41252
|
}
|
|
40950
41253
|
function moveFile(from, to) {
|
|
40951
41254
|
try {
|
|
40952
|
-
(0,
|
|
41255
|
+
(0, import_node_fs71.renameSync)(from, to);
|
|
40953
41256
|
} catch (err2) {
|
|
40954
41257
|
if (err2.code !== "EXDEV") throw err2;
|
|
40955
|
-
(0,
|
|
40956
|
-
(0,
|
|
41258
|
+
(0, import_node_fs71.cpSync)(from, to);
|
|
41259
|
+
(0, import_node_fs71.rmSync)(from, { force: true });
|
|
40957
41260
|
}
|
|
40958
41261
|
}
|
|
40959
41262
|
function carryLegacyContents(gateDir, verityDir) {
|
|
41263
|
+
if (!isRealDir(gateDir) || !isRealDir(verityDir)) return 0;
|
|
40960
41264
|
let copied = 0;
|
|
40961
41265
|
const walk2 = (relDir) => {
|
|
40962
|
-
|
|
40963
|
-
|
|
40964
|
-
|
|
40965
|
-
|
|
40966
|
-
|
|
40967
|
-
|
|
41266
|
+
let entries;
|
|
41267
|
+
try {
|
|
41268
|
+
entries = (0, import_node_fs71.readdirSync)((0, import_node_path61.join)(gateDir, relDir), { withFileTypes: true });
|
|
41269
|
+
} catch {
|
|
41270
|
+
return;
|
|
41271
|
+
}
|
|
41272
|
+
for (const entry of entries) {
|
|
41273
|
+
const rel = relDir ? (0, import_node_path61.join)(relDir, entry.name) : entry.name;
|
|
41274
|
+
if (entry.isSymbolicLink()) continue;
|
|
41275
|
+
if (entry.isDirectory()) {
|
|
40968
41276
|
walk2(rel);
|
|
40969
|
-
|
|
40970
|
-
|
|
40971
|
-
|
|
41277
|
+
continue;
|
|
41278
|
+
}
|
|
41279
|
+
if (!entry.isFile() || !ensureRealDirs(verityDir, relDir)) continue;
|
|
41280
|
+
const opened = openRegularInRoot(gateDir, rel);
|
|
41281
|
+
if (!opened.ok) continue;
|
|
41282
|
+
try {
|
|
41283
|
+
(0, import_node_fs71.writeFileSync)((0, import_node_path61.join)(verityDir, rel), readOpened(opened.fd, opened.size), { flag: "wx", mode: 384 });
|
|
40972
41284
|
copied++;
|
|
41285
|
+
} catch {
|
|
40973
41286
|
}
|
|
40974
41287
|
}
|
|
40975
41288
|
};
|
|
40976
41289
|
walk2("");
|
|
40977
41290
|
return copied;
|
|
40978
41291
|
}
|
|
41292
|
+
function isRealDir(path) {
|
|
41293
|
+
try {
|
|
41294
|
+
const st = (0, import_node_fs71.lstatSync)(path);
|
|
41295
|
+
return st.isDirectory() && !st.isSymbolicLink();
|
|
41296
|
+
} catch {
|
|
41297
|
+
return false;
|
|
41298
|
+
}
|
|
41299
|
+
}
|
|
41300
|
+
function ensureRealDirs(root, relDir) {
|
|
41301
|
+
let current = root;
|
|
41302
|
+
for (const segment of relDir.split(/[\\/]/).filter(Boolean)) {
|
|
41303
|
+
current = (0, import_node_path61.join)(current, segment);
|
|
41304
|
+
try {
|
|
41305
|
+
(0, import_node_fs71.mkdirSync)(current);
|
|
41306
|
+
} catch (e) {
|
|
41307
|
+
if (e.code !== "EEXIST") return false;
|
|
41308
|
+
}
|
|
41309
|
+
if (!isRealDir(current)) return false;
|
|
41310
|
+
}
|
|
41311
|
+
return true;
|
|
41312
|
+
}
|
|
40979
41313
|
async function needsMigration(root = repoRoot()) {
|
|
40980
|
-
const gateDir = (0,
|
|
40981
|
-
const verityDir = (0,
|
|
40982
|
-
if ((0,
|
|
40983
|
-
if ((0,
|
|
40984
|
-
if ((0,
|
|
41314
|
+
const gateDir = (0, import_node_path61.join)(root, ".gate");
|
|
41315
|
+
const verityDir = (0, import_node_path61.join)(root, ".verity");
|
|
41316
|
+
if ((0, import_node_fs71.existsSync)(gateDir) && !(0, import_node_fs71.existsSync)(verityDir)) return true;
|
|
41317
|
+
if ((0, import_node_fs71.existsSync)(gateDir) && (0, import_node_fs71.existsSync)(verityDir)) {
|
|
41318
|
+
if ((0, import_node_fs71.existsSync)((0, import_node_path61.join)(gateDir, "credentials")) && !(0, import_node_fs71.existsSync)((0, import_node_path61.join)(verityDir, "credentials"))) {
|
|
40985
41319
|
return true;
|
|
40986
41320
|
}
|
|
40987
|
-
if ((0,
|
|
41321
|
+
if ((0, import_node_fs71.existsSync)((0, import_node_path61.join)(gateDir, "memory")) && !(0, import_node_fs71.existsSync)((0, import_node_path61.join)(verityDir, "memory"))) {
|
|
40988
41322
|
return true;
|
|
40989
41323
|
}
|
|
40990
41324
|
}
|
|
40991
|
-
const claudeMd = (0,
|
|
40992
|
-
if ((0,
|
|
41325
|
+
const claudeMd = (0, import_node_path61.join)(root, "CLAUDE.md");
|
|
41326
|
+
if ((0, import_node_fs71.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
|
|
40993
41327
|
return true;
|
|
40994
41328
|
}
|
|
40995
|
-
if ((0,
|
|
41329
|
+
if ((0, import_node_fs71.existsSync)((0, import_node_path61.join)(root, "GATE.md")) && !(0, import_node_fs71.existsSync)((0, import_node_path61.join)(root, "VERITY.md"))) {
|
|
40996
41330
|
return true;
|
|
40997
41331
|
}
|
|
40998
41332
|
if (await hasLegacyHooksAt(root)) return true;
|
|
@@ -41018,10 +41352,10 @@ function registerMigrateCommand(program2) {
|
|
|
41018
41352
|
}
|
|
41019
41353
|
|
|
41020
41354
|
// src/commands/init/ui.ts
|
|
41021
|
-
var
|
|
41022
|
-
var
|
|
41023
|
-
var
|
|
41024
|
-
var
|
|
41355
|
+
var import_node_fs72 = require("node:fs");
|
|
41356
|
+
var import_node_path62 = require("node:path");
|
|
41357
|
+
var import_node_os13 = require("node:os");
|
|
41358
|
+
var import_node_child_process20 = require("node:child_process");
|
|
41025
41359
|
function createInitUi(opts) {
|
|
41026
41360
|
const term = opts.term ?? detectTerm();
|
|
41027
41361
|
const screen = new Screen(term);
|
|
@@ -41038,25 +41372,26 @@ function installInterrupt(ui) {
|
|
|
41038
41372
|
process.once("SIGINT", stop2);
|
|
41039
41373
|
}
|
|
41040
41374
|
var SEEN_FILE = ".init-seen";
|
|
41041
|
-
function firstInitOnMachine(home = process.env.HOME || (0,
|
|
41042
|
-
return !(0,
|
|
41375
|
+
function firstInitOnMachine(home = process.env.HOME || (0, import_node_os13.homedir)()) {
|
|
41376
|
+
return !(0, import_node_fs72.existsSync)((0, import_node_path62.join)(home, ".verity", SEEN_FILE));
|
|
41043
41377
|
}
|
|
41044
|
-
function markInitSeen(home = process.env.HOME || (0,
|
|
41045
|
-
replaceInRoot((0,
|
|
41378
|
+
function markInitSeen(home = process.env.HOME || (0, import_node_os13.homedir)()) {
|
|
41379
|
+
replaceInRoot((0, import_node_path62.join)(home, ".verity"), SEEN_FILE, `${(/* @__PURE__ */ new Date()).toISOString()}
|
|
41046
41380
|
`);
|
|
41047
41381
|
}
|
|
41048
41382
|
function repoLabel() {
|
|
41049
41383
|
try {
|
|
41050
|
-
const url = (0,
|
|
41384
|
+
const url = (0, import_node_child_process20.execSync)("git remote get-url origin", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
41051
41385
|
const parsed = parseRemote(url);
|
|
41052
41386
|
if (parsed) return terminalText(`${parsed.owner}/${parsed.repo}`, 120);
|
|
41053
41387
|
} catch {
|
|
41054
41388
|
}
|
|
41055
|
-
return terminalText((0,
|
|
41389
|
+
return terminalText((0, import_node_path62.basename)(repoRoot()), 120);
|
|
41056
41390
|
}
|
|
41057
41391
|
|
|
41058
41392
|
// src/lib/prereqs.ts
|
|
41059
|
-
var
|
|
41393
|
+
var import_node_child_process21 = require("node:child_process");
|
|
41394
|
+
var import_node_fs73 = require("node:fs");
|
|
41060
41395
|
var MIN_NODE_MAJOR = 20;
|
|
41061
41396
|
function which(bin) {
|
|
41062
41397
|
return whichSync(bin, { real: false });
|
|
@@ -41077,7 +41412,7 @@ function checkNode() {
|
|
|
41077
41412
|
function checkGit() {
|
|
41078
41413
|
let detail = "";
|
|
41079
41414
|
try {
|
|
41080
|
-
detail = (0,
|
|
41415
|
+
detail = (0, import_node_child_process21.execSync)("git --version", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
41081
41416
|
} catch {
|
|
41082
41417
|
return {
|
|
41083
41418
|
id: "git",
|
|
@@ -41101,21 +41436,38 @@ function checkClaude() {
|
|
|
41101
41436
|
required: false
|
|
41102
41437
|
};
|
|
41103
41438
|
}
|
|
41104
|
-
|
|
41105
|
-
|
|
41439
|
+
var ANALYSIS_CLI_REMEDY = "Reinstall Verity, which includes it: npm install -g @codacy/verity-cli";
|
|
41440
|
+
function checkAnalysisCli(opts = {}) {
|
|
41441
|
+
const base = { id: "analysis-cli", label: "@codacy/analysis-cli", required: false };
|
|
41442
|
+
const analyzer = resolveAnalyzer(opts);
|
|
41443
|
+
const shown = (opts.onPathDisplay ?? (() => which("codacy-analysis")))();
|
|
41444
|
+
if (!analyzer) {
|
|
41445
|
+
return { ...base, status: "warn", detail: "not found", remedy: `${ANALYSIS_CLI_REMEDY} (static findings are unavailable until then)` };
|
|
41446
|
+
}
|
|
41447
|
+
if (analyzer.source === "path") {
|
|
41448
|
+
return { ...base, status: "ok", detail: `${shown ?? analyzer.path} (on PATH)`, source: "path" };
|
|
41449
|
+
}
|
|
41450
|
+
const unused = shown && !sameFile(shown, analyzer.path) ? shown : void 0;
|
|
41106
41451
|
return {
|
|
41107
|
-
|
|
41108
|
-
|
|
41109
|
-
|
|
41110
|
-
|
|
41111
|
-
|
|
41112
|
-
|
|
41452
|
+
...base,
|
|
41453
|
+
status: "ok",
|
|
41454
|
+
detail: `${analyzer.version} (bundled with Verity)`,
|
|
41455
|
+
source: "bundled",
|
|
41456
|
+
version: analyzer.version,
|
|
41457
|
+
...unused && { unused }
|
|
41113
41458
|
};
|
|
41114
41459
|
}
|
|
41460
|
+
function sameFile(a, b) {
|
|
41461
|
+
try {
|
|
41462
|
+
return (0, import_node_fs73.realpathSync)(a) === (0, import_node_fs73.realpathSync)(b);
|
|
41463
|
+
} catch {
|
|
41464
|
+
return false;
|
|
41465
|
+
}
|
|
41466
|
+
}
|
|
41115
41467
|
var INSTALL_TIMEOUT_MS = 12e4;
|
|
41116
41468
|
function run3(command, args2, opts = {}) {
|
|
41117
41469
|
return new Promise((resolve9) => {
|
|
41118
|
-
const child = (0,
|
|
41470
|
+
const child = (0, import_node_child_process21.spawn)(command, args2, {
|
|
41119
41471
|
stdio: opts.inherit ? "inherit" : "pipe",
|
|
41120
41472
|
timeout: INSTALL_TIMEOUT_MS
|
|
41121
41473
|
});
|
|
@@ -41145,7 +41497,7 @@ async function installAnalysisCli(opts = {}) {
|
|
|
41145
41497
|
label: "@codacy/analysis-cli",
|
|
41146
41498
|
status: "warn",
|
|
41147
41499
|
detail: "install failed",
|
|
41148
|
-
remedy:
|
|
41500
|
+
remedy: ANALYSIS_CLI_REMEDY,
|
|
41149
41501
|
required: false
|
|
41150
41502
|
};
|
|
41151
41503
|
if (opts.sudo === false || !process.stdin.isTTY || !process.stdout.isTTY) return failed;
|
|
@@ -41234,7 +41586,7 @@ async function prerequisitesStep(ui) {
|
|
|
41234
41586
|
const analysis = report.checks.find((c) => c.id === "analysis-cli");
|
|
41235
41587
|
if (analysis && analysis.status !== "ok") {
|
|
41236
41588
|
const s = ui.screen.s;
|
|
41237
|
-
const installed2 = await ui.screen.spin(`${s.gray}\u2502${s.reset} `, () => "
|
|
41589
|
+
const installed2 = await ui.screen.spin(`${s.gray}\u2502${s.reset} `, () => "Verity's copy of the Codacy analysis CLI is missing. Installing it (it runs the Trivy security scan)", installAnalysisCli({ quiet: true, sudo: false }));
|
|
41238
41590
|
report.checks[report.checks.indexOf(analysis)] = installed2;
|
|
41239
41591
|
if (installed2.status === "ok") ui.rail.ticked("Installed the Codacy analysis CLI");
|
|
41240
41592
|
}
|
|
@@ -41371,9 +41723,9 @@ async function scaffoldStep(ui, given = {}) {
|
|
|
41371
41723
|
}
|
|
41372
41724
|
|
|
41373
41725
|
// src/commands/init/wiring.ts
|
|
41374
|
-
var
|
|
41726
|
+
var import_node_fs74 = require("node:fs");
|
|
41375
41727
|
var import_promises18 = require("node:fs/promises");
|
|
41376
|
-
var
|
|
41728
|
+
var import_node_path63 = require("node:path");
|
|
41377
41729
|
var DEFAULT_MOMENTS = ["stop", "pre-commit", "pre-push"];
|
|
41378
41730
|
async function momentsFromInstalledHooks() {
|
|
41379
41731
|
const status = await checkAllVerityHooks();
|
|
@@ -41446,12 +41798,12 @@ var SKILLS = [
|
|
|
41446
41798
|
];
|
|
41447
41799
|
function resolveDataDir2() {
|
|
41448
41800
|
const candidates2 = [
|
|
41449
|
-
(0,
|
|
41450
|
-
(0,
|
|
41451
|
-
(0,
|
|
41801
|
+
(0, import_node_path63.join)(__dirname, "..", "data"),
|
|
41802
|
+
(0, import_node_path63.join)(__dirname, "..", "..", "data"),
|
|
41803
|
+
(0, import_node_path63.join)(process.cwd(), "cli", "data")
|
|
41452
41804
|
];
|
|
41453
41805
|
for (const candidate of candidates2) {
|
|
41454
|
-
if ((0,
|
|
41806
|
+
if ((0, import_node_fs74.existsSync)((0, import_node_path63.join)(candidate, "skills"))) return candidate;
|
|
41455
41807
|
}
|
|
41456
41808
|
throw new Error("Could not find Verity skill data. Reinstall: npm install -g @codacy/verity-cli");
|
|
41457
41809
|
}
|
|
@@ -41459,9 +41811,9 @@ async function skillIsCurrent(src, dest) {
|
|
|
41459
41811
|
const list2 = (dir) => {
|
|
41460
41812
|
const out2 = [];
|
|
41461
41813
|
const walk2 = (d, prefix) => {
|
|
41462
|
-
for (const e of (0,
|
|
41814
|
+
for (const e of (0, import_node_fs74.readdirSync)(d, { withFileTypes: true })) {
|
|
41463
41815
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
41464
|
-
if (e.isDirectory()) walk2((0,
|
|
41816
|
+
if (e.isDirectory()) walk2((0, import_node_path63.join)(d, e.name), rel);
|
|
41465
41817
|
else if (e.isFile()) out2.push(rel);
|
|
41466
41818
|
}
|
|
41467
41819
|
};
|
|
@@ -41472,7 +41824,7 @@ async function skillIsCurrent(src, dest) {
|
|
|
41472
41824
|
const shipped = list2(src);
|
|
41473
41825
|
if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
|
|
41474
41826
|
for (const rel of shipped) {
|
|
41475
|
-
if (await (0, import_promises18.readFile)((0,
|
|
41827
|
+
if (await (0, import_promises18.readFile)((0, import_node_path63.join)(src, rel), "utf-8") !== await (0, import_promises18.readFile)((0, import_node_path63.join)(dest, rel), "utf-8")) return false;
|
|
41476
41828
|
}
|
|
41477
41829
|
return true;
|
|
41478
41830
|
} catch {
|
|
@@ -41480,16 +41832,16 @@ async function skillIsCurrent(src, dest) {
|
|
|
41480
41832
|
}
|
|
41481
41833
|
}
|
|
41482
41834
|
async function installSkills(force) {
|
|
41483
|
-
const source2 = (0,
|
|
41835
|
+
const source2 = (0, import_node_path63.join)(resolveDataDir2(), "skills");
|
|
41484
41836
|
const missing = [];
|
|
41485
41837
|
for (const skill of SKILLS) {
|
|
41486
|
-
const src = (0,
|
|
41487
|
-
const dest = (0,
|
|
41488
|
-
if (!(0,
|
|
41838
|
+
const src = (0, import_node_path63.join)(source2, skill);
|
|
41839
|
+
const dest = (0, import_node_path63.join)(".claude/skills", skill);
|
|
41840
|
+
if (!(0, import_node_fs74.existsSync)(src)) {
|
|
41489
41841
|
missing.push(skill);
|
|
41490
41842
|
continue;
|
|
41491
41843
|
}
|
|
41492
|
-
if ((0,
|
|
41844
|
+
if ((0, import_node_fs74.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) continue;
|
|
41493
41845
|
await (0, import_promises18.mkdir)(dest, { recursive: true });
|
|
41494
41846
|
await (0, import_promises18.cp)(src, dest, { recursive: true, force: true });
|
|
41495
41847
|
}
|
|
@@ -41529,7 +41881,7 @@ async function hooksStep(ui, ctx) {
|
|
|
41529
41881
|
}
|
|
41530
41882
|
|
|
41531
41883
|
// src/commands/init/sign-in.ts
|
|
41532
|
-
var
|
|
41884
|
+
var import_node_child_process22 = require("node:child_process");
|
|
41533
41885
|
async function classifyExistingLogin(serviceUrl, remote, opts) {
|
|
41534
41886
|
const existing = await resolveToken(opts.token);
|
|
41535
41887
|
if (!existing.ok) return { kind: "none" };
|
|
@@ -41554,7 +41906,7 @@ async function classifyExistingLogin(serviceUrl, remote, opts) {
|
|
|
41554
41906
|
}
|
|
41555
41907
|
function gitRemote() {
|
|
41556
41908
|
try {
|
|
41557
|
-
return (0,
|
|
41909
|
+
return (0, import_node_child_process22.execSync)("git remote get-url origin", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
41558
41910
|
} catch {
|
|
41559
41911
|
return "";
|
|
41560
41912
|
}
|
|
@@ -41686,7 +42038,7 @@ async function signInStep(ui, resolution, opts) {
|
|
|
41686
42038
|
}
|
|
41687
42039
|
|
|
41688
42040
|
// src/commands/init/standard.ts
|
|
41689
|
-
var
|
|
42041
|
+
var import_node_fs75 = require("node:fs");
|
|
41690
42042
|
|
|
41691
42043
|
// src/commands/init/rules.ts
|
|
41692
42044
|
async function projectLabel(token, serviceUrl, verbose) {
|
|
@@ -41766,13 +42118,13 @@ async function generate(ui, globals, profile, replaces) {
|
|
|
41766
42118
|
return { status: "fallback" };
|
|
41767
42119
|
}
|
|
41768
42120
|
const secs2 = Math.max(1, Math.round((Date.now() - started) / 1e3));
|
|
41769
|
-
const
|
|
42121
|
+
const docs = profile.docs.length;
|
|
41770
42122
|
if (outcome.rules.length === 0) {
|
|
41771
42123
|
rail.warn("No project rules this time");
|
|
41772
42124
|
rail.line("The proposed rules were too generic, or not safe to use. The built-in rules apply.");
|
|
41773
42125
|
} else {
|
|
41774
42126
|
const n2 = outcome.rules.length;
|
|
41775
|
-
const from = [`${commits} ${commits === 1 ? "commit" : "commits"}`, ...
|
|
42127
|
+
const from = [`${commits} ${commits === 1 ? "commit" : "commits"}`, ...docs ? [`${docs} ${docs === 1 ? "doc" : "docs"}`] : []].join(" and ");
|
|
41776
42128
|
rail.done(`${n2} ${n2 === 1 ? "rule" : "rules"} for this repository ${s.gray}\xB7 from ${from} \xB7 ${secs2}s${s.reset}`);
|
|
41777
42129
|
await rail.rules(outcome.rules);
|
|
41778
42130
|
if (outcome.rejected > 0) rail.line(`${outcome.rejected} proposed ${outcome.rejected === 1 ? "rule was" : "rules were"} left out: too generic, or not safe to use.`);
|
|
@@ -41885,7 +42237,7 @@ async function standardStep(ui, ctx) {
|
|
|
41885
42237
|
const d = await deriveFromCatalogue(ui, ctx.globals);
|
|
41886
42238
|
return end({ source: d.ok ? "derived" : "none", version: d.version, profile: profile2 });
|
|
41887
42239
|
};
|
|
41888
|
-
if ((0,
|
|
42240
|
+
if ((0, import_node_fs75.existsSync)(projectPath(STANDARD_FILE))) {
|
|
41889
42241
|
const sync = await pushLocalStandardIfMissing(ctx.globals);
|
|
41890
42242
|
rail.done("Kept your Standard");
|
|
41891
42243
|
rail.line(`${STANDARD_FILE} is already here, so this run leaves it as it is.`);
|
|
@@ -42010,7 +42362,7 @@ async function runInit(program2, opts) {
|
|
|
42010
42362
|
standardAnswer = v;
|
|
42011
42363
|
}
|
|
42012
42364
|
const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
|
|
42013
|
-
if (!projectMarkers.some((m) => (0,
|
|
42365
|
+
if (!projectMarkers.some((m) => (0, import_node_fs76.existsSync)(m))) {
|
|
42014
42366
|
printError('No project detected in the current directory. Run "verity init" from your project root.');
|
|
42015
42367
|
process.exit(1);
|
|
42016
42368
|
}
|
|
@@ -42046,10 +42398,10 @@ async function runInit(program2, opts) {
|
|
|
42046
42398
|
trace.mark("prerequisites", "ok");
|
|
42047
42399
|
await scaffoldStep(ui, { untrackMemory: opts.untrackMemory === true, untrackState: opts.untrackState === true });
|
|
42048
42400
|
trace.mark("scaffold", "ok");
|
|
42049
|
-
await (0, import_promises19.mkdir)((0,
|
|
42401
|
+
await (0, import_promises19.mkdir)((0, import_node_path64.join)(process.env.HOME ?? "", ".verity"), { recursive: true });
|
|
42050
42402
|
await repoStep(ui, detectProject());
|
|
42051
42403
|
const previous = await readSetupState();
|
|
42052
|
-
const setUpBefore = (0,
|
|
42404
|
+
const setUpBefore = (0, import_node_fs76.existsSync)(projectPath(STANDARD_FILE));
|
|
42053
42405
|
const answers = await askSetupQuestions(defaultsOnly, previous, { moments: givenMoments, telemetry: givenTelemetry });
|
|
42054
42406
|
trace.mark("questions", "ok", givenMoments || givenTelemetry !== void 0 || profileAnswer || standardAnswer ? "asked" : "defaults");
|
|
42055
42407
|
const plan = planMoments(answers.moments, { given: givenMoments !== void 0, defaultsOnly });
|
|
@@ -42093,7 +42445,7 @@ async function runInit(program2, opts) {
|
|
|
42093
42445
|
// The effective answer: the next run starts from this record.
|
|
42094
42446
|
moments: plan.momentIds,
|
|
42095
42447
|
...telemetry ? { telemetry } : {},
|
|
42096
|
-
init: { completed_at: (/* @__PURE__ */ new Date()).toISOString(), cli_version: true ? "0.35.0-experimental.
|
|
42448
|
+
init: { completed_at: (/* @__PURE__ */ new Date()).toISOString(), cli_version: true ? "0.35.0-experimental.7c5e75b" : "dev" }
|
|
42097
42449
|
});
|
|
42098
42450
|
} catch (err2) {
|
|
42099
42451
|
rail.line(`Could not record the setup answers: ${terminalText(err2.message, 200)}`, "warn");
|
|
@@ -42124,7 +42476,7 @@ function registerInitCommand(program2) {
|
|
|
42124
42476
|
}
|
|
42125
42477
|
|
|
42126
42478
|
// src/commands/doctor.ts
|
|
42127
|
-
var
|
|
42479
|
+
var import_node_fs77 = require("node:fs");
|
|
42128
42480
|
async function buildReport() {
|
|
42129
42481
|
const prereqs = await checkPrereqs({ install: false });
|
|
42130
42482
|
const state = await readSetupState();
|
|
@@ -42133,8 +42485,8 @@ async function buildReport() {
|
|
|
42133
42485
|
const provenance = cliProvenance();
|
|
42134
42486
|
const telemetry = await checkTelemetry();
|
|
42135
42487
|
const artifacts = {
|
|
42136
|
-
standard: (0,
|
|
42137
|
-
verityMd: (0,
|
|
42488
|
+
standard: (0, import_node_fs77.existsSync)(projectPath(STANDARD_FILE)),
|
|
42489
|
+
verityMd: (0, import_node_fs77.existsSync)(projectPath(VERITY_MD_FILE))
|
|
42138
42490
|
};
|
|
42139
42491
|
const next = [];
|
|
42140
42492
|
for (const c of prereqs.checks) {
|
|
@@ -42173,6 +42525,11 @@ async function buildReport() {
|
|
|
42173
42525
|
if (state?.telemetry === "deferred") {
|
|
42174
42526
|
next.push('Telemetry was requested but needs a token \u2014 run "verity login", then "verity telemetry install".');
|
|
42175
42527
|
}
|
|
42528
|
+
if (telemetry.staleLocalKeys.length > 0) {
|
|
42529
|
+
next.push(
|
|
42530
|
+
`.claude/settings.local.json still holds ${telemetry.staleLocalKeys.length} old Verity telemetry key(s). Claude Code 2.1.282 and later ignores them there, so nothing is exported from them. Run "verity telemetry install" to export from this machine instead (it removes them), or "verity telemetry uninstall" to turn telemetry off and remove them.`
|
|
42531
|
+
);
|
|
42532
|
+
}
|
|
42176
42533
|
const memory2 = {
|
|
42177
42534
|
posture: memoryPosture(),
|
|
42178
42535
|
trackedFiles: committedMemoryFiles().length,
|
|
@@ -42220,7 +42577,7 @@ async function buildReport() {
|
|
|
42220
42577
|
noAnalysisMoment,
|
|
42221
42578
|
versions
|
|
42222
42579
|
},
|
|
42223
|
-
telemetry: { enabled: telemetry.enabled, endpoint: telemetry.endpoint },
|
|
42580
|
+
telemetry: { enabled: telemetry.enabled, endpoint: telemetry.endpoint, staleLocalKeys: telemetry.staleLocalKeys },
|
|
42224
42581
|
artifacts,
|
|
42225
42582
|
memory: memory2,
|
|
42226
42583
|
trackedState,
|
|
@@ -42243,6 +42600,7 @@ function registerDoctorCommand(program2) {
|
|
|
42243
42600
|
for (const c of report.prerequisites) {
|
|
42244
42601
|
if (c.status === "ok") printInfo(` ${c.label} ${c.detail} \u2713`);
|
|
42245
42602
|
else printWarn(` ${c.label}: ${c.detail}${c.remedy ? ` \u2014 ${c.remedy}` : ""}`);
|
|
42603
|
+
if (c.unused) printInfo(` ${c.unused}: not used (Verity runs its bundled copy)`);
|
|
42246
42604
|
}
|
|
42247
42605
|
printInfo("Setup:");
|
|
42248
42606
|
printInfo(` verity init: ${report.phases.init.done ? `done ${report.phases.init.completed_at ?? ""}`.trim() : "NOT run here"}`);
|
|
@@ -42264,7 +42622,9 @@ function registerDoctorCommand(program2) {
|
|
|
42264
42622
|
if (cfg.formal_refused) printWarn(` ${formalRefusalMessage(cfg.formal_refused)}`);
|
|
42265
42623
|
}
|
|
42266
42624
|
printInfo(` Infra (intent/baseline/compact/session-end): ${[report.hooks.intent, report.hooks.baseline, report.hooks.compact, report.hooks.sessionEnd].filter(Boolean).length}/4`);
|
|
42267
|
-
printInfo(
|
|
42625
|
+
printInfo(
|
|
42626
|
+
`Telemetry: ${report.telemetry.enabled ? `enabled \u2192 ${report.telemetry.endpoint} (every Claude Code session on this machine)` : "disabled"}`
|
|
42627
|
+
);
|
|
42268
42628
|
if (process.platform === "win32") printWarn(WINDOWS_STATIC_NOTE);
|
|
42269
42629
|
else printInfo("Static analysis: Trivy (dependencies, malicious packages, secrets)");
|
|
42270
42630
|
printInfo("Artifacts:");
|
|
@@ -42285,8 +42645,8 @@ function registerDoctorCommand(program2) {
|
|
|
42285
42645
|
}
|
|
42286
42646
|
|
|
42287
42647
|
// src/commands/uninstall.ts
|
|
42288
|
-
var
|
|
42289
|
-
var
|
|
42648
|
+
var import_node_fs78 = require("node:fs");
|
|
42649
|
+
var import_node_path65 = require("node:path");
|
|
42290
42650
|
function registerUninstallCommand(program2) {
|
|
42291
42651
|
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) => {
|
|
42292
42652
|
const dryRun = opts.dryRun ?? false;
|
|
@@ -42295,11 +42655,11 @@ function registerUninstallCommand(program2) {
|
|
|
42295
42655
|
const actions = [];
|
|
42296
42656
|
const skillsRoot = projectPath(".claude/skills");
|
|
42297
42657
|
for (const name2 of PROJECT_SKILL_NAMES) {
|
|
42298
|
-
const dir = (0,
|
|
42299
|
-
if ((0,
|
|
42658
|
+
const dir = (0, import_node_path65.join)(skillsRoot, name2);
|
|
42659
|
+
if ((0, import_node_fs78.existsSync)(dir)) {
|
|
42300
42660
|
actions.push({
|
|
42301
42661
|
label: `Remove .claude/skills/${name2}/`,
|
|
42302
|
-
apply: () => (0,
|
|
42662
|
+
apply: () => (0, import_node_fs78.rmSync)(dir, { recursive: true, force: true })
|
|
42303
42663
|
});
|
|
42304
42664
|
}
|
|
42305
42665
|
}
|
|
@@ -42313,24 +42673,24 @@ function registerUninstallCommand(program2) {
|
|
|
42313
42673
|
});
|
|
42314
42674
|
}
|
|
42315
42675
|
const verityDir = projectPath(VERITY_DIR);
|
|
42316
|
-
if ((0,
|
|
42676
|
+
if ((0, import_node_fs78.existsSync)(verityDir)) {
|
|
42317
42677
|
actions.push({
|
|
42318
42678
|
label: `Remove ${VERITY_DIR}/`,
|
|
42319
|
-
apply: () => (0,
|
|
42679
|
+
apply: () => (0, import_node_fs78.rmSync)(verityDir, { recursive: true, force: true })
|
|
42320
42680
|
});
|
|
42321
42681
|
}
|
|
42322
42682
|
if (!keepVerityMd) {
|
|
42323
42683
|
const verityMd = projectPath(VERITY_MD_FILE);
|
|
42324
|
-
if ((0,
|
|
42684
|
+
if ((0, import_node_fs78.existsSync)(verityMd)) {
|
|
42325
42685
|
actions.push({
|
|
42326
42686
|
label: `Remove ${VERITY_MD_FILE}`,
|
|
42327
|
-
apply: () => (0,
|
|
42687
|
+
apply: () => (0, import_node_fs78.rmSync)(verityMd, { force: true })
|
|
42328
42688
|
});
|
|
42329
42689
|
}
|
|
42330
42690
|
}
|
|
42331
42691
|
const cleanupEmptyDir = (path) => {
|
|
42332
|
-
if ((0,
|
|
42333
|
-
(0,
|
|
42692
|
+
if ((0, import_node_fs78.existsSync)(path) && (0, import_node_fs78.statSync)(path).isDirectory() && (0, import_node_fs78.readdirSync)(path).length === 0) {
|
|
42693
|
+
(0, import_node_fs78.rmdirSync)(path);
|
|
42334
42694
|
}
|
|
42335
42695
|
};
|
|
42336
42696
|
actions.push({
|
|
@@ -42341,11 +42701,11 @@ function registerUninstallCommand(program2) {
|
|
|
42341
42701
|
}
|
|
42342
42702
|
});
|
|
42343
42703
|
const home = process.env.HOME ?? "";
|
|
42344
|
-
const globalVerityDir = (0,
|
|
42345
|
-
if (purgeGlobal && (0,
|
|
42704
|
+
const globalVerityDir = (0, import_node_path65.join)(home, ".verity");
|
|
42705
|
+
if (purgeGlobal && (0, import_node_fs78.existsSync)(globalVerityDir)) {
|
|
42346
42706
|
actions.push({
|
|
42347
42707
|
label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
|
|
42348
|
-
apply: () => (0,
|
|
42708
|
+
apply: () => (0, import_node_fs78.rmSync)(globalVerityDir, { recursive: true, force: true })
|
|
42349
42709
|
});
|
|
42350
42710
|
}
|
|
42351
42711
|
if (actions.length === 0) {
|
|
@@ -42564,8 +42924,8 @@ function registerTaskCommands(program2) {
|
|
|
42564
42924
|
}
|
|
42565
42925
|
|
|
42566
42926
|
// src/commands/reset.ts
|
|
42567
|
-
var
|
|
42568
|
-
var
|
|
42927
|
+
var import_node_fs79 = require("node:fs");
|
|
42928
|
+
var import_node_path66 = require("node:path");
|
|
42569
42929
|
function registerResetCommand(program2) {
|
|
42570
42930
|
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) => {
|
|
42571
42931
|
const globals = program2.opts();
|
|
@@ -42605,18 +42965,18 @@ function registerResetCommand(program2) {
|
|
|
42605
42965
|
} catch {
|
|
42606
42966
|
}
|
|
42607
42967
|
}
|
|
42608
|
-
const purged = purgeVerityDir((0,
|
|
42968
|
+
const purged = purgeVerityDir((0, import_node_path66.basename)(CACHE_DIR), (name2) => name2.startsWith("pending-"));
|
|
42609
42969
|
if (purged === null) printError(`Did not purge ${CACHE_DIR}: it is not a directory inside ${VERITY_DIR}.`);
|
|
42610
42970
|
const stateDir2 = projectPath(VERITY_DIR);
|
|
42611
42971
|
const filesToClear = [
|
|
42612
|
-
(0,
|
|
42613
|
-
(0,
|
|
42614
|
-
(0,
|
|
42972
|
+
(0, import_node_path66.basename)(INTENT_FILE),
|
|
42973
|
+
(0, import_node_path66.basename)(HASH_FILE),
|
|
42974
|
+
(0, import_node_path66.basename)(BASELINE_SHA_FILE),
|
|
42615
42975
|
".iteration-count",
|
|
42616
42976
|
".last-analysis"
|
|
42617
42977
|
];
|
|
42618
42978
|
for (const name2 of filesToClear) {
|
|
42619
|
-
if (lstatOrNull((0,
|
|
42979
|
+
if (lstatOrNull((0, import_node_path66.join)(stateDir2, name2)) && !replaceInRoot(stateDir2, name2, "")) {
|
|
42620
42980
|
printError(`Did not clear ${VERITY_DIR}/${name2}: it is not a regular file inside ${VERITY_DIR}.`);
|
|
42621
42981
|
}
|
|
42622
42982
|
}
|
|
@@ -42631,29 +42991,29 @@ function registerResetCommand(program2) {
|
|
|
42631
42991
|
}
|
|
42632
42992
|
function lstatOrNull(path) {
|
|
42633
42993
|
try {
|
|
42634
|
-
return (0,
|
|
42994
|
+
return (0, import_node_fs79.lstatSync)(path);
|
|
42635
42995
|
} catch {
|
|
42636
42996
|
return null;
|
|
42637
42997
|
}
|
|
42638
42998
|
}
|
|
42639
42999
|
function purgeVerityDir(child, select) {
|
|
42640
43000
|
const verityDir = projectPath(VERITY_DIR);
|
|
42641
|
-
const dir = (0,
|
|
43001
|
+
const dir = (0, import_node_path66.join)(verityDir, child);
|
|
42642
43002
|
const parent = lstatOrNull(verityDir);
|
|
42643
43003
|
const st = lstatOrNull(dir);
|
|
42644
43004
|
if (!st) return 0;
|
|
42645
43005
|
if (!parent || parent.isSymbolicLink() || !parent.isDirectory()) return null;
|
|
42646
43006
|
if (st.isSymbolicLink() || !st.isDirectory()) return null;
|
|
42647
43007
|
try {
|
|
42648
|
-
if ((0,
|
|
43008
|
+
if ((0, import_node_fs79.realpathSync)(dir) !== (0, import_node_path66.join)((0, import_node_fs79.realpathSync)(verityDir), child)) return null;
|
|
42649
43009
|
} catch {
|
|
42650
43010
|
return null;
|
|
42651
43011
|
}
|
|
42652
43012
|
let removed = 0;
|
|
42653
|
-
for (const entry of (0,
|
|
43013
|
+
for (const entry of (0, import_node_fs79.readdirSync)(dir, { withFileTypes: true })) {
|
|
42654
43014
|
if (entry.isDirectory() || !select(entry.name)) continue;
|
|
42655
43015
|
try {
|
|
42656
|
-
(0,
|
|
43016
|
+
(0, import_node_fs79.unlinkSync)((0, import_node_path66.join)(dir, entry.name));
|
|
42657
43017
|
removed++;
|
|
42658
43018
|
} catch {
|
|
42659
43019
|
}
|
|
@@ -42662,7 +43022,7 @@ function purgeVerityDir(child, select) {
|
|
|
42662
43022
|
}
|
|
42663
43023
|
|
|
42664
43024
|
// src/commands/reflect.ts
|
|
42665
|
-
var
|
|
43025
|
+
var import_node_fs80 = require("node:fs");
|
|
42666
43026
|
|
|
42667
43027
|
// src/lib/reflection-globs.ts
|
|
42668
43028
|
var MAX_GLOBS = 6;
|
|
@@ -42700,7 +43060,7 @@ async function writeNodeToDisk(args2) {
|
|
|
42700
43060
|
{ treePaths: listTrackedFiles(), recordBaseline: false }
|
|
42701
43061
|
);
|
|
42702
43062
|
if (written === 0) return false;
|
|
42703
|
-
return (0,
|
|
43063
|
+
return (0, import_node_fs80.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
|
|
42704
43064
|
} catch {
|
|
42705
43065
|
return false;
|
|
42706
43066
|
}
|
|
@@ -43137,9 +43497,15 @@ function registerRunCommand(program2) {
|
|
|
43137
43497
|
}
|
|
43138
43498
|
|
|
43139
43499
|
// src/commands/telemetry.ts
|
|
43140
|
-
var
|
|
43500
|
+
var import_node_fs81 = require("node:fs");
|
|
43501
|
+
var SCOPE = "every Claude Code session on this machine";
|
|
43502
|
+
function declineHeaders(why) {
|
|
43503
|
+
process.stderr.write(`Verity telemetry is off here: ${why} Nothing is exported from this session.
|
|
43504
|
+
`);
|
|
43505
|
+
process.exitCode = 1;
|
|
43506
|
+
}
|
|
43141
43507
|
async function recordTelemetryChoice(choice) {
|
|
43142
|
-
if (!(0,
|
|
43508
|
+
if (!(0, import_node_fs81.existsSync)(projectPath(SETUP_STATE_FILE))) return;
|
|
43143
43509
|
try {
|
|
43144
43510
|
if ((await readSetupState())?.telemetry === choice) return;
|
|
43145
43511
|
await writeSetupState({ telemetry: choice });
|
|
@@ -43147,8 +43513,8 @@ async function recordTelemetryChoice(choice) {
|
|
|
43147
43513
|
}
|
|
43148
43514
|
}
|
|
43149
43515
|
function registerTelemetryCommands(program2) {
|
|
43150
|
-
const telemetry = program2.command("telemetry").description(
|
|
43151
|
-
telemetry.command("install").description(
|
|
43516
|
+
const telemetry = program2.command("telemetry").description(`Manage Claude Code OpenTelemetry export to Verity (cost & usage) for ${SCOPE}`);
|
|
43517
|
+
telemetry.command("install").description(`Export cost & usage to Verity from ${SCOPE} (writes your Claude Code user settings)`).action(async () => {
|
|
43152
43518
|
const globals = program2.opts();
|
|
43153
43519
|
const tokenResult = await resolveToken(globals.token);
|
|
43154
43520
|
if (!tokenResult.ok) {
|
|
@@ -43160,35 +43526,51 @@ function registerTelemetryCommands(program2) {
|
|
|
43160
43526
|
printError(urlResult.error);
|
|
43161
43527
|
process.exit(1);
|
|
43162
43528
|
}
|
|
43163
|
-
const
|
|
43164
|
-
if (!pin.attach && pin.reason === "unpinnable") {
|
|
43165
|
-
printWarn("Your Verity credential does not record which service issued it, so this endpoint");
|
|
43166
|
-
printWarn(" cannot be verified \u2014 a repository could point your telemetry elsewhere.");
|
|
43167
|
-
printWarn(' Run "verity login" to re-issue the credential; Verity can check it after that.');
|
|
43168
|
-
}
|
|
43169
|
-
const result = await installTelemetry(urlResult.data);
|
|
43529
|
+
const result = await installTelemetry(urlResult.data, { token: tokenResult.data.token });
|
|
43170
43530
|
if (!result.ok) {
|
|
43171
43531
|
printError(result.error);
|
|
43172
43532
|
process.exit(1);
|
|
43173
43533
|
}
|
|
43174
43534
|
await recordTelemetryChoice("enabled");
|
|
43175
43535
|
printInfo(`Telemetry enabled \u2192 ${result.data.endpoint}`);
|
|
43176
|
-
printInfo(`
|
|
43536
|
+
printInfo(` scope: ${SCOPE}`);
|
|
43537
|
+
printInfo(` wrote ${displayPath(result.data.settingsPath)} (no token stored \u2014 resolved at runtime via otelHeadersHelper)`);
|
|
43538
|
+
if (result.data.healedLocalKeys.length > 0) {
|
|
43539
|
+
printInfo(` removed ${result.data.healedLocalKeys.length} old telemetry key(s) from ${SETTINGS_LOCAL_FILE2}`);
|
|
43540
|
+
}
|
|
43541
|
+
printInfo(" only Verity projects send data. In other repositories Claude Code shows a startup");
|
|
43542
|
+
printInfo(' warning that "verity telemetry headers" exited 1, and it exports nothing there.');
|
|
43177
43543
|
printInfo(" takes effect on your NEXT Claude Code session; first metrics appear within ~60s of activity");
|
|
43178
43544
|
printInfo(" view cost & usage at /usage");
|
|
43179
43545
|
});
|
|
43180
|
-
telemetry.command("headers").description("Print the OTLP
|
|
43546
|
+
telemetry.command("headers").description("Print the OTLP headers as JSON for Claude Code otelHeadersHelper (exits 1 outside a Verity project)").action(async () => {
|
|
43547
|
+
if (!isTelemetryProject()) {
|
|
43548
|
+
declineHeaders("this directory is not in a Verity project.");
|
|
43549
|
+
return;
|
|
43550
|
+
}
|
|
43181
43551
|
const globals = program2.opts();
|
|
43182
43552
|
const tokenResult = await resolveToken(globals.token);
|
|
43183
|
-
if (tokenResult.ok) {
|
|
43184
|
-
|
|
43185
|
-
|
|
43186
|
-
|
|
43187
|
-
|
|
43188
|
-
|
|
43189
|
-
|
|
43190
|
-
|
|
43553
|
+
if (!tokenResult.ok) {
|
|
43554
|
+
declineHeaders('this Verity project has no token on this machine. Run "verity login".');
|
|
43555
|
+
return;
|
|
43556
|
+
}
|
|
43557
|
+
const endpoints = await sessionExportEndpoints();
|
|
43558
|
+
if (endpoints.length === 0) {
|
|
43559
|
+
declineHeaders("no OTLP endpoint is configured for this session.");
|
|
43560
|
+
return;
|
|
43561
|
+
}
|
|
43562
|
+
for (const endpoint of endpoints) {
|
|
43563
|
+
const refusal = await telemetryPinRefusal(tokenResult.data.token, endpoint);
|
|
43564
|
+
if (refusal) {
|
|
43565
|
+
declineHeaders(refusal);
|
|
43566
|
+
return;
|
|
43567
|
+
}
|
|
43191
43568
|
}
|
|
43569
|
+
const remote = requestRemote();
|
|
43570
|
+
printJsonCompact({
|
|
43571
|
+
Authorization: `Bearer ${tokenResult.data.token}`,
|
|
43572
|
+
...remote ? { "X-Verity-Remote": remote } : {}
|
|
43573
|
+
});
|
|
43192
43574
|
});
|
|
43193
43575
|
telemetry.command("check").description("Show whether Claude Code telemetry export to Verity is enabled").option("--json", "Output status as JSON").action(async (opts) => {
|
|
43194
43576
|
const status = await checkTelemetry();
|
|
@@ -43197,21 +43579,36 @@ function registerTelemetryCommands(program2) {
|
|
|
43197
43579
|
return;
|
|
43198
43580
|
}
|
|
43199
43581
|
if (status.enabled) {
|
|
43200
|
-
printInfo(`Telemetry: enabled \u2192 ${status.endpoint}`);
|
|
43582
|
+
printInfo(`Telemetry: enabled \u2192 ${status.endpoint} (${SCOPE})`);
|
|
43201
43583
|
} else {
|
|
43202
43584
|
printWarn('Telemetry: disabled. Run "verity telemetry install" to enable cost & usage tracking.');
|
|
43203
43585
|
}
|
|
43586
|
+
if (status.staleLocalKeys.length > 0) {
|
|
43587
|
+
printWarn(
|
|
43588
|
+
` ${SETTINGS_LOCAL_FILE2} still holds ${status.staleLocalKeys.length} old Verity telemetry key(s), which Claude Code ignores there. "verity telemetry install" removes them.`
|
|
43589
|
+
);
|
|
43590
|
+
}
|
|
43204
43591
|
});
|
|
43205
|
-
telemetry.command("uninstall").description(
|
|
43592
|
+
telemetry.command("uninstall").description(`Stop the telemetry export to Verity from ${SCOPE}`).action(async () => {
|
|
43206
43593
|
const result = await uninstallTelemetry();
|
|
43207
43594
|
if (!result.ok) {
|
|
43208
43595
|
printError(result.error);
|
|
43209
43596
|
process.exit(1);
|
|
43210
43597
|
}
|
|
43211
43598
|
await recordTelemetryChoice("declined");
|
|
43212
|
-
|
|
43213
|
-
|
|
43214
|
-
|
|
43599
|
+
const { removed, settingsPath, foreignEndpoint, healedLocalKeys } = result.data;
|
|
43600
|
+
if (removed > 0) {
|
|
43601
|
+
printInfo(`Telemetry disabled (${removed} keys removed from ${displayPath(settingsPath)})`);
|
|
43602
|
+
} else if (foreignEndpoint) {
|
|
43603
|
+
printInfo(
|
|
43604
|
+
`${displayPath(settingsPath)} exports to another destination, so Verity left it unchanged.`
|
|
43605
|
+
);
|
|
43606
|
+
} else {
|
|
43607
|
+
printInfo("Telemetry was not enabled \u2014 nothing to remove.");
|
|
43608
|
+
}
|
|
43609
|
+
if (healedLocalKeys.length > 0) {
|
|
43610
|
+
printInfo(` removed ${healedLocalKeys.length} old telemetry key(s) from ${SETTINGS_LOCAL_FILE2}`);
|
|
43611
|
+
}
|
|
43215
43612
|
});
|
|
43216
43613
|
}
|
|
43217
43614
|
|
|
@@ -43253,8 +43650,8 @@ function renderSeatUsage(d, now = /* @__PURE__ */ new Date()) {
|
|
|
43253
43650
|
lines.push(
|
|
43254
43651
|
`Session ${utcHm(d.session.start)}\u2013${utcHm(d.session.resets_at)} (resets in ${inText(now, new Date(d.session.resets_at))}) \xB7 week from Mon ${utcDay2(d.week.start)} (resets Mon ${utcDay2(d.week.resets_at)}, 00:00 UTC)`
|
|
43255
43652
|
);
|
|
43256
|
-
if (!d.plan) lines.push("No plan is set for this org: counts only.
|
|
43257
|
-
else if (!d.enforced) lines.push("Limits are shown for information. They are not enforced
|
|
43653
|
+
if (!d.plan) lines.push("No plan is set for this org: counts only.");
|
|
43654
|
+
else if (!d.enforced) lines.push("Limits are shown for information. They are not enforced yet.");
|
|
43258
43655
|
const me = d.members.find((m) => m.me);
|
|
43259
43656
|
if (me) {
|
|
43260
43657
|
const w = me.weeks[0];
|
|
@@ -43358,8 +43755,8 @@ function registerUsageCommand(program2) {
|
|
|
43358
43755
|
}
|
|
43359
43756
|
|
|
43360
43757
|
// src/commands/prove.ts
|
|
43361
|
-
var
|
|
43362
|
-
var
|
|
43758
|
+
var import_node_fs82 = require("node:fs");
|
|
43759
|
+
var import_node_path67 = require("node:path");
|
|
43363
43760
|
|
|
43364
43761
|
// src/lib/prove/hint-pool.ts
|
|
43365
43762
|
var STOP2 = /* @__PURE__ */ new Set([
|
|
@@ -43501,7 +43898,7 @@ function registerProveCommand(program2) {
|
|
|
43501
43898
|
process.exit(2);
|
|
43502
43899
|
}
|
|
43503
43900
|
const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
|
|
43504
|
-
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0,
|
|
43901
|
+
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path67.relative)(root, (0, import_node_path67.resolve)(p)) || ".") });
|
|
43505
43902
|
if (opts.hint && paths.length === 0) {
|
|
43506
43903
|
const hit = hintMatches(root, opts.hint);
|
|
43507
43904
|
if (hit.files.length > 0) {
|
|
@@ -43555,7 +43952,7 @@ function registerProveCommand(program2) {
|
|
|
43555
43952
|
});
|
|
43556
43953
|
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) => {
|
|
43557
43954
|
const root = repoRoot();
|
|
43558
|
-
if (!(0,
|
|
43955
|
+
if (!(0, import_node_fs82.existsSync)((0, import_node_path67.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
43559
43956
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
43560
43957
|
process.exit(2);
|
|
43561
43958
|
}
|
|
@@ -43579,7 +43976,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
43579
43976
|
const reports = [];
|
|
43580
43977
|
for (const f of files) {
|
|
43581
43978
|
const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
|
|
43582
|
-
report.file = (0,
|
|
43979
|
+
report.file = (0, import_node_path67.relative)(root, f);
|
|
43583
43980
|
reports.push(report);
|
|
43584
43981
|
try {
|
|
43585
43982
|
writeResult(root, report);
|
|
@@ -43617,7 +44014,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
43617
44014
|
printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
|
|
43618
44015
|
process.exit(2);
|
|
43619
44016
|
}
|
|
43620
|
-
if (!(0,
|
|
44017
|
+
if (!(0, import_node_fs82.existsSync)((0, import_node_path67.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
43621
44018
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
43622
44019
|
process.exit(2);
|
|
43623
44020
|
}
|
|
@@ -43648,7 +44045,7 @@ ${report.error ?? ""}`);
|
|
|
43648
44045
|
printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
|
|
43649
44046
|
return;
|
|
43650
44047
|
}
|
|
43651
|
-
const modelSource = readRegularFileInRoot(root, (0,
|
|
44048
|
+
const modelSource = readRegularFileInRoot(root, (0, import_node_path67.relative)(root, file), 512 * 1024);
|
|
43652
44049
|
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`);
|
|
43653
44050
|
const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
|
|
43654
44051
|
const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
|
|
@@ -43668,7 +44065,7 @@ ${report.error ?? ""}`);
|
|
|
43668
44065
|
});
|
|
43669
44066
|
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) => {
|
|
43670
44067
|
const root = repoRoot();
|
|
43671
|
-
let files = paths.map((p) => (0,
|
|
44068
|
+
let files = paths.map((p) => (0, import_node_path67.relative)(root, (0, import_node_path67.resolve)(p)));
|
|
43672
44069
|
if (files.length === 0) {
|
|
43673
44070
|
const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
|
|
43674
44071
|
const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
|
|
@@ -43742,7 +44139,7 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
43742
44139
|
let revise;
|
|
43743
44140
|
if (opts.revise) {
|
|
43744
44141
|
const existing = resolveModelFile(root, opts.revise);
|
|
43745
|
-
const src = existing ? readRegularFileInRoot(root, (0,
|
|
44142
|
+
const src = existing ? readRegularFileInRoot(root, (0, import_node_path67.relative)(root, existing), 64 * 1024) : null;
|
|
43746
44143
|
if (!src || !src.ok || !opts.note) {
|
|
43747
44144
|
printError("--revise needs an existing model under Models/ and --note - with what the replay showed on stdin");
|
|
43748
44145
|
process.exit(2);
|
|
@@ -43782,8 +44179,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
43782
44179
|
});
|
|
43783
44180
|
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) => {
|
|
43784
44181
|
const root = repoRoot();
|
|
43785
|
-
const rel0 = (0,
|
|
43786
|
-
const rel = rel0.startsWith("..") || (0,
|
|
44182
|
+
const rel0 = (0, import_node_path67.relative)(root, (0, import_node_path67.isAbsolute)(file) ? file : (0, import_node_path67.join)(root, file)).replace(/\\/g, "/");
|
|
44183
|
+
const rel = rel0.startsWith("..") || (0, import_node_path67.isAbsolute)(rel0) ? null : rel0;
|
|
43787
44184
|
if (!rel) {
|
|
43788
44185
|
printError(`${file} is not inside this repository`);
|
|
43789
44186
|
process.exit(2);
|
|
@@ -43799,8 +44196,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
43799
44196
|
});
|
|
43800
44197
|
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) => {
|
|
43801
44198
|
const root = repoRoot();
|
|
43802
|
-
const rel = (0,
|
|
43803
|
-
const digest = rel.startsWith("..") || (0,
|
|
44199
|
+
const rel = (0, import_node_path67.relative)(root, (0, import_node_path67.isAbsolute)(file) ? file : (0, import_node_path67.join)(root, file));
|
|
44200
|
+
const digest = rel.startsWith("..") || (0, import_node_path67.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
|
|
43804
44201
|
if (!digest) {
|
|
43805
44202
|
printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
|
|
43806
44203
|
process.exit(2);
|
|
@@ -43834,10 +44231,10 @@ function refreshScaffold(root) {
|
|
|
43834
44231
|
}
|
|
43835
44232
|
|
|
43836
44233
|
// src/commands/lean.ts
|
|
43837
|
-
var
|
|
43838
|
-
var
|
|
43839
|
-
var
|
|
43840
|
-
var
|
|
44234
|
+
var import_node_fs83 = require("node:fs");
|
|
44235
|
+
var import_node_child_process23 = require("node:child_process");
|
|
44236
|
+
var import_node_os14 = require("node:os");
|
|
44237
|
+
var import_node_path68 = require("node:path");
|
|
43841
44238
|
function registerLeanCommand(program2) {
|
|
43842
44239
|
const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
|
|
43843
44240
|
lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
|
|
@@ -43845,7 +44242,7 @@ function registerLeanCommand(program2) {
|
|
|
43845
44242
|
let version = null;
|
|
43846
44243
|
if (tc) {
|
|
43847
44244
|
try {
|
|
43848
|
-
version = (0,
|
|
44245
|
+
version = (0, import_node_child_process23.execFileSync)(tc.lake.replace(/lake(\.exe)?$/, "lean$1"), ["--version"], { env: tc.env, encoding: "utf-8", timeout: 1e4 }).trim();
|
|
43849
44246
|
} catch {
|
|
43850
44247
|
version = null;
|
|
43851
44248
|
}
|
|
@@ -43856,7 +44253,7 @@ function registerLeanCommand(program2) {
|
|
|
43856
44253
|
const bg = readInstallState();
|
|
43857
44254
|
const background = bg ? { ...bg, running: bg.state === "running" && installRunning() } : null;
|
|
43858
44255
|
if (opts.json) {
|
|
43859
|
-
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0,
|
|
44256
|
+
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs83.existsSync)((0, import_node_path68.join)(managed, "bin")), asset: leanAssetName(), background });
|
|
43860
44257
|
return;
|
|
43861
44258
|
}
|
|
43862
44259
|
printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
|
|
@@ -43873,11 +44270,11 @@ function registerLeanCommand(program2) {
|
|
|
43873
44270
|
if (opts.background) process.exit(await runBackgroundInstall());
|
|
43874
44271
|
const asset = leanAssetName();
|
|
43875
44272
|
if (!asset) {
|
|
43876
|
-
printError(`no Lean release for ${(0,
|
|
44273
|
+
printError(`no Lean release for ${(0, import_node_os14.platform)()}/${(0, import_node_os14.arch)()}`);
|
|
43877
44274
|
process.exit(2);
|
|
43878
44275
|
}
|
|
43879
44276
|
const dir = pinnedVersionDir();
|
|
43880
|
-
if ((0,
|
|
44277
|
+
if ((0, import_node_fs83.existsSync)((0, import_node_path68.join)(dir, "bin", "lake")) && !opts.force) {
|
|
43881
44278
|
printInfo(`already installed at ${dir}`);
|
|
43882
44279
|
return;
|
|
43883
44280
|
}
|
|
@@ -43913,18 +44310,21 @@ function registerLeanCommand(program2) {
|
|
|
43913
44310
|
});
|
|
43914
44311
|
lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
|
|
43915
44312
|
const dir = pinnedVersionDir();
|
|
43916
|
-
if (!(0,
|
|
44313
|
+
if (!(0, import_node_fs83.existsSync)(dir)) {
|
|
43917
44314
|
printInfo("nothing to remove");
|
|
43918
44315
|
return;
|
|
43919
44316
|
}
|
|
43920
|
-
(0,
|
|
44317
|
+
(0, import_node_fs83.rmSync)(dir, { recursive: true, force: true });
|
|
43921
44318
|
printInfo(`removed ${dir}`);
|
|
43922
44319
|
});
|
|
43923
44320
|
}
|
|
43924
44321
|
|
|
43925
44322
|
// src/cli.ts
|
|
43926
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.35.0-experimental.
|
|
43927
|
-
|
|
44323
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.35.0-experimental.7c5e75b").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) => {
|
|
44324
|
+
const isTelemetryHelper = actionCommand.name() === "headers" && actionCommand.parent?.name() === "telemetry";
|
|
44325
|
+
if (!isTelemetryHelper) {
|
|
44326
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.35.0-experimental.7c5e75b");
|
|
44327
|
+
}
|
|
43928
44328
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
43929
44329
|
try {
|
|
43930
44330
|
await foldLegacyLocalCredential();
|