@codacy/verity-cli 0.34.0-experimental.37a6dcf → 0.34.0-experimental.3d4888f
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 +464 -394
- package/package.json +1 -1
package/bin/verity.js
CHANGED
|
@@ -10435,13 +10435,13 @@ var require_web_tree_sitter2 = __commonJS2({
|
|
|
10435
10435
|
}
|
|
10436
10436
|
readAsync = /* @__PURE__ */ __name(async (url) => {
|
|
10437
10437
|
if (isFileURI(url)) {
|
|
10438
|
-
return new Promise((
|
|
10438
|
+
return new Promise((resolve9, reject) => {
|
|
10439
10439
|
var xhr = new XMLHttpRequest();
|
|
10440
10440
|
xhr.open("GET", url, true);
|
|
10441
10441
|
xhr.responseType = "arraybuffer";
|
|
10442
10442
|
xhr.onload = () => {
|
|
10443
10443
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
10444
|
-
|
|
10444
|
+
resolve9(xhr.response);
|
|
10445
10445
|
return;
|
|
10446
10446
|
}
|
|
10447
10447
|
reject(xhr.status);
|
|
@@ -10634,9 +10634,9 @@ var require_web_tree_sitter2 = __commonJS2({
|
|
|
10634
10634
|
__name(receiveInstantiationResult, "receiveInstantiationResult");
|
|
10635
10635
|
var info2 = getWasmImports();
|
|
10636
10636
|
if (Module["instantiateWasm"]) {
|
|
10637
|
-
return new Promise((
|
|
10637
|
+
return new Promise((resolve9, reject) => {
|
|
10638
10638
|
Module["instantiateWasm"](info2, (mod, inst) => {
|
|
10639
|
-
|
|
10639
|
+
resolve9(receiveInstance(mod, inst));
|
|
10640
10640
|
});
|
|
10641
10641
|
});
|
|
10642
10642
|
}
|
|
@@ -11969,8 +11969,8 @@ var require_web_tree_sitter2 = __commonJS2({
|
|
|
11969
11969
|
if (runtimeInitialized) {
|
|
11970
11970
|
moduleRtn = Module;
|
|
11971
11971
|
} else {
|
|
11972
|
-
moduleRtn = new Promise((
|
|
11973
|
-
readyPromiseResolve =
|
|
11972
|
+
moduleRtn = new Promise((resolve9, reject) => {
|
|
11973
|
+
readyPromiseResolve = resolve9;
|
|
11974
11974
|
readyPromiseReject = reject;
|
|
11975
11975
|
});
|
|
11976
11976
|
}
|
|
@@ -14447,8 +14447,87 @@ var import_node_child_process4 = require("node:child_process");
|
|
|
14447
14447
|
|
|
14448
14448
|
// src/constants.ts
|
|
14449
14449
|
var import_node_child_process = require("node:child_process");
|
|
14450
|
+
var import_node_fs2 = require("node:fs");
|
|
14451
|
+
var import_node_path2 = require("node:path");
|
|
14452
|
+
|
|
14453
|
+
// src/lib/context-identity.ts
|
|
14454
|
+
var import_node_crypto = require("node:crypto");
|
|
14450
14455
|
var import_node_fs = require("node:fs");
|
|
14456
|
+
var import_node_os = require("node:os");
|
|
14451
14457
|
var import_node_path = require("node:path");
|
|
14458
|
+
var SHARED_SENTINELS = /* @__PURE__ */ new Set([
|
|
14459
|
+
"",
|
|
14460
|
+
"-",
|
|
14461
|
+
"n/a",
|
|
14462
|
+
"na",
|
|
14463
|
+
"none",
|
|
14464
|
+
"null",
|
|
14465
|
+
"undefined",
|
|
14466
|
+
"unknown",
|
|
14467
|
+
"anon",
|
|
14468
|
+
"anonymous",
|
|
14469
|
+
"default",
|
|
14470
|
+
"_default"
|
|
14471
|
+
]);
|
|
14472
|
+
function isSharedSentinel(value) {
|
|
14473
|
+
if (value == null) return true;
|
|
14474
|
+
return SHARED_SENTINELS.has(value.trim().toLowerCase());
|
|
14475
|
+
}
|
|
14476
|
+
var ephemeral = /* @__PURE__ */ new Map();
|
|
14477
|
+
function ephemeralId(slot, width) {
|
|
14478
|
+
let id = ephemeral.get(slot);
|
|
14479
|
+
if (!id) {
|
|
14480
|
+
id = `eph-${(0, import_node_crypto.randomBytes)(Math.ceil(width / 2)).toString("hex").slice(0, width - 4)}`;
|
|
14481
|
+
ephemeral.set(slot, id);
|
|
14482
|
+
}
|
|
14483
|
+
return id;
|
|
14484
|
+
}
|
|
14485
|
+
function contextIdentity(input) {
|
|
14486
|
+
const tokenUsable = !isSharedSentinel(input.token ?? null);
|
|
14487
|
+
const sessionUsable = !isSharedSentinel(input.sessionId ?? null);
|
|
14488
|
+
const userKey = tokenUsable ? (0, import_node_crypto.createHash)("sha256").update(String(input.token)).digest("hex").slice(0, 12) : ephemeralId("user", 12);
|
|
14489
|
+
const sessionKey2 = sessionUsable ? (0, import_node_crypto.createHash)("sha256").update(String(input.sessionId)).digest("hex").slice(0, 16) : ephemeralId("session", 16);
|
|
14490
|
+
let treeKey = "no-tree";
|
|
14491
|
+
const rawTree = input.treeRoot;
|
|
14492
|
+
if (rawTree && !isSharedSentinel(rawTree)) {
|
|
14493
|
+
let resolved = rawTree;
|
|
14494
|
+
try {
|
|
14495
|
+
resolved = import_node_fs.realpathSync.native(rawTree);
|
|
14496
|
+
} catch {
|
|
14497
|
+
}
|
|
14498
|
+
treeKey = (0, import_node_crypto.createHash)("sha256").update(resolved).digest("hex").slice(0, 12);
|
|
14499
|
+
}
|
|
14500
|
+
return {
|
|
14501
|
+
userKey,
|
|
14502
|
+
treeKey,
|
|
14503
|
+
sessionKey: sessionKey2,
|
|
14504
|
+
userKeySource: tokenUsable ? "token" : "ephemeral",
|
|
14505
|
+
sessionKeySource: sessionUsable ? "session_id" : "ephemeral",
|
|
14506
|
+
ephemeral: !tokenUsable || !sessionUsable
|
|
14507
|
+
};
|
|
14508
|
+
}
|
|
14509
|
+
function verityHome() {
|
|
14510
|
+
const override = process.env.VERITY_HOME;
|
|
14511
|
+
return override && override.trim() ? (0, import_node_path.resolve)(override) : (0, import_node_path.join)((0, import_node_os.homedir)(), ".verity");
|
|
14512
|
+
}
|
|
14513
|
+
function dossierDir(identity) {
|
|
14514
|
+
return (0, import_node_path.join)(verityHome(), "sessions", identity.userKey, identity.treeKey, identity.sessionKey);
|
|
14515
|
+
}
|
|
14516
|
+
function treeDir(identity) {
|
|
14517
|
+
return (0, import_node_path.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
|
|
14518
|
+
}
|
|
14519
|
+
function scopeIdentity(token, sessionId) {
|
|
14520
|
+
const t = (token ?? "").trim();
|
|
14521
|
+
const s = (sessionId ?? "").trim();
|
|
14522
|
+
const userKey = t.length > 0 ? (0, import_node_crypto.createHash)("sha256").update(t).digest("hex").slice(0, 12) : "anon";
|
|
14523
|
+
const sessionKey2 = s.length > 0 ? (0, import_node_crypto.createHash)("sha256").update(s).digest("hex").slice(0, 16) : "_default";
|
|
14524
|
+
return { userKey, sessionKey: sessionKey2, bucket: `${userKey}/${sessionKey2}` };
|
|
14525
|
+
}
|
|
14526
|
+
function sessionScopeKey(token, sessionId) {
|
|
14527
|
+
return scopeIdentity(token, sessionId).bucket;
|
|
14528
|
+
}
|
|
14529
|
+
|
|
14530
|
+
// src/constants.ts
|
|
14452
14531
|
var _repoRoot = null;
|
|
14453
14532
|
function repoRoot() {
|
|
14454
14533
|
if (_repoRoot === null) {
|
|
@@ -14476,17 +14555,36 @@ function mainWorktreeRoot() {
|
|
|
14476
14555
|
_mainRoot = null;
|
|
14477
14556
|
return _mainRoot;
|
|
14478
14557
|
}
|
|
14479
|
-
const abs = common.startsWith("/") ? common : (0,
|
|
14480
|
-
_mainRoot = (0,
|
|
14558
|
+
const abs = common.startsWith("/") ? common : (0, import_node_path2.join)(repoRoot(), common);
|
|
14559
|
+
_mainRoot = (0, import_node_path2.dirname)(abs);
|
|
14481
14560
|
} catch {
|
|
14482
14561
|
_mainRoot = null;
|
|
14483
14562
|
}
|
|
14484
14563
|
return _mainRoot;
|
|
14485
14564
|
}
|
|
14486
14565
|
function verityConfigured() {
|
|
14487
|
-
if ((
|
|
14566
|
+
if (isProjectVerityDir((0, import_node_path2.join)(repoRoot(), VERITY_DIR))) return true;
|
|
14488
14567
|
const main = mainWorktreeRoot();
|
|
14489
|
-
return !!main && (
|
|
14568
|
+
return !!main && isProjectVerityDir((0, import_node_path2.join)(main, VERITY_DIR));
|
|
14569
|
+
}
|
|
14570
|
+
function isProjectVerityDir(dir) {
|
|
14571
|
+
return (0, import_node_fs2.existsSync)(dir) && !isMachineStore(dir);
|
|
14572
|
+
}
|
|
14573
|
+
function isMachineStore(dir) {
|
|
14574
|
+
const here = canonicalPath(dir);
|
|
14575
|
+
const stores = [process.env.HOME ? (0, import_node_path2.join)(process.env.HOME, VERITY_DIR) : null, verityHome()];
|
|
14576
|
+
return stores.some((s) => s !== null && canonicalPath(s) === here);
|
|
14577
|
+
}
|
|
14578
|
+
function canonicalPath(p) {
|
|
14579
|
+
try {
|
|
14580
|
+
return import_node_fs2.realpathSync.native(p);
|
|
14581
|
+
} catch {
|
|
14582
|
+
}
|
|
14583
|
+
try {
|
|
14584
|
+
return (0, import_node_path2.join)(import_node_fs2.realpathSync.native((0, import_node_path2.dirname)(p)), (0, import_node_path2.basename)(p));
|
|
14585
|
+
} catch {
|
|
14586
|
+
return (0, import_node_path2.resolve)(p);
|
|
14587
|
+
}
|
|
14490
14588
|
}
|
|
14491
14589
|
var VERITY_DIR = ".verity";
|
|
14492
14590
|
var CREDENTIALS_FILE = `${VERITY_DIR}/credentials`;
|
|
@@ -14507,7 +14605,7 @@ var MEMORY_DIR = `${VERITY_DIR}/memory`;
|
|
|
14507
14605
|
var CODACY_CONFIG_FILE = ".codacy/codacy.config.json";
|
|
14508
14606
|
var VERITYIGNORE_FILE = ".verityignore";
|
|
14509
14607
|
function projectPath(relativePath) {
|
|
14510
|
-
return (0,
|
|
14608
|
+
return (0, import_node_path2.join)(repoRoot(), relativePath);
|
|
14511
14609
|
}
|
|
14512
14610
|
var MAX_DELTA_BYTES = 194560;
|
|
14513
14611
|
var MAX_FILES = 40;
|
|
@@ -14681,7 +14779,7 @@ function printVerbose(msg, verbose) {
|
|
|
14681
14779
|
}
|
|
14682
14780
|
|
|
14683
14781
|
// src/lib/debug-log.ts
|
|
14684
|
-
var
|
|
14782
|
+
var import_node_fs3 = require("node:fs");
|
|
14685
14783
|
function isDebugEnabled() {
|
|
14686
14784
|
const v = process.env.VERITY_DEBUG;
|
|
14687
14785
|
if (v === "0" || v === "false" || v === "off") return false;
|
|
@@ -14699,24 +14797,24 @@ function writeLine(obj) {
|
|
|
14699
14797
|
try {
|
|
14700
14798
|
const dir = projectPath(DEBUG_LOG_DIR);
|
|
14701
14799
|
const file = projectPath(DEBUG_LOG_FILE);
|
|
14702
|
-
(0,
|
|
14800
|
+
(0, import_node_fs3.mkdirSync)(dir, { recursive: true });
|
|
14703
14801
|
rotateIfNeeded(file);
|
|
14704
|
-
(0,
|
|
14802
|
+
(0, import_node_fs3.appendFileSync)(file, JSON.stringify(obj) + "\n");
|
|
14705
14803
|
} catch {
|
|
14706
14804
|
}
|
|
14707
14805
|
}
|
|
14708
14806
|
function rotateIfNeeded(file) {
|
|
14709
14807
|
try {
|
|
14710
|
-
const s = (0,
|
|
14808
|
+
const s = (0, import_node_fs3.statSync)(file);
|
|
14711
14809
|
if (s.size < DEBUG_LOG_MAX_BYTES) return;
|
|
14712
|
-
(0,
|
|
14810
|
+
(0, import_node_fs3.renameSync)(file, `${file}.1`);
|
|
14713
14811
|
} catch {
|
|
14714
14812
|
}
|
|
14715
14813
|
}
|
|
14716
14814
|
|
|
14717
14815
|
// src/lib/credentials.ts
|
|
14718
14816
|
var import_promises = require("node:fs/promises");
|
|
14719
|
-
var
|
|
14817
|
+
var import_node_path3 = require("node:path");
|
|
14720
14818
|
var import_node_child_process2 = require("node:child_process");
|
|
14721
14819
|
function globalCredentialsPath() {
|
|
14722
14820
|
return `${process.env.HOME}/.verity/credentials`;
|
|
@@ -14791,7 +14889,7 @@ async function readGlobalCredential(remote) {
|
|
|
14791
14889
|
}
|
|
14792
14890
|
async function upsertGlobalCredential(remote, rec) {
|
|
14793
14891
|
const path = globalCredentialsPath();
|
|
14794
|
-
await (0, import_promises.mkdir)((0,
|
|
14892
|
+
await (0, import_promises.mkdir)((0, import_node_path3.dirname)(path), { recursive: true });
|
|
14795
14893
|
let content = "";
|
|
14796
14894
|
try {
|
|
14797
14895
|
content = await (0, import_promises.readFile)(path, "utf-8");
|
|
@@ -14935,10 +15033,10 @@ async function foldLegacyLocalCredential(remoteArg) {
|
|
|
14935
15033
|
|
|
14936
15034
|
// src/lib/git.ts
|
|
14937
15035
|
var import_node_child_process3 = require("node:child_process");
|
|
14938
|
-
var
|
|
14939
|
-
var
|
|
15036
|
+
var import_node_fs4 = require("node:fs");
|
|
15037
|
+
var import_node_path4 = require("node:path");
|
|
14940
15038
|
function resolveFile(relpath) {
|
|
14941
|
-
return (0,
|
|
15039
|
+
return (0, import_node_fs4.existsSync)(relpath) ? relpath : null;
|
|
14942
15040
|
}
|
|
14943
15041
|
function execGit(cmd) {
|
|
14944
15042
|
try {
|
|
@@ -14956,7 +15054,7 @@ function readBaselineSha() {
|
|
|
14956
15054
|
if (sha === null) return null;
|
|
14957
15055
|
if (!commitResolves(sha)) {
|
|
14958
15056
|
try {
|
|
14959
|
-
(0,
|
|
15057
|
+
(0, import_node_fs4.unlinkSync)(BASELINE_SHA_FILE);
|
|
14960
15058
|
} catch {
|
|
14961
15059
|
}
|
|
14962
15060
|
return null;
|
|
@@ -14964,10 +15062,10 @@ function readBaselineSha() {
|
|
|
14964
15062
|
return sha;
|
|
14965
15063
|
}
|
|
14966
15064
|
function readRawBaselineSha() {
|
|
14967
|
-
if (!(0,
|
|
15065
|
+
if (!(0, import_node_fs4.existsSync)(BASELINE_SHA_FILE)) return null;
|
|
14968
15066
|
let sha;
|
|
14969
15067
|
try {
|
|
14970
|
-
sha = (0,
|
|
15068
|
+
sha = (0, import_node_fs4.readFileSync)(BASELINE_SHA_FILE, "utf-8").trim();
|
|
14971
15069
|
} catch {
|
|
14972
15070
|
return null;
|
|
14973
15071
|
}
|
|
@@ -14976,8 +15074,8 @@ function readRawBaselineSha() {
|
|
|
14976
15074
|
function writeBaselineSha(sha) {
|
|
14977
15075
|
if (!SHA_RE.test(sha)) return;
|
|
14978
15076
|
try {
|
|
14979
|
-
(0,
|
|
14980
|
-
(0,
|
|
15077
|
+
(0, import_node_fs4.mkdirSync)((0, import_node_path4.dirname)(BASELINE_SHA_FILE), { recursive: true });
|
|
15078
|
+
(0, import_node_fs4.writeFileSync)(BASELINE_SHA_FILE, sha);
|
|
14981
15079
|
} catch {
|
|
14982
15080
|
}
|
|
14983
15081
|
}
|
|
@@ -15065,17 +15163,17 @@ function showContentAtRef(ref, repoRelPath) {
|
|
|
15065
15163
|
}
|
|
15066
15164
|
function filterAnalyzable(files) {
|
|
15067
15165
|
return files.filter((f) => {
|
|
15068
|
-
const ext = (0,
|
|
15166
|
+
const ext = (0, import_node_path4.extname)(f).slice(1);
|
|
15069
15167
|
return ANALYZABLE_EXTENSIONS.has(ext);
|
|
15070
15168
|
});
|
|
15071
15169
|
}
|
|
15072
15170
|
function filterReviewable(files) {
|
|
15073
15171
|
return files.filter((f) => {
|
|
15074
|
-
const ext = (0,
|
|
15172
|
+
const ext = (0, import_node_path4.extname)(f).slice(1);
|
|
15075
15173
|
if (ANALYZABLE_EXTENSIONS.has(ext)) return false;
|
|
15076
15174
|
if (REVIEWABLE_EXTENSIONS.has(ext)) return true;
|
|
15077
|
-
const
|
|
15078
|
-
if (REVIEWABLE_FILENAMES.has(
|
|
15175
|
+
const basename9 = f.split("/").pop() ?? "";
|
|
15176
|
+
if (REVIEWABLE_FILENAMES.has(basename9)) return true;
|
|
15079
15177
|
if (REVIEWABLE_PATH_PATTERNS.some((p) => p.test(f))) return true;
|
|
15080
15178
|
return false;
|
|
15081
15179
|
});
|
|
@@ -15550,7 +15648,7 @@ async function maybeHealServiceUrl(resolution, verbose) {
|
|
|
15550
15648
|
|
|
15551
15649
|
// src/lib/register.ts
|
|
15552
15650
|
var readline = __toESM2(require("node:readline/promises"));
|
|
15553
|
-
var
|
|
15651
|
+
var import_node_os2 = require("node:os");
|
|
15554
15652
|
|
|
15555
15653
|
// src/lib/spinner.ts
|
|
15556
15654
|
var FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
@@ -15638,7 +15736,7 @@ function startSpinner(label2, opts = {}) {
|
|
|
15638
15736
|
}
|
|
15639
15737
|
|
|
15640
15738
|
// src/lib/provider-auth.ts
|
|
15641
|
-
var sleep = (ms) => new Promise((
|
|
15739
|
+
var sleep = (ms) => new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
15642
15740
|
var form = (fields) => new URLSearchParams(fields).toString();
|
|
15643
15741
|
async function githubAccountId(owner) {
|
|
15644
15742
|
try {
|
|
@@ -15903,7 +16001,7 @@ function deviceLabel() {
|
|
|
15903
16001
|
const override = process.env.VERITY_DEVICE_LABEL?.trim();
|
|
15904
16002
|
if (override) return override;
|
|
15905
16003
|
try {
|
|
15906
|
-
return (0,
|
|
16004
|
+
return (0, import_node_os2.hostname)() || void 0;
|
|
15907
16005
|
} catch {
|
|
15908
16006
|
return void 0;
|
|
15909
16007
|
}
|
|
@@ -16061,8 +16159,8 @@ function registerAuthCommands(program2) {
|
|
|
16061
16159
|
}
|
|
16062
16160
|
|
|
16063
16161
|
// src/lib/pending-login.ts
|
|
16064
|
-
var
|
|
16065
|
-
var
|
|
16162
|
+
var import_node_fs5 = require("node:fs");
|
|
16163
|
+
var import_node_path5 = require("node:path");
|
|
16066
16164
|
function pendingLoginPath() {
|
|
16067
16165
|
return `${process.env.HOME}/.verity/pending-login.json`;
|
|
16068
16166
|
}
|
|
@@ -16078,26 +16176,26 @@ function savePendingLogin(dc, serviceUrl, now = Date.now()) {
|
|
|
16078
16176
|
created_at: new Date(now).toISOString()
|
|
16079
16177
|
};
|
|
16080
16178
|
const path = pendingLoginPath();
|
|
16081
|
-
(0,
|
|
16179
|
+
(0, import_node_fs5.mkdirSync)((0, import_node_path5.dirname)(path), { recursive: true });
|
|
16082
16180
|
clearPendingLogin();
|
|
16083
|
-
(0,
|
|
16181
|
+
(0, import_node_fs5.writeFileSync)(path, JSON.stringify(record, null, 2) + "\n", { mode: 384, flag: "wx" });
|
|
16084
16182
|
try {
|
|
16085
|
-
(0,
|
|
16183
|
+
(0, import_node_fs5.chmodSync)(path, 384);
|
|
16086
16184
|
} catch {
|
|
16087
16185
|
}
|
|
16088
16186
|
return record;
|
|
16089
16187
|
}
|
|
16090
16188
|
function readPendingLogin(now = Date.now()) {
|
|
16091
16189
|
const path = pendingLoginPath();
|
|
16092
|
-
if (!(0,
|
|
16190
|
+
if (!(0, import_node_fs5.existsSync)(path)) return { status: "none" };
|
|
16093
16191
|
try {
|
|
16094
|
-
if ((0,
|
|
16192
|
+
if ((0, import_node_fs5.lstatSync)(path).isSymbolicLink()) return { status: "invalid", reason: "it is a symlink" };
|
|
16095
16193
|
} catch {
|
|
16096
16194
|
return { status: "none" };
|
|
16097
16195
|
}
|
|
16098
16196
|
let parsed;
|
|
16099
16197
|
try {
|
|
16100
|
-
parsed = JSON.parse((0,
|
|
16198
|
+
parsed = JSON.parse((0, import_node_fs5.readFileSync)(path, "utf-8"));
|
|
16101
16199
|
} catch {
|
|
16102
16200
|
return { status: "invalid", reason: "it is not valid JSON" };
|
|
16103
16201
|
}
|
|
@@ -16118,7 +16216,7 @@ function readPendingLogin(now = Date.now()) {
|
|
|
16118
16216
|
}
|
|
16119
16217
|
function clearPendingLogin() {
|
|
16120
16218
|
try {
|
|
16121
|
-
(0,
|
|
16219
|
+
(0, import_node_fs5.unlinkSync)(pendingLoginPath());
|
|
16122
16220
|
return true;
|
|
16123
16221
|
} catch {
|
|
16124
16222
|
return false;
|
|
@@ -16674,11 +16772,11 @@ function registerLogoutCommand(program2) {
|
|
|
16674
16772
|
|
|
16675
16773
|
// src/lib/hooks.ts
|
|
16676
16774
|
var import_promises4 = require("node:fs/promises");
|
|
16677
|
-
var
|
|
16775
|
+
var import_node_path7 = require("node:path");
|
|
16678
16776
|
|
|
16679
16777
|
// src/lib/json-file.ts
|
|
16680
16778
|
var import_promises3 = require("node:fs/promises");
|
|
16681
|
-
var
|
|
16779
|
+
var import_node_path6 = require("node:path");
|
|
16682
16780
|
function jsonSemanticEqual(a, b) {
|
|
16683
16781
|
if (a === b) return true;
|
|
16684
16782
|
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
|
|
@@ -16724,7 +16822,7 @@ async function writeJsonFilePreservingStyle(file, value) {
|
|
|
16724
16822
|
const indent = currentRaw !== null ? detectJsonIndent(currentRaw) : 2;
|
|
16725
16823
|
const next = JSON.stringify(value, null, indent) + "\n";
|
|
16726
16824
|
if (next === currentRaw) return false;
|
|
16727
|
-
await (0, import_promises3.mkdir)((0,
|
|
16825
|
+
await (0, import_promises3.mkdir)((0, import_node_path6.dirname)(file), { recursive: true });
|
|
16728
16826
|
await (0, import_promises3.writeFile)(file, next);
|
|
16729
16827
|
return true;
|
|
16730
16828
|
}
|
|
@@ -16909,13 +17007,13 @@ async function writeSettings(settings) {
|
|
|
16909
17007
|
}
|
|
16910
17008
|
async function readSettingsAt(root) {
|
|
16911
17009
|
try {
|
|
16912
|
-
return JSON.parse(await (0, import_promises4.readFile)((0,
|
|
17010
|
+
return JSON.parse(await (0, import_promises4.readFile)((0, import_node_path7.join)(root, CLAUDE_SETTINGS_FILE), "utf-8"));
|
|
16913
17011
|
} catch {
|
|
16914
17012
|
return {};
|
|
16915
17013
|
}
|
|
16916
17014
|
}
|
|
16917
17015
|
async function writeSettingsAt(root, settings) {
|
|
16918
|
-
await writeJsonFilePreservingStyle((0,
|
|
17016
|
+
await writeJsonFilePreservingStyle((0, import_node_path7.join)(root, CLAUDE_SETTINGS_FILE), settings);
|
|
16919
17017
|
}
|
|
16920
17018
|
async function hasLegacyHooksAt(root) {
|
|
16921
17019
|
const settings = await readSettingsAt(root);
|
|
@@ -17104,12 +17202,12 @@ async function applyMomentSelection(moments) {
|
|
|
17104
17202
|
}
|
|
17105
17203
|
|
|
17106
17204
|
// src/lib/project-config.ts
|
|
17107
|
-
var
|
|
17108
|
-
var
|
|
17205
|
+
var import_node_fs7 = require("node:fs");
|
|
17206
|
+
var import_node_path9 = require("node:path");
|
|
17109
17207
|
|
|
17110
17208
|
// src/lib/repo-controlled.ts
|
|
17111
|
-
var
|
|
17112
|
-
var
|
|
17209
|
+
var import_node_fs6 = require("node:fs");
|
|
17210
|
+
var import_node_path8 = require("node:path");
|
|
17113
17211
|
|
|
17114
17212
|
// src/lib/hardened-git.ts
|
|
17115
17213
|
var import_node_child_process5 = require("node:child_process");
|
|
@@ -17190,7 +17288,7 @@ function repoControlled(worktree, rel) {
|
|
|
17190
17288
|
for (let i2 = 1; i2 <= parts2.length; i2++) {
|
|
17191
17289
|
let st;
|
|
17192
17290
|
try {
|
|
17193
|
-
st = (0,
|
|
17291
|
+
st = (0, import_node_fs6.lstatSync)((0, import_node_path8.join)(worktree, ...parts2.slice(0, i2)));
|
|
17194
17292
|
} catch (err2) {
|
|
17195
17293
|
const code = err2?.code;
|
|
17196
17294
|
if (code === "ENOENT" || code === "ENOTDIR") return null;
|
|
@@ -17214,8 +17312,8 @@ function parseMoments(raw) {
|
|
|
17214
17312
|
}
|
|
17215
17313
|
function readConfigFile(path) {
|
|
17216
17314
|
try {
|
|
17217
|
-
if (!(0,
|
|
17218
|
-
const raw = JSON.parse((0,
|
|
17315
|
+
if (!(0, import_node_fs7.existsSync)(path)) return null;
|
|
17316
|
+
const raw = JSON.parse((0, import_node_fs7.readFileSync)(path, "utf-8"));
|
|
17219
17317
|
const moments = Array.isArray(raw.git_moments) ? raw.git_moments.filter(isMoment) : [];
|
|
17220
17318
|
const source2 = raw.git_moments_source === "user" || raw.git_moments_source === "init" ? raw.git_moments_source : void 0;
|
|
17221
17319
|
return {
|
|
@@ -17232,13 +17330,13 @@ function candidates() {
|
|
|
17232
17330
|
const out2 = [{ path: local, source: "local" }];
|
|
17233
17331
|
const main = mainWorktreeRoot();
|
|
17234
17332
|
if (main) {
|
|
17235
|
-
const inherited = (0,
|
|
17333
|
+
const inherited = (0, import_node_path9.join)(main, PROJECT_CONFIG_FILE);
|
|
17236
17334
|
if (inherited !== local) out2.push({ path: inherited, source: "main-worktree" });
|
|
17237
17335
|
}
|
|
17238
17336
|
return out2;
|
|
17239
17337
|
}
|
|
17240
17338
|
function formalRefusal(path) {
|
|
17241
|
-
return repoControlled((0,
|
|
17339
|
+
return repoControlled((0, import_node_path9.dirname)((0, import_node_path9.dirname)(path)), PROJECT_CONFIG_FILE);
|
|
17242
17340
|
}
|
|
17243
17341
|
function readProjectConfigRaw() {
|
|
17244
17342
|
for (const { path, source: source2 } of candidates()) {
|
|
@@ -17274,8 +17372,8 @@ function writeProjectConfig(patch) {
|
|
|
17274
17372
|
...patch
|
|
17275
17373
|
};
|
|
17276
17374
|
const target = projectPath(PROJECT_CONFIG_FILE);
|
|
17277
|
-
(0,
|
|
17278
|
-
(0,
|
|
17375
|
+
(0, import_node_fs7.mkdirSync)((0, import_node_path9.dirname)(target), { recursive: true });
|
|
17376
|
+
(0, import_node_fs7.writeFileSync)(target, JSON.stringify(next, null, 2) + "\n");
|
|
17279
17377
|
return next;
|
|
17280
17378
|
}
|
|
17281
17379
|
function resolveGuardMoments(explicit) {
|
|
@@ -17284,11 +17382,11 @@ function resolveGuardMoments(explicit) {
|
|
|
17284
17382
|
}
|
|
17285
17383
|
|
|
17286
17384
|
// src/lib/plugin-ownership.ts
|
|
17287
|
-
var
|
|
17385
|
+
var import_node_fs10 = require("node:fs");
|
|
17288
17386
|
|
|
17289
17387
|
// src/lib/which.ts
|
|
17290
|
-
var
|
|
17291
|
-
var
|
|
17388
|
+
var import_node_fs8 = require("node:fs");
|
|
17389
|
+
var import_node_path10 = require("node:path");
|
|
17292
17390
|
function executableExtensions(platform4, pathext) {
|
|
17293
17391
|
if (platform4 !== "win32") return [""];
|
|
17294
17392
|
const raw = (pathext ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean);
|
|
@@ -17306,14 +17404,14 @@ function whichSync(bin, opts = {}) {
|
|
|
17306
17404
|
if (!rawPath) return null;
|
|
17307
17405
|
const exts = executableExtensions(platform4, opts.pathext ?? process.env.PATHEXT);
|
|
17308
17406
|
const real = opts.real ?? true;
|
|
17309
|
-
for (const dir of rawPath.split(
|
|
17407
|
+
for (const dir of rawPath.split(import_node_path10.delimiter)) {
|
|
17310
17408
|
if (!dir) continue;
|
|
17311
17409
|
for (const ext of exts) {
|
|
17312
|
-
const candidate = (0,
|
|
17410
|
+
const candidate = (0, import_node_path10.join)(dir, bin + ext);
|
|
17313
17411
|
try {
|
|
17314
|
-
if (!(0,
|
|
17315
|
-
if (platform4 !== "win32") (0,
|
|
17316
|
-
return real ? (0,
|
|
17412
|
+
if (!(0, import_node_fs8.statSync)(candidate).isFile()) continue;
|
|
17413
|
+
if (platform4 !== "win32") (0, import_node_fs8.accessSync)(candidate, import_node_fs8.constants.X_OK);
|
|
17414
|
+
return real ? (0, import_node_fs8.realpathSync)(candidate) : candidate;
|
|
17317
17415
|
} catch {
|
|
17318
17416
|
continue;
|
|
17319
17417
|
}
|
|
@@ -17323,11 +17421,11 @@ function whichSync(bin, opts = {}) {
|
|
|
17323
17421
|
}
|
|
17324
17422
|
|
|
17325
17423
|
// src/lib/plugin-ownership.ts
|
|
17326
|
-
var
|
|
17327
|
-
var
|
|
17424
|
+
var import_node_os3 = require("node:os");
|
|
17425
|
+
var import_node_path11 = require("node:path");
|
|
17328
17426
|
|
|
17329
17427
|
// src/lib/stderr-log.ts
|
|
17330
|
-
var
|
|
17428
|
+
var import_node_fs9 = require("node:fs");
|
|
17331
17429
|
var TOKEN_RE2 = /verity_[0-9a-f]{16,}/g;
|
|
17332
17430
|
var ANSI_RE = /\u001b\[[0-?]*[ -/]*[@-~]/g;
|
|
17333
17431
|
function scrub(s) {
|
|
@@ -17340,9 +17438,9 @@ function append(text) {
|
|
|
17340
17438
|
try {
|
|
17341
17439
|
const dir = projectPath(DEBUG_LOG_DIR);
|
|
17342
17440
|
const file = projectPath(STDERR_LOG_FILE);
|
|
17343
|
-
(0,
|
|
17441
|
+
(0, import_node_fs9.mkdirSync)(dir, { recursive: true });
|
|
17344
17442
|
rotateIfNeeded(file);
|
|
17345
|
-
(0,
|
|
17443
|
+
(0, import_node_fs9.appendFileSync)(file, text);
|
|
17346
17444
|
} catch {
|
|
17347
17445
|
}
|
|
17348
17446
|
}
|
|
@@ -17390,8 +17488,8 @@ function markerPath() {
|
|
|
17390
17488
|
}
|
|
17391
17489
|
function readMarker() {
|
|
17392
17490
|
try {
|
|
17393
|
-
if (!(0,
|
|
17394
|
-
const raw = JSON.parse((0,
|
|
17491
|
+
if (!(0, import_node_fs10.existsSync)(markerPath())) return null;
|
|
17492
|
+
const raw = JSON.parse((0, import_node_fs10.readFileSync)(markerPath(), "utf-8"));
|
|
17395
17493
|
const pluginRoot = typeof raw.plugin_root === "string" ? raw.plugin_root : "";
|
|
17396
17494
|
if (!pluginRoot || CONTROL_CHARS2.test(pluginRoot)) return null;
|
|
17397
17495
|
const version = typeof raw.version === "string" && !CONTROL_CHARS2.test(raw.version) ? raw.version : null;
|
|
@@ -17409,23 +17507,23 @@ function recordPluginOwnership(sessionId) {
|
|
|
17409
17507
|
const pluginRoot = process.env.VERITY_PLUGIN_ROOT;
|
|
17410
17508
|
if (!pluginRoot) return;
|
|
17411
17509
|
try {
|
|
17412
|
-
(0,
|
|
17510
|
+
(0, import_node_fs10.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
|
|
17413
17511
|
const marker = {
|
|
17414
17512
|
session_id: sessionId,
|
|
17415
17513
|
plugin_root: pluginRoot,
|
|
17416
17514
|
version: process.env.VERITY_PLUGIN_VERSION || null,
|
|
17417
17515
|
ts: Math.floor(Date.now() / 1e3)
|
|
17418
17516
|
};
|
|
17419
|
-
(0,
|
|
17517
|
+
(0, import_node_fs10.writeFileSync)(markerPath(), JSON.stringify(marker));
|
|
17420
17518
|
} catch {
|
|
17421
17519
|
}
|
|
17422
17520
|
}
|
|
17423
17521
|
function claudeConfigDir() {
|
|
17424
|
-
return process.env.CLAUDE_CONFIG_DIR || (0,
|
|
17522
|
+
return process.env.CLAUDE_CONFIG_DIR || (0, import_node_path11.join)((0, import_node_os3.homedir)(), ".claude");
|
|
17425
17523
|
}
|
|
17426
17524
|
function readJsonFile(path) {
|
|
17427
17525
|
try {
|
|
17428
|
-
const parsed = JSON.parse((0,
|
|
17526
|
+
const parsed = JSON.parse((0, import_node_fs10.readFileSync)(path, "utf-8"));
|
|
17429
17527
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
17430
17528
|
} catch {
|
|
17431
17529
|
return null;
|
|
@@ -17433,9 +17531,9 @@ function readJsonFile(path) {
|
|
|
17433
17531
|
}
|
|
17434
17532
|
function enabledPluginSetting(key) {
|
|
17435
17533
|
const files = [
|
|
17436
|
-
projectPath((0,
|
|
17437
|
-
projectPath((0,
|
|
17438
|
-
(0,
|
|
17534
|
+
projectPath((0, import_node_path11.join)(".claude", "settings.local.json")),
|
|
17535
|
+
projectPath((0, import_node_path11.join)(".claude", "settings.json")),
|
|
17536
|
+
(0, import_node_path11.join)(claudeConfigDir(), "settings.json")
|
|
17439
17537
|
];
|
|
17440
17538
|
for (const file of files) {
|
|
17441
17539
|
const map = readJsonFile(file)?.enabledPlugins;
|
|
@@ -17447,11 +17545,11 @@ function enabledPluginSetting(key) {
|
|
|
17447
17545
|
}
|
|
17448
17546
|
function marketplaceLocations() {
|
|
17449
17547
|
const out2 = /* @__PURE__ */ new Map();
|
|
17450
|
-
const known = readJsonFile((0,
|
|
17548
|
+
const known = readJsonFile((0, import_node_path11.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
|
|
17451
17549
|
if (!known) return out2;
|
|
17452
17550
|
for (const [name2, entry] of Object.entries(known)) {
|
|
17453
17551
|
const loc2 = entry?.installLocation;
|
|
17454
|
-
if (typeof loc2 === "string" && loc2) out2.set(name2, (0,
|
|
17552
|
+
if (typeof loc2 === "string" && loc2) out2.set(name2, (0, import_node_path11.resolve)(loc2));
|
|
17455
17553
|
}
|
|
17456
17554
|
return out2;
|
|
17457
17555
|
}
|
|
@@ -17465,7 +17563,7 @@ function globalVerityVersion() {
|
|
|
17465
17563
|
const entry = verityPathEntry();
|
|
17466
17564
|
if (!entry) return null;
|
|
17467
17565
|
try {
|
|
17468
|
-
const pkg = readJsonFile((0,
|
|
17566
|
+
const pkg = readJsonFile((0, import_node_path11.join)((0, import_node_path11.dirname)((0, import_node_fs10.realpathSync)(entry)), "..", "package.json"));
|
|
17469
17567
|
if (pkg?.name !== "@codacy/verity-cli" || typeof pkg.version !== "string") return null;
|
|
17470
17568
|
return pkg.version;
|
|
17471
17569
|
} catch {
|
|
@@ -17482,7 +17580,7 @@ var VERITY_MARKETPLACE_REPO = "codacy/verity";
|
|
|
17482
17580
|
function marketplaceConflict() {
|
|
17483
17581
|
const wanted = VERITY_MARKETPLACE;
|
|
17484
17582
|
for (const file of ["settings.json", "settings.local.json"]) {
|
|
17485
|
-
const path = (0,
|
|
17583
|
+
const path = (0, import_node_path11.join)(claudeConfigDir(), file);
|
|
17486
17584
|
const declared = readJsonFile(path)?.extraKnownMarketplaces ?? null;
|
|
17487
17585
|
const entry2 = declared && typeof declared === "object" ? declared[wanted] : void 0;
|
|
17488
17586
|
if (entry2 && typeof entry2 === "object") {
|
|
@@ -17492,7 +17590,7 @@ function marketplaceConflict() {
|
|
|
17492
17590
|
}
|
|
17493
17591
|
}
|
|
17494
17592
|
}
|
|
17495
|
-
const known = readJsonFile((0,
|
|
17593
|
+
const known = readJsonFile((0, import_node_path11.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
|
|
17496
17594
|
const entry = known?.[wanted];
|
|
17497
17595
|
if (entry && typeof entry === "object" && !pointsAtVerity(entry.source)) {
|
|
17498
17596
|
return { name: wanted, declaredAs: describeSource(entry.source) };
|
|
@@ -17513,7 +17611,7 @@ function describeSource(src) {
|
|
|
17513
17611
|
return target ? `${kind} \u2192 ${target}` : kind;
|
|
17514
17612
|
}
|
|
17515
17613
|
function legacyMarketplaceInstall() {
|
|
17516
|
-
const plugins = readJsonFile((0,
|
|
17614
|
+
const plugins = readJsonFile((0, import_node_path11.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17517
17615
|
if (!plugins || typeof plugins !== "object") return null;
|
|
17518
17616
|
for (const key of Object.keys(plugins)) {
|
|
17519
17617
|
const at = key.lastIndexOf("@");
|
|
@@ -17525,13 +17623,13 @@ function legacyMarketplaceInstall() {
|
|
|
17525
17623
|
}
|
|
17526
17624
|
function realpathOr(p) {
|
|
17527
17625
|
try {
|
|
17528
|
-
return
|
|
17626
|
+
return import_node_fs10.realpathSync.native(p);
|
|
17529
17627
|
} catch {
|
|
17530
|
-
return (0,
|
|
17628
|
+
return (0, import_node_path11.resolve)(p);
|
|
17531
17629
|
}
|
|
17532
17630
|
}
|
|
17533
17631
|
function isWithin(want, dir) {
|
|
17534
|
-
return want === dir || want.startsWith(dir +
|
|
17632
|
+
return want === dir || want.startsWith(dir + import_node_path11.sep);
|
|
17535
17633
|
}
|
|
17536
17634
|
function entryAppliesHere(entry, here) {
|
|
17537
17635
|
const e = entry;
|
|
@@ -17541,9 +17639,9 @@ function entryAppliesHere(entry, here) {
|
|
|
17541
17639
|
return forProject === here;
|
|
17542
17640
|
}
|
|
17543
17641
|
function registrySays(pluginRoot) {
|
|
17544
|
-
const plugins = readJsonFile((0,
|
|
17642
|
+
const plugins = readJsonFile((0, import_node_path11.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17545
17643
|
if (!plugins || typeof plugins !== "object") return "unverified";
|
|
17546
|
-
const want = (0,
|
|
17644
|
+
const want = (0, import_node_path11.resolve)(pluginRoot);
|
|
17547
17645
|
const here = realpathOr(repoRoot());
|
|
17548
17646
|
const markets = marketplaceLocations();
|
|
17549
17647
|
for (const [key, value] of Object.entries(plugins)) {
|
|
@@ -17552,15 +17650,15 @@ function registrySays(pluginRoot) {
|
|
|
17552
17650
|
const applicable = (Array.isArray(value) ? value : []).filter((entry) => entryAppliesHere(entry, here));
|
|
17553
17651
|
const claims = applicable.some((entry) => {
|
|
17554
17652
|
const installPath = entry?.installPath;
|
|
17555
|
-
return typeof installPath === "string" && (0,
|
|
17653
|
+
return typeof installPath === "string" && (0, import_node_path11.resolve)(installPath) === want;
|
|
17556
17654
|
}) || source2 !== void 0 && applicable.length > 0 && isWithin(want, source2);
|
|
17557
17655
|
if (claims) {
|
|
17558
17656
|
if (enabledPluginSetting(key) === false) return "gone";
|
|
17559
|
-
return (0,
|
|
17657
|
+
return (0, import_node_fs10.existsSync)(pluginRoot) ? "live" : "gone";
|
|
17560
17658
|
}
|
|
17561
17659
|
}
|
|
17562
|
-
const managed = (0,
|
|
17563
|
-
return want === managed || want.startsWith(managed +
|
|
17660
|
+
const managed = (0, import_node_path11.resolve)((0, import_node_path11.join)(claudeConfigDir(), "plugins", "cache"));
|
|
17661
|
+
return want === managed || want.startsWith(managed + import_node_path11.sep) ? "gone" : "unverified";
|
|
17564
17662
|
}
|
|
17565
17663
|
var _live = /* @__PURE__ */ new Map();
|
|
17566
17664
|
function pluginLiveness(pluginRoot) {
|
|
@@ -17574,7 +17672,7 @@ function clearStalePluginMarker() {
|
|
|
17574
17672
|
const marker = readMarker();
|
|
17575
17673
|
if (!marker || pluginLiveness(marker.plugin_root) !== "gone") return null;
|
|
17576
17674
|
try {
|
|
17577
|
-
(0,
|
|
17675
|
+
(0, import_node_fs10.rmSync)(markerPath(), { force: true });
|
|
17578
17676
|
} catch {
|
|
17579
17677
|
return null;
|
|
17580
17678
|
}
|
|
@@ -17602,7 +17700,7 @@ function pluginActiveHere() {
|
|
|
17602
17700
|
return activePluginInstall() !== null;
|
|
17603
17701
|
}
|
|
17604
17702
|
function registeredVerityPlugin() {
|
|
17605
|
-
const plugins = readJsonFile((0,
|
|
17703
|
+
const plugins = readJsonFile((0, import_node_path11.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17606
17704
|
if (!plugins || typeof plugins !== "object") return null;
|
|
17607
17705
|
const here = realpathOr(repoRoot());
|
|
17608
17706
|
for (const [key, value] of Object.entries(plugins)) {
|
|
@@ -17612,7 +17710,7 @@ function registeredVerityPlugin() {
|
|
|
17612
17710
|
for (const entry of Array.isArray(value) ? value : []) {
|
|
17613
17711
|
const e = entry;
|
|
17614
17712
|
const installPath = typeof e.installPath === "string" ? e.installPath : "";
|
|
17615
|
-
if (!installPath || !(0,
|
|
17713
|
+
if (!installPath || !(0, import_node_fs10.existsSync)(installPath)) continue;
|
|
17616
17714
|
if (!entryAppliesHere(entry, here)) continue;
|
|
17617
17715
|
return { pluginRoot: installPath, version: typeof e.version === "string" ? e.version : null };
|
|
17618
17716
|
}
|
|
@@ -17664,28 +17762,28 @@ async function resolveHookWiring() {
|
|
|
17664
17762
|
}
|
|
17665
17763
|
|
|
17666
17764
|
// src/lib/cli-provenance.ts
|
|
17667
|
-
var
|
|
17668
|
-
var
|
|
17669
|
-
var
|
|
17765
|
+
var import_node_fs11 = require("node:fs");
|
|
17766
|
+
var import_node_os4 = require("node:os");
|
|
17767
|
+
var import_node_path12 = require("node:path");
|
|
17670
17768
|
var CLI_PACKAGE = "@codacy/verity-cli";
|
|
17671
|
-
var CLI_ENTRY = (0,
|
|
17769
|
+
var CLI_ENTRY = (0, import_node_path12.join)("node_modules", CLI_PACKAGE, "bin", "verity.js");
|
|
17672
17770
|
function readJson(path) {
|
|
17673
17771
|
try {
|
|
17674
|
-
const parsed = JSON.parse((0,
|
|
17772
|
+
const parsed = JSON.parse((0, import_node_fs11.readFileSync)(path, "utf-8"));
|
|
17675
17773
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
17676
17774
|
} catch {
|
|
17677
17775
|
return null;
|
|
17678
17776
|
}
|
|
17679
17777
|
}
|
|
17680
17778
|
function versionUnder(base) {
|
|
17681
|
-
const entry = (0,
|
|
17682
|
-
if (!(0,
|
|
17683
|
-
const pkg = readJson((0,
|
|
17779
|
+
const entry = (0, import_node_path12.join)(base, CLI_ENTRY);
|
|
17780
|
+
if (!(0, import_node_fs11.existsSync)(entry)) return null;
|
|
17781
|
+
const pkg = readJson((0, import_node_path12.join)(base, "node_modules", CLI_PACKAGE, "package.json"));
|
|
17684
17782
|
return typeof pkg?.version === "string" ? pkg.version : null;
|
|
17685
17783
|
}
|
|
17686
17784
|
function versionForEntry(entry) {
|
|
17687
17785
|
try {
|
|
17688
|
-
const pkg = readJson((0,
|
|
17786
|
+
const pkg = readJson((0, import_node_path12.join)((0, import_node_path12.dirname)((0, import_node_fs11.realpathSync)(entry)), "..", "package.json"));
|
|
17689
17787
|
return typeof pkg?.version === "string" ? pkg.version : null;
|
|
17690
17788
|
} catch {
|
|
17691
17789
|
return null;
|
|
@@ -17693,16 +17791,16 @@ function versionForEntry(entry) {
|
|
|
17693
17791
|
}
|
|
17694
17792
|
function resolveHooksCli(pluginRoot) {
|
|
17695
17793
|
const override = process.env.VERITY_CLI_PATH;
|
|
17696
|
-
if (override && (0,
|
|
17794
|
+
if (override && (0, import_node_fs11.existsSync)(override)) {
|
|
17697
17795
|
return { version: versionForEntry(override), rung: "override" };
|
|
17698
17796
|
}
|
|
17699
17797
|
const fromPlugin = versionUnder(pluginRoot);
|
|
17700
17798
|
if (fromPlugin !== null) return { version: fromPlugin, rung: "plugin" };
|
|
17701
|
-
if ((0,
|
|
17702
|
-
const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0,
|
|
17799
|
+
if ((0, import_node_fs11.existsSync)((0, import_node_path12.join)(pluginRoot, CLI_ENTRY))) return { version: null, rung: "plugin" };
|
|
17800
|
+
const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0, import_node_path12.join)((0, import_node_os4.homedir)(), ".verity", "plugin-cli");
|
|
17703
17801
|
const fromData = versionUnder(dataDir);
|
|
17704
17802
|
if (fromData !== null) return { version: fromData, rung: "plugin-data" };
|
|
17705
|
-
if ((0,
|
|
17803
|
+
if ((0, import_node_fs11.existsSync)((0, import_node_path12.join)(dataDir, CLI_ENTRY))) return { version: null, rung: "plugin-data" };
|
|
17706
17804
|
const global = globalVerityVersion();
|
|
17707
17805
|
if (global !== null) return { version: global, rung: "global" };
|
|
17708
17806
|
return null;
|
|
@@ -17804,7 +17902,7 @@ function pluginCliInvocation() {
|
|
|
17804
17902
|
return resolverCommand(root);
|
|
17805
17903
|
}
|
|
17806
17904
|
function resolverCommand(root) {
|
|
17807
|
-
return `node ${JSON.stringify((0,
|
|
17905
|
+
return `node ${JSON.stringify((0, import_node_path12.join)(root, "scripts", "verity.mjs"))}`;
|
|
17808
17906
|
}
|
|
17809
17907
|
|
|
17810
17908
|
// src/commands/hooks.ts
|
|
@@ -17940,18 +18038,18 @@ function registerHooksCommands(program2) {
|
|
|
17940
18038
|
}
|
|
17941
18039
|
|
|
17942
18040
|
// src/commands/intent.ts
|
|
17943
|
-
var
|
|
18041
|
+
var import_node_crypto10 = require("node:crypto");
|
|
17944
18042
|
|
|
17945
18043
|
// src/lib/conversation-buffer.ts
|
|
17946
18044
|
var import_promises5 = require("node:fs/promises");
|
|
17947
|
-
var
|
|
18045
|
+
var import_node_fs12 = require("node:fs");
|
|
17948
18046
|
var import_node_child_process6 = require("node:child_process");
|
|
17949
|
-
var
|
|
18047
|
+
var import_node_crypto2 = require("node:crypto");
|
|
17950
18048
|
function stripImageReferences(text) {
|
|
17951
18049
|
return text.replace(/\[Image #\d+\]/g, "[screenshot \u2014 not available for review]");
|
|
17952
18050
|
}
|
|
17953
18051
|
function bufferTmpPath() {
|
|
17954
|
-
return `${CONVERSATION_BUFFER_FILE}.${process.pid}.${(0,
|
|
18052
|
+
return `${CONVERSATION_BUFFER_FILE}.${process.pid}.${(0, import_node_crypto2.randomBytes)(4).toString("hex")}.tmp`;
|
|
17955
18053
|
}
|
|
17956
18054
|
async function appendToConversationBuffer(prompt, sessionId) {
|
|
17957
18055
|
try {
|
|
@@ -17980,7 +18078,7 @@ async function appendToConversationBuffer(prompt, sessionId) {
|
|
|
17980
18078
|
}
|
|
17981
18079
|
async function readAndClearConversationBuffer(currentSessionId) {
|
|
17982
18080
|
try {
|
|
17983
|
-
if ((0,
|
|
18081
|
+
if ((0, import_node_fs12.existsSync)(CONVERSATION_BUFFER_FILE)) {
|
|
17984
18082
|
const entries = await readBufferEntries();
|
|
17985
18083
|
let mine = entries;
|
|
17986
18084
|
let others = [];
|
|
@@ -18004,7 +18102,7 @@ async function readAndClearConversationBuffer(currentSessionId) {
|
|
|
18004
18102
|
};
|
|
18005
18103
|
}
|
|
18006
18104
|
}
|
|
18007
|
-
if ((0,
|
|
18105
|
+
if ((0, import_node_fs12.existsSync)(INTENT_FILE)) {
|
|
18008
18106
|
try {
|
|
18009
18107
|
const content = await (0, import_promises5.readFile)(INTENT_FILE, "utf-8");
|
|
18010
18108
|
await (0, import_promises5.unlink)(INTENT_FILE).catch(() => {
|
|
@@ -18295,83 +18393,6 @@ function isCommandOnlyTurn(input) {
|
|
|
18295
18393
|
return commands.every(isNonAuthoringCommand);
|
|
18296
18394
|
}
|
|
18297
18395
|
|
|
18298
|
-
// src/lib/context-identity.ts
|
|
18299
|
-
var import_node_crypto2 = require("node:crypto");
|
|
18300
|
-
var import_node_fs12 = require("node:fs");
|
|
18301
|
-
var import_node_os4 = require("node:os");
|
|
18302
|
-
var import_node_path12 = require("node:path");
|
|
18303
|
-
var SHARED_SENTINELS = /* @__PURE__ */ new Set([
|
|
18304
|
-
"",
|
|
18305
|
-
"-",
|
|
18306
|
-
"n/a",
|
|
18307
|
-
"na",
|
|
18308
|
-
"none",
|
|
18309
|
-
"null",
|
|
18310
|
-
"undefined",
|
|
18311
|
-
"unknown",
|
|
18312
|
-
"anon",
|
|
18313
|
-
"anonymous",
|
|
18314
|
-
"default",
|
|
18315
|
-
"_default"
|
|
18316
|
-
]);
|
|
18317
|
-
function isSharedSentinel(value) {
|
|
18318
|
-
if (value == null) return true;
|
|
18319
|
-
return SHARED_SENTINELS.has(value.trim().toLowerCase());
|
|
18320
|
-
}
|
|
18321
|
-
var ephemeral = /* @__PURE__ */ new Map();
|
|
18322
|
-
function ephemeralId(slot, width) {
|
|
18323
|
-
let id = ephemeral.get(slot);
|
|
18324
|
-
if (!id) {
|
|
18325
|
-
id = `eph-${(0, import_node_crypto2.randomBytes)(Math.ceil(width / 2)).toString("hex").slice(0, width - 4)}`;
|
|
18326
|
-
ephemeral.set(slot, id);
|
|
18327
|
-
}
|
|
18328
|
-
return id;
|
|
18329
|
-
}
|
|
18330
|
-
function contextIdentity(input) {
|
|
18331
|
-
const tokenUsable = !isSharedSentinel(input.token ?? null);
|
|
18332
|
-
const sessionUsable = !isSharedSentinel(input.sessionId ?? null);
|
|
18333
|
-
const userKey = tokenUsable ? (0, import_node_crypto2.createHash)("sha256").update(String(input.token)).digest("hex").slice(0, 12) : ephemeralId("user", 12);
|
|
18334
|
-
const sessionKey2 = sessionUsable ? (0, import_node_crypto2.createHash)("sha256").update(String(input.sessionId)).digest("hex").slice(0, 16) : ephemeralId("session", 16);
|
|
18335
|
-
let treeKey = "no-tree";
|
|
18336
|
-
const rawTree = input.treeRoot;
|
|
18337
|
-
if (rawTree && !isSharedSentinel(rawTree)) {
|
|
18338
|
-
let resolved = rawTree;
|
|
18339
|
-
try {
|
|
18340
|
-
resolved = import_node_fs12.realpathSync.native(rawTree);
|
|
18341
|
-
} catch {
|
|
18342
|
-
}
|
|
18343
|
-
treeKey = (0, import_node_crypto2.createHash)("sha256").update(resolved).digest("hex").slice(0, 12);
|
|
18344
|
-
}
|
|
18345
|
-
return {
|
|
18346
|
-
userKey,
|
|
18347
|
-
treeKey,
|
|
18348
|
-
sessionKey: sessionKey2,
|
|
18349
|
-
userKeySource: tokenUsable ? "token" : "ephemeral",
|
|
18350
|
-
sessionKeySource: sessionUsable ? "session_id" : "ephemeral",
|
|
18351
|
-
ephemeral: !tokenUsable || !sessionUsable
|
|
18352
|
-
};
|
|
18353
|
-
}
|
|
18354
|
-
function verityHome() {
|
|
18355
|
-
const override = process.env.VERITY_HOME;
|
|
18356
|
-
return override && override.trim() ? (0, import_node_path12.resolve)(override) : (0, import_node_path12.join)((0, import_node_os4.homedir)(), ".verity");
|
|
18357
|
-
}
|
|
18358
|
-
function dossierDir(identity) {
|
|
18359
|
-
return (0, import_node_path12.join)(verityHome(), "sessions", identity.userKey, identity.treeKey, identity.sessionKey);
|
|
18360
|
-
}
|
|
18361
|
-
function treeDir(identity) {
|
|
18362
|
-
return (0, import_node_path12.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
|
|
18363
|
-
}
|
|
18364
|
-
function scopeIdentity(token, sessionId) {
|
|
18365
|
-
const t = (token ?? "").trim();
|
|
18366
|
-
const s = (sessionId ?? "").trim();
|
|
18367
|
-
const userKey = t.length > 0 ? (0, import_node_crypto2.createHash)("sha256").update(t).digest("hex").slice(0, 12) : "anon";
|
|
18368
|
-
const sessionKey2 = s.length > 0 ? (0, import_node_crypto2.createHash)("sha256").update(s).digest("hex").slice(0, 16) : "_default";
|
|
18369
|
-
return { userKey, sessionKey: sessionKey2, bucket: `${userKey}/${sessionKey2}` };
|
|
18370
|
-
}
|
|
18371
|
-
function sessionScopeKey(token, sessionId) {
|
|
18372
|
-
return scopeIdentity(token, sessionId).bucket;
|
|
18373
|
-
}
|
|
18374
|
-
|
|
18375
18396
|
// src/lib/task-context-buffer.ts
|
|
18376
18397
|
var import_promises6 = require("node:fs/promises");
|
|
18377
18398
|
var import_node_fs13 = require("node:fs");
|
|
@@ -20544,7 +20565,7 @@ Body content (\u22648KB). Use [[node-id]] wikilinks for cross-references.
|
|
|
20544
20565
|
|
|
20545
20566
|
// src/lib/dossier-session.ts
|
|
20546
20567
|
var import_node_fs26 = require("node:fs");
|
|
20547
|
-
var
|
|
20568
|
+
var import_node_crypto9 = require("node:crypto");
|
|
20548
20569
|
var import_node_path22 = require("node:path");
|
|
20549
20570
|
|
|
20550
20571
|
// src/lib/pending-repeat.ts
|
|
@@ -20621,6 +20642,7 @@ function isRepeatOfAny(text, priorFingerprints, threshold = REPEAT_THRESHOLD) {
|
|
|
20621
20642
|
}
|
|
20622
20643
|
|
|
20623
20644
|
// src/lib/dossier/bounds.ts
|
|
20645
|
+
var import_node_crypto5 = require("node:crypto");
|
|
20624
20646
|
var MAX_LINE_BYTES = 4096;
|
|
20625
20647
|
var MAX_GOAL_CHARS = 2e3;
|
|
20626
20648
|
var GOAL_KEEP = 8;
|
|
@@ -20632,10 +20654,17 @@ var NOT_MINE_CAP = 300;
|
|
|
20632
20654
|
var STATEMENTS_OPEN_CAP = 40;
|
|
20633
20655
|
var COMMANDS_CAP = 12;
|
|
20634
20656
|
var DIVERGENCE_CAP = 10;
|
|
20635
|
-
var
|
|
20657
|
+
var DIVERGENCE_BULK_AT = 300;
|
|
20658
|
+
var DIVERGENCE_KEYS_PER_LINE = 200;
|
|
20636
20659
|
function divergenceKey(path, hash) {
|
|
20637
20660
|
return `${path}@${hash ?? "unknown"}`;
|
|
20638
20661
|
}
|
|
20662
|
+
function packedDivergenceDigest(key) {
|
|
20663
|
+
return (0, import_node_crypto5.createHash)("sha256").update(key).digest("hex").slice(0, 12);
|
|
20664
|
+
}
|
|
20665
|
+
function packedDivergenceKey(digest) {
|
|
20666
|
+
return `#${digest}`;
|
|
20667
|
+
}
|
|
20639
20668
|
var MARKS_CAP = 50;
|
|
20640
20669
|
var ROTATE_BYTES = 1048576;
|
|
20641
20670
|
var ROTATE_KEEP = 2;
|
|
@@ -20649,7 +20678,7 @@ function statementAnchorKey(file, patternId) {
|
|
|
20649
20678
|
}
|
|
20650
20679
|
|
|
20651
20680
|
// src/lib/dossier/log.ts
|
|
20652
|
-
var
|
|
20681
|
+
var import_node_crypto6 = require("node:crypto");
|
|
20653
20682
|
var import_node_fs22 = require("node:fs");
|
|
20654
20683
|
var import_node_path20 = require("node:path");
|
|
20655
20684
|
var CRC_TABLE = (() => {
|
|
@@ -20691,7 +20720,7 @@ function nextSeq() {
|
|
|
20691
20720
|
function encodeEvent(ev) {
|
|
20692
20721
|
const full = {
|
|
20693
20722
|
v: 1,
|
|
20694
|
-
id: (0,
|
|
20723
|
+
id: (0, import_node_crypto6.randomBytes)(4).toString("hex"),
|
|
20695
20724
|
...ev
|
|
20696
20725
|
};
|
|
20697
20726
|
let body2 = JSON.stringify(full);
|
|
@@ -20762,7 +20791,7 @@ function rotateIfNeeded2(d) {
|
|
|
20762
20791
|
}
|
|
20763
20792
|
|
|
20764
20793
|
// src/lib/dossier/fold-dossier.ts
|
|
20765
|
-
var
|
|
20794
|
+
var import_node_crypto7 = require("node:crypto");
|
|
20766
20795
|
var import_node_fs23 = require("node:fs");
|
|
20767
20796
|
var import_node_path21 = require("node:path");
|
|
20768
20797
|
var EMPTY_CAPABILITIES = () => ({
|
|
@@ -20854,7 +20883,7 @@ function reduce(state, events, now) {
|
|
|
20854
20883
|
state.meta.seq = Math.max(state.meta.seq, ev.seq);
|
|
20855
20884
|
switch (ev.k) {
|
|
20856
20885
|
case "goal": {
|
|
20857
|
-
const hash = (0,
|
|
20886
|
+
const hash = (0, import_node_crypto7.createHash)("sha256").update(ev.text).digest("hex").slice(0, 16);
|
|
20858
20887
|
const prev = state.goal[state.goal.length - 1];
|
|
20859
20888
|
if (prev && prev.hash === hash) {
|
|
20860
20889
|
prev.repeats = (prev.repeats ?? 0) + 1;
|
|
@@ -20982,12 +21011,13 @@ function reduce(state, events, now) {
|
|
|
20982
21011
|
break;
|
|
20983
21012
|
}
|
|
20984
21013
|
case "divergence": {
|
|
20985
|
-
state.divergence.counts[ev.kind] = (state.divergence.counts[ev.kind] ?? 0) + 1;
|
|
20986
21014
|
state.divergence.events.push({ kind: ev.kind, path: ev.path, at: ev.at });
|
|
20987
|
-
const
|
|
20988
|
-
|
|
21015
|
+
const keys = Array.isArray(ev.keys) ? ev.keys.filter((k) => typeof k === "string").map(packedDivergenceKey) : [divergenceKey(ev.path, ev.hash ?? null)];
|
|
21016
|
+
for (const key of keys) {
|
|
21017
|
+
if (seenDivergence.has(key)) continue;
|
|
20989
21018
|
seenDivergence.add(key);
|
|
20990
|
-
|
|
21019
|
+
state.divergence.seen.push(key);
|
|
21020
|
+
state.divergence.counts[ev.kind] = (state.divergence.counts[ev.kind] ?? 0) + 1;
|
|
20991
21021
|
}
|
|
20992
21022
|
break;
|
|
20993
21023
|
}
|
|
@@ -21294,14 +21324,14 @@ function assessContinuity(i2) {
|
|
|
21294
21324
|
}
|
|
21295
21325
|
|
|
21296
21326
|
// src/lib/dossier/reanchor.ts
|
|
21297
|
-
var
|
|
21327
|
+
var import_node_crypto8 = require("node:crypto");
|
|
21298
21328
|
var import_node_fs25 = require("node:fs");
|
|
21299
21329
|
function lineSha(text) {
|
|
21300
|
-
return (0,
|
|
21330
|
+
return (0, import_node_crypto8.createHash)("sha256").update(text.trim()).digest("hex").slice(0, HASH_WIDTH);
|
|
21301
21331
|
}
|
|
21302
21332
|
function fileHash(path) {
|
|
21303
21333
|
try {
|
|
21304
|
-
return (0,
|
|
21334
|
+
return (0, import_node_crypto8.createHash)("sha256").update((0, import_node_fs25.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
|
|
21305
21335
|
} catch {
|
|
21306
21336
|
return null;
|
|
21307
21337
|
}
|
|
@@ -21798,7 +21828,7 @@ function recordTurn(d, t) {
|
|
|
21798
21828
|
// Identity is the COMMAND, not its category — otherwise `npm test -- a` and
|
|
21799
21829
|
// `npm test -- b` are one row and the streak counts two different commands
|
|
21800
21830
|
// as a run of one.
|
|
21801
|
-
cmd_hash: (0,
|
|
21831
|
+
cmd_hash: (0, import_node_crypto9.createHash)("sha256").update(c.head || c.class).digest("hex").slice(0, 12),
|
|
21802
21832
|
head: c.head || c.class,
|
|
21803
21833
|
status: toStatus(c.last_status)
|
|
21804
21834
|
});
|
|
@@ -21816,10 +21846,23 @@ function recordTurn(d, t) {
|
|
|
21816
21846
|
}
|
|
21817
21847
|
}
|
|
21818
21848
|
const seenDivergence = t.known?.divergence ?? /* @__PURE__ */ new Set();
|
|
21849
|
+
const fresh = [];
|
|
21819
21850
|
for (const u of t.unobserved) {
|
|
21820
21851
|
const hash = fileHash((0, import_node_path22.join)(root, u.p));
|
|
21821
|
-
|
|
21822
|
-
|
|
21852
|
+
const key = divergenceKey(u.p, hash);
|
|
21853
|
+
const digest = packedDivergenceDigest(key);
|
|
21854
|
+
if (seenDivergence.has(key) || seenDivergence.has(packedDivergenceKey(digest))) continue;
|
|
21855
|
+
fresh.push({ path: u.p, hash, digest });
|
|
21856
|
+
}
|
|
21857
|
+
if (fresh.length > DIVERGENCE_BULK_AT) {
|
|
21858
|
+
for (let i2 = 0; i2 < fresh.length; i2 += DIVERGENCE_KEYS_PER_LINE) {
|
|
21859
|
+
const slice2 = fresh.slice(i2, i2 + DIVERGENCE_KEYS_PER_LINE);
|
|
21860
|
+
appendEvent(d, { k: "divergence", kind: "external_mutation", path: slice2[0].path, keys: slice2.map((f) => f.digest) });
|
|
21861
|
+
}
|
|
21862
|
+
} else {
|
|
21863
|
+
for (const f of fresh) {
|
|
21864
|
+
appendEvent(d, { k: "divergence", kind: "external_mutation", path: f.path, hash: f.hash });
|
|
21865
|
+
}
|
|
21823
21866
|
}
|
|
21824
21867
|
const newCompactions = (t.compactions ?? 0) - (t.known?.compactions ?? 0);
|
|
21825
21868
|
for (let i2 = 0; i2 < newCompactions; i2++) {
|
|
@@ -22084,7 +22127,7 @@ async function fireClassify(prompt, sessionId, globals) {
|
|
|
22084
22127
|
logEvent("classify_skipped", { reason: "no_service_url", detail: urlResult.error });
|
|
22085
22128
|
return;
|
|
22086
22129
|
}
|
|
22087
|
-
const promptHash = (0,
|
|
22130
|
+
const promptHash = (0, import_node_crypto10.createHash)("sha256").update(prompt).digest("hex");
|
|
22088
22131
|
const result = await apiRequest({
|
|
22089
22132
|
method: "POST",
|
|
22090
22133
|
path: "/classify-task",
|
|
@@ -22128,7 +22171,7 @@ var import_node_path26 = require("node:path");
|
|
|
22128
22171
|
// src/lib/baseline.ts
|
|
22129
22172
|
var import_node_fs28 = require("node:fs");
|
|
22130
22173
|
var import_node_path25 = require("node:path");
|
|
22131
|
-
var
|
|
22174
|
+
var import_node_crypto11 = require("node:crypto");
|
|
22132
22175
|
|
|
22133
22176
|
// src/lib/snapshot.ts
|
|
22134
22177
|
var import_node_fs27 = require("node:fs");
|
|
@@ -22397,7 +22440,7 @@ var MIRROR_MAX_BYTES = 2 * 1024 * 1024;
|
|
|
22397
22440
|
var DEFAULT_SESSION_KEY = "_default";
|
|
22398
22441
|
function sessionKey(sessionId) {
|
|
22399
22442
|
if (!sessionId) return DEFAULT_SESSION_KEY;
|
|
22400
|
-
return (0,
|
|
22443
|
+
return (0, import_node_crypto11.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
|
|
22401
22444
|
}
|
|
22402
22445
|
function sessionDir(key) {
|
|
22403
22446
|
return (0, import_node_path25.join)(projectPath(BASELINE_DIR), key);
|
|
@@ -22859,17 +22902,17 @@ async function readHookStdin() {
|
|
|
22859
22902
|
try {
|
|
22860
22903
|
if (process.stdin.isTTY) return {};
|
|
22861
22904
|
const chunks = [];
|
|
22862
|
-
const timeout = new Promise((
|
|
22863
|
-
const read2 = new Promise((
|
|
22905
|
+
const timeout = new Promise((resolve9) => setTimeout(() => resolve9({}), 500));
|
|
22906
|
+
const read2 = new Promise((resolve9) => {
|
|
22864
22907
|
process.stdin.on("data", (c) => chunks.push(c));
|
|
22865
22908
|
process.stdin.on("end", () => {
|
|
22866
22909
|
try {
|
|
22867
|
-
|
|
22910
|
+
resolve9(JSON.parse(Buffer.concat(chunks).toString("utf-8").trim() || "{}"));
|
|
22868
22911
|
} catch {
|
|
22869
|
-
|
|
22912
|
+
resolve9({});
|
|
22870
22913
|
}
|
|
22871
22914
|
});
|
|
22872
|
-
process.stdin.on("error", () =>
|
|
22915
|
+
process.stdin.on("error", () => resolve9({}));
|
|
22873
22916
|
process.stdin.resume();
|
|
22874
22917
|
});
|
|
22875
22918
|
return await Promise.race([read2, timeout]);
|
|
@@ -24317,10 +24360,10 @@ var import_node_fs38 = require("node:fs");
|
|
|
24317
24360
|
|
|
24318
24361
|
// src/lib/debounce.ts
|
|
24319
24362
|
var import_node_fs37 = require("node:fs");
|
|
24320
|
-
var
|
|
24363
|
+
var import_node_crypto12 = require("node:crypto");
|
|
24321
24364
|
function scopedFile(base, sessionId) {
|
|
24322
24365
|
if (!sessionId) return base;
|
|
24323
|
-
return `${base}.${(0,
|
|
24366
|
+
return `${base}.${(0, import_node_crypto12.createHash)("sha1").update(sessionId).digest("hex").slice(0, 12)}`;
|
|
24324
24367
|
}
|
|
24325
24368
|
function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
|
|
24326
24369
|
const file = scopedFile(DEBOUNCE_FILE, sessionId);
|
|
@@ -24361,7 +24404,7 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
|
|
|
24361
24404
|
return "No files modified since last analysis";
|
|
24362
24405
|
}
|
|
24363
24406
|
function computeContentHash(files) {
|
|
24364
|
-
const hash = (0,
|
|
24407
|
+
const hash = (0, import_node_crypto12.createHash)("sha1");
|
|
24365
24408
|
const sorted = [...files].sort();
|
|
24366
24409
|
for (const f of sorted) {
|
|
24367
24410
|
const resolved = resolveFile(f) ?? f;
|
|
@@ -24984,6 +25027,7 @@ function createRun(opts, globals) {
|
|
|
24984
25027
|
|
|
24985
25028
|
// src/commands/analyze/index.ts
|
|
24986
25029
|
var import_node_fs52 = require("node:fs");
|
|
25030
|
+
var import_node_path40 = require("node:path");
|
|
24987
25031
|
|
|
24988
25032
|
// src/lib/repo-context.ts
|
|
24989
25033
|
var import_node_child_process11 = require("node:child_process");
|
|
@@ -26786,28 +26830,28 @@ async function readStopHookStdin() {
|
|
|
26786
26830
|
try {
|
|
26787
26831
|
if (process.stdin.isTTY) return empty;
|
|
26788
26832
|
const chunks = [];
|
|
26789
|
-
const timeout = new Promise((
|
|
26790
|
-
const read2 = new Promise((
|
|
26833
|
+
const timeout = new Promise((resolve9) => setTimeout(() => resolve9(empty), 500));
|
|
26834
|
+
const read2 = new Promise((resolve9) => {
|
|
26791
26835
|
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
26792
26836
|
process.stdin.on("end", () => {
|
|
26793
26837
|
const raw = Buffer.concat(chunks).toString("utf-8").trim();
|
|
26794
26838
|
if (!raw) {
|
|
26795
|
-
|
|
26839
|
+
resolve9(empty);
|
|
26796
26840
|
return;
|
|
26797
26841
|
}
|
|
26798
26842
|
try {
|
|
26799
26843
|
const data = JSON.parse(raw);
|
|
26800
|
-
|
|
26844
|
+
resolve9({
|
|
26801
26845
|
assistantMessage: typeof data.last_assistant_message === "string" ? data.last_assistant_message : null,
|
|
26802
26846
|
stopReason: typeof data.stop_reason === "string" ? data.stop_reason : null,
|
|
26803
26847
|
transcriptPath: typeof data.transcript_path === "string" ? data.transcript_path : null,
|
|
26804
26848
|
sessionId: typeof data.session_id === "string" ? data.session_id : null
|
|
26805
26849
|
});
|
|
26806
26850
|
} catch {
|
|
26807
|
-
|
|
26851
|
+
resolve9(empty);
|
|
26808
26852
|
}
|
|
26809
26853
|
});
|
|
26810
|
-
process.stdin.on("error", () =>
|
|
26854
|
+
process.stdin.on("error", () => resolve9(empty));
|
|
26811
26855
|
process.stdin.resume();
|
|
26812
26856
|
});
|
|
26813
26857
|
return await Promise.race([read2, timeout]);
|
|
@@ -27073,7 +27117,7 @@ function channelSilence(input) {
|
|
|
27073
27117
|
// src/lib/cli-version.ts
|
|
27074
27118
|
function cliVersion() {
|
|
27075
27119
|
try {
|
|
27076
|
-
return true ? "0.34.0-experimental.
|
|
27120
|
+
return true ? "0.34.0-experimental.3d4888f" : "dev";
|
|
27077
27121
|
} catch {
|
|
27078
27122
|
return "dev";
|
|
27079
27123
|
}
|
|
@@ -28541,7 +28585,7 @@ async function contextFiles(run4) {
|
|
|
28541
28585
|
}
|
|
28542
28586
|
|
|
28543
28587
|
// src/lib/code/index.ts
|
|
28544
|
-
var
|
|
28588
|
+
var import_node_crypto13 = require("node:crypto");
|
|
28545
28589
|
|
|
28546
28590
|
// src/lib/code/languages.ts
|
|
28547
28591
|
var JS_LIKE = {
|
|
@@ -30319,7 +30363,7 @@ function byPath(fns, name2) {
|
|
|
30319
30363
|
function makeCodeMap(rt) {
|
|
30320
30364
|
const cache = /* @__PURE__ */ new Map();
|
|
30321
30365
|
const outline = (path, content, deadlineAt = Date.now() + DEFAULT_PARSE_MS) => {
|
|
30322
|
-
const key = `${path}\0${(0,
|
|
30366
|
+
const key = `${path}\0${(0, import_node_crypto13.createHash)("sha1").update(content).digest("hex")}`;
|
|
30323
30367
|
const hit = cache.get(key);
|
|
30324
30368
|
if (hit) return { source: "tree-sitter", value: hit, elapsedMs: 0 };
|
|
30325
30369
|
let r;
|
|
@@ -31688,6 +31732,22 @@ async function workingMemory(run4) {
|
|
|
31688
31732
|
Object.assign(run4, { incrementReport, memory: memory2, memorySession, reachability });
|
|
31689
31733
|
}
|
|
31690
31734
|
|
|
31735
|
+
// src/lib/payload-bounds.ts
|
|
31736
|
+
var MAX_WIRE_PATHS = 500;
|
|
31737
|
+
function boundPaths(paths, first, max = MAX_WIRE_PATHS) {
|
|
31738
|
+
if (paths.length <= max) return [...paths];
|
|
31739
|
+
const present = new Set(paths);
|
|
31740
|
+
const kept = /* @__PURE__ */ new Set();
|
|
31741
|
+
const out2 = [];
|
|
31742
|
+
for (const p of [...first, ...paths]) {
|
|
31743
|
+
if (out2.length >= max) break;
|
|
31744
|
+
if (!present.has(p) || kept.has(p)) continue;
|
|
31745
|
+
kept.add(p);
|
|
31746
|
+
out2.push(p);
|
|
31747
|
+
}
|
|
31748
|
+
return out2;
|
|
31749
|
+
}
|
|
31750
|
+
|
|
31691
31751
|
// src/lib/note-budget.ts
|
|
31692
31752
|
var import_node_fs49 = require("node:fs");
|
|
31693
31753
|
var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
|
|
@@ -31802,6 +31862,7 @@ async function buildRequest(run4) {
|
|
|
31802
31862
|
(conversation?.prompts?.length ?? 0) > 0
|
|
31803
31863
|
);
|
|
31804
31864
|
const noteConfirmation = peekNoteOutcome();
|
|
31865
|
+
const unobserved = foldResult?.unobserved ?? [];
|
|
31805
31866
|
const excludedByReason = {};
|
|
31806
31867
|
for (const e of codeDelta.excluded ?? []) {
|
|
31807
31868
|
excludedByReason[e.reason] = (excludedByReason[e.reason] ?? 0) + 1;
|
|
@@ -31846,7 +31907,9 @@ async function buildRequest(run4) {
|
|
|
31846
31907
|
coverage_telemetry: coverageTelemetry,
|
|
31847
31908
|
static_results: staticResults,
|
|
31848
31909
|
code_delta: codeDelta,
|
|
31849
|
-
|
|
31910
|
+
// Bounded, reviewed paths first — the server applies the same bound. The
|
|
31911
|
+
// full count is `coverage_telemetry.for_review`. VRT-242.
|
|
31912
|
+
changed_files: boundPaths(allForReview, codeDelta.files.map((f) => f.path)),
|
|
31850
31913
|
standard_version: "latest",
|
|
31851
31914
|
analysis_mode: analysisMode,
|
|
31852
31915
|
plan_only: analysisMode === "plan",
|
|
@@ -31897,7 +31960,9 @@ async function buildRequest(run4) {
|
|
|
31897
31960
|
// `hash_at_last_verdict` is frozen at each verdict and `hash_now` tracks
|
|
31898
31961
|
// disk, so their inequality IS "changed since we last spoke".
|
|
31899
31962
|
authored_since_verdict: memorySession ? foldDossier(memorySession.d).authored_all.filter((a) => a.hash_now !== a.hash_at_last_verdict).map((a) => a.path) : [],
|
|
31900
|
-
|
|
31963
|
+
// The server reads only how many; a bulk change sent every path. VRT-242.
|
|
31964
|
+
unobserved: unobserved.slice(0, MAX_WIRE_PATHS),
|
|
31965
|
+
...unobserved.length > MAX_WIRE_PATHS && { unobserved_total: unobserved.length },
|
|
31901
31966
|
commands: foldResult?.commands ?? [],
|
|
31902
31967
|
tools: foldResult?.tools ?? [],
|
|
31903
31968
|
tasks: foldResult?.tasks ?? [],
|
|
@@ -32061,11 +32126,11 @@ async function buildRequest(run4) {
|
|
|
32061
32126
|
|
|
32062
32127
|
// src/lib/offline.ts
|
|
32063
32128
|
var import_node_fs50 = require("node:fs");
|
|
32064
|
-
var
|
|
32129
|
+
var import_node_crypto14 = require("node:crypto");
|
|
32065
32130
|
function cacheRequest(body2) {
|
|
32066
32131
|
try {
|
|
32067
32132
|
(0, import_node_fs50.mkdirSync)(CACHE_DIR, { recursive: true });
|
|
32068
|
-
const suffix = (0,
|
|
32133
|
+
const suffix = (0, import_node_crypto14.randomBytes)(4).toString("hex");
|
|
32069
32134
|
const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
|
|
32070
32135
|
(0, import_node_fs50.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body2)));
|
|
32071
32136
|
} catch {
|
|
@@ -32108,8 +32173,10 @@ function buildOfflineFallback(reason, staticResults) {
|
|
|
32108
32173
|
}
|
|
32109
32174
|
|
|
32110
32175
|
// src/lib/retry.ts
|
|
32176
|
+
var WORKER_RESOURCE_LIMIT = 546;
|
|
32111
32177
|
function shouldWarmRetryAnalyze(result) {
|
|
32112
32178
|
if (result.ok) return false;
|
|
32179
|
+
if (result.http_status === WORKER_RESOURCE_LIMIT) return false;
|
|
32113
32180
|
if (result.category === "network" || result.category === "timeout") return true;
|
|
32114
32181
|
if (result.category === "http_5xx") return true;
|
|
32115
32182
|
if (result.category === "invalid_json" && (result.http_status ?? 0) >= 500) return true;
|
|
@@ -32119,7 +32186,7 @@ function shouldWarmRetryAnalyze(result) {
|
|
|
32119
32186
|
// src/commands/analyze/phases/12-transmit.ts
|
|
32120
32187
|
async function transmit(run4) {
|
|
32121
32188
|
const { globals } = run4;
|
|
32122
|
-
const {
|
|
32189
|
+
const { requestBody, serviceUrl, staticResults, token } = run4;
|
|
32123
32190
|
const ANALYZE_TIMEOUT_MS = 1e5;
|
|
32124
32191
|
let result = await analyzeRequest({
|
|
32125
32192
|
serviceUrl,
|
|
@@ -32156,11 +32223,12 @@ async function transmit(run4) {
|
|
|
32156
32223
|
}
|
|
32157
32224
|
if (!result.ok) {
|
|
32158
32225
|
cacheRequest(requestBody);
|
|
32226
|
+
const sentKb = () => Math.round(Buffer.byteLength(JSON.stringify(requestBody)) / 1024);
|
|
32159
32227
|
let message;
|
|
32160
32228
|
if (result.http_status === 413) {
|
|
32161
|
-
|
|
32162
|
-
|
|
32163
|
-
message = `Verity:
|
|
32229
|
+
message = `Verity: request rejected \u2014 payload too large (${sentKb()} KB sent: ${result.error}). Commit or stash pre-existing changes, or run with --mode skip if you didn't intend to submit code this turn.`;
|
|
32230
|
+
} else if (result.http_status === WORKER_RESOURCE_LIMIT) {
|
|
32231
|
+
message = `Verity: the service ran out of CPU or memory on this request (HTTP 546, ${sentKb()} KB sent). This is not a cold start: the same change fails the same way, so it was not retried. Commit or stash unrelated changes to shrink the request (local analysis this run).`;
|
|
32164
32232
|
} else if (result.category === "network" || result.category === "timeout") {
|
|
32165
32233
|
message = `Verity offline \u2014 ${result.error}`;
|
|
32166
32234
|
} else if (result.error.startsWith("STALE_VERIFICATION")) {
|
|
@@ -33038,7 +33106,7 @@ function registerAnalyzeCommand(program2) {
|
|
|
33038
33106
|
var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
|
|
33039
33107
|
async function runAnalyze(opts, globals) {
|
|
33040
33108
|
if (!verityConfigured()) {
|
|
33041
|
-
(0, import_node_fs52.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
|
|
33109
|
+
(0, import_node_fs52.writeSync)(2, isMachineStore((0, import_node_path40.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');
|
|
33042
33110
|
process.exit(0);
|
|
33043
33111
|
}
|
|
33044
33112
|
const run4 = createRun(opts, globals);
|
|
@@ -33060,10 +33128,11 @@ async function runAnalyze(opts, globals) {
|
|
|
33060
33128
|
|
|
33061
33129
|
// src/commands/baseline.ts
|
|
33062
33130
|
var import_node_fs54 = require("node:fs");
|
|
33131
|
+
var import_node_path42 = require("node:path");
|
|
33063
33132
|
|
|
33064
33133
|
// src/lib/project-skills.ts
|
|
33065
33134
|
var import_node_fs53 = require("node:fs");
|
|
33066
|
-
var
|
|
33135
|
+
var import_node_path41 = require("node:path");
|
|
33067
33136
|
var PROJECT_SKILL_NAMES = [
|
|
33068
33137
|
"verity-setup",
|
|
33069
33138
|
"verity-analyze",
|
|
@@ -33090,13 +33159,13 @@ var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
|
|
|
33090
33159
|
function staleProjectSkills() {
|
|
33091
33160
|
const root = projectPath(".claude/skills");
|
|
33092
33161
|
if (!(0, import_node_fs53.existsSync)(root)) return [];
|
|
33093
|
-
return ALL.filter((name2) => (0, import_node_fs53.existsSync)((0,
|
|
33162
|
+
return ALL.filter((name2) => (0, import_node_fs53.existsSync)((0, import_node_path41.join)(root, name2)));
|
|
33094
33163
|
}
|
|
33095
33164
|
function removeProjectSkills() {
|
|
33096
33165
|
const root = projectPath(".claude/skills");
|
|
33097
33166
|
const removed = [];
|
|
33098
33167
|
for (const name2 of staleProjectSkills()) {
|
|
33099
|
-
(0, import_node_fs53.rmSync)((0,
|
|
33168
|
+
(0, import_node_fs53.rmSync)((0, import_node_path41.join)(root, name2), { recursive: true, force: true });
|
|
33100
33169
|
removed.push(name2);
|
|
33101
33170
|
}
|
|
33102
33171
|
return removed;
|
|
@@ -33129,6 +33198,7 @@ function registerBaselineCommands(program2) {
|
|
|
33129
33198
|
const skewMsg = skew ? `Verity: your global \`verity\` CLI is ${skew.global} but the hooks run ${skew.hooks}. Fix it before using \`verity\` in a terminal: ${skew.remedy}` : null;
|
|
33130
33199
|
const skewNote = skew ? `Before anything else, including /verity:init's questions, tell the user their global \`verity\` is ${skew.global}, the hooks run ${skew.hooks}, and \`${skew.remedy}\` fixes it. Until they have, do not send them to run \`verity login\` in a terminal: that runs the global one, which can sign this machine in to a different server.` : null;
|
|
33131
33200
|
if (!verityConfigured()) {
|
|
33201
|
+
if (isMachineStore((0, import_node_path42.join)(repoRoot(), VERITY_DIR))) process.exit(0);
|
|
33132
33202
|
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.";
|
|
33133
33203
|
const lines = [
|
|
33134
33204
|
`Verity is installed but this project is not set up yet, so the quality gate will not review anything here. ${how}`
|
|
@@ -33352,7 +33422,7 @@ async function runReview(opts, globals) {
|
|
|
33352
33422
|
|
|
33353
33423
|
// src/commands/guard.ts
|
|
33354
33424
|
var import_node_fs59 = require("node:fs");
|
|
33355
|
-
var
|
|
33425
|
+
var import_node_path47 = require("node:path");
|
|
33356
33426
|
|
|
33357
33427
|
// src/lib/terminal-text.ts
|
|
33358
33428
|
var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/g;
|
|
@@ -33445,7 +33515,7 @@ async function runAgentReview(options) {
|
|
|
33445
33515
|
}
|
|
33446
33516
|
if (!settled) {
|
|
33447
33517
|
const wait = Math.max(0, remaining() - FINISH_TIMEOUT_MS);
|
|
33448
|
-
await Promise.race([oneShotDone, new Promise((
|
|
33518
|
+
await Promise.race([oneShotDone, new Promise((resolve9) => setTimeout(resolve9, wait))]);
|
|
33449
33519
|
}
|
|
33450
33520
|
const finished = await options.http.post(
|
|
33451
33521
|
"/agent-review/finish",
|
|
@@ -33460,8 +33530,8 @@ async function runAgentReview(options) {
|
|
|
33460
33530
|
}
|
|
33461
33531
|
|
|
33462
33532
|
// src/lib/prove/auto.ts
|
|
33463
|
-
var
|
|
33464
|
-
var
|
|
33533
|
+
var import_node_path46 = require("node:path");
|
|
33534
|
+
var import_node_crypto19 = require("node:crypto");
|
|
33465
33535
|
|
|
33466
33536
|
// src/lib/prove/signals.ts
|
|
33467
33537
|
var DEFAULT_SINCE = "180 days ago";
|
|
@@ -35189,16 +35259,16 @@ var import_node_child_process15 = require("node:child_process");
|
|
|
35189
35259
|
var import_node_os8 = require("node:os");
|
|
35190
35260
|
var import_node_fs58 = require("node:fs");
|
|
35191
35261
|
var import_node_os9 = require("node:os");
|
|
35192
|
-
var
|
|
35262
|
+
var import_node_path45 = require("node:path");
|
|
35193
35263
|
|
|
35194
35264
|
// src/lib/prove/scaffold.ts
|
|
35195
35265
|
var import_node_fs57 = require("node:fs");
|
|
35196
|
-
var
|
|
35266
|
+
var import_node_path44 = require("node:path");
|
|
35197
35267
|
|
|
35198
35268
|
// src/lib/prove/safe-write.ts
|
|
35199
35269
|
var import_node_fs56 = require("node:fs");
|
|
35200
|
-
var
|
|
35201
|
-
var
|
|
35270
|
+
var import_node_crypto15 = require("node:crypto");
|
|
35271
|
+
var import_node_path43 = require("node:path");
|
|
35202
35272
|
var SafeWriteError = class extends Error {
|
|
35203
35273
|
constructor(reason, path) {
|
|
35204
35274
|
super(`refusing to write ${path}: ${reason}`);
|
|
@@ -35210,7 +35280,7 @@ var SafeWriteError = class extends Error {
|
|
|
35210
35280
|
var FLAGS3 = import_node_fs56.constants;
|
|
35211
35281
|
var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
|
|
35212
35282
|
function assertPlainRelative(rel) {
|
|
35213
|
-
if (!rel || (0,
|
|
35283
|
+
if (!rel || (0, import_node_path43.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
|
|
35214
35284
|
for (const part of rel.split(/[\\/]/)) {
|
|
35215
35285
|
if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
|
|
35216
35286
|
}
|
|
@@ -35219,7 +35289,7 @@ function ensureDirsNoFollow(root, rel) {
|
|
|
35219
35289
|
const parts2 = rel.split(/[\\/]/);
|
|
35220
35290
|
let cur = root;
|
|
35221
35291
|
for (const part of parts2.slice(0, -1)) {
|
|
35222
|
-
cur = (0,
|
|
35292
|
+
cur = (0, import_node_path43.join)(cur, part);
|
|
35223
35293
|
let st;
|
|
35224
35294
|
try {
|
|
35225
35295
|
st = (0, import_node_fs56.lstatSync)(cur);
|
|
@@ -35230,10 +35300,10 @@ function ensureDirsNoFollow(root, rel) {
|
|
|
35230
35300
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
|
|
35231
35301
|
if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
|
|
35232
35302
|
}
|
|
35233
|
-
return (0,
|
|
35303
|
+
return (0, import_node_path43.join)(root, rel);
|
|
35234
35304
|
}
|
|
35235
35305
|
function insideRoot(realRoot, realPath) {
|
|
35236
|
-
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(
|
|
35306
|
+
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path43.sep) ? realRoot : realRoot + import_node_path43.sep);
|
|
35237
35307
|
}
|
|
35238
35308
|
function removeQuietly(path) {
|
|
35239
35309
|
try {
|
|
@@ -35244,7 +35314,7 @@ function removeQuietly(path) {
|
|
|
35244
35314
|
function writeFileInRootNoFollow(root, rel, content) {
|
|
35245
35315
|
assertPlainRelative(rel);
|
|
35246
35316
|
const dest = ensureDirsNoFollow(root, rel);
|
|
35247
|
-
const dir = (0,
|
|
35317
|
+
const dir = (0, import_node_path43.dirname)(dest);
|
|
35248
35318
|
try {
|
|
35249
35319
|
const st = (0, import_node_fs56.lstatSync)(dest);
|
|
35250
35320
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
|
|
@@ -35258,7 +35328,7 @@ function writeFileInRootNoFollow(root, rel, content) {
|
|
|
35258
35328
|
} catch {
|
|
35259
35329
|
throw new SafeWriteError("unwritable", root);
|
|
35260
35330
|
}
|
|
35261
|
-
const tmp = (0,
|
|
35331
|
+
const tmp = (0, import_node_path43.join)(dir, `.${(0, import_node_path43.basename)(dest)}.${(0, import_node_crypto15.randomBytes)(6).toString("hex")}.tmp`);
|
|
35262
35332
|
let fd;
|
|
35263
35333
|
try {
|
|
35264
35334
|
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);
|
|
@@ -35302,7 +35372,7 @@ function pathHasNoLink(root, rel) {
|
|
|
35302
35372
|
}
|
|
35303
35373
|
let cur = root;
|
|
35304
35374
|
for (const part of rel.split(/[\\/]/)) {
|
|
35305
|
-
cur = cur +
|
|
35375
|
+
cur = cur + import_node_path43.sep + part;
|
|
35306
35376
|
try {
|
|
35307
35377
|
if ((0, import_node_fs56.lstatSync)(cur).isSymbolicLink()) return false;
|
|
35308
35378
|
} catch {
|
|
@@ -35614,20 +35684,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
|
|
|
35614
35684
|
never committed; what reaches the team is the bug report and the fix.
|
|
35615
35685
|
`;
|
|
35616
35686
|
function scaffoldProofs(root) {
|
|
35617
|
-
const proofsDir = (0,
|
|
35687
|
+
const proofsDir = (0, import_node_path44.join)(root, PROOFS_DIR);
|
|
35618
35688
|
const written = [];
|
|
35619
35689
|
const kept = [];
|
|
35620
35690
|
for (const stray of ["lakefile.lean"]) {
|
|
35621
35691
|
const rel = `${PROOFS_DIR}/${stray}`;
|
|
35622
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35692
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path44.join)(root, rel));
|
|
35623
35693
|
try {
|
|
35624
|
-
(0, import_node_fs57.rmSync)((0,
|
|
35694
|
+
(0, import_node_fs57.rmSync)((0, import_node_path44.join)(root, rel), { force: true });
|
|
35625
35695
|
} catch {
|
|
35626
35696
|
}
|
|
35627
35697
|
}
|
|
35628
35698
|
for (const f of PROOFS_TEMPLATE_FILES) {
|
|
35629
35699
|
const rel = `${PROOFS_DIR}/${f.path}`;
|
|
35630
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35700
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path44.join)(root, rel));
|
|
35631
35701
|
const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
|
|
35632
35702
|
if (current.ok && current.content === f.content) {
|
|
35633
35703
|
kept.push(rel);
|
|
@@ -35640,8 +35710,8 @@ function scaffoldProofs(root) {
|
|
|
35640
35710
|
[`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
|
|
35641
35711
|
[`${MODELS_DIR}/README.md`, MODELS_README]
|
|
35642
35712
|
]) {
|
|
35643
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35644
|
-
if (existsNoFollow((0,
|
|
35713
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path44.join)(root, rel));
|
|
35714
|
+
if (existsNoFollow((0, import_node_path44.join)(root, rel))) {
|
|
35645
35715
|
kept.push(rel);
|
|
35646
35716
|
continue;
|
|
35647
35717
|
}
|
|
@@ -35660,7 +35730,7 @@ function existsNoFollow(abs) {
|
|
|
35660
35730
|
}
|
|
35661
35731
|
|
|
35662
35732
|
// src/lib/prove/report.ts
|
|
35663
|
-
var
|
|
35733
|
+
var import_node_crypto16 = require("node:crypto");
|
|
35664
35734
|
var IDENT2 = /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$/;
|
|
35665
35735
|
var SHA256 = /^(sha256:)?[0-9a-f]{64}$/;
|
|
35666
35736
|
var KINDS2 = /* @__PURE__ */ new Set(["structural", "intent"]);
|
|
@@ -35808,7 +35878,7 @@ function sha256InRoot(root, file) {
|
|
|
35808
35878
|
const opened = openRegularInRoot(root, file);
|
|
35809
35879
|
if (!opened.ok) return null;
|
|
35810
35880
|
try {
|
|
35811
|
-
return (0,
|
|
35881
|
+
return (0, import_node_crypto16.createHash)("sha256").update(readOpened(opened.fd, opened.size)).digest("hex");
|
|
35812
35882
|
} catch {
|
|
35813
35883
|
return null;
|
|
35814
35884
|
}
|
|
@@ -35910,17 +35980,17 @@ function renderReport(r) {
|
|
|
35910
35980
|
|
|
35911
35981
|
// src/lib/prove/runner.ts
|
|
35912
35982
|
function verityLeanHome(env = process.env) {
|
|
35913
|
-
return env.VERITY_LEAN_HOME ?? (0,
|
|
35983
|
+
return env.VERITY_LEAN_HOME ?? (0, import_node_path45.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
|
|
35914
35984
|
}
|
|
35915
35985
|
function findToolchain(env = process.env) {
|
|
35916
|
-
const managedBin = (0,
|
|
35917
|
-
const elanBin = (0,
|
|
35918
|
-
const elanHas = (0, import_node_fs58.existsSync)((0,
|
|
35919
|
-
const userPath = (env.PATH ?? "").split(
|
|
35920
|
-
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(
|
|
35986
|
+
const managedBin = (0, import_node_path45.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
|
|
35987
|
+
const elanBin = (0, import_node_path45.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
|
|
35988
|
+
const elanHas = (0, import_node_fs58.existsSync)((0, import_node_path45.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
|
|
35989
|
+
const userPath = (env.PATH ?? "").split(import_node_path45.delimiter).filter((d) => d && (elanHas || (0, import_node_path45.resolve)(d) !== (0, import_node_path45.resolve)(elanBin)));
|
|
35990
|
+
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path45.delimiter);
|
|
35921
35991
|
const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
|
|
35922
35992
|
const exe = process.platform === "win32" ? "lake.exe" : "lake";
|
|
35923
|
-
const candidates2 = [(0,
|
|
35993
|
+
const candidates2 = [(0, import_node_path45.join)(managedBin, exe), ...elanHas ? [(0, import_node_path45.join)(elanBin, exe)] : [], exe];
|
|
35924
35994
|
for (const candidate of candidates2) {
|
|
35925
35995
|
try {
|
|
35926
35996
|
(0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
|
|
@@ -35958,7 +36028,7 @@ function run2(tc, cwd, args2, timeoutMs) {
|
|
|
35958
36028
|
function runAsync(tc, cwd, args2, timeoutMs) {
|
|
35959
36029
|
const started = Date.now();
|
|
35960
36030
|
const MAX = 16 * 1024 * 1024;
|
|
35961
|
-
return new Promise((
|
|
36031
|
+
return new Promise((resolve9) => {
|
|
35962
36032
|
const posix = (0, import_node_os8.platform)() !== "win32";
|
|
35963
36033
|
const child = (0, import_node_child_process15.spawn)(tc.lake, args2, { cwd, env: tc.env, stdio: ["ignore", "pipe", "pipe"], detached: posix });
|
|
35964
36034
|
let stdout = "";
|
|
@@ -35986,8 +36056,8 @@ function runAsync(tc, cwd, args2, timeoutMs) {
|
|
|
35986
36056
|
if (settled) return;
|
|
35987
36057
|
settled = true;
|
|
35988
36058
|
clearTimeout(timer);
|
|
35989
|
-
if (ok)
|
|
35990
|
-
else
|
|
36059
|
+
if (ok) resolve9({ ok: true, stdout, stderr: "", durationMs: Date.now() - started, timedOut: false });
|
|
36060
|
+
else resolve9({ ok: false, stdout, stderr: stderr || message || "", durationMs: Date.now() - started, timedOut });
|
|
35991
36061
|
};
|
|
35992
36062
|
child.on("error", (err2) => finish(false, err2.message));
|
|
35993
36063
|
child.on("close", (code) => finish(code === 0 && !timedOut));
|
|
@@ -35999,7 +36069,7 @@ function proofsWorkspaceProblem(root) {
|
|
|
35999
36069
|
for (const rel of [".verity", PROOFS_DIR, `${PROOFS_DIR}/.lake`]) {
|
|
36000
36070
|
let st;
|
|
36001
36071
|
try {
|
|
36002
|
-
st = (0, import_node_fs58.lstatSync)((0,
|
|
36072
|
+
st = (0, import_node_fs58.lstatSync)((0, import_node_path45.join)(root, rel));
|
|
36003
36073
|
} catch {
|
|
36004
36074
|
break;
|
|
36005
36075
|
}
|
|
@@ -36019,44 +36089,44 @@ function refused(problem) {
|
|
|
36019
36089
|
function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
36020
36090
|
const problem = proofsWorkspaceProblem(root);
|
|
36021
36091
|
if (problem) return refused(problem);
|
|
36022
|
-
return run2(tc, (0,
|
|
36092
|
+
return run2(tc, (0, import_node_path45.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36023
36093
|
}
|
|
36024
36094
|
async function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
36025
36095
|
const problem = proofsWorkspaceProblem(root);
|
|
36026
36096
|
if (problem) return refused(problem);
|
|
36027
|
-
return runAsync(tc, (0,
|
|
36097
|
+
return runAsync(tc, (0, import_node_path45.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36028
36098
|
}
|
|
36029
36099
|
function isModelInRoot(modelsAbs, rel) {
|
|
36030
|
-
if (!rel.endsWith(".lean") || (0,
|
|
36100
|
+
if (!rel.endsWith(".lean") || (0, import_node_path45.isAbsolute)(rel) || rel.startsWith("..")) return false;
|
|
36031
36101
|
return statRegularInRoot(modelsAbs, rel).ok;
|
|
36032
36102
|
}
|
|
36033
36103
|
function resolveModelFile(root, arg) {
|
|
36034
|
-
const modelsAbs = (0,
|
|
36035
|
-
const asPath = (0,
|
|
36104
|
+
const modelsAbs = (0, import_node_path45.join)(root, MODELS_DIR);
|
|
36105
|
+
const asPath = (0, import_node_path45.relative)(modelsAbs, (0, import_node_path45.isAbsolute)(arg) ? arg : (0, import_node_path45.resolve)(root, arg));
|
|
36036
36106
|
const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
|
|
36037
36107
|
for (const rel of candidates2) {
|
|
36038
|
-
if (isModelInRoot(modelsAbs, rel)) return (0,
|
|
36108
|
+
if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path45.join)(modelsAbs, rel);
|
|
36039
36109
|
}
|
|
36040
36110
|
return null;
|
|
36041
36111
|
}
|
|
36042
36112
|
function listModelFiles(root) {
|
|
36043
|
-
const modelsAbs = (0,
|
|
36113
|
+
const modelsAbs = (0, import_node_path45.join)(root, MODELS_DIR);
|
|
36044
36114
|
if (!(0, import_node_fs58.existsSync)(modelsAbs)) return [];
|
|
36045
|
-
return (0, import_node_fs58.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0,
|
|
36115
|
+
return (0, import_node_fs58.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path45.join)(modelsAbs, f));
|
|
36046
36116
|
}
|
|
36047
36117
|
function trimDiagnostics(text) {
|
|
36048
36118
|
return text.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
|
|
36049
36119
|
}
|
|
36050
36120
|
function checkModel(tc, root, modelFile, opts = {}) {
|
|
36051
|
-
const proofsAbs = (0,
|
|
36052
|
-
const rel = (0,
|
|
36121
|
+
const proofsAbs = (0, import_node_path45.join)(root, PROOFS_DIR);
|
|
36122
|
+
const rel = (0, import_node_path45.relative)(proofsAbs, modelFile);
|
|
36053
36123
|
const problem = proofsWorkspaceProblem(root);
|
|
36054
36124
|
const res = problem ? refused(problem) : run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36055
36125
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36056
36126
|
}
|
|
36057
36127
|
async function checkModelAsync(tc, root, modelFile, opts = {}) {
|
|
36058
|
-
const proofsAbs = (0,
|
|
36059
|
-
const rel = (0,
|
|
36128
|
+
const proofsAbs = (0, import_node_path45.join)(root, PROOFS_DIR);
|
|
36129
|
+
const rel = (0, import_node_path45.relative)(proofsAbs, modelFile);
|
|
36060
36130
|
const problem = proofsWorkspaceProblem(root);
|
|
36061
36131
|
const res = problem ? refused(problem) : await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36062
36132
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
@@ -36065,10 +36135,10 @@ function toReport(res, root, modelFile, timeoutMs) {
|
|
|
36065
36135
|
const parsed = parseVerityLines(res.stdout);
|
|
36066
36136
|
const combined = `${res.stdout}
|
|
36067
36137
|
${res.stderr}`;
|
|
36068
|
-
const name2 = parsed.header?.model ?? (0,
|
|
36138
|
+
const name2 = parsed.header?.model ?? (0, import_node_path45.basename)(modelFile, ".lean");
|
|
36069
36139
|
const report = {
|
|
36070
36140
|
model: name2,
|
|
36071
|
-
file: (0,
|
|
36141
|
+
file: (0, import_node_path45.relative)(root, modelFile),
|
|
36072
36142
|
ok: res.ok,
|
|
36073
36143
|
header: parsed.header,
|
|
36074
36144
|
properties: parsed.properties,
|
|
@@ -36143,7 +36213,7 @@ function mergeFormalFindings(response, outcome, pushedFiles) {
|
|
|
36143
36213
|
}
|
|
36144
36214
|
|
|
36145
36215
|
// src/lib/prove/scalpel.ts
|
|
36146
|
-
var
|
|
36216
|
+
var import_node_crypto17 = require("node:crypto");
|
|
36147
36217
|
var ARITHMETIC = /Math\.(?:round|floor|ceil|trunc)\(|\bround\(|\bdivmod\(|[\w)\]]\s*(?:\*|\/(?!\/)|%)\s*[\w(]/;
|
|
36148
36218
|
function functionHazard(numbered2) {
|
|
36149
36219
|
const sites = effectSites(numbered2);
|
|
@@ -36173,7 +36243,7 @@ function semanticFingerprint(numbered2) {
|
|
|
36173
36243
|
if (LOG_LINE.test(t)) continue;
|
|
36174
36244
|
kept.push(t.replace(/\s+/g, " "));
|
|
36175
36245
|
}
|
|
36176
|
-
return (0,
|
|
36246
|
+
return (0, import_node_crypto17.createHash)("sha256").update(kept.join("\n")).digest("hex");
|
|
36177
36247
|
}
|
|
36178
36248
|
function readVerified(root, now = Date.now()) {
|
|
36179
36249
|
const read2 = readRegularFileInRoot(root, VERIFIED_FILE, 256 * 1024);
|
|
@@ -36196,9 +36266,9 @@ function recordVerified(root, rec, now = Date.now()) {
|
|
|
36196
36266
|
}
|
|
36197
36267
|
|
|
36198
36268
|
// src/lib/prove/context.ts
|
|
36199
|
-
var
|
|
36269
|
+
var import_node_crypto18 = require("node:crypto");
|
|
36200
36270
|
var CONTEXT_BUDGET_MS = 2e3;
|
|
36201
|
-
var sha256 = (s) => (0,
|
|
36271
|
+
var sha256 = (s) => (0, import_node_crypto18.createHash)("sha256").update(s).digest("hex");
|
|
36202
36272
|
var TEST_PATH4 = /(^|\/)(tests?|__tests__|spec)\/|\.(test|spec)\.[a-z]+$/;
|
|
36203
36273
|
function slice(content, f, maxLines) {
|
|
36204
36274
|
const all = content.split("\n");
|
|
@@ -36387,7 +36457,7 @@ function workingTreeReader(root) {
|
|
|
36387
36457
|
};
|
|
36388
36458
|
}
|
|
36389
36459
|
function sha256Of(content) {
|
|
36390
|
-
return (0,
|
|
36460
|
+
return (0, import_node_crypto19.createHash)("sha256").update(content).digest("hex");
|
|
36391
36461
|
}
|
|
36392
36462
|
function defaultDeps(opts) {
|
|
36393
36463
|
const env = opts.env ?? process.env;
|
|
@@ -36638,7 +36708,7 @@ async function runFormalPhase(input) {
|
|
|
36638
36708
|
modelName = gen.name;
|
|
36639
36709
|
const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
|
|
36640
36710
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
36641
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
36711
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path46.join)(root, rel);
|
|
36642
36712
|
progress.model = { name: gen.name, file: rel, rounds: round };
|
|
36643
36713
|
progress.step = "check";
|
|
36644
36714
|
report = await deps.check(root, abs);
|
|
@@ -36699,11 +36769,11 @@ async function runFormalPhase(input) {
|
|
|
36699
36769
|
const budget = Math.max(2e4, timeLeft() - 5e3);
|
|
36700
36770
|
const byId = /* @__PURE__ */ new Map();
|
|
36701
36771
|
let stoppedEarly = false;
|
|
36702
|
-
await new Promise((
|
|
36772
|
+
await new Promise((resolve9) => {
|
|
36703
36773
|
let left = toReplay.length;
|
|
36704
|
-
if (left === 0) return
|
|
36774
|
+
if (left === 0) return resolve9();
|
|
36705
36775
|
const settle = () => {
|
|
36706
|
-
if (--left === 0)
|
|
36776
|
+
if (--left === 0) resolve9();
|
|
36707
36777
|
};
|
|
36708
36778
|
for (const p of toReplay) {
|
|
36709
36779
|
void (async () => {
|
|
@@ -36716,7 +36786,7 @@ async function runFormalPhase(input) {
|
|
|
36716
36786
|
if (!stoppedEarly) byId.set(p.id, r);
|
|
36717
36787
|
if (r.verdict === "reproduced" && !stoppedEarly && !isCrash(p)) {
|
|
36718
36788
|
stoppedEarly = true;
|
|
36719
|
-
|
|
36789
|
+
resolve9();
|
|
36720
36790
|
}
|
|
36721
36791
|
})().catch(() => {
|
|
36722
36792
|
byId.set(p.id, null);
|
|
@@ -36760,7 +36830,7 @@ async function runFormalPhase(input) {
|
|
|
36760
36830
|
return done({
|
|
36761
36831
|
status: "checked",
|
|
36762
36832
|
target,
|
|
36763
|
-
model: { name: modelName, file: (0,
|
|
36833
|
+
model: { name: modelName, file: (0, import_node_path46.relative)(root, (0, import_node_path46.join)(root, modelFile)), rounds },
|
|
36764
36834
|
properties: report.properties,
|
|
36765
36835
|
findings
|
|
36766
36836
|
});
|
|
@@ -36823,7 +36893,7 @@ async function generateAndCheck(root, req, opts) {
|
|
|
36823
36893
|
}
|
|
36824
36894
|
const rel = `${dir}/${gen.name}.lean`;
|
|
36825
36895
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
36826
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
36896
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path46.join)(root, rel);
|
|
36827
36897
|
const report = await opts.deps.check(root, abs);
|
|
36828
36898
|
const abstracts = report.header?.abstracts ?? [];
|
|
36829
36899
|
const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
|
|
@@ -36911,10 +36981,10 @@ function runFormalPhaseWithin(input) {
|
|
|
36911
36981
|
if (left <= 0) return Promise.resolve(skippedOutcome("deadline", "no time left"));
|
|
36912
36982
|
const progress = input.progress ?? {};
|
|
36913
36983
|
let timer = null;
|
|
36914
|
-
const cutoff = new Promise((
|
|
36984
|
+
const cutoff = new Promise((resolve9) => {
|
|
36915
36985
|
timer = setTimeout(() => {
|
|
36916
36986
|
progress.cancelled = true;
|
|
36917
|
-
|
|
36987
|
+
resolve9(cutOffOutcome(progress, `hard stop after ${Math.round(left / 1e3)} s during ${progress.step ?? "setup"}`, left));
|
|
36918
36988
|
}, left);
|
|
36919
36989
|
});
|
|
36920
36990
|
return Promise.race([runFormalPhase({ ...input, progress }), cutoff]).finally(() => {
|
|
@@ -36952,12 +37022,12 @@ var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
|
|
|
36952
37022
|
var WRITERS_BUDGET_MS = 1500;
|
|
36953
37023
|
var EXCERPT_MAX_LINES2 = 30;
|
|
36954
37024
|
var GUARD_BLOCK_CAP = 2;
|
|
36955
|
-
var GUARD_ITER_FILE = (0,
|
|
37025
|
+
var GUARD_ITER_FILE = (0, import_node_path47.join)(VERITY_DIR, ".guard-iteration");
|
|
36956
37026
|
function readPreToolUseStdin() {
|
|
36957
37027
|
const empty = { command: "", cwd: null, sessionId: null };
|
|
36958
|
-
return new Promise((
|
|
37028
|
+
return new Promise((resolve9) => {
|
|
36959
37029
|
try {
|
|
36960
|
-
if (process.stdin.isTTY) return
|
|
37030
|
+
if (process.stdin.isTTY) return resolve9(empty);
|
|
36961
37031
|
const chunks = [];
|
|
36962
37032
|
let timer;
|
|
36963
37033
|
let settled = false;
|
|
@@ -36970,7 +37040,7 @@ function readPreToolUseStdin() {
|
|
|
36970
37040
|
process.stdin.removeListener("end", onEnd);
|
|
36971
37041
|
process.stdin.removeListener("error", onError);
|
|
36972
37042
|
process.stdin.pause();
|
|
36973
|
-
|
|
37043
|
+
resolve9(value);
|
|
36974
37044
|
};
|
|
36975
37045
|
const onEnd = () => {
|
|
36976
37046
|
try {
|
|
@@ -36991,7 +37061,7 @@ function readPreToolUseStdin() {
|
|
|
36991
37061
|
process.stdin.on("error", onError);
|
|
36992
37062
|
process.stdin.resume();
|
|
36993
37063
|
} catch {
|
|
36994
|
-
|
|
37064
|
+
resolve9(empty);
|
|
36995
37065
|
}
|
|
36996
37066
|
});
|
|
36997
37067
|
}
|
|
@@ -37720,7 +37790,7 @@ function registerIgnoreCommand(program2) {
|
|
|
37720
37790
|
}
|
|
37721
37791
|
|
|
37722
37792
|
// src/commands/waive.ts
|
|
37723
|
-
var
|
|
37793
|
+
var import_node_crypto20 = require("node:crypto");
|
|
37724
37794
|
var import_node_fs60 = require("node:fs");
|
|
37725
37795
|
function registerWaiveCommand(program2) {
|
|
37726
37796
|
program2.command("waive <pattern-id>").description("Record an accepted-risk disposition for an open finding (voids when the file changes)").option("--file <path>", "File the finding is anchored to, REPO-RELATIVE (recommended \u2014 narrows the waive)").requiredOption("--reason <text>", "The human disposition this records (reviewer finding, ADR, \u2026)").action(async (patternId, opts) => {
|
|
@@ -37750,7 +37820,7 @@ function registerWaiveCommand(program2) {
|
|
|
37750
37820
|
if (opts.file) {
|
|
37751
37821
|
body2.file = opts.file;
|
|
37752
37822
|
try {
|
|
37753
|
-
body2.file_sha256 = (0,
|
|
37823
|
+
body2.file_sha256 = (0, import_node_crypto20.createHash)("sha256").update((0, import_node_fs60.readFileSync)(opts.file)).digest("hex");
|
|
37754
37824
|
} catch {
|
|
37755
37825
|
printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
|
|
37756
37826
|
process.exit(1);
|
|
@@ -37778,7 +37848,7 @@ function registerWaiveCommand(program2) {
|
|
|
37778
37848
|
var import_node_fs65 = require("node:fs");
|
|
37779
37849
|
var import_promises20 = require("node:fs/promises");
|
|
37780
37850
|
var import_yaml6 = __toESM2(require_dist());
|
|
37781
|
-
var
|
|
37851
|
+
var import_node_path51 = require("node:path");
|
|
37782
37852
|
var import_node_child_process19 = require("node:child_process");
|
|
37783
37853
|
|
|
37784
37854
|
// src/lib/banner.ts
|
|
@@ -37918,13 +37988,13 @@ function checkAnalysisCli() {
|
|
|
37918
37988
|
}
|
|
37919
37989
|
var INSTALL_TIMEOUT_MS = 12e4;
|
|
37920
37990
|
function run3(command, args2, opts = {}) {
|
|
37921
|
-
return new Promise((
|
|
37991
|
+
return new Promise((resolve9) => {
|
|
37922
37992
|
const child = (0, import_node_child_process16.spawn)(command, args2, {
|
|
37923
37993
|
stdio: opts.inherit ? "inherit" : "pipe",
|
|
37924
37994
|
timeout: INSTALL_TIMEOUT_MS
|
|
37925
37995
|
});
|
|
37926
|
-
child.on("error", () =>
|
|
37927
|
-
child.on("close", (code) =>
|
|
37996
|
+
child.on("error", () => resolve9(false));
|
|
37997
|
+
child.on("close", (code) => resolve9(code === 0));
|
|
37928
37998
|
});
|
|
37929
37999
|
}
|
|
37930
38000
|
async function installAnalysisCli() {
|
|
@@ -38229,7 +38299,7 @@ function registerDoctorCommand(program2) {
|
|
|
38229
38299
|
|
|
38230
38300
|
// src/commands/migrate.ts
|
|
38231
38301
|
var import_node_fs62 = require("node:fs");
|
|
38232
|
-
var
|
|
38302
|
+
var import_node_path48 = require("node:path");
|
|
38233
38303
|
var import_node_child_process17 = require("node:child_process");
|
|
38234
38304
|
var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
|
|
38235
38305
|
function defaultNpmRemover(pkg) {
|
|
@@ -38266,8 +38336,8 @@ async function runMigration(opts = {}) {
|
|
|
38266
38336
|
return { actions, migrated: actions.length > 0 };
|
|
38267
38337
|
}
|
|
38268
38338
|
function migrateProjectDir(root, actions) {
|
|
38269
|
-
const gateDir = (0,
|
|
38270
|
-
const verityDir = (0,
|
|
38339
|
+
const gateDir = (0, import_node_path48.join)(root, ".gate");
|
|
38340
|
+
const verityDir = (0, import_node_path48.join)(root, ".verity");
|
|
38271
38341
|
if ((0, import_node_fs62.existsSync)(gateDir) && !(0, import_node_fs62.existsSync)(verityDir)) {
|
|
38272
38342
|
return migrateProjectDirRename(root, gateDir, verityDir, actions);
|
|
38273
38343
|
}
|
|
@@ -38321,11 +38391,11 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
|
|
|
38321
38391
|
}
|
|
38322
38392
|
function migrateGlobalCredentials(home, actions) {
|
|
38323
38393
|
if (!home) return;
|
|
38324
|
-
const gateCreds = (0,
|
|
38325
|
-
const verityCreds = (0,
|
|
38394
|
+
const gateCreds = (0, import_node_path48.join)(home, ".gate", "credentials");
|
|
38395
|
+
const verityCreds = (0, import_node_path48.join)(home, ".verity", "credentials");
|
|
38326
38396
|
if (!(0, import_node_fs62.existsSync)(gateCreds)) return;
|
|
38327
38397
|
if (!(0, import_node_fs62.existsSync)(verityCreds)) {
|
|
38328
|
-
(0, import_node_fs62.mkdirSync)((0,
|
|
38398
|
+
(0, import_node_fs62.mkdirSync)((0, import_node_path48.join)(home, ".verity"), { recursive: true });
|
|
38329
38399
|
moveFile(gateCreds, verityCreds);
|
|
38330
38400
|
actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
|
|
38331
38401
|
return;
|
|
@@ -38347,7 +38417,7 @@ async function migrateLegacyHooks(root, actions) {
|
|
|
38347
38417
|
}
|
|
38348
38418
|
}
|
|
38349
38419
|
async function migrateClaudeMd(root, actions) {
|
|
38350
|
-
const claudeMd = (0,
|
|
38420
|
+
const claudeMd = (0, import_node_path48.join)(root, "CLAUDE.md");
|
|
38351
38421
|
const hadLegacyBlock = (0, import_node_fs62.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
|
|
38352
38422
|
if (!hadLegacyBlock) return;
|
|
38353
38423
|
try {
|
|
@@ -38358,8 +38428,8 @@ async function migrateClaudeMd(root, actions) {
|
|
|
38358
38428
|
}
|
|
38359
38429
|
}
|
|
38360
38430
|
function migrateStandardFile(root, actions) {
|
|
38361
|
-
const gateMd = (0,
|
|
38362
|
-
const verityMd = (0,
|
|
38431
|
+
const gateMd = (0, import_node_path48.join)(root, "GATE.md");
|
|
38432
|
+
const verityMd = (0, import_node_path48.join)(root, "VERITY.md");
|
|
38363
38433
|
if (!(0, import_node_fs62.existsSync)(gateMd) || (0, import_node_fs62.existsSync)(verityMd)) return;
|
|
38364
38434
|
let moved = false;
|
|
38365
38435
|
if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
|
|
@@ -38376,7 +38446,7 @@ function migrateStandardFile(root, actions) {
|
|
|
38376
38446
|
actions.push("Renamed GATE.md \u2192 VERITY.md");
|
|
38377
38447
|
}
|
|
38378
38448
|
async function migrateTelemetryHeaders(root, actions) {
|
|
38379
|
-
const file = (0,
|
|
38449
|
+
const file = (0, import_node_path48.join)(root, ".claude", "settings.local.json");
|
|
38380
38450
|
if (!(0, import_node_fs62.existsSync)(file)) return;
|
|
38381
38451
|
let settings;
|
|
38382
38452
|
try {
|
|
@@ -38466,15 +38536,15 @@ function moveFile(from, to) {
|
|
|
38466
38536
|
function carryLegacyContents(gateDir, verityDir) {
|
|
38467
38537
|
let copied = 0;
|
|
38468
38538
|
const walk2 = (relDir) => {
|
|
38469
|
-
const srcDir = (0,
|
|
38539
|
+
const srcDir = (0, import_node_path48.join)(gateDir, relDir);
|
|
38470
38540
|
for (const entry of (0, import_node_fs62.readdirSync)(srcDir)) {
|
|
38471
|
-
const rel = relDir ? (0,
|
|
38472
|
-
const src = (0,
|
|
38473
|
-
const dest = (0,
|
|
38541
|
+
const rel = relDir ? (0, import_node_path48.join)(relDir, entry) : entry;
|
|
38542
|
+
const src = (0, import_node_path48.join)(gateDir, rel);
|
|
38543
|
+
const dest = (0, import_node_path48.join)(verityDir, rel);
|
|
38474
38544
|
if ((0, import_node_fs62.statSync)(src).isDirectory()) {
|
|
38475
38545
|
walk2(rel);
|
|
38476
38546
|
} else if (!(0, import_node_fs62.existsSync)(dest)) {
|
|
38477
|
-
(0, import_node_fs62.mkdirSync)((0,
|
|
38547
|
+
(0, import_node_fs62.mkdirSync)((0, import_node_path48.dirname)(dest), { recursive: true });
|
|
38478
38548
|
(0, import_node_fs62.cpSync)(src, dest);
|
|
38479
38549
|
copied++;
|
|
38480
38550
|
}
|
|
@@ -38484,22 +38554,22 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
38484
38554
|
return copied;
|
|
38485
38555
|
}
|
|
38486
38556
|
async function needsMigration(root = repoRoot()) {
|
|
38487
|
-
const gateDir = (0,
|
|
38488
|
-
const verityDir = (0,
|
|
38557
|
+
const gateDir = (0, import_node_path48.join)(root, ".gate");
|
|
38558
|
+
const verityDir = (0, import_node_path48.join)(root, ".verity");
|
|
38489
38559
|
if ((0, import_node_fs62.existsSync)(gateDir) && !(0, import_node_fs62.existsSync)(verityDir)) return true;
|
|
38490
38560
|
if ((0, import_node_fs62.existsSync)(gateDir) && (0, import_node_fs62.existsSync)(verityDir)) {
|
|
38491
|
-
if ((0, import_node_fs62.existsSync)((0,
|
|
38561
|
+
if ((0, import_node_fs62.existsSync)((0, import_node_path48.join)(gateDir, "credentials")) && !(0, import_node_fs62.existsSync)((0, import_node_path48.join)(verityDir, "credentials"))) {
|
|
38492
38562
|
return true;
|
|
38493
38563
|
}
|
|
38494
|
-
if ((0, import_node_fs62.existsSync)((0,
|
|
38564
|
+
if ((0, import_node_fs62.existsSync)((0, import_node_path48.join)(gateDir, "memory")) && !(0, import_node_fs62.existsSync)((0, import_node_path48.join)(verityDir, "memory"))) {
|
|
38495
38565
|
return true;
|
|
38496
38566
|
}
|
|
38497
38567
|
}
|
|
38498
|
-
const claudeMd = (0,
|
|
38568
|
+
const claudeMd = (0, import_node_path48.join)(root, "CLAUDE.md");
|
|
38499
38569
|
if ((0, import_node_fs62.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
|
|
38500
38570
|
return true;
|
|
38501
38571
|
}
|
|
38502
|
-
if ((0, import_node_fs62.existsSync)((0,
|
|
38572
|
+
if ((0, import_node_fs62.existsSync)((0, import_node_path48.join)(root, "GATE.md")) && !(0, import_node_fs62.existsSync)((0, import_node_path48.join)(root, "VERITY.md"))) {
|
|
38503
38573
|
return true;
|
|
38504
38574
|
}
|
|
38505
38575
|
if (await hasLegacyHooksAt(root)) return true;
|
|
@@ -38628,7 +38698,7 @@ function runSelect(opts) {
|
|
|
38628
38698
|
cursor: initialIdx[0] ?? 0,
|
|
38629
38699
|
chosen: new Set(mode2 === "single" ? [initialIdx[0] ?? 0] : initialIdx)
|
|
38630
38700
|
};
|
|
38631
|
-
return new Promise((
|
|
38701
|
+
return new Promise((resolve9) => {
|
|
38632
38702
|
let painted = 0;
|
|
38633
38703
|
let settled = false;
|
|
38634
38704
|
const draw = () => {
|
|
@@ -38676,7 +38746,7 @@ function runSelect(opts) {
|
|
|
38676
38746
|
if (settled) return;
|
|
38677
38747
|
settled = true;
|
|
38678
38748
|
restore();
|
|
38679
|
-
|
|
38749
|
+
resolve9(value);
|
|
38680
38750
|
};
|
|
38681
38751
|
readline2.emitKeypressEvents(input);
|
|
38682
38752
|
input.setRawMode(true);
|
|
@@ -38697,9 +38767,9 @@ async function askLine(question, io = {}) {
|
|
|
38697
38767
|
output: io.output ?? process.stdout
|
|
38698
38768
|
});
|
|
38699
38769
|
try {
|
|
38700
|
-
return await new Promise((
|
|
38701
|
-
rl.question(question).then((a) =>
|
|
38702
|
-
rl.once("close", () => setImmediate(() =>
|
|
38770
|
+
return await new Promise((resolve9) => {
|
|
38771
|
+
rl.question(question).then((a) => resolve9(a.trim())).catch(() => resolve9(null));
|
|
38772
|
+
rl.once("close", () => setImmediate(() => resolve9(null)));
|
|
38703
38773
|
});
|
|
38704
38774
|
} finally {
|
|
38705
38775
|
rl.close();
|
|
@@ -38781,10 +38851,10 @@ async function promptMultiSelect(question, choices, fallback) {
|
|
|
38781
38851
|
|
|
38782
38852
|
// src/lib/prove/lean-install.ts
|
|
38783
38853
|
var import_node_fs63 = require("node:fs");
|
|
38784
|
-
var
|
|
38854
|
+
var import_node_crypto21 = require("node:crypto");
|
|
38785
38855
|
var import_node_child_process18 = require("node:child_process");
|
|
38786
38856
|
var import_node_os10 = require("node:os");
|
|
38787
|
-
var
|
|
38857
|
+
var import_node_path49 = require("node:path");
|
|
38788
38858
|
var import_promises18 = require("node:stream/promises");
|
|
38789
38859
|
var import_node_stream = require("node:stream");
|
|
38790
38860
|
var RELEASES = "https://releases.lean-lang.org/lean4";
|
|
@@ -38798,7 +38868,7 @@ function freeBytes(dir) {
|
|
|
38798
38868
|
const st = (0, import_node_fs63.statfsSync)(d);
|
|
38799
38869
|
return Number(st.bavail) * Number(st.bsize);
|
|
38800
38870
|
} catch {
|
|
38801
|
-
const up = (0,
|
|
38871
|
+
const up = (0, import_node_path49.join)(d, "..");
|
|
38802
38872
|
if (up === d) return null;
|
|
38803
38873
|
d = up;
|
|
38804
38874
|
}
|
|
@@ -38818,9 +38888,9 @@ function expectedSha256(asset, version = pinnedVersion()) {
|
|
|
38818
38888
|
return LEAN_ASSET_SHA256[version]?.[asset] ?? null;
|
|
38819
38889
|
}
|
|
38820
38890
|
function sha256File(path) {
|
|
38821
|
-
return new Promise((
|
|
38822
|
-
const hash = (0,
|
|
38823
|
-
(0, import_node_fs63.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () =>
|
|
38891
|
+
return new Promise((resolve9, reject) => {
|
|
38892
|
+
const hash = (0, import_node_crypto21.createHash)("sha256");
|
|
38893
|
+
(0, import_node_fs63.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve9(hash.digest("hex"))).on("error", reject);
|
|
38824
38894
|
});
|
|
38825
38895
|
}
|
|
38826
38896
|
async function verifyDownload(zip, asset, version = pinnedVersion()) {
|
|
@@ -38840,7 +38910,7 @@ function leanAssetName(version = pinnedVersion()) {
|
|
|
38840
38910
|
return suffix ? `lean-${v}-${suffix}.zip` : null;
|
|
38841
38911
|
}
|
|
38842
38912
|
function pinnedVersionDir(env = process.env) {
|
|
38843
|
-
return (0,
|
|
38913
|
+
return (0, import_node_path49.join)(verityLeanHome(env), pinnedVersion());
|
|
38844
38914
|
}
|
|
38845
38915
|
function lakeBinary() {
|
|
38846
38916
|
return (0, import_node_os10.platform)() === "win32" ? "lake.exe" : "lake";
|
|
@@ -38856,7 +38926,7 @@ function unzip(zip, dest) {
|
|
|
38856
38926
|
} catch (err2) {
|
|
38857
38927
|
errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
|
|
38858
38928
|
try {
|
|
38859
|
-
for (const e of (0, import_node_fs63.readdirSync)(dest)) (0, import_node_fs63.rmSync)((0,
|
|
38929
|
+
for (const e of (0, import_node_fs63.readdirSync)(dest)) (0, import_node_fs63.rmSync)((0, import_node_path49.join)(dest, e), { recursive: true, force: true });
|
|
38860
38930
|
} catch {
|
|
38861
38931
|
}
|
|
38862
38932
|
}
|
|
@@ -38932,10 +39002,10 @@ async function installLean(opts = {}) {
|
|
|
38932
39002
|
const gb = (n) => (n / 1024 ** 3).toFixed(1);
|
|
38933
39003
|
return { ok: false, error: `not enough disk space for Lean: ${gb(free)} GB free where ${home} lives, needs about ${gb(needed)} GB` };
|
|
38934
39004
|
}
|
|
38935
|
-
const tmp = (0,
|
|
39005
|
+
const tmp = (0, import_node_path49.join)(home, ".tmp");
|
|
38936
39006
|
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
38937
39007
|
(0, import_node_fs63.mkdirSync)(tmp, { recursive: true });
|
|
38938
|
-
const zip = (0,
|
|
39008
|
+
const zip = (0, import_node_path49.join)(tmp, asset);
|
|
38939
39009
|
say(`downloading ${url}`);
|
|
38940
39010
|
let lastPct = -1;
|
|
38941
39011
|
try {
|
|
@@ -38958,7 +39028,7 @@ async function installLean(opts = {}) {
|
|
|
38958
39028
|
return { ok: false, error: verified.error };
|
|
38959
39029
|
}
|
|
38960
39030
|
say("unpacking (this takes a minute)");
|
|
38961
|
-
const unpack = (0,
|
|
39031
|
+
const unpack = (0, import_node_path49.join)(tmp, "unpack");
|
|
38962
39032
|
(0, import_node_fs63.mkdirSync)(unpack);
|
|
38963
39033
|
const unpacked = unzip(zip, unpack);
|
|
38964
39034
|
if (!unpacked.ok) {
|
|
@@ -38966,8 +39036,8 @@ async function installLean(opts = {}) {
|
|
|
38966
39036
|
return { ok: false, error: `unpack failed: ${unpacked.error}` };
|
|
38967
39037
|
}
|
|
38968
39038
|
const entries = (0, import_node_fs63.readdirSync)(unpack);
|
|
38969
|
-
const top = entries.length === 1 && (0, import_node_fs63.statSync)((0,
|
|
38970
|
-
if (!(0, import_node_fs63.existsSync)((0,
|
|
39039
|
+
const top = entries.length === 1 && (0, import_node_fs63.statSync)((0, import_node_path49.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path49.join)(unpack, entries[0]) : unpack;
|
|
39040
|
+
if (!(0, import_node_fs63.existsSync)((0, import_node_path49.join)(top, "bin", lakeBinary()))) {
|
|
38971
39041
|
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
38972
39042
|
return { ok: false, error: "the archive did not contain bin/lake" };
|
|
38973
39043
|
}
|
|
@@ -38981,7 +39051,7 @@ async function installLean(opts = {}) {
|
|
|
38981
39051
|
// src/lib/remote-config.ts
|
|
38982
39052
|
var import_node_fs64 = require("node:fs");
|
|
38983
39053
|
var import_promises19 = require("node:fs/promises");
|
|
38984
|
-
var
|
|
39054
|
+
var import_node_path50 = require("node:path");
|
|
38985
39055
|
var import_yaml5 = __toESM2(require_dist());
|
|
38986
39056
|
var IGNORE_RIDER = "verityignore";
|
|
38987
39057
|
async function fetchRemoteSetup(opts) {
|
|
@@ -39059,7 +39129,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
39059
39129
|
}
|
|
39060
39130
|
async function writeOut(relative6, body2) {
|
|
39061
39131
|
const target = projectPath(relative6);
|
|
39062
|
-
await (0, import_promises19.mkdir)((0,
|
|
39132
|
+
await (0, import_promises19.mkdir)((0, import_node_path50.dirname)(target), { recursive: true });
|
|
39063
39133
|
await (0, import_promises19.writeFile)(target, body2);
|
|
39064
39134
|
}
|
|
39065
39135
|
function describeRemote(found) {
|
|
@@ -39176,15 +39246,15 @@ async function runOptionalAuth(resolution, opts = {}) {
|
|
|
39176
39246
|
}
|
|
39177
39247
|
function resolveDataDir2() {
|
|
39178
39248
|
const candidates2 = [
|
|
39179
|
-
(0,
|
|
39249
|
+
(0, import_node_path51.join)(__dirname, "..", "data"),
|
|
39180
39250
|
// installed: node_modules/@codacy/verity-cli/data
|
|
39181
|
-
(0,
|
|
39251
|
+
(0, import_node_path51.join)(__dirname, "..", "..", "data"),
|
|
39182
39252
|
// edge case: nested resolution
|
|
39183
|
-
(0,
|
|
39253
|
+
(0, import_node_path51.join)(process.cwd(), "cli", "data")
|
|
39184
39254
|
// local dev: running from repo root
|
|
39185
39255
|
];
|
|
39186
39256
|
for (const candidate of candidates2) {
|
|
39187
|
-
if ((0, import_node_fs65.existsSync)((0,
|
|
39257
|
+
if ((0, import_node_fs65.existsSync)((0, import_node_path51.join)(candidate, "skills"))) {
|
|
39188
39258
|
return candidate;
|
|
39189
39259
|
}
|
|
39190
39260
|
}
|
|
@@ -39202,7 +39272,7 @@ async function skillIsCurrent(src, dest) {
|
|
|
39202
39272
|
const walk2 = (d, prefix) => {
|
|
39203
39273
|
for (const e of (0, import_node_fs65.readdirSync)(d, { withFileTypes: true })) {
|
|
39204
39274
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
39205
|
-
if (e.isDirectory()) walk2((0,
|
|
39275
|
+
if (e.isDirectory()) walk2((0, import_node_path51.join)(d, e.name), rel);
|
|
39206
39276
|
else if (e.isFile()) out2.push(rel);
|
|
39207
39277
|
}
|
|
39208
39278
|
};
|
|
@@ -39213,8 +39283,8 @@ async function skillIsCurrent(src, dest) {
|
|
|
39213
39283
|
const shipped = list2(src);
|
|
39214
39284
|
if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
|
|
39215
39285
|
for (const rel of shipped) {
|
|
39216
|
-
const a = await (0, import_promises20.readFile)((0,
|
|
39217
|
-
const b = await (0, import_promises20.readFile)((0,
|
|
39286
|
+
const a = await (0, import_promises20.readFile)((0, import_node_path51.join)(src, rel), "utf-8");
|
|
39287
|
+
const b = await (0, import_promises20.readFile)((0, import_node_path51.join)(dest, rel), "utf-8");
|
|
39218
39288
|
if (a !== b) return false;
|
|
39219
39289
|
}
|
|
39220
39290
|
return true;
|
|
@@ -39514,12 +39584,12 @@ async function handoffToSetup(enabled, claudeInstalled) {
|
|
|
39514
39584
|
async function installSkills(force, step) {
|
|
39515
39585
|
step("Installing skills");
|
|
39516
39586
|
const dataDir = resolveDataDir2();
|
|
39517
|
-
const skillsSource = (0,
|
|
39587
|
+
const skillsSource = (0, import_node_path51.join)(dataDir, "skills");
|
|
39518
39588
|
const skillsDest = ".claude/skills";
|
|
39519
39589
|
let skillsInstalled = 0;
|
|
39520
39590
|
for (const skill of SKILLS) {
|
|
39521
|
-
const src = (0,
|
|
39522
|
-
const dest = (0,
|
|
39591
|
+
const src = (0, import_node_path51.join)(skillsSource, skill);
|
|
39592
|
+
const dest = (0, import_node_path51.join)(skillsDest, skill);
|
|
39523
39593
|
if (!(0, import_node_fs65.existsSync)(src)) {
|
|
39524
39594
|
printWarn(` Skill data not found: ${skill}`);
|
|
39525
39595
|
continue;
|
|
@@ -39827,7 +39897,7 @@ function registerInitCommand(program2) {
|
|
|
39827
39897
|
untrackMemory: opts.untrackMemory === true,
|
|
39828
39898
|
untrackState: opts.untrackState === true
|
|
39829
39899
|
});
|
|
39830
|
-
const globalVerityDir = (0,
|
|
39900
|
+
const globalVerityDir = (0, import_node_path51.join)(process.env.HOME ?? "", ".verity");
|
|
39831
39901
|
await (0, import_promises20.mkdir)(globalVerityDir, { recursive: true });
|
|
39832
39902
|
console.log("");
|
|
39833
39903
|
step("Wiring Claude Code hooks");
|
|
@@ -39932,7 +40002,7 @@ function registerInitCommand(program2) {
|
|
|
39932
40002
|
...telemetryChoice ? { telemetry: telemetryChoice } : {},
|
|
39933
40003
|
init: {
|
|
39934
40004
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
39935
|
-
cli_version: true ? "0.34.0-experimental.
|
|
40005
|
+
cli_version: true ? "0.34.0-experimental.3d4888f" : "dev"
|
|
39936
40006
|
}
|
|
39937
40007
|
});
|
|
39938
40008
|
} catch (err2) {
|
|
@@ -39983,7 +40053,7 @@ function registerInitCommand(program2) {
|
|
|
39983
40053
|
|
|
39984
40054
|
// src/commands/uninstall.ts
|
|
39985
40055
|
var import_node_fs66 = require("node:fs");
|
|
39986
|
-
var
|
|
40056
|
+
var import_node_path52 = require("node:path");
|
|
39987
40057
|
function registerUninstallCommand(program2) {
|
|
39988
40058
|
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) => {
|
|
39989
40059
|
const dryRun = opts.dryRun ?? false;
|
|
@@ -39992,7 +40062,7 @@ function registerUninstallCommand(program2) {
|
|
|
39992
40062
|
const actions = [];
|
|
39993
40063
|
const skillsRoot = projectPath(".claude/skills");
|
|
39994
40064
|
for (const name2 of PROJECT_SKILL_NAMES) {
|
|
39995
|
-
const dir = (0,
|
|
40065
|
+
const dir = (0, import_node_path52.join)(skillsRoot, name2);
|
|
39996
40066
|
if ((0, import_node_fs66.existsSync)(dir)) {
|
|
39997
40067
|
actions.push({
|
|
39998
40068
|
label: `Remove .claude/skills/${name2}/`,
|
|
@@ -40038,7 +40108,7 @@ function registerUninstallCommand(program2) {
|
|
|
40038
40108
|
}
|
|
40039
40109
|
});
|
|
40040
40110
|
const home = process.env.HOME ?? "";
|
|
40041
|
-
const globalVerityDir = (0,
|
|
40111
|
+
const globalVerityDir = (0, import_node_path52.join)(home, ".verity");
|
|
40042
40112
|
if (purgeGlobal && (0, import_node_fs66.existsSync)(globalVerityDir)) {
|
|
40043
40113
|
actions.push({
|
|
40044
40114
|
label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
|
|
@@ -40237,7 +40307,7 @@ function registerTaskCommands(program2) {
|
|
|
40237
40307
|
|
|
40238
40308
|
// src/commands/reset.ts
|
|
40239
40309
|
var import_node_fs67 = require("node:fs");
|
|
40240
|
-
var
|
|
40310
|
+
var import_node_path53 = require("node:path");
|
|
40241
40311
|
function registerResetCommand(program2) {
|
|
40242
40312
|
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) => {
|
|
40243
40313
|
const globals = program2.opts();
|
|
@@ -40278,7 +40348,7 @@ function registerResetCommand(program2) {
|
|
|
40278
40348
|
for (const entry of (0, import_node_fs67.readdirSync)(cacheDir)) {
|
|
40279
40349
|
if (entry.startsWith("pending-")) {
|
|
40280
40350
|
try {
|
|
40281
|
-
(0, import_node_fs67.unlinkSync)((0,
|
|
40351
|
+
(0, import_node_fs67.unlinkSync)((0, import_node_path53.join)(cacheDir, entry));
|
|
40282
40352
|
purged++;
|
|
40283
40353
|
} catch {
|
|
40284
40354
|
}
|
|
@@ -40305,7 +40375,7 @@ function registerResetCommand(program2) {
|
|
|
40305
40375
|
if ((0, import_node_fs67.existsSync)(logsDir)) {
|
|
40306
40376
|
for (const entry of (0, import_node_fs67.readdirSync)(logsDir)) {
|
|
40307
40377
|
try {
|
|
40308
|
-
(0, import_node_fs67.unlinkSync)((0,
|
|
40378
|
+
(0, import_node_fs67.unlinkSync)((0, import_node_path53.join)(logsDir, entry));
|
|
40309
40379
|
} catch {
|
|
40310
40380
|
}
|
|
40311
40381
|
}
|
|
@@ -40325,7 +40395,7 @@ var PATH_TOKEN = /[A-Za-z0-9_./-]*[A-Za-z0-9_-]\.[A-Za-z0-9]{1,8}(?::\d+(?::\d+)
|
|
|
40325
40395
|
function clean(token) {
|
|
40326
40396
|
return token.replace(/:\d+(?::\d+)?$/, "").replace(/^[`'"(\[]+/, "").replace(/[`'"),\].;!?]+$/, "").replace(/^\.\//, "");
|
|
40327
40397
|
}
|
|
40328
|
-
function
|
|
40398
|
+
function resolve7(token, treePaths) {
|
|
40329
40399
|
if (treePaths.includes(token)) return token;
|
|
40330
40400
|
const suffix = token.startsWith("/") ? token : `/${token}`;
|
|
40331
40401
|
const matches = treePaths.filter((p) => p.endsWith(suffix));
|
|
@@ -40338,7 +40408,7 @@ function deriveFileGlobs(text, treePaths) {
|
|
|
40338
40408
|
for (const raw of text.match(PATH_TOKEN) ?? []) {
|
|
40339
40409
|
const token = clean(raw);
|
|
40340
40410
|
if (!token) continue;
|
|
40341
|
-
const path =
|
|
40411
|
+
const path = resolve7(token, treePaths);
|
|
40342
40412
|
if (!path || seen.has(path)) continue;
|
|
40343
40413
|
seen.add(path);
|
|
40344
40414
|
out2.push(path);
|
|
@@ -40867,7 +40937,7 @@ function registerTelemetryCommands(program2) {
|
|
|
40867
40937
|
|
|
40868
40938
|
// src/commands/prove.ts
|
|
40869
40939
|
var import_node_fs70 = require("node:fs");
|
|
40870
|
-
var
|
|
40940
|
+
var import_node_path54 = require("node:path");
|
|
40871
40941
|
|
|
40872
40942
|
// src/lib/prove/hint-pool.ts
|
|
40873
40943
|
var STOP2 = /* @__PURE__ */ new Set([
|
|
@@ -41003,7 +41073,7 @@ function registerProveCommand(program2) {
|
|
|
41003
41073
|
process.exit(2);
|
|
41004
41074
|
}
|
|
41005
41075
|
const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
|
|
41006
|
-
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0,
|
|
41076
|
+
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path54.relative)(root, (0, import_node_path54.resolve)(p)) || ".") });
|
|
41007
41077
|
if (opts.hint && paths.length === 0) {
|
|
41008
41078
|
const hit = hintMatches(root, opts.hint);
|
|
41009
41079
|
if (hit.files.length > 0) {
|
|
@@ -41057,7 +41127,7 @@ function registerProveCommand(program2) {
|
|
|
41057
41127
|
});
|
|
41058
41128
|
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) => {
|
|
41059
41129
|
const root = repoRoot();
|
|
41060
|
-
if (!(0, import_node_fs70.existsSync)((0,
|
|
41130
|
+
if (!(0, import_node_fs70.existsSync)((0, import_node_path54.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41061
41131
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41062
41132
|
process.exit(2);
|
|
41063
41133
|
}
|
|
@@ -41081,7 +41151,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41081
41151
|
const reports = [];
|
|
41082
41152
|
for (const f of files) {
|
|
41083
41153
|
const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
|
|
41084
|
-
report.file = (0,
|
|
41154
|
+
report.file = (0, import_node_path54.relative)(root, f);
|
|
41085
41155
|
reports.push(report);
|
|
41086
41156
|
try {
|
|
41087
41157
|
writeResult(root, report);
|
|
@@ -41119,7 +41189,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41119
41189
|
printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
|
|
41120
41190
|
process.exit(2);
|
|
41121
41191
|
}
|
|
41122
|
-
if (!(0, import_node_fs70.existsSync)((0,
|
|
41192
|
+
if (!(0, import_node_fs70.existsSync)((0, import_node_path54.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41123
41193
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41124
41194
|
process.exit(2);
|
|
41125
41195
|
}
|
|
@@ -41150,7 +41220,7 @@ ${report.error ?? ""}`);
|
|
|
41150
41220
|
printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
|
|
41151
41221
|
return;
|
|
41152
41222
|
}
|
|
41153
|
-
const modelSource = readRegularFileInRoot(root, (0,
|
|
41223
|
+
const modelSource = readRegularFileInRoot(root, (0, import_node_path54.relative)(root, file), 512 * 1024);
|
|
41154
41224
|
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`);
|
|
41155
41225
|
const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
|
|
41156
41226
|
const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
|
|
@@ -41170,7 +41240,7 @@ ${report.error ?? ""}`);
|
|
|
41170
41240
|
});
|
|
41171
41241
|
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) => {
|
|
41172
41242
|
const root = repoRoot();
|
|
41173
|
-
let files = paths.map((p) => (0,
|
|
41243
|
+
let files = paths.map((p) => (0, import_node_path54.relative)(root, (0, import_node_path54.resolve)(p)));
|
|
41174
41244
|
if (files.length === 0) {
|
|
41175
41245
|
const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
|
|
41176
41246
|
const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
|
|
@@ -41230,7 +41300,7 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41230
41300
|
let revise;
|
|
41231
41301
|
if (opts.revise) {
|
|
41232
41302
|
const existing = resolveModelFile(root, opts.revise);
|
|
41233
|
-
const src = existing ? readRegularFileInRoot(root, (0,
|
|
41303
|
+
const src = existing ? readRegularFileInRoot(root, (0, import_node_path54.relative)(root, existing), 64 * 1024) : null;
|
|
41234
41304
|
if (!src || !src.ok || !opts.note) {
|
|
41235
41305
|
printError('--revise needs an existing model under Models/ and --note "<what the replay showed>"');
|
|
41236
41306
|
process.exit(2);
|
|
@@ -41269,8 +41339,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41269
41339
|
});
|
|
41270
41340
|
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) => {
|
|
41271
41341
|
const root = repoRoot();
|
|
41272
|
-
const rel0 = (0,
|
|
41273
|
-
const rel = rel0.startsWith("..") || (0,
|
|
41342
|
+
const rel0 = (0, import_node_path54.relative)(root, (0, import_node_path54.isAbsolute)(file) ? file : (0, import_node_path54.join)(root, file)).replace(/\\/g, "/");
|
|
41343
|
+
const rel = rel0.startsWith("..") || (0, import_node_path54.isAbsolute)(rel0) ? null : rel0;
|
|
41274
41344
|
if (!rel) {
|
|
41275
41345
|
printError(`${file} is not inside this repository`);
|
|
41276
41346
|
process.exit(2);
|
|
@@ -41286,8 +41356,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41286
41356
|
});
|
|
41287
41357
|
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) => {
|
|
41288
41358
|
const root = repoRoot();
|
|
41289
|
-
const rel = (0,
|
|
41290
|
-
const digest = rel.startsWith("..") || (0,
|
|
41359
|
+
const rel = (0, import_node_path54.relative)(root, (0, import_node_path54.isAbsolute)(file) ? file : (0, import_node_path54.join)(root, file));
|
|
41360
|
+
const digest = rel.startsWith("..") || (0, import_node_path54.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
|
|
41291
41361
|
if (!digest) {
|
|
41292
41362
|
printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
|
|
41293
41363
|
process.exit(2);
|
|
@@ -41324,7 +41394,7 @@ function refreshScaffold(root) {
|
|
|
41324
41394
|
var import_node_fs71 = require("node:fs");
|
|
41325
41395
|
var import_node_child_process20 = require("node:child_process");
|
|
41326
41396
|
var import_node_os11 = require("node:os");
|
|
41327
|
-
var
|
|
41397
|
+
var import_node_path55 = require("node:path");
|
|
41328
41398
|
function registerLeanCommand(program2) {
|
|
41329
41399
|
const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
|
|
41330
41400
|
lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
|
|
@@ -41341,7 +41411,7 @@ function registerLeanCommand(program2) {
|
|
|
41341
41411
|
const managed = pinnedVersionDir();
|
|
41342
41412
|
const matches = version ? version.includes(pin) : false;
|
|
41343
41413
|
if (opts.json) {
|
|
41344
|
-
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs71.existsSync)((0,
|
|
41414
|
+
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs71.existsSync)((0, import_node_path55.join)(managed, "bin")), asset: leanAssetName() });
|
|
41345
41415
|
return;
|
|
41346
41416
|
}
|
|
41347
41417
|
printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
|
|
@@ -41359,7 +41429,7 @@ function registerLeanCommand(program2) {
|
|
|
41359
41429
|
process.exit(2);
|
|
41360
41430
|
}
|
|
41361
41431
|
const dir = pinnedVersionDir();
|
|
41362
|
-
if ((0, import_node_fs71.existsSync)((0,
|
|
41432
|
+
if ((0, import_node_fs71.existsSync)((0, import_node_path55.join)(dir, "bin", "lake")) && !opts.force) {
|
|
41363
41433
|
printInfo(`already installed at ${dir}`);
|
|
41364
41434
|
return;
|
|
41365
41435
|
}
|
|
@@ -41405,8 +41475,8 @@ function registerLeanCommand(program2) {
|
|
|
41405
41475
|
}
|
|
41406
41476
|
|
|
41407
41477
|
// src/cli.ts
|
|
41408
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.
|
|
41409
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.
|
|
41478
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.3d4888f").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) => {
|
|
41479
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.3d4888f");
|
|
41410
41480
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
41411
41481
|
try {
|
|
41412
41482
|
await foldLegacyLocalCredential();
|