@codacy/verity-cli 0.34.0-experimental.37a6dcf → 0.34.0-experimental.380b51f
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/README.md +2 -0
- package/bin/verity.js +820 -598
- package/data/skills/verity-analyze/SKILL.md +17 -5
- package/data/skills/verity-feedback/SKILL.md +19 -3
- package/data/skills/verity-learn/SKILL.md +19 -7
- package/data/skills/verity-memory/SKILL.md +21 -8
- package/data/skills/verity-prove/SKILL.md +35 -9
- package/data/skills/verity-reflect/SKILL.md +16 -3
- 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");
|
|
@@ -20037,6 +20058,97 @@ var LEGACY_MD_END = "<!-- gate-memory:end -->";
|
|
|
20037
20058
|
var LEGACY_PRESERVE_START = "<!-- gate-memory:preserve -->";
|
|
20038
20059
|
var LEGACY_PRESERVE_END = "<!-- /gate-memory:preserve -->";
|
|
20039
20060
|
var CLAUDE_MD_PROSE = [
|
|
20061
|
+
"## Project Memory",
|
|
20062
|
+
"",
|
|
20063
|
+
"This project has a knowledge graph maintained at `.verity/memory/`. Before starting",
|
|
20064
|
+
"non-trivial work, scan `.verity/memory/index.md` for decisions, gotchas, and patterns",
|
|
20065
|
+
"that may apply to the change you are about to make. Open specific node files via",
|
|
20066
|
+
"the Read tool when the title or scope suggests relevance.",
|
|
20067
|
+
"",
|
|
20068
|
+
"The graph is auto-maintained by Verity. Files at `.verity/memory/_archive/` are",
|
|
20069
|
+
"superseded \u2014 ignore them unless investigating history.",
|
|
20070
|
+
"",
|
|
20071
|
+
"Knowledge the organization's other repositories learned is mirrored outside the",
|
|
20072
|
+
"repo at `~/.verity/orgs/<host>/<owner>/memory/` (`verity memory org` lists it).",
|
|
20073
|
+
"Each claim says where it came from; one that is wrong here is demoted for",
|
|
20074
|
+
'everyone with `verity memory demote <id> --reason "\u2026"`.',
|
|
20075
|
+
"",
|
|
20076
|
+
"## Quality gate: accepted risks",
|
|
20077
|
+
"",
|
|
20078
|
+
"When the Verity pre-commit/pre-push gate FAILs, fix the findings \u2014 that is the",
|
|
20079
|
+
'default. Use `verity waive <pattern-id> --file <path> --reason "\u2026"` ONLY to relay',
|
|
20080
|
+
"a risk a human has explicitly accepted: a named code-review finding, an ADR, or",
|
|
20081
|
+
"the user saying so in this conversation. The --reason must cite that source.",
|
|
20082
|
+
"",
|
|
20083
|
+
"Never waive on your own judgment, to get past a block, or pre-emptively. A waive",
|
|
20084
|
+
"binds to the file's current bytes and voids automatically when the file changes,",
|
|
20085
|
+
"and every waive is recorded in the run ledger. For a pattern-level false positive",
|
|
20086
|
+
"use `verity feedback finding <run-id> <pattern-id> false_positive` instead.",
|
|
20087
|
+
"",
|
|
20088
|
+
"## Post-task reflection",
|
|
20089
|
+
"",
|
|
20090
|
+
`When a task is complete (you've created a PR, the user says "done" or "ship it",`,
|
|
20091
|
+
"or the work is clearly finished), **draft the reflection yourself** \u2014 1\u20133",
|
|
20092
|
+
"concrete things worth remembering (a decision, a gotcha, or a pattern), each",
|
|
20093
|
+
"cited with the files / PR / commands / error-signatures it came from. Skip",
|
|
20094
|
+
"entirely if nothing non-obvious happened \u2014 that judgement is the ONLY filter,",
|
|
20095
|
+
"because nothing reviews the reflection before it lands.",
|
|
20096
|
+
"",
|
|
20097
|
+
"Then record it straight away. There is no confirm step, in any environment:",
|
|
20098
|
+
"",
|
|
20099
|
+
"```bash",
|
|
20100
|
+
"verity reflect --user-input - --kind <kind> <<'VERITY_EOF_<random>'",
|
|
20101
|
+
"<your draft>",
|
|
20102
|
+
"VERITY_EOF_<random>",
|
|
20103
|
+
"```",
|
|
20104
|
+
"",
|
|
20105
|
+
'The draft goes through the quoted heredoc, never inside `"\u2026"` on the command',
|
|
20106
|
+
'line, where a `"` or `$(\u2026)` in it would run in the shell. Replace `<random>`',
|
|
20107
|
+
"with 8 random letters and digits that you pick for this call, the same at both",
|
|
20108
|
+
"ends. Text written before you picked them cannot end the heredoc early.",
|
|
20109
|
+
"",
|
|
20110
|
+
"Add `--confirmed` ONLY when the user authored or dictated the words. Without",
|
|
20111
|
+
"it the node is stored as `source: agent` \u2014 Verity thought this, nobody checked",
|
|
20112
|
+
"it. With it, `source: user` at full confidence \u2014 a person stands behind this.",
|
|
20113
|
+
"Never claim the second for your own draft, however good it is.",
|
|
20114
|
+
"",
|
|
20115
|
+
"**Name the files in the text.** Verity scopes the reflection to the paths it",
|
|
20116
|
+
"cites, and a reflection that names no file in this repo is never retrieved for",
|
|
20117
|
+
"a later review \u2014 it is recorded and then invisible. The command says so when it",
|
|
20118
|
+
"happens; `--file-globs '<path or glob>'` is the fix when the prose cannot carry",
|
|
20119
|
+
"the paths.",
|
|
20120
|
+
"",
|
|
20121
|
+
"Then tell the user, in one line, what you recorded and where: the command",
|
|
20122
|
+
"prints the node id, the path under `.verity/memory/`, and a dashboard link.",
|
|
20123
|
+
"They did not agree to it in advance, so say it happened \u2014 editing or deleting",
|
|
20124
|
+
"that file is how they correct it.",
|
|
20125
|
+
"",
|
|
20126
|
+
"> Durable, hand-curated guidance goes in the preserve region below (it survives",
|
|
20127
|
+
"> regeneration) or anywhere OUTSIDE these markers. Everything else between the",
|
|
20128
|
+
"> markers is tool-owned and overwritten on each run.",
|
|
20129
|
+
"",
|
|
20130
|
+
"## Housekeeping Turns",
|
|
20131
|
+
"",
|
|
20132
|
+
"When a turn will be pure housekeeping \u2014 pulling, installing dependencies,",
|
|
20133
|
+
"rebasing, a formatting sweep you are not authoring \u2014 declare it BEFORE doing it:",
|
|
20134
|
+
"",
|
|
20135
|
+
"```bash",
|
|
20136
|
+
'verity ignore --turn --agent --reason "pulling latest before starting"',
|
|
20137
|
+
"```",
|
|
20138
|
+
"",
|
|
20139
|
+
"This skips the review for that turn, which saves the turn Verity would",
|
|
20140
|
+
"otherwise spend saying it had nothing to say. Use `--for 30m` instead of",
|
|
20141
|
+
"`--turn` when a single piece of housekeeping spans several turns.",
|
|
20142
|
+
"",
|
|
20143
|
+
"**It is a claim about the turn, not a way to silence review.** The declaration",
|
|
20144
|
+
"is checked against what the turn actually did: if anything is authored \u2014 by you,",
|
|
20145
|
+
"by a subagent, or by a shell command that can write files \u2014 it voids, the review",
|
|
20146
|
+
"runs anyway, and the broken declaration is reported. So declare housekeeping you",
|
|
20147
|
+
"are about to do, never work you have already done, and never as a way to get past",
|
|
20148
|
+
"a finding. Declarations are budgeted per session and every one is recorded with",
|
|
20149
|
+
"its reason."
|
|
20150
|
+
].join("\n");
|
|
20151
|
+
var CLAUDE_MD_PROSE_PRE_STDIN = [
|
|
20040
20152
|
"## Project Memory",
|
|
20041
20153
|
"",
|
|
20042
20154
|
"This project has a knowledge graph maintained at `.verity/memory/`. Before starting",
|
|
@@ -20478,6 +20590,7 @@ function stripKnownProse(interior) {
|
|
|
20478
20590
|
const trimmed = interior.replace(/^\n+/, "");
|
|
20479
20591
|
for (const prose of [
|
|
20480
20592
|
CLAUDE_MD_PROSE,
|
|
20593
|
+
CLAUDE_MD_PROSE_PRE_STDIN,
|
|
20481
20594
|
CLAUDE_MD_PROSE_PRE_ORG,
|
|
20482
20595
|
CLAUDE_MD_PROSE_PRE_AUTORECORD,
|
|
20483
20596
|
CLAUDE_MD_PROSE_PRE_REFLECT,
|
|
@@ -20544,7 +20657,7 @@ Body content (\u22648KB). Use [[node-id]] wikilinks for cross-references.
|
|
|
20544
20657
|
|
|
20545
20658
|
// src/lib/dossier-session.ts
|
|
20546
20659
|
var import_node_fs26 = require("node:fs");
|
|
20547
|
-
var
|
|
20660
|
+
var import_node_crypto9 = require("node:crypto");
|
|
20548
20661
|
var import_node_path22 = require("node:path");
|
|
20549
20662
|
|
|
20550
20663
|
// src/lib/pending-repeat.ts
|
|
@@ -20621,6 +20734,7 @@ function isRepeatOfAny(text, priorFingerprints, threshold = REPEAT_THRESHOLD) {
|
|
|
20621
20734
|
}
|
|
20622
20735
|
|
|
20623
20736
|
// src/lib/dossier/bounds.ts
|
|
20737
|
+
var import_node_crypto5 = require("node:crypto");
|
|
20624
20738
|
var MAX_LINE_BYTES = 4096;
|
|
20625
20739
|
var MAX_GOAL_CHARS = 2e3;
|
|
20626
20740
|
var GOAL_KEEP = 8;
|
|
@@ -20632,10 +20746,17 @@ var NOT_MINE_CAP = 300;
|
|
|
20632
20746
|
var STATEMENTS_OPEN_CAP = 40;
|
|
20633
20747
|
var COMMANDS_CAP = 12;
|
|
20634
20748
|
var DIVERGENCE_CAP = 10;
|
|
20635
|
-
var
|
|
20749
|
+
var DIVERGENCE_BULK_AT = 300;
|
|
20750
|
+
var DIVERGENCE_KEYS_PER_LINE = 200;
|
|
20636
20751
|
function divergenceKey(path, hash) {
|
|
20637
20752
|
return `${path}@${hash ?? "unknown"}`;
|
|
20638
20753
|
}
|
|
20754
|
+
function packedDivergenceDigest(key) {
|
|
20755
|
+
return (0, import_node_crypto5.createHash)("sha256").update(key).digest("hex").slice(0, 12);
|
|
20756
|
+
}
|
|
20757
|
+
function packedDivergenceKey(digest) {
|
|
20758
|
+
return `#${digest}`;
|
|
20759
|
+
}
|
|
20639
20760
|
var MARKS_CAP = 50;
|
|
20640
20761
|
var ROTATE_BYTES = 1048576;
|
|
20641
20762
|
var ROTATE_KEEP = 2;
|
|
@@ -20649,7 +20770,7 @@ function statementAnchorKey(file, patternId) {
|
|
|
20649
20770
|
}
|
|
20650
20771
|
|
|
20651
20772
|
// src/lib/dossier/log.ts
|
|
20652
|
-
var
|
|
20773
|
+
var import_node_crypto6 = require("node:crypto");
|
|
20653
20774
|
var import_node_fs22 = require("node:fs");
|
|
20654
20775
|
var import_node_path20 = require("node:path");
|
|
20655
20776
|
var CRC_TABLE = (() => {
|
|
@@ -20691,7 +20812,7 @@ function nextSeq() {
|
|
|
20691
20812
|
function encodeEvent(ev) {
|
|
20692
20813
|
const full = {
|
|
20693
20814
|
v: 1,
|
|
20694
|
-
id: (0,
|
|
20815
|
+
id: (0, import_node_crypto6.randomBytes)(4).toString("hex"),
|
|
20695
20816
|
...ev
|
|
20696
20817
|
};
|
|
20697
20818
|
let body2 = JSON.stringify(full);
|
|
@@ -20762,7 +20883,7 @@ function rotateIfNeeded2(d) {
|
|
|
20762
20883
|
}
|
|
20763
20884
|
|
|
20764
20885
|
// src/lib/dossier/fold-dossier.ts
|
|
20765
|
-
var
|
|
20886
|
+
var import_node_crypto7 = require("node:crypto");
|
|
20766
20887
|
var import_node_fs23 = require("node:fs");
|
|
20767
20888
|
var import_node_path21 = require("node:path");
|
|
20768
20889
|
var EMPTY_CAPABILITIES = () => ({
|
|
@@ -20854,7 +20975,7 @@ function reduce(state, events, now) {
|
|
|
20854
20975
|
state.meta.seq = Math.max(state.meta.seq, ev.seq);
|
|
20855
20976
|
switch (ev.k) {
|
|
20856
20977
|
case "goal": {
|
|
20857
|
-
const hash = (0,
|
|
20978
|
+
const hash = (0, import_node_crypto7.createHash)("sha256").update(ev.text).digest("hex").slice(0, 16);
|
|
20858
20979
|
const prev = state.goal[state.goal.length - 1];
|
|
20859
20980
|
if (prev && prev.hash === hash) {
|
|
20860
20981
|
prev.repeats = (prev.repeats ?? 0) + 1;
|
|
@@ -20982,12 +21103,13 @@ function reduce(state, events, now) {
|
|
|
20982
21103
|
break;
|
|
20983
21104
|
}
|
|
20984
21105
|
case "divergence": {
|
|
20985
|
-
state.divergence.counts[ev.kind] = (state.divergence.counts[ev.kind] ?? 0) + 1;
|
|
20986
21106
|
state.divergence.events.push({ kind: ev.kind, path: ev.path, at: ev.at });
|
|
20987
|
-
const
|
|
20988
|
-
|
|
21107
|
+
const keys = Array.isArray(ev.keys) ? ev.keys.filter((k) => typeof k === "string").map(packedDivergenceKey) : [divergenceKey(ev.path, ev.hash ?? null)];
|
|
21108
|
+
for (const key of keys) {
|
|
21109
|
+
if (seenDivergence.has(key)) continue;
|
|
20989
21110
|
seenDivergence.add(key);
|
|
20990
|
-
|
|
21111
|
+
state.divergence.seen.push(key);
|
|
21112
|
+
state.divergence.counts[ev.kind] = (state.divergence.counts[ev.kind] ?? 0) + 1;
|
|
20991
21113
|
}
|
|
20992
21114
|
break;
|
|
20993
21115
|
}
|
|
@@ -21294,14 +21416,14 @@ function assessContinuity(i2) {
|
|
|
21294
21416
|
}
|
|
21295
21417
|
|
|
21296
21418
|
// src/lib/dossier/reanchor.ts
|
|
21297
|
-
var
|
|
21419
|
+
var import_node_crypto8 = require("node:crypto");
|
|
21298
21420
|
var import_node_fs25 = require("node:fs");
|
|
21299
21421
|
function lineSha(text) {
|
|
21300
|
-
return (0,
|
|
21422
|
+
return (0, import_node_crypto8.createHash)("sha256").update(text.trim()).digest("hex").slice(0, HASH_WIDTH);
|
|
21301
21423
|
}
|
|
21302
21424
|
function fileHash(path) {
|
|
21303
21425
|
try {
|
|
21304
|
-
return (0,
|
|
21426
|
+
return (0, import_node_crypto8.createHash)("sha256").update((0, import_node_fs25.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
|
|
21305
21427
|
} catch {
|
|
21306
21428
|
return null;
|
|
21307
21429
|
}
|
|
@@ -21798,7 +21920,7 @@ function recordTurn(d, t) {
|
|
|
21798
21920
|
// Identity is the COMMAND, not its category — otherwise `npm test -- a` and
|
|
21799
21921
|
// `npm test -- b` are one row and the streak counts two different commands
|
|
21800
21922
|
// as a run of one.
|
|
21801
|
-
cmd_hash: (0,
|
|
21923
|
+
cmd_hash: (0, import_node_crypto9.createHash)("sha256").update(c.head || c.class).digest("hex").slice(0, 12),
|
|
21802
21924
|
head: c.head || c.class,
|
|
21803
21925
|
status: toStatus(c.last_status)
|
|
21804
21926
|
});
|
|
@@ -21816,10 +21938,23 @@ function recordTurn(d, t) {
|
|
|
21816
21938
|
}
|
|
21817
21939
|
}
|
|
21818
21940
|
const seenDivergence = t.known?.divergence ?? /* @__PURE__ */ new Set();
|
|
21941
|
+
const fresh = [];
|
|
21819
21942
|
for (const u of t.unobserved) {
|
|
21820
21943
|
const hash = fileHash((0, import_node_path22.join)(root, u.p));
|
|
21821
|
-
|
|
21822
|
-
|
|
21944
|
+
const key = divergenceKey(u.p, hash);
|
|
21945
|
+
const digest = packedDivergenceDigest(key);
|
|
21946
|
+
if (seenDivergence.has(key) || seenDivergence.has(packedDivergenceKey(digest))) continue;
|
|
21947
|
+
fresh.push({ path: u.p, hash, digest });
|
|
21948
|
+
}
|
|
21949
|
+
if (fresh.length > DIVERGENCE_BULK_AT) {
|
|
21950
|
+
for (let i2 = 0; i2 < fresh.length; i2 += DIVERGENCE_KEYS_PER_LINE) {
|
|
21951
|
+
const slice2 = fresh.slice(i2, i2 + DIVERGENCE_KEYS_PER_LINE);
|
|
21952
|
+
appendEvent(d, { k: "divergence", kind: "external_mutation", path: slice2[0].path, keys: slice2.map((f) => f.digest) });
|
|
21953
|
+
}
|
|
21954
|
+
} else {
|
|
21955
|
+
for (const f of fresh) {
|
|
21956
|
+
appendEvent(d, { k: "divergence", kind: "external_mutation", path: f.path, hash: f.hash });
|
|
21957
|
+
}
|
|
21823
21958
|
}
|
|
21824
21959
|
const newCompactions = (t.compactions ?? 0) - (t.known?.compactions ?? 0);
|
|
21825
21960
|
for (let i2 = 0; i2 < newCompactions; i2++) {
|
|
@@ -22084,7 +22219,7 @@ async function fireClassify(prompt, sessionId, globals) {
|
|
|
22084
22219
|
logEvent("classify_skipped", { reason: "no_service_url", detail: urlResult.error });
|
|
22085
22220
|
return;
|
|
22086
22221
|
}
|
|
22087
|
-
const promptHash = (0,
|
|
22222
|
+
const promptHash = (0, import_node_crypto10.createHash)("sha256").update(prompt).digest("hex");
|
|
22088
22223
|
const result = await apiRequest({
|
|
22089
22224
|
method: "POST",
|
|
22090
22225
|
path: "/classify-task",
|
|
@@ -22128,7 +22263,7 @@ var import_node_path26 = require("node:path");
|
|
|
22128
22263
|
// src/lib/baseline.ts
|
|
22129
22264
|
var import_node_fs28 = require("node:fs");
|
|
22130
22265
|
var import_node_path25 = require("node:path");
|
|
22131
|
-
var
|
|
22266
|
+
var import_node_crypto11 = require("node:crypto");
|
|
22132
22267
|
|
|
22133
22268
|
// src/lib/snapshot.ts
|
|
22134
22269
|
var import_node_fs27 = require("node:fs");
|
|
@@ -22397,7 +22532,7 @@ var MIRROR_MAX_BYTES = 2 * 1024 * 1024;
|
|
|
22397
22532
|
var DEFAULT_SESSION_KEY = "_default";
|
|
22398
22533
|
function sessionKey(sessionId) {
|
|
22399
22534
|
if (!sessionId) return DEFAULT_SESSION_KEY;
|
|
22400
|
-
return (0,
|
|
22535
|
+
return (0, import_node_crypto11.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
|
|
22401
22536
|
}
|
|
22402
22537
|
function sessionDir(key) {
|
|
22403
22538
|
return (0, import_node_path25.join)(projectPath(BASELINE_DIR), key);
|
|
@@ -22859,17 +22994,17 @@ async function readHookStdin() {
|
|
|
22859
22994
|
try {
|
|
22860
22995
|
if (process.stdin.isTTY) return {};
|
|
22861
22996
|
const chunks = [];
|
|
22862
|
-
const timeout = new Promise((
|
|
22863
|
-
const read2 = new Promise((
|
|
22997
|
+
const timeout = new Promise((resolve9) => setTimeout(() => resolve9({}), 500));
|
|
22998
|
+
const read2 = new Promise((resolve9) => {
|
|
22864
22999
|
process.stdin.on("data", (c) => chunks.push(c));
|
|
22865
23000
|
process.stdin.on("end", () => {
|
|
22866
23001
|
try {
|
|
22867
|
-
|
|
23002
|
+
resolve9(JSON.parse(Buffer.concat(chunks).toString("utf-8").trim() || "{}"));
|
|
22868
23003
|
} catch {
|
|
22869
|
-
|
|
23004
|
+
resolve9({});
|
|
22870
23005
|
}
|
|
22871
23006
|
});
|
|
22872
|
-
process.stdin.on("error", () =>
|
|
23007
|
+
process.stdin.on("error", () => resolve9({}));
|
|
22873
23008
|
process.stdin.resume();
|
|
22874
23009
|
});
|
|
22875
23010
|
return await Promise.race([read2, timeout]);
|
|
@@ -24317,10 +24452,10 @@ var import_node_fs38 = require("node:fs");
|
|
|
24317
24452
|
|
|
24318
24453
|
// src/lib/debounce.ts
|
|
24319
24454
|
var import_node_fs37 = require("node:fs");
|
|
24320
|
-
var
|
|
24455
|
+
var import_node_crypto12 = require("node:crypto");
|
|
24321
24456
|
function scopedFile(base, sessionId) {
|
|
24322
24457
|
if (!sessionId) return base;
|
|
24323
|
-
return `${base}.${(0,
|
|
24458
|
+
return `${base}.${(0, import_node_crypto12.createHash)("sha1").update(sessionId).digest("hex").slice(0, 12)}`;
|
|
24324
24459
|
}
|
|
24325
24460
|
function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
|
|
24326
24461
|
const file = scopedFile(DEBOUNCE_FILE, sessionId);
|
|
@@ -24361,7 +24496,7 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
|
|
|
24361
24496
|
return "No files modified since last analysis";
|
|
24362
24497
|
}
|
|
24363
24498
|
function computeContentHash(files) {
|
|
24364
|
-
const hash = (0,
|
|
24499
|
+
const hash = (0, import_node_crypto12.createHash)("sha1");
|
|
24365
24500
|
const sorted = [...files].sort();
|
|
24366
24501
|
for (const f of sorted) {
|
|
24367
24502
|
const resolved = resolveFile(f) ?? f;
|
|
@@ -24817,20 +24952,56 @@ function registerStatusCommand(program2) {
|
|
|
24817
24952
|
});
|
|
24818
24953
|
}
|
|
24819
24954
|
|
|
24955
|
+
// src/lib/text-input.ts
|
|
24956
|
+
var import_node_fs39 = require("node:fs");
|
|
24957
|
+
var MAX_STDIN_BYTES = 64 * 1024;
|
|
24958
|
+
function readTextInput(value, flag, readStdin2 = () => (0, import_node_fs39.readFileSync)(0)) {
|
|
24959
|
+
if (value !== "-") return { ok: true, text: value };
|
|
24960
|
+
let raw;
|
|
24961
|
+
try {
|
|
24962
|
+
raw = readStdin2();
|
|
24963
|
+
} catch (err2) {
|
|
24964
|
+
return { ok: false, error: `Could not read ${flag} from stdin: ${err2.message}` };
|
|
24965
|
+
}
|
|
24966
|
+
if (raw.length > MAX_STDIN_BYTES) {
|
|
24967
|
+
return { ok: false, error: `${flag} from stdin is ${raw.length} bytes; the limit is ${MAX_STDIN_BYTES}.` };
|
|
24968
|
+
}
|
|
24969
|
+
const text = raw.toString("utf8").replace(/\r?\n$/, "");
|
|
24970
|
+
if (!text.trim()) return { ok: false, error: `${flag} from stdin is empty.` };
|
|
24971
|
+
return { ok: true, text };
|
|
24972
|
+
}
|
|
24973
|
+
|
|
24974
|
+
// src/lib/terminal-text.ts
|
|
24975
|
+
var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/g;
|
|
24976
|
+
function terminalText(value, max = 4e3) {
|
|
24977
|
+
if (typeof value !== "string") return "";
|
|
24978
|
+
const clean2 = value.replace(CONTROL, "");
|
|
24979
|
+
return clean2.length > max ? `${clean2.slice(0, max - 1)}\u2026` : clean2;
|
|
24980
|
+
}
|
|
24981
|
+
function terminalUrl(value) {
|
|
24982
|
+
const clean2 = terminalText(value, 2e3);
|
|
24983
|
+
return /^https?:\/\/\S+$/.test(clean2) ? clean2 : "";
|
|
24984
|
+
}
|
|
24985
|
+
|
|
24820
24986
|
// src/commands/feedback.ts
|
|
24821
24987
|
function registerFeedbackCommand(program2) {
|
|
24822
24988
|
const feedbackCmd = program2.command("feedback").description("Send feedback to the Verity team");
|
|
24823
|
-
feedbackCmd.command("message <text>").description("Send general feedback").option("--session-id <id>", "Session identifier").option("--model <name>", "Agent model name").action(async (
|
|
24824
|
-
|
|
24825
|
-
await sendGeneralFeedback(message, opts, globals);
|
|
24989
|
+
feedbackCmd.command("message <text>").description("Send general feedback (- reads the message from stdin, so the words never pass through shell quoting)").option("--session-id <id>", "Session identifier").option("--model <name>", "Agent model name").action(async (text, opts) => {
|
|
24990
|
+
await sendMessageArg(text, opts, program2.opts());
|
|
24826
24991
|
});
|
|
24827
|
-
feedbackCmd.command("finding <run-id> <pattern-id> <action> [note]").description("Submit per-finding feedback (false_positive, acknowledged, useful, etc.)").option("--file <path>", "File path the finding applies to").option("--line <n>", "Line number", parseInt).action(async (runId, patternId, action,
|
|
24992
|
+
feedbackCmd.command("finding <run-id> <pattern-id> <action> [note]").description("Submit per-finding feedback (false_positive, acknowledged, useful, etc.); a note of - is read from stdin").option("--file <path>", "File path the finding applies to").option("--line <n>", "Line number", parseInt).action(async (runId, patternId, action, inlineNote, opts) => {
|
|
24828
24993
|
const globals = program2.opts();
|
|
24829
24994
|
const validActions = ["false_positive", "acknowledged", "will_fix_later", "wrong_severity", "useful"];
|
|
24830
24995
|
if (!validActions.includes(action)) {
|
|
24831
24996
|
printError(`Invalid action "${action}". Must be one of: ${validActions.join(", ")}`);
|
|
24832
24997
|
process.exit(1);
|
|
24833
24998
|
}
|
|
24999
|
+
const noteInput = readTextInput(inlineNote, "the note");
|
|
25000
|
+
if (!noteInput.ok) {
|
|
25001
|
+
printError(noteInput.error);
|
|
25002
|
+
process.exit(1);
|
|
25003
|
+
}
|
|
25004
|
+
const note = noteInput.text;
|
|
24834
25005
|
const tokenResult = await resolveToken(globals.token);
|
|
24835
25006
|
if (!tokenResult.ok) {
|
|
24836
25007
|
printError(tokenResult.error);
|
|
@@ -24866,21 +25037,28 @@ function registerFeedbackCommand(program2) {
|
|
|
24866
25037
|
});
|
|
24867
25038
|
feedbackCmd.argument("[message]", "Feedback message (for backwards compat)").option("--session-id <id>", "Session identifier").option("--model <name>", "Agent model name").action(async (message, opts) => {
|
|
24868
25039
|
if (!message) return;
|
|
24869
|
-
|
|
24870
|
-
await sendGeneralFeedback(message, opts, globals);
|
|
25040
|
+
await sendMessageArg(message, opts, program2.opts());
|
|
24871
25041
|
});
|
|
24872
25042
|
}
|
|
25043
|
+
async function sendMessageArg(arg, opts, globals) {
|
|
25044
|
+
const input = readTextInput(arg, "the message");
|
|
25045
|
+
if (!input.ok || !input.text) {
|
|
25046
|
+
printError(input.ok ? "Nothing to send." : input.error);
|
|
25047
|
+
process.exit(1);
|
|
25048
|
+
}
|
|
25049
|
+
await sendGeneralFeedback(input.text, opts, globals);
|
|
25050
|
+
}
|
|
24873
25051
|
async function sendGeneralFeedback(message, opts, globals) {
|
|
24874
25052
|
const tokenResult = await resolveToken(globals.token);
|
|
24875
25053
|
if (!tokenResult.ok) {
|
|
24876
25054
|
printError(tokenResult.error);
|
|
24877
|
-
printInfo(`Your message: ${message}`);
|
|
25055
|
+
printInfo(`Your message: ${terminalText(message, message.length)}`);
|
|
24878
25056
|
process.exit(1);
|
|
24879
25057
|
}
|
|
24880
25058
|
const urlResult = await resolveServiceUrl(globals.serviceUrl);
|
|
24881
25059
|
if (!urlResult.ok) {
|
|
24882
25060
|
printError(urlResult.error);
|
|
24883
|
-
printInfo(`Your message: ${message}`);
|
|
25061
|
+
printInfo(`Your message: ${terminalText(message, message.length)}`);
|
|
24884
25062
|
process.exit(1);
|
|
24885
25063
|
}
|
|
24886
25064
|
const body2 = { message };
|
|
@@ -24898,7 +25076,7 @@ async function sendGeneralFeedback(message, opts, globals) {
|
|
|
24898
25076
|
});
|
|
24899
25077
|
if (!result.ok) {
|
|
24900
25078
|
printError(`Couldn't send feedback: ${result.error}`);
|
|
24901
|
-
printInfo(`Your message: ${message}`);
|
|
25079
|
+
printInfo(`Your message: ${terminalText(message, message.length)}`);
|
|
24902
25080
|
process.exit(1);
|
|
24903
25081
|
}
|
|
24904
25082
|
printInfo("Thanks, feedback sent!");
|
|
@@ -24983,7 +25161,8 @@ function createRun(opts, globals) {
|
|
|
24983
25161
|
}
|
|
24984
25162
|
|
|
24985
25163
|
// src/commands/analyze/index.ts
|
|
24986
|
-
var
|
|
25164
|
+
var import_node_fs53 = require("node:fs");
|
|
25165
|
+
var import_node_path40 = require("node:path");
|
|
24987
25166
|
|
|
24988
25167
|
// src/lib/repo-context.ts
|
|
24989
25168
|
var import_node_child_process11 = require("node:child_process");
|
|
@@ -25947,7 +26126,7 @@ function installRunEvidence(run4) {
|
|
|
25947
26126
|
}
|
|
25948
26127
|
|
|
25949
26128
|
// src/lib/git-frame.ts
|
|
25950
|
-
var
|
|
26129
|
+
var import_node_fs40 = require("node:fs");
|
|
25951
26130
|
var import_node_os6 = require("node:os");
|
|
25952
26131
|
var import_node_path30 = require("node:path");
|
|
25953
26132
|
var import_node_path31 = require("node:path");
|
|
@@ -26117,14 +26296,14 @@ function gitAt(dir, args2) {
|
|
|
26117
26296
|
}
|
|
26118
26297
|
function realpathOr2(p) {
|
|
26119
26298
|
try {
|
|
26120
|
-
return
|
|
26299
|
+
return import_node_fs40.realpathSync.native(p);
|
|
26121
26300
|
} catch {
|
|
26122
26301
|
return (0, import_node_path30.resolve)(p);
|
|
26123
26302
|
}
|
|
26124
26303
|
}
|
|
26125
26304
|
function resolveFrame(input) {
|
|
26126
26305
|
const found = findMomentSegment(input.command, input.on);
|
|
26127
|
-
const hookDirUsable = !!input.hookCwd && (0,
|
|
26306
|
+
const hookDirUsable = !!input.hookCwd && (0, import_node_fs40.existsSync)(input.hookCwd);
|
|
26128
26307
|
const baseDir = hookDirUsable ? input.hookCwd : process.cwd();
|
|
26129
26308
|
let anchor = hookDirUsable ? "hook-cwd" : "process-cwd";
|
|
26130
26309
|
const refuse = (refusal) => ({
|
|
@@ -26147,7 +26326,7 @@ function resolveFrame(input) {
|
|
|
26147
26326
|
if (dirs.size > 1) return refuse(`target:multiple ${found.moment} targets in one command`);
|
|
26148
26327
|
const targetDir = dirs.size === 1 ? [...dirs][0] : baseDir;
|
|
26149
26328
|
if (targetDir !== baseDir) {
|
|
26150
|
-
if (!(0,
|
|
26329
|
+
if (!(0, import_node_fs40.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
|
|
26151
26330
|
dir = targetDir;
|
|
26152
26331
|
}
|
|
26153
26332
|
}
|
|
@@ -26334,7 +26513,7 @@ function stagedRange(frame, command) {
|
|
|
26334
26513
|
return { kind: "staged", base: "HEAD", head: "INDEX", via: "staged-in-command", refusal: plan.reason };
|
|
26335
26514
|
}
|
|
26336
26515
|
const mergeHead = frame.gitDir ? (0, import_node_path31.join)(frame.gitDir, "MERGE_HEAD") : null;
|
|
26337
|
-
if (mergeHead && (0,
|
|
26516
|
+
if (mergeHead && (0, import_node_fs40.existsSync)(mergeHead)) {
|
|
26338
26517
|
const vsHead = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "HEAD"]).split("\n").filter(Boolean));
|
|
26339
26518
|
const vsMerge = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "MERGE_HEAD"]).split("\n").filter(Boolean));
|
|
26340
26519
|
const resolutions = new Set([...vsHead].filter((f) => vsMerge.has(f) && !isVerityOwnedPath(f)));
|
|
@@ -26468,7 +26647,7 @@ function truthy(v) {
|
|
|
26468
26647
|
}
|
|
26469
26648
|
|
|
26470
26649
|
// src/lib/transcript.ts
|
|
26471
|
-
var
|
|
26650
|
+
var import_node_fs41 = require("node:fs");
|
|
26472
26651
|
var MAX_READ_BYTES = 256 * 1024;
|
|
26473
26652
|
var SMALL_FILE_BYTES = 64 * 1024;
|
|
26474
26653
|
var MAX_FILES_LIST = 20;
|
|
@@ -26495,7 +26674,7 @@ async function extractActionSummary(transcriptPath) {
|
|
|
26495
26674
|
function readTurnLines(transcriptPath) {
|
|
26496
26675
|
let size;
|
|
26497
26676
|
try {
|
|
26498
|
-
size = (0,
|
|
26677
|
+
size = (0, import_node_fs41.statSync)(transcriptPath).size;
|
|
26499
26678
|
} catch {
|
|
26500
26679
|
return null;
|
|
26501
26680
|
}
|
|
@@ -26503,7 +26682,7 @@ function readTurnLines(transcriptPath) {
|
|
|
26503
26682
|
let raw;
|
|
26504
26683
|
let windowed = false;
|
|
26505
26684
|
if (size <= SMALL_FILE_BYTES) {
|
|
26506
|
-
raw = (0,
|
|
26685
|
+
raw = (0, import_node_fs41.readFileSync)(transcriptPath, "utf-8");
|
|
26507
26686
|
} else {
|
|
26508
26687
|
windowed = true;
|
|
26509
26688
|
const buf = Buffer.alloc(Math.min(MAX_READ_BYTES, size));
|
|
@@ -26786,28 +26965,28 @@ async function readStopHookStdin() {
|
|
|
26786
26965
|
try {
|
|
26787
26966
|
if (process.stdin.isTTY) return empty;
|
|
26788
26967
|
const chunks = [];
|
|
26789
|
-
const timeout = new Promise((
|
|
26790
|
-
const read2 = new Promise((
|
|
26968
|
+
const timeout = new Promise((resolve9) => setTimeout(() => resolve9(empty), 500));
|
|
26969
|
+
const read2 = new Promise((resolve9) => {
|
|
26791
26970
|
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
26792
26971
|
process.stdin.on("end", () => {
|
|
26793
26972
|
const raw = Buffer.concat(chunks).toString("utf-8").trim();
|
|
26794
26973
|
if (!raw) {
|
|
26795
|
-
|
|
26974
|
+
resolve9(empty);
|
|
26796
26975
|
return;
|
|
26797
26976
|
}
|
|
26798
26977
|
try {
|
|
26799
26978
|
const data = JSON.parse(raw);
|
|
26800
|
-
|
|
26979
|
+
resolve9({
|
|
26801
26980
|
assistantMessage: typeof data.last_assistant_message === "string" ? data.last_assistant_message : null,
|
|
26802
26981
|
stopReason: typeof data.stop_reason === "string" ? data.stop_reason : null,
|
|
26803
26982
|
transcriptPath: typeof data.transcript_path === "string" ? data.transcript_path : null,
|
|
26804
26983
|
sessionId: typeof data.session_id === "string" ? data.session_id : null
|
|
26805
26984
|
});
|
|
26806
26985
|
} catch {
|
|
26807
|
-
|
|
26986
|
+
resolve9(empty);
|
|
26808
26987
|
}
|
|
26809
26988
|
});
|
|
26810
|
-
process.stdin.on("error", () =>
|
|
26989
|
+
process.stdin.on("error", () => resolve9(empty));
|
|
26811
26990
|
process.stdin.resume();
|
|
26812
26991
|
});
|
|
26813
26992
|
return await Promise.race([read2, timeout]);
|
|
@@ -27073,7 +27252,7 @@ function channelSilence(input) {
|
|
|
27073
27252
|
// src/lib/cli-version.ts
|
|
27074
27253
|
function cliVersion() {
|
|
27075
27254
|
try {
|
|
27076
|
-
return true ? "0.34.0-experimental.
|
|
27255
|
+
return true ? "0.34.0-experimental.380b51f" : "dev";
|
|
27077
27256
|
} catch {
|
|
27078
27257
|
return "dev";
|
|
27079
27258
|
}
|
|
@@ -27114,7 +27293,7 @@ async function sendSkipBeacon(ctx, reason) {
|
|
|
27114
27293
|
|
|
27115
27294
|
// src/lib/static-analysis.ts
|
|
27116
27295
|
var import_node_child_process12 = require("node:child_process");
|
|
27117
|
-
var
|
|
27296
|
+
var import_node_fs42 = require("node:fs");
|
|
27118
27297
|
var SEVERITY_ORDER = {
|
|
27119
27298
|
Error: 0,
|
|
27120
27299
|
Critical: 0,
|
|
@@ -27170,7 +27349,7 @@ function runCodacyAnalysis(files) {
|
|
|
27170
27349
|
if (files.length === 0) return empty;
|
|
27171
27350
|
const existingFiles = files.filter((f) => {
|
|
27172
27351
|
try {
|
|
27173
|
-
return (0,
|
|
27352
|
+
return (0, import_node_fs42.existsSync)(f);
|
|
27174
27353
|
} catch {
|
|
27175
27354
|
return false;
|
|
27176
27355
|
}
|
|
@@ -27439,7 +27618,7 @@ async function scope(run4) {
|
|
|
27439
27618
|
}
|
|
27440
27619
|
|
|
27441
27620
|
// src/lib/specs.ts
|
|
27442
|
-
var
|
|
27621
|
+
var import_node_fs43 = require("node:fs");
|
|
27443
27622
|
var import_node_path32 = require("node:path");
|
|
27444
27623
|
var SPEC_CANDIDATES = [
|
|
27445
27624
|
"CLAUDE.md",
|
|
@@ -27481,7 +27660,7 @@ function discoverSpecs(consulted = []) {
|
|
|
27481
27660
|
const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
|
|
27482
27661
|
if (totalBytes >= totalCap) return false;
|
|
27483
27662
|
if (seen.has(specPath)) return true;
|
|
27484
|
-
if (!(0,
|
|
27663
|
+
if (!(0, import_node_fs43.existsSync)(specPath)) return true;
|
|
27485
27664
|
seen.add(specPath);
|
|
27486
27665
|
const remaining = totalCap - totalBytes;
|
|
27487
27666
|
const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
|
|
@@ -27504,7 +27683,7 @@ function discoverSpecs(consulted = []) {
|
|
|
27504
27683
|
if (!addSpec(candidate)) break;
|
|
27505
27684
|
}
|
|
27506
27685
|
for (const dir of ["spec", "docs"]) {
|
|
27507
|
-
if (!(0,
|
|
27686
|
+
if (!(0, import_node_fs43.existsSync)(dir)) continue;
|
|
27508
27687
|
try {
|
|
27509
27688
|
const mdFiles = findMdFiles(dir, 2).sort();
|
|
27510
27689
|
for (const mdFile of mdFiles) {
|
|
@@ -27519,7 +27698,7 @@ function findMdFiles(dir, maxDepth, depth = 0) {
|
|
|
27519
27698
|
if (depth >= maxDepth) return [];
|
|
27520
27699
|
const result = [];
|
|
27521
27700
|
try {
|
|
27522
|
-
const entries = (0,
|
|
27701
|
+
const entries = (0, import_node_fs43.readdirSync)(dir, { withFileTypes: true });
|
|
27523
27702
|
for (const entry of entries) {
|
|
27524
27703
|
const fullPath = (0, import_node_path32.join)(dir, entry.name);
|
|
27525
27704
|
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -27539,13 +27718,13 @@ function discoverPlans() {
|
|
|
27539
27718
|
if (isRealDirectoryChain(process.cwd(), [".claude", "plans"])) {
|
|
27540
27719
|
sources.push({ root: process.cwd(), prefix: (0, import_node_path32.join)(".claude", "plans") });
|
|
27541
27720
|
}
|
|
27542
|
-
if (home && (0,
|
|
27721
|
+
if (home && (0, import_node_fs43.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
|
|
27543
27722
|
const candidates2 = [];
|
|
27544
27723
|
const seen = /* @__PURE__ */ new Set();
|
|
27545
27724
|
for (const source2 of sources) {
|
|
27546
27725
|
let names2;
|
|
27547
27726
|
try {
|
|
27548
|
-
names2 = (0,
|
|
27727
|
+
names2 = (0, import_node_fs43.readdirSync)(source2.prefix ? (0, import_node_path32.join)(source2.root, source2.prefix) : source2.root);
|
|
27549
27728
|
} catch {
|
|
27550
27729
|
continue;
|
|
27551
27730
|
}
|
|
@@ -27572,7 +27751,7 @@ function isRealDirectoryChain(root, parts2) {
|
|
|
27572
27751
|
for (const part of parts2) {
|
|
27573
27752
|
current = (0, import_node_path32.join)(current, part);
|
|
27574
27753
|
try {
|
|
27575
|
-
if (!(0,
|
|
27754
|
+
if (!(0, import_node_fs43.lstatSync)(current).isDirectory()) return false;
|
|
27576
27755
|
} catch {
|
|
27577
27756
|
return false;
|
|
27578
27757
|
}
|
|
@@ -27587,7 +27766,7 @@ function discoverGuardDocs(rangeFiles2) {
|
|
|
27587
27766
|
if (result.length >= MAX_SPEC_FILES) break;
|
|
27588
27767
|
if (!GUARD_DOC_EXT.test(path)) continue;
|
|
27589
27768
|
if (path.startsWith("/") || path.includes("..")) continue;
|
|
27590
|
-
if (!(0,
|
|
27769
|
+
if (!(0, import_node_fs43.existsSync)(path)) continue;
|
|
27591
27770
|
const opened = openRegularInRoot(process.cwd(), path);
|
|
27592
27771
|
if (!opened.ok) continue;
|
|
27593
27772
|
if (opened.size > MAX_PLAN_FILE_BYTES || totalBytes + opened.size > MAX_TOTAL_SPEC_BYTES) {
|
|
@@ -27773,7 +27952,7 @@ async function mode(run4) {
|
|
|
27773
27952
|
}
|
|
27774
27953
|
|
|
27775
27954
|
// src/lib/fold.ts
|
|
27776
|
-
var
|
|
27955
|
+
var import_node_fs44 = require("node:fs");
|
|
27777
27956
|
var import_node_path33 = require("node:path");
|
|
27778
27957
|
var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
|
|
27779
27958
|
"user",
|
|
@@ -27911,7 +28090,7 @@ function candidateRoots(repoRoot2) {
|
|
|
27911
28090
|
const norm2 = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
27912
28091
|
const out2 = [norm2];
|
|
27913
28092
|
try {
|
|
27914
|
-
const real =
|
|
28093
|
+
const real = import_node_fs44.realpathSync.native(norm2).replace(/\\/g, "/").replace(/\/+$/, "");
|
|
27915
28094
|
if (real !== norm2) out2.push(real);
|
|
27916
28095
|
} catch {
|
|
27917
28096
|
}
|
|
@@ -27999,8 +28178,8 @@ function fold(transcriptPath, opts = {}) {
|
|
|
27999
28178
|
}
|
|
28000
28179
|
};
|
|
28001
28180
|
try {
|
|
28002
|
-
if (!(0,
|
|
28003
|
-
ingest((0,
|
|
28181
|
+
if (!(0, import_node_fs44.existsSync)(transcriptPath)) return result;
|
|
28182
|
+
ingest((0, import_node_fs44.readFileSync)(transcriptPath, "utf8"), "agent");
|
|
28004
28183
|
result.coverage.complete = true;
|
|
28005
28184
|
} catch {
|
|
28006
28185
|
return result;
|
|
@@ -28011,19 +28190,19 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28011
28190
|
(0, import_node_path33.basename)(transcriptPath).replace(/\.jsonl$/, ""),
|
|
28012
28191
|
"subagents"
|
|
28013
28192
|
);
|
|
28014
|
-
if ((0,
|
|
28193
|
+
if ((0, import_node_fs44.existsSync)(sidecarDir)) {
|
|
28015
28194
|
const maxFiles = opts.maxSidecars ?? 200;
|
|
28016
28195
|
const maxBytes = opts.maxSidecarBytes ?? 16 * 1024 * 1024;
|
|
28017
28196
|
const found = [];
|
|
28018
28197
|
const walk2 = (d, depth) => {
|
|
28019
28198
|
if (depth > 4) return;
|
|
28020
|
-
for (const e of (0,
|
|
28199
|
+
for (const e of (0, import_node_fs44.readdirSync)(d, { withFileTypes: true })) {
|
|
28021
28200
|
const p = (0, import_node_path33.join)(d, e.name);
|
|
28022
28201
|
if (e.isDirectory()) {
|
|
28023
28202
|
walk2(p, depth + 1);
|
|
28024
28203
|
} else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
|
|
28025
28204
|
try {
|
|
28026
|
-
const st = (0,
|
|
28205
|
+
const st = (0, import_node_fs44.statSync)(p);
|
|
28027
28206
|
found.push({ path: p, size: st.size, mtimeMs: st.mtimeMs });
|
|
28028
28207
|
} catch {
|
|
28029
28208
|
result.coverage.malformed++;
|
|
@@ -28040,7 +28219,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28040
28219
|
continue;
|
|
28041
28220
|
}
|
|
28042
28221
|
try {
|
|
28043
|
-
ingest((0,
|
|
28222
|
+
ingest((0, import_node_fs44.readFileSync)(f.path, "utf8"), "subagent");
|
|
28044
28223
|
bytes += f.size;
|
|
28045
28224
|
result.coverage.subagentFiles++;
|
|
28046
28225
|
} catch {
|
|
@@ -28075,7 +28254,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28075
28254
|
}
|
|
28076
28255
|
function classifyUnobserved(path) {
|
|
28077
28256
|
try {
|
|
28078
|
-
const st = (0,
|
|
28257
|
+
const st = (0, import_node_fs44.statSync)(path);
|
|
28079
28258
|
if (!st.isFile()) return "unreadable";
|
|
28080
28259
|
} catch {
|
|
28081
28260
|
return "unreadable";
|
|
@@ -28390,20 +28569,20 @@ async function evidence(run4) {
|
|
|
28390
28569
|
}
|
|
28391
28570
|
|
|
28392
28571
|
// src/lib/cache-cleanup.ts
|
|
28393
|
-
var
|
|
28572
|
+
var import_node_fs45 = require("node:fs");
|
|
28394
28573
|
var import_node_path34 = require("node:path");
|
|
28395
28574
|
var CACHE_TTL_DAYS = 7;
|
|
28396
28575
|
function pruneStaleCache() {
|
|
28397
28576
|
try {
|
|
28398
28577
|
const dir = projectPath(CACHE_DIR);
|
|
28399
28578
|
const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
|
|
28400
|
-
for (const entry of (0,
|
|
28579
|
+
for (const entry of (0, import_node_fs45.readdirSync)(dir)) {
|
|
28401
28580
|
if (!entry.startsWith("pending-")) continue;
|
|
28402
28581
|
const path = (0, import_node_path34.join)(dir, entry);
|
|
28403
28582
|
try {
|
|
28404
|
-
const stat3 = (0,
|
|
28583
|
+
const stat3 = (0, import_node_fs45.statSync)(path);
|
|
28405
28584
|
if (stat3.mtimeMs < cutoff) {
|
|
28406
|
-
(0,
|
|
28585
|
+
(0, import_node_fs45.unlinkSync)(path);
|
|
28407
28586
|
logEvent("cache_entry_pruned", {
|
|
28408
28587
|
path: entry,
|
|
28409
28588
|
age_days: Math.round((Date.now() - stat3.mtimeMs) / 864e5)
|
|
@@ -28417,7 +28596,7 @@ function pruneStaleCache() {
|
|
|
28417
28596
|
}
|
|
28418
28597
|
|
|
28419
28598
|
// src/lib/context-files.ts
|
|
28420
|
-
var
|
|
28599
|
+
var import_node_fs46 = require("node:fs");
|
|
28421
28600
|
var import_node_os7 = require("node:os");
|
|
28422
28601
|
var MAX_CONTEXT_FILES = 10;
|
|
28423
28602
|
var MAX_CONTEXT_FILE_BYTES = 10240;
|
|
@@ -28475,7 +28654,7 @@ function gatherContextFiles(contextPaths, deltaFiles, opts) {
|
|
|
28475
28654
|
continue;
|
|
28476
28655
|
}
|
|
28477
28656
|
try {
|
|
28478
|
-
const content = (0,
|
|
28657
|
+
const content = (0, import_node_fs46.readFileSync)(safePath, "utf8");
|
|
28479
28658
|
const bytes = Buffer.byteLength(content);
|
|
28480
28659
|
if (bytes > MAX_CONTEXT_FILE_BYTES) {
|
|
28481
28660
|
logEvent("context_file_skipped", { path: filePath, reason: "too_large", bytes });
|
|
@@ -28541,7 +28720,7 @@ async function contextFiles(run4) {
|
|
|
28541
28720
|
}
|
|
28542
28721
|
|
|
28543
28722
|
// src/lib/code/index.ts
|
|
28544
|
-
var
|
|
28723
|
+
var import_node_crypto13 = require("node:crypto");
|
|
28545
28724
|
|
|
28546
28725
|
// src/lib/code/languages.ts
|
|
28547
28726
|
var JS_LIKE = {
|
|
@@ -28633,7 +28812,7 @@ function languageOf2(path) {
|
|
|
28633
28812
|
}
|
|
28634
28813
|
|
|
28635
28814
|
// src/lib/code/runtime.ts
|
|
28636
|
-
var
|
|
28815
|
+
var import_node_fs47 = require("node:fs");
|
|
28637
28816
|
var import_node_path35 = require("node:path");
|
|
28638
28817
|
var import_web_tree_sitter2 = __toESM2(require_web_tree_sitter2());
|
|
28639
28818
|
|
|
@@ -28705,7 +28884,7 @@ function grammarCandidates(file, pkg, env = process.env) {
|
|
|
28705
28884
|
}
|
|
28706
28885
|
function locateGrammar(id, env = process.env) {
|
|
28707
28886
|
const g = grammars_default[id];
|
|
28708
|
-
return grammarCandidates(g.file, g.package, env).find((p) => (0,
|
|
28887
|
+
return grammarCandidates(g.file, g.package, env).find((p) => (0, import_node_fs47.existsSync)(p)) ?? null;
|
|
28709
28888
|
}
|
|
28710
28889
|
var loading = null;
|
|
28711
28890
|
function loadRuntime(env = process.env) {
|
|
@@ -30319,7 +30498,7 @@ function byPath(fns, name2) {
|
|
|
30319
30498
|
function makeCodeMap(rt) {
|
|
30320
30499
|
const cache = /* @__PURE__ */ new Map();
|
|
30321
30500
|
const outline = (path, content, deadlineAt = Date.now() + DEFAULT_PARSE_MS) => {
|
|
30322
|
-
const key = `${path}\0${(0,
|
|
30501
|
+
const key = `${path}\0${(0, import_node_crypto13.createHash)("sha1").update(content).digest("hex")}`;
|
|
30323
30502
|
const hit = cache.get(key);
|
|
30324
30503
|
if (hit) return { source: "tree-sitter", value: hit, elapsedMs: 0 };
|
|
30325
30504
|
let r;
|
|
@@ -31034,7 +31213,7 @@ async function repoContext(run4) {
|
|
|
31034
31213
|
|
|
31035
31214
|
// src/lib/seed-runner.ts
|
|
31036
31215
|
var import_promises15 = require("node:fs/promises");
|
|
31037
|
-
var
|
|
31216
|
+
var import_node_fs48 = require("node:fs");
|
|
31038
31217
|
var import_node_path36 = require("node:path");
|
|
31039
31218
|
var import_yaml4 = __toESM2(require_dist());
|
|
31040
31219
|
|
|
@@ -31259,7 +31438,7 @@ async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
|
|
|
31259
31438
|
const titles = /* @__PURE__ */ new Set();
|
|
31260
31439
|
for (const dir of NODE_DIRS) {
|
|
31261
31440
|
const full = (0, import_node_path36.join)(memoryDir3, dir);
|
|
31262
|
-
if (!(0,
|
|
31441
|
+
if (!(0, import_node_fs48.existsSync)(full)) continue;
|
|
31263
31442
|
let files;
|
|
31264
31443
|
try {
|
|
31265
31444
|
files = await (0, import_promises15.readdir)(full);
|
|
@@ -31341,7 +31520,7 @@ function renderNodeMarkdown(candidate, nodeId, createdAt) {
|
|
|
31341
31520
|
return fm;
|
|
31342
31521
|
}
|
|
31343
31522
|
async function runSeed(opts) {
|
|
31344
|
-
if (!(0,
|
|
31523
|
+
if (!(0, import_node_fs48.existsSync)(STANDARD_FILE)) {
|
|
31345
31524
|
return { created: 0, existing: 0, failed: 0, skipped: "no_standard", candidates: [] };
|
|
31346
31525
|
}
|
|
31347
31526
|
let standardDoc;
|
|
@@ -31353,7 +31532,7 @@ async function runSeed(opts) {
|
|
|
31353
31532
|
}
|
|
31354
31533
|
const knowledgeSpec = standardDoc.knowledge_spec ?? {};
|
|
31355
31534
|
let readmeContent;
|
|
31356
|
-
if ((0,
|
|
31535
|
+
if ((0, import_node_fs48.existsSync)("README.md")) {
|
|
31357
31536
|
try {
|
|
31358
31537
|
readmeContent = await (0, import_promises15.readFile)("README.md", "utf-8");
|
|
31359
31538
|
} catch {
|
|
@@ -31361,7 +31540,7 @@ async function runSeed(opts) {
|
|
|
31361
31540
|
}
|
|
31362
31541
|
let claudeMdContent;
|
|
31363
31542
|
for (const p of ["CLAUDE.md", ".claude/CLAUDE.md"]) {
|
|
31364
|
-
if ((0,
|
|
31543
|
+
if ((0, import_node_fs48.existsSync)(p)) {
|
|
31365
31544
|
try {
|
|
31366
31545
|
claudeMdContent = await (0, import_promises15.readFile)(p, "utf-8");
|
|
31367
31546
|
break;
|
|
@@ -31441,7 +31620,7 @@ async function runSeed(opts) {
|
|
|
31441
31620
|
continue;
|
|
31442
31621
|
}
|
|
31443
31622
|
const deduplicated = res.data.deduplicated === true;
|
|
31444
|
-
if (deduplicated && (0,
|
|
31623
|
+
if (deduplicated && (0, import_node_fs48.existsSync)(targetPath)) {
|
|
31445
31624
|
existing++;
|
|
31446
31625
|
continue;
|
|
31447
31626
|
}
|
|
@@ -31463,7 +31642,7 @@ async function runSeed(opts) {
|
|
|
31463
31642
|
}
|
|
31464
31643
|
|
|
31465
31644
|
// src/commands/analyze/phases/08-memory-manifest.ts
|
|
31466
|
-
var
|
|
31645
|
+
var import_node_fs49 = require("node:fs");
|
|
31467
31646
|
var import_node_path37 = require("node:path");
|
|
31468
31647
|
async function memoryManifest(run4) {
|
|
31469
31648
|
const { globals } = run4;
|
|
@@ -31475,8 +31654,8 @@ async function memoryManifest(run4) {
|
|
|
31475
31654
|
try {
|
|
31476
31655
|
await ensureMemoryDir();
|
|
31477
31656
|
const seedMarker = (0, import_node_path37.join)(VERITY_DIR, ".seeded");
|
|
31478
|
-
const hasStandard = (0,
|
|
31479
|
-
const alreadyTried = (0,
|
|
31657
|
+
const hasStandard = (0, import_node_fs49.existsSync)(STANDARD_FILE);
|
|
31658
|
+
const alreadyTried = (0, import_node_fs49.existsSync)(seedMarker);
|
|
31480
31659
|
if (hasStandard && !alreadyTried) {
|
|
31481
31660
|
const preManifest = await buildManifest();
|
|
31482
31661
|
if (preManifest.nodes.length === 0) {
|
|
@@ -31489,7 +31668,7 @@ async function memoryManifest(run4) {
|
|
|
31489
31668
|
dryRun: false
|
|
31490
31669
|
});
|
|
31491
31670
|
if (seedResult.created > 0 || seedResult.existing > 0) {
|
|
31492
|
-
(0,
|
|
31671
|
+
(0, import_node_fs49.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created} existing=${seedResult.existing}
|
|
31493
31672
|
`);
|
|
31494
31673
|
if (seedResult.created > 0) {
|
|
31495
31674
|
autoSeedNotice = `Seeded ${seedResult.created} knowledge node(s) from your existing Standard (one-time).`;
|
|
@@ -31500,7 +31679,7 @@ async function memoryManifest(run4) {
|
|
|
31500
31679
|
failed: seedResult.failed
|
|
31501
31680
|
});
|
|
31502
31681
|
} else if (seedResult.skipped === "already_seeded") {
|
|
31503
|
-
(0,
|
|
31682
|
+
(0, import_node_fs49.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
|
|
31504
31683
|
`);
|
|
31505
31684
|
} else {
|
|
31506
31685
|
logEvent("auto_seed_noop", {
|
|
@@ -31688,8 +31867,24 @@ async function workingMemory(run4) {
|
|
|
31688
31867
|
Object.assign(run4, { incrementReport, memory: memory2, memorySession, reachability });
|
|
31689
31868
|
}
|
|
31690
31869
|
|
|
31870
|
+
// src/lib/payload-bounds.ts
|
|
31871
|
+
var MAX_WIRE_PATHS = 500;
|
|
31872
|
+
function boundPaths(paths, first, max = MAX_WIRE_PATHS) {
|
|
31873
|
+
if (paths.length <= max) return [...paths];
|
|
31874
|
+
const present = new Set(paths);
|
|
31875
|
+
const kept = /* @__PURE__ */ new Set();
|
|
31876
|
+
const out2 = [];
|
|
31877
|
+
for (const p of [...first, ...paths]) {
|
|
31878
|
+
if (out2.length >= max) break;
|
|
31879
|
+
if (!present.has(p) || kept.has(p)) continue;
|
|
31880
|
+
kept.add(p);
|
|
31881
|
+
out2.push(p);
|
|
31882
|
+
}
|
|
31883
|
+
return out2;
|
|
31884
|
+
}
|
|
31885
|
+
|
|
31691
31886
|
// src/lib/note-budget.ts
|
|
31692
|
-
var
|
|
31887
|
+
var import_node_fs50 = require("node:fs");
|
|
31693
31888
|
var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
|
|
31694
31889
|
var EPISODE_STALE_SECONDS = 30 * 60;
|
|
31695
31890
|
var FRESH = { delivered: 0, tasksCompleted: 0, ts: 0 };
|
|
@@ -31711,9 +31906,9 @@ function advisoryBudgetSpent(episode, rawDecision) {
|
|
|
31711
31906
|
}
|
|
31712
31907
|
function readAdvisoryEpisode(sessionId) {
|
|
31713
31908
|
const file = scopedFile(ADVISORY_EPISODE_FILE, sessionId);
|
|
31714
|
-
if (!(0,
|
|
31909
|
+
if (!(0, import_node_fs50.existsSync)(file)) return null;
|
|
31715
31910
|
try {
|
|
31716
|
-
const o = JSON.parse((0,
|
|
31911
|
+
const o = JSON.parse((0, import_node_fs50.readFileSync)(file, "utf-8")) ?? {};
|
|
31717
31912
|
const delivered = typeof o.delivered === "number" ? o.delivered : NaN;
|
|
31718
31913
|
if (isNaN(delivered)) return null;
|
|
31719
31914
|
return {
|
|
@@ -31727,8 +31922,8 @@ function readAdvisoryEpisode(sessionId) {
|
|
|
31727
31922
|
}
|
|
31728
31923
|
function writeAdvisoryEpisode(episode, sessionId) {
|
|
31729
31924
|
try {
|
|
31730
|
-
(0,
|
|
31731
|
-
(0,
|
|
31925
|
+
(0, import_node_fs50.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
31926
|
+
(0, import_node_fs50.writeFileSync)(
|
|
31732
31927
|
scopedFile(ADVISORY_EPISODE_FILE, sessionId),
|
|
31733
31928
|
JSON.stringify({ v: 1, ...episode })
|
|
31734
31929
|
);
|
|
@@ -31802,6 +31997,7 @@ async function buildRequest(run4) {
|
|
|
31802
31997
|
(conversation?.prompts?.length ?? 0) > 0
|
|
31803
31998
|
);
|
|
31804
31999
|
const noteConfirmation = peekNoteOutcome();
|
|
32000
|
+
const unobserved = foldResult?.unobserved ?? [];
|
|
31805
32001
|
const excludedByReason = {};
|
|
31806
32002
|
for (const e of codeDelta.excluded ?? []) {
|
|
31807
32003
|
excludedByReason[e.reason] = (excludedByReason[e.reason] ?? 0) + 1;
|
|
@@ -31846,7 +32042,9 @@ async function buildRequest(run4) {
|
|
|
31846
32042
|
coverage_telemetry: coverageTelemetry,
|
|
31847
32043
|
static_results: staticResults,
|
|
31848
32044
|
code_delta: codeDelta,
|
|
31849
|
-
|
|
32045
|
+
// Bounded, reviewed paths first — the server applies the same bound. The
|
|
32046
|
+
// full count is `coverage_telemetry.for_review`. VRT-242.
|
|
32047
|
+
changed_files: boundPaths(allForReview, codeDelta.files.map((f) => f.path)),
|
|
31850
32048
|
standard_version: "latest",
|
|
31851
32049
|
analysis_mode: analysisMode,
|
|
31852
32050
|
plan_only: analysisMode === "plan",
|
|
@@ -31897,7 +32095,9 @@ async function buildRequest(run4) {
|
|
|
31897
32095
|
// `hash_at_last_verdict` is frozen at each verdict and `hash_now` tracks
|
|
31898
32096
|
// disk, so their inequality IS "changed since we last spoke".
|
|
31899
32097
|
authored_since_verdict: memorySession ? foldDossier(memorySession.d).authored_all.filter((a) => a.hash_now !== a.hash_at_last_verdict).map((a) => a.path) : [],
|
|
31900
|
-
|
|
32098
|
+
// The server reads only how many; a bulk change sent every path. VRT-242.
|
|
32099
|
+
unobserved: unobserved.slice(0, MAX_WIRE_PATHS),
|
|
32100
|
+
...unobserved.length > MAX_WIRE_PATHS && { unobserved_total: unobserved.length },
|
|
31901
32101
|
commands: foldResult?.commands ?? [],
|
|
31902
32102
|
tools: foldResult?.tools ?? [],
|
|
31903
32103
|
tasks: foldResult?.tasks ?? [],
|
|
@@ -32060,14 +32260,14 @@ async function buildRequest(run4) {
|
|
|
32060
32260
|
}
|
|
32061
32261
|
|
|
32062
32262
|
// src/lib/offline.ts
|
|
32063
|
-
var
|
|
32064
|
-
var
|
|
32263
|
+
var import_node_fs51 = require("node:fs");
|
|
32264
|
+
var import_node_crypto14 = require("node:crypto");
|
|
32065
32265
|
function cacheRequest(body2) {
|
|
32066
32266
|
try {
|
|
32067
|
-
(0,
|
|
32068
|
-
const suffix = (0,
|
|
32267
|
+
(0, import_node_fs51.mkdirSync)(CACHE_DIR, { recursive: true });
|
|
32268
|
+
const suffix = (0, import_node_crypto14.randomBytes)(4).toString("hex");
|
|
32069
32269
|
const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
|
|
32070
|
-
(0,
|
|
32270
|
+
(0, import_node_fs51.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body2)));
|
|
32071
32271
|
} catch {
|
|
32072
32272
|
}
|
|
32073
32273
|
}
|
|
@@ -32108,8 +32308,10 @@ function buildOfflineFallback(reason, staticResults) {
|
|
|
32108
32308
|
}
|
|
32109
32309
|
|
|
32110
32310
|
// src/lib/retry.ts
|
|
32311
|
+
var WORKER_RESOURCE_LIMIT = 546;
|
|
32111
32312
|
function shouldWarmRetryAnalyze(result) {
|
|
32112
32313
|
if (result.ok) return false;
|
|
32314
|
+
if (result.http_status === WORKER_RESOURCE_LIMIT) return false;
|
|
32113
32315
|
if (result.category === "network" || result.category === "timeout") return true;
|
|
32114
32316
|
if (result.category === "http_5xx") return true;
|
|
32115
32317
|
if (result.category === "invalid_json" && (result.http_status ?? 0) >= 500) return true;
|
|
@@ -32119,7 +32321,7 @@ function shouldWarmRetryAnalyze(result) {
|
|
|
32119
32321
|
// src/commands/analyze/phases/12-transmit.ts
|
|
32120
32322
|
async function transmit(run4) {
|
|
32121
32323
|
const { globals } = run4;
|
|
32122
|
-
const {
|
|
32324
|
+
const { requestBody, serviceUrl, staticResults, token } = run4;
|
|
32123
32325
|
const ANALYZE_TIMEOUT_MS = 1e5;
|
|
32124
32326
|
let result = await analyzeRequest({
|
|
32125
32327
|
serviceUrl,
|
|
@@ -32156,11 +32358,12 @@ async function transmit(run4) {
|
|
|
32156
32358
|
}
|
|
32157
32359
|
if (!result.ok) {
|
|
32158
32360
|
cacheRequest(requestBody);
|
|
32361
|
+
const sentKb = () => Math.round(Buffer.byteLength(JSON.stringify(requestBody)) / 1024);
|
|
32159
32362
|
let message;
|
|
32160
32363
|
if (result.http_status === 413) {
|
|
32161
|
-
|
|
32162
|
-
|
|
32163
|
-
message = `Verity:
|
|
32364
|
+
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.`;
|
|
32365
|
+
} else if (result.http_status === WORKER_RESOURCE_LIMIT) {
|
|
32366
|
+
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
32367
|
} else if (result.category === "network" || result.category === "timeout") {
|
|
32165
32368
|
message = `Verity offline \u2014 ${result.error}`;
|
|
32166
32369
|
} else if (result.error.startsWith("STALE_VERIFICATION")) {
|
|
@@ -32186,7 +32389,7 @@ async function transmit(run4) {
|
|
|
32186
32389
|
}
|
|
32187
32390
|
|
|
32188
32391
|
// src/commands/analyze/phases/13-reconcile.ts
|
|
32189
|
-
var
|
|
32392
|
+
var import_node_fs52 = require("node:fs");
|
|
32190
32393
|
var import_node_path39 = require("node:path");
|
|
32191
32394
|
async function reconcile(run4) {
|
|
32192
32395
|
const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory: memory2, memorySession, response, reviewable, securityFiles, turnId } = run4;
|
|
@@ -32216,7 +32419,7 @@ async function reconcile(run4) {
|
|
|
32216
32419
|
const st = foldDossier(memorySession.d);
|
|
32217
32420
|
openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line2) => {
|
|
32218
32421
|
try {
|
|
32219
|
-
const src = (0,
|
|
32422
|
+
const src = (0, import_node_fs52.readFileSync)((0, import_node_path39.join)(repoRoot(), file), "utf8").split("\n");
|
|
32220
32423
|
const at = src[line2 - 1];
|
|
32221
32424
|
return at === void 0 ? null : lineSha(at);
|
|
32222
32425
|
} catch {
|
|
@@ -33038,7 +33241,7 @@ function registerAnalyzeCommand(program2) {
|
|
|
33038
33241
|
var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
|
|
33039
33242
|
async function runAnalyze(opts, globals) {
|
|
33040
33243
|
if (!verityConfigured()) {
|
|
33041
|
-
(0,
|
|
33244
|
+
(0, import_node_fs53.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
33245
|
process.exit(0);
|
|
33043
33246
|
}
|
|
33044
33247
|
const run4 = createRun(opts, globals);
|
|
@@ -33059,11 +33262,12 @@ async function runAnalyze(opts, globals) {
|
|
|
33059
33262
|
}
|
|
33060
33263
|
|
|
33061
33264
|
// src/commands/baseline.ts
|
|
33062
|
-
var
|
|
33265
|
+
var import_node_fs55 = require("node:fs");
|
|
33266
|
+
var import_node_path42 = require("node:path");
|
|
33063
33267
|
|
|
33064
33268
|
// src/lib/project-skills.ts
|
|
33065
|
-
var
|
|
33066
|
-
var
|
|
33269
|
+
var import_node_fs54 = require("node:fs");
|
|
33270
|
+
var import_node_path41 = require("node:path");
|
|
33067
33271
|
var PROJECT_SKILL_NAMES = [
|
|
33068
33272
|
"verity-setup",
|
|
33069
33273
|
"verity-analyze",
|
|
@@ -33089,14 +33293,14 @@ var LEGACY_SKILL_NAMES = [
|
|
|
33089
33293
|
var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
|
|
33090
33294
|
function staleProjectSkills() {
|
|
33091
33295
|
const root = projectPath(".claude/skills");
|
|
33092
|
-
if (!(0,
|
|
33093
|
-
return ALL.filter((name2) => (0,
|
|
33296
|
+
if (!(0, import_node_fs54.existsSync)(root)) return [];
|
|
33297
|
+
return ALL.filter((name2) => (0, import_node_fs54.existsSync)((0, import_node_path41.join)(root, name2)));
|
|
33094
33298
|
}
|
|
33095
33299
|
function removeProjectSkills() {
|
|
33096
33300
|
const root = projectPath(".claude/skills");
|
|
33097
33301
|
const removed = [];
|
|
33098
33302
|
for (const name2 of staleProjectSkills()) {
|
|
33099
|
-
(0,
|
|
33303
|
+
(0, import_node_fs54.rmSync)((0, import_node_path41.join)(root, name2), { recursive: true, force: true });
|
|
33100
33304
|
removed.push(name2);
|
|
33101
33305
|
}
|
|
33102
33306
|
return removed;
|
|
@@ -33129,6 +33333,7 @@ function registerBaselineCommands(program2) {
|
|
|
33129
33333
|
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
33334
|
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
33335
|
if (!verityConfigured()) {
|
|
33336
|
+
if (isMachineStore((0, import_node_path42.join)(repoRoot(), VERITY_DIR))) process.exit(0);
|
|
33132
33337
|
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
33338
|
const lines = [
|
|
33134
33339
|
`Verity is installed but this project is not set up yet, so the quality gate will not review anything here. ${how}`
|
|
@@ -33161,13 +33366,13 @@ function registerBaselineCommands(program2) {
|
|
|
33161
33366
|
let memoryMsg = null;
|
|
33162
33367
|
let memoryAgentLine = null;
|
|
33163
33368
|
const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
|
|
33164
|
-
if (realStart && !(0,
|
|
33369
|
+
if (realStart && !(0, import_node_fs55.existsSync)(memoryNotice)) {
|
|
33165
33370
|
const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
|
|
33166
33371
|
if (trackedGraph > 0) {
|
|
33167
33372
|
memoryMsg = `Verity: this project commits its knowledge base (${trackedGraph} files under .verity/memory/), so Verity's generated notes show up in every diff and pull request. Run \`verity memory untrack\` to keep them on disk but out of git, or \`verity memory track\` to keep committing them on purpose.`;
|
|
33168
33373
|
memoryAgentLine = `This project has ${trackedGraph} knowledge-graph files tracked in git under .verity/memory/. As of Verity 0.32.6 the graph is machine-local by default \u2014 it is rebuilt from the service, and committing it puts generated notes in every pull request. If the user wants that stopped, run \`verity memory untrack\` for them: it keeps every file on disk and stages their removal from the index, so they only need to commit \u2014 and their teammates' working copies will vanish on the next pull and re-sync from the service, which is expected. If they would rather keep committing it, \`verity memory track\` records that and nothing will offer again.`;
|
|
33169
33374
|
try {
|
|
33170
|
-
(0,
|
|
33375
|
+
(0, import_node_fs55.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
|
|
33171
33376
|
} catch {
|
|
33172
33377
|
}
|
|
33173
33378
|
}
|
|
@@ -33268,10 +33473,16 @@ function hookSource(value) {
|
|
|
33268
33473
|
}
|
|
33269
33474
|
|
|
33270
33475
|
// src/commands/review.ts
|
|
33271
|
-
var
|
|
33476
|
+
var import_node_fs56 = require("node:fs");
|
|
33272
33477
|
function registerReviewCommand(program2) {
|
|
33273
|
-
program2.command("review").description("Run on-demand Verity analysis (advisory, never blocks)").requiredOption("--files <paths>", "Comma-separated file list").option("--changed <paths>", "Subset of --files that were modified").option("--intent <text>", "User intent description (max 2000 chars)").option("--specs <paths>", "Comma-separated spec file paths").option("--json", "Output raw JSON response").action(async (opts) => {
|
|
33478
|
+
program2.command("review").description("Run on-demand Verity analysis (advisory, never blocks)").requiredOption("--files <paths>", "Comma-separated file list").option("--changed <paths>", "Subset of --files that were modified").option("--intent <text>", "User intent description (max 2000 chars); - reads it from stdin, so the words never pass through shell quoting").option("--specs <paths>", "Comma-separated spec file paths").option("--json", "Output raw JSON response").action(async (opts) => {
|
|
33274
33479
|
const globals = program2.opts();
|
|
33480
|
+
const intent = readTextInput(opts.intent, "--intent");
|
|
33481
|
+
if (!intent.ok) {
|
|
33482
|
+
printError(intent.error);
|
|
33483
|
+
process.exit(0);
|
|
33484
|
+
}
|
|
33485
|
+
opts.intent = intent.text;
|
|
33275
33486
|
try {
|
|
33276
33487
|
await runReview(opts, globals);
|
|
33277
33488
|
} catch (err2) {
|
|
@@ -33285,7 +33496,7 @@ async function runReview(opts, globals) {
|
|
|
33285
33496
|
const changedFiles = opts.changed ? opts.changed.split(",").map((f) => f.trim()).filter(Boolean) : allFiles;
|
|
33286
33497
|
const analyzable = filterAnalyzable(allFiles);
|
|
33287
33498
|
const securityFiles = filterSecurity(allFiles);
|
|
33288
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0,
|
|
33499
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs56.existsSync)(f) || resolveFile(f) !== null);
|
|
33289
33500
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
33290
33501
|
const codeDelta = collectCodeDelta(allFiles);
|
|
33291
33502
|
const tokenResult = await resolveToken(globals.token);
|
|
@@ -33351,20 +33562,8 @@ async function runReview(opts, globals) {
|
|
|
33351
33562
|
}
|
|
33352
33563
|
|
|
33353
33564
|
// src/commands/guard.ts
|
|
33354
|
-
var
|
|
33355
|
-
var
|
|
33356
|
-
|
|
33357
|
-
// src/lib/terminal-text.ts
|
|
33358
|
-
var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/g;
|
|
33359
|
-
function terminalText(value, max = 4e3) {
|
|
33360
|
-
if (typeof value !== "string") return "";
|
|
33361
|
-
const clean2 = value.replace(CONTROL, "");
|
|
33362
|
-
return clean2.length > max ? `${clean2.slice(0, max - 1)}\u2026` : clean2;
|
|
33363
|
-
}
|
|
33364
|
-
function terminalUrl(value) {
|
|
33365
|
-
const clean2 = terminalText(value, 2e3);
|
|
33366
|
-
return /^https?:\/\/\S+$/.test(clean2) ? clean2 : "";
|
|
33367
|
-
}
|
|
33565
|
+
var import_node_fs60 = require("node:fs");
|
|
33566
|
+
var import_node_path47 = require("node:path");
|
|
33368
33567
|
|
|
33369
33568
|
// src/lib/agent-driver.ts
|
|
33370
33569
|
var AGENT_DEADLINE_MS = {
|
|
@@ -33445,7 +33644,7 @@ async function runAgentReview(options) {
|
|
|
33445
33644
|
}
|
|
33446
33645
|
if (!settled) {
|
|
33447
33646
|
const wait = Math.max(0, remaining() - FINISH_TIMEOUT_MS);
|
|
33448
|
-
await Promise.race([oneShotDone, new Promise((
|
|
33647
|
+
await Promise.race([oneShotDone, new Promise((resolve9) => setTimeout(resolve9, wait))]);
|
|
33449
33648
|
}
|
|
33450
33649
|
const finished = await options.http.post(
|
|
33451
33650
|
"/agent-review/finish",
|
|
@@ -33460,8 +33659,8 @@ async function runAgentReview(options) {
|
|
|
33460
33659
|
}
|
|
33461
33660
|
|
|
33462
33661
|
// src/lib/prove/auto.ts
|
|
33463
|
-
var
|
|
33464
|
-
var
|
|
33662
|
+
var import_node_path46 = require("node:path");
|
|
33663
|
+
var import_node_crypto19 = require("node:crypto");
|
|
33465
33664
|
|
|
33466
33665
|
// src/lib/prove/signals.ts
|
|
33467
33666
|
var DEFAULT_SINCE = "180 days ago";
|
|
@@ -35187,18 +35386,18 @@ function renderReplay(model, property, r) {
|
|
|
35187
35386
|
// src/lib/prove/runner.ts
|
|
35188
35387
|
var import_node_child_process15 = require("node:child_process");
|
|
35189
35388
|
var import_node_os8 = require("node:os");
|
|
35190
|
-
var
|
|
35389
|
+
var import_node_fs59 = require("node:fs");
|
|
35191
35390
|
var import_node_os9 = require("node:os");
|
|
35192
|
-
var
|
|
35391
|
+
var import_node_path45 = require("node:path");
|
|
35193
35392
|
|
|
35194
35393
|
// src/lib/prove/scaffold.ts
|
|
35195
|
-
var
|
|
35196
|
-
var
|
|
35394
|
+
var import_node_fs58 = require("node:fs");
|
|
35395
|
+
var import_node_path44 = require("node:path");
|
|
35197
35396
|
|
|
35198
35397
|
// src/lib/prove/safe-write.ts
|
|
35199
|
-
var
|
|
35200
|
-
var
|
|
35201
|
-
var
|
|
35398
|
+
var import_node_fs57 = require("node:fs");
|
|
35399
|
+
var import_node_crypto15 = require("node:crypto");
|
|
35400
|
+
var import_node_path43 = require("node:path");
|
|
35202
35401
|
var SafeWriteError = class extends Error {
|
|
35203
35402
|
constructor(reason, path) {
|
|
35204
35403
|
super(`refusing to write ${path}: ${reason}`);
|
|
@@ -35207,10 +35406,10 @@ var SafeWriteError = class extends Error {
|
|
|
35207
35406
|
this.name = "SafeWriteError";
|
|
35208
35407
|
}
|
|
35209
35408
|
};
|
|
35210
|
-
var FLAGS3 =
|
|
35409
|
+
var FLAGS3 = import_node_fs57.constants;
|
|
35211
35410
|
var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
|
|
35212
35411
|
function assertPlainRelative(rel) {
|
|
35213
|
-
if (!rel || (0,
|
|
35412
|
+
if (!rel || (0, import_node_path43.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
|
|
35214
35413
|
for (const part of rel.split(/[\\/]/)) {
|
|
35215
35414
|
if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
|
|
35216
35415
|
}
|
|
@@ -35219,34 +35418,34 @@ function ensureDirsNoFollow(root, rel) {
|
|
|
35219
35418
|
const parts2 = rel.split(/[\\/]/);
|
|
35220
35419
|
let cur = root;
|
|
35221
35420
|
for (const part of parts2.slice(0, -1)) {
|
|
35222
|
-
cur = (0,
|
|
35421
|
+
cur = (0, import_node_path43.join)(cur, part);
|
|
35223
35422
|
let st;
|
|
35224
35423
|
try {
|
|
35225
|
-
st = (0,
|
|
35424
|
+
st = (0, import_node_fs57.lstatSync)(cur);
|
|
35226
35425
|
} catch {
|
|
35227
|
-
(0,
|
|
35426
|
+
(0, import_node_fs57.mkdirSync)(cur);
|
|
35228
35427
|
continue;
|
|
35229
35428
|
}
|
|
35230
35429
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
|
|
35231
35430
|
if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
|
|
35232
35431
|
}
|
|
35233
|
-
return (0,
|
|
35432
|
+
return (0, import_node_path43.join)(root, rel);
|
|
35234
35433
|
}
|
|
35235
35434
|
function insideRoot(realRoot, realPath) {
|
|
35236
|
-
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(
|
|
35435
|
+
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path43.sep) ? realRoot : realRoot + import_node_path43.sep);
|
|
35237
35436
|
}
|
|
35238
35437
|
function removeQuietly(path) {
|
|
35239
35438
|
try {
|
|
35240
|
-
(0,
|
|
35439
|
+
(0, import_node_fs57.unlinkSync)(path);
|
|
35241
35440
|
} catch {
|
|
35242
35441
|
}
|
|
35243
35442
|
}
|
|
35244
35443
|
function writeFileInRootNoFollow(root, rel, content) {
|
|
35245
35444
|
assertPlainRelative(rel);
|
|
35246
35445
|
const dest = ensureDirsNoFollow(root, rel);
|
|
35247
|
-
const dir = (0,
|
|
35446
|
+
const dir = (0, import_node_path43.dirname)(dest);
|
|
35248
35447
|
try {
|
|
35249
|
-
const st = (0,
|
|
35448
|
+
const st = (0, import_node_fs57.lstatSync)(dest);
|
|
35250
35449
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
|
|
35251
35450
|
if (!st.isFile()) throw new SafeWriteError("not-regular", dest);
|
|
35252
35451
|
} catch (err2) {
|
|
@@ -35254,41 +35453,41 @@ function writeFileInRootNoFollow(root, rel, content) {
|
|
|
35254
35453
|
}
|
|
35255
35454
|
let realRoot;
|
|
35256
35455
|
try {
|
|
35257
|
-
realRoot = (0,
|
|
35456
|
+
realRoot = (0, import_node_fs57.realpathSync)(root);
|
|
35258
35457
|
} catch {
|
|
35259
35458
|
throw new SafeWriteError("unwritable", root);
|
|
35260
35459
|
}
|
|
35261
|
-
const tmp = (0,
|
|
35460
|
+
const tmp = (0, import_node_path43.join)(dir, `.${(0, import_node_path43.basename)(dest)}.${(0, import_node_crypto15.randomBytes)(6).toString("hex")}.tmp`);
|
|
35262
35461
|
let fd;
|
|
35263
35462
|
try {
|
|
35264
|
-
fd = (0,
|
|
35463
|
+
fd = (0, import_node_fs57.openSync)(tmp, import_node_fs57.constants.O_WRONLY | import_node_fs57.constants.O_CREAT | import_node_fs57.constants.O_EXCL | NOFOLLOW2, 420);
|
|
35265
35464
|
} catch {
|
|
35266
35465
|
throw new SafeWriteError("unwritable", tmp);
|
|
35267
35466
|
}
|
|
35268
35467
|
try {
|
|
35269
|
-
const opened = (0,
|
|
35468
|
+
const opened = (0, import_node_fs57.fstatSync)(fd, { bigint: true });
|
|
35270
35469
|
let realTmp;
|
|
35271
35470
|
try {
|
|
35272
|
-
realTmp = (0,
|
|
35471
|
+
realTmp = (0, import_node_fs57.realpathSync)(tmp);
|
|
35273
35472
|
} catch {
|
|
35274
35473
|
throw new SafeWriteError("escaped", tmp);
|
|
35275
35474
|
}
|
|
35276
|
-
const there = (0,
|
|
35475
|
+
const there = (0, import_node_fs57.lstatSync)(realTmp, { bigint: true });
|
|
35277
35476
|
if (!opened.isFile() || there.ino !== opened.ino || there.dev !== opened.dev || !insideRoot(realRoot, realTmp)) {
|
|
35278
35477
|
throw new SafeWriteError("escaped", tmp);
|
|
35279
35478
|
}
|
|
35280
35479
|
const buf = Buffer.from(content, "utf-8");
|
|
35281
35480
|
let off = 0;
|
|
35282
|
-
while (off < buf.length) off += (0,
|
|
35481
|
+
while (off < buf.length) off += (0, import_node_fs57.writeSync)(fd, buf, off, buf.length - off);
|
|
35283
35482
|
} catch (err2) {
|
|
35284
|
-
(0,
|
|
35483
|
+
(0, import_node_fs57.closeSync)(fd);
|
|
35285
35484
|
removeQuietly(tmp);
|
|
35286
35485
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", tmp);
|
|
35287
35486
|
}
|
|
35288
|
-
(0,
|
|
35487
|
+
(0, import_node_fs57.closeSync)(fd);
|
|
35289
35488
|
try {
|
|
35290
|
-
if (!insideRoot(realRoot, (0,
|
|
35291
|
-
(0,
|
|
35489
|
+
if (!insideRoot(realRoot, (0, import_node_fs57.realpathSync)(dir)) || (0, import_node_fs57.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
|
|
35490
|
+
(0, import_node_fs57.renameSync)(tmp, dest);
|
|
35292
35491
|
} catch (err2) {
|
|
35293
35492
|
removeQuietly(tmp);
|
|
35294
35493
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", dest);
|
|
@@ -35302,9 +35501,9 @@ function pathHasNoLink(root, rel) {
|
|
|
35302
35501
|
}
|
|
35303
35502
|
let cur = root;
|
|
35304
35503
|
for (const part of rel.split(/[\\/]/)) {
|
|
35305
|
-
cur = cur +
|
|
35504
|
+
cur = cur + import_node_path43.sep + part;
|
|
35306
35505
|
try {
|
|
35307
|
-
if ((0,
|
|
35506
|
+
if ((0, import_node_fs57.lstatSync)(cur).isSymbolicLink()) return false;
|
|
35308
35507
|
} catch {
|
|
35309
35508
|
return true;
|
|
35310
35509
|
}
|
|
@@ -35614,20 +35813,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
|
|
|
35614
35813
|
never committed; what reaches the team is the bug report and the fix.
|
|
35615
35814
|
`;
|
|
35616
35815
|
function scaffoldProofs(root) {
|
|
35617
|
-
const proofsDir = (0,
|
|
35816
|
+
const proofsDir = (0, import_node_path44.join)(root, PROOFS_DIR);
|
|
35618
35817
|
const written = [];
|
|
35619
35818
|
const kept = [];
|
|
35620
35819
|
for (const stray of ["lakefile.lean"]) {
|
|
35621
35820
|
const rel = `${PROOFS_DIR}/${stray}`;
|
|
35622
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35821
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path44.join)(root, rel));
|
|
35623
35822
|
try {
|
|
35624
|
-
(0,
|
|
35823
|
+
(0, import_node_fs58.rmSync)((0, import_node_path44.join)(root, rel), { force: true });
|
|
35625
35824
|
} catch {
|
|
35626
35825
|
}
|
|
35627
35826
|
}
|
|
35628
35827
|
for (const f of PROOFS_TEMPLATE_FILES) {
|
|
35629
35828
|
const rel = `${PROOFS_DIR}/${f.path}`;
|
|
35630
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35829
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path44.join)(root, rel));
|
|
35631
35830
|
const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
|
|
35632
35831
|
if (current.ok && current.content === f.content) {
|
|
35633
35832
|
kept.push(rel);
|
|
@@ -35640,8 +35839,8 @@ function scaffoldProofs(root) {
|
|
|
35640
35839
|
[`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
|
|
35641
35840
|
[`${MODELS_DIR}/README.md`, MODELS_README]
|
|
35642
35841
|
]) {
|
|
35643
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35644
|
-
if (existsNoFollow((0,
|
|
35842
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path44.join)(root, rel));
|
|
35843
|
+
if (existsNoFollow((0, import_node_path44.join)(root, rel))) {
|
|
35645
35844
|
kept.push(rel);
|
|
35646
35845
|
continue;
|
|
35647
35846
|
}
|
|
@@ -35652,7 +35851,7 @@ function scaffoldProofs(root) {
|
|
|
35652
35851
|
}
|
|
35653
35852
|
function existsNoFollow(abs) {
|
|
35654
35853
|
try {
|
|
35655
|
-
(0,
|
|
35854
|
+
(0, import_node_fs58.lstatSync)(abs);
|
|
35656
35855
|
return true;
|
|
35657
35856
|
} catch {
|
|
35658
35857
|
return false;
|
|
@@ -35660,7 +35859,7 @@ function existsNoFollow(abs) {
|
|
|
35660
35859
|
}
|
|
35661
35860
|
|
|
35662
35861
|
// src/lib/prove/report.ts
|
|
35663
|
-
var
|
|
35862
|
+
var import_node_crypto16 = require("node:crypto");
|
|
35664
35863
|
var IDENT2 = /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$/;
|
|
35665
35864
|
var SHA256 = /^(sha256:)?[0-9a-f]{64}$/;
|
|
35666
35865
|
var KINDS2 = /* @__PURE__ */ new Set(["structural", "intent"]);
|
|
@@ -35808,7 +36007,7 @@ function sha256InRoot(root, file) {
|
|
|
35808
36007
|
const opened = openRegularInRoot(root, file);
|
|
35809
36008
|
if (!opened.ok) return null;
|
|
35810
36009
|
try {
|
|
35811
|
-
return (0,
|
|
36010
|
+
return (0, import_node_crypto16.createHash)("sha256").update(readOpened(opened.fd, opened.size)).digest("hex");
|
|
35812
36011
|
} catch {
|
|
35813
36012
|
return null;
|
|
35814
36013
|
}
|
|
@@ -35910,17 +36109,17 @@ function renderReport(r) {
|
|
|
35910
36109
|
|
|
35911
36110
|
// src/lib/prove/runner.ts
|
|
35912
36111
|
function verityLeanHome(env = process.env) {
|
|
35913
|
-
return env.VERITY_LEAN_HOME ?? (0,
|
|
36112
|
+
return env.VERITY_LEAN_HOME ?? (0, import_node_path45.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
|
|
35914
36113
|
}
|
|
35915
36114
|
function findToolchain(env = process.env) {
|
|
35916
|
-
const managedBin = (0,
|
|
35917
|
-
const elanBin = (0,
|
|
35918
|
-
const elanHas = (0,
|
|
35919
|
-
const userPath = (env.PATH ?? "").split(
|
|
35920
|
-
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(
|
|
36115
|
+
const managedBin = (0, import_node_path45.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
|
|
36116
|
+
const elanBin = (0, import_node_path45.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
|
|
36117
|
+
const elanHas = (0, import_node_fs59.existsSync)((0, import_node_path45.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
|
|
36118
|
+
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)));
|
|
36119
|
+
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path45.delimiter);
|
|
35921
36120
|
const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
|
|
35922
36121
|
const exe = process.platform === "win32" ? "lake.exe" : "lake";
|
|
35923
|
-
const candidates2 = [(0,
|
|
36122
|
+
const candidates2 = [(0, import_node_path45.join)(managedBin, exe), ...elanHas ? [(0, import_node_path45.join)(elanBin, exe)] : [], exe];
|
|
35924
36123
|
for (const candidate of candidates2) {
|
|
35925
36124
|
try {
|
|
35926
36125
|
(0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
|
|
@@ -35958,7 +36157,7 @@ function run2(tc, cwd, args2, timeoutMs) {
|
|
|
35958
36157
|
function runAsync(tc, cwd, args2, timeoutMs) {
|
|
35959
36158
|
const started = Date.now();
|
|
35960
36159
|
const MAX = 16 * 1024 * 1024;
|
|
35961
|
-
return new Promise((
|
|
36160
|
+
return new Promise((resolve9) => {
|
|
35962
36161
|
const posix = (0, import_node_os8.platform)() !== "win32";
|
|
35963
36162
|
const child = (0, import_node_child_process15.spawn)(tc.lake, args2, { cwd, env: tc.env, stdio: ["ignore", "pipe", "pipe"], detached: posix });
|
|
35964
36163
|
let stdout = "";
|
|
@@ -35986,8 +36185,8 @@ function runAsync(tc, cwd, args2, timeoutMs) {
|
|
|
35986
36185
|
if (settled) return;
|
|
35987
36186
|
settled = true;
|
|
35988
36187
|
clearTimeout(timer);
|
|
35989
|
-
if (ok)
|
|
35990
|
-
else
|
|
36188
|
+
if (ok) resolve9({ ok: true, stdout, stderr: "", durationMs: Date.now() - started, timedOut: false });
|
|
36189
|
+
else resolve9({ ok: false, stdout, stderr: stderr || message || "", durationMs: Date.now() - started, timedOut });
|
|
35991
36190
|
};
|
|
35992
36191
|
child.on("error", (err2) => finish(false, err2.message));
|
|
35993
36192
|
child.on("close", (code) => finish(code === 0 && !timedOut));
|
|
@@ -35999,7 +36198,7 @@ function proofsWorkspaceProblem(root) {
|
|
|
35999
36198
|
for (const rel of [".verity", PROOFS_DIR, `${PROOFS_DIR}/.lake`]) {
|
|
36000
36199
|
let st;
|
|
36001
36200
|
try {
|
|
36002
|
-
st = (0,
|
|
36201
|
+
st = (0, import_node_fs59.lstatSync)((0, import_node_path45.join)(root, rel));
|
|
36003
36202
|
} catch {
|
|
36004
36203
|
break;
|
|
36005
36204
|
}
|
|
@@ -36019,44 +36218,44 @@ function refused(problem) {
|
|
|
36019
36218
|
function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
36020
36219
|
const problem = proofsWorkspaceProblem(root);
|
|
36021
36220
|
if (problem) return refused(problem);
|
|
36022
|
-
return run2(tc, (0,
|
|
36221
|
+
return run2(tc, (0, import_node_path45.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36023
36222
|
}
|
|
36024
36223
|
async function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
36025
36224
|
const problem = proofsWorkspaceProblem(root);
|
|
36026
36225
|
if (problem) return refused(problem);
|
|
36027
|
-
return runAsync(tc, (0,
|
|
36226
|
+
return runAsync(tc, (0, import_node_path45.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36028
36227
|
}
|
|
36029
36228
|
function isModelInRoot(modelsAbs, rel) {
|
|
36030
|
-
if (!rel.endsWith(".lean") || (0,
|
|
36229
|
+
if (!rel.endsWith(".lean") || (0, import_node_path45.isAbsolute)(rel) || rel.startsWith("..")) return false;
|
|
36031
36230
|
return statRegularInRoot(modelsAbs, rel).ok;
|
|
36032
36231
|
}
|
|
36033
36232
|
function resolveModelFile(root, arg) {
|
|
36034
|
-
const modelsAbs = (0,
|
|
36035
|
-
const asPath = (0,
|
|
36233
|
+
const modelsAbs = (0, import_node_path45.join)(root, MODELS_DIR);
|
|
36234
|
+
const asPath = (0, import_node_path45.relative)(modelsAbs, (0, import_node_path45.isAbsolute)(arg) ? arg : (0, import_node_path45.resolve)(root, arg));
|
|
36036
36235
|
const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
|
|
36037
36236
|
for (const rel of candidates2) {
|
|
36038
|
-
if (isModelInRoot(modelsAbs, rel)) return (0,
|
|
36237
|
+
if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path45.join)(modelsAbs, rel);
|
|
36039
36238
|
}
|
|
36040
36239
|
return null;
|
|
36041
36240
|
}
|
|
36042
36241
|
function listModelFiles(root) {
|
|
36043
|
-
const modelsAbs = (0,
|
|
36044
|
-
if (!(0,
|
|
36045
|
-
return (0,
|
|
36242
|
+
const modelsAbs = (0, import_node_path45.join)(root, MODELS_DIR);
|
|
36243
|
+
if (!(0, import_node_fs59.existsSync)(modelsAbs)) return [];
|
|
36244
|
+
return (0, import_node_fs59.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path45.join)(modelsAbs, f));
|
|
36046
36245
|
}
|
|
36047
36246
|
function trimDiagnostics(text) {
|
|
36048
36247
|
return text.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
|
|
36049
36248
|
}
|
|
36050
36249
|
function checkModel(tc, root, modelFile, opts = {}) {
|
|
36051
|
-
const proofsAbs = (0,
|
|
36052
|
-
const rel = (0,
|
|
36250
|
+
const proofsAbs = (0, import_node_path45.join)(root, PROOFS_DIR);
|
|
36251
|
+
const rel = (0, import_node_path45.relative)(proofsAbs, modelFile);
|
|
36053
36252
|
const problem = proofsWorkspaceProblem(root);
|
|
36054
36253
|
const res = problem ? refused(problem) : run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36055
36254
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36056
36255
|
}
|
|
36057
36256
|
async function checkModelAsync(tc, root, modelFile, opts = {}) {
|
|
36058
|
-
const proofsAbs = (0,
|
|
36059
|
-
const rel = (0,
|
|
36257
|
+
const proofsAbs = (0, import_node_path45.join)(root, PROOFS_DIR);
|
|
36258
|
+
const rel = (0, import_node_path45.relative)(proofsAbs, modelFile);
|
|
36060
36259
|
const problem = proofsWorkspaceProblem(root);
|
|
36061
36260
|
const res = problem ? refused(problem) : await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36062
36261
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
@@ -36065,10 +36264,10 @@ function toReport(res, root, modelFile, timeoutMs) {
|
|
|
36065
36264
|
const parsed = parseVerityLines(res.stdout);
|
|
36066
36265
|
const combined = `${res.stdout}
|
|
36067
36266
|
${res.stderr}`;
|
|
36068
|
-
const name2 = parsed.header?.model ?? (0,
|
|
36267
|
+
const name2 = parsed.header?.model ?? (0, import_node_path45.basename)(modelFile, ".lean");
|
|
36069
36268
|
const report = {
|
|
36070
36269
|
model: name2,
|
|
36071
|
-
file: (0,
|
|
36270
|
+
file: (0, import_node_path45.relative)(root, modelFile),
|
|
36072
36271
|
ok: res.ok,
|
|
36073
36272
|
header: parsed.header,
|
|
36074
36273
|
properties: parsed.properties,
|
|
@@ -36143,7 +36342,7 @@ function mergeFormalFindings(response, outcome, pushedFiles) {
|
|
|
36143
36342
|
}
|
|
36144
36343
|
|
|
36145
36344
|
// src/lib/prove/scalpel.ts
|
|
36146
|
-
var
|
|
36345
|
+
var import_node_crypto17 = require("node:crypto");
|
|
36147
36346
|
var ARITHMETIC = /Math\.(?:round|floor|ceil|trunc)\(|\bround\(|\bdivmod\(|[\w)\]]\s*(?:\*|\/(?!\/)|%)\s*[\w(]/;
|
|
36148
36347
|
function functionHazard(numbered2) {
|
|
36149
36348
|
const sites = effectSites(numbered2);
|
|
@@ -36173,7 +36372,7 @@ function semanticFingerprint(numbered2) {
|
|
|
36173
36372
|
if (LOG_LINE.test(t)) continue;
|
|
36174
36373
|
kept.push(t.replace(/\s+/g, " "));
|
|
36175
36374
|
}
|
|
36176
|
-
return (0,
|
|
36375
|
+
return (0, import_node_crypto17.createHash)("sha256").update(kept.join("\n")).digest("hex");
|
|
36177
36376
|
}
|
|
36178
36377
|
function readVerified(root, now = Date.now()) {
|
|
36179
36378
|
const read2 = readRegularFileInRoot(root, VERIFIED_FILE, 256 * 1024);
|
|
@@ -36196,9 +36395,9 @@ function recordVerified(root, rec, now = Date.now()) {
|
|
|
36196
36395
|
}
|
|
36197
36396
|
|
|
36198
36397
|
// src/lib/prove/context.ts
|
|
36199
|
-
var
|
|
36398
|
+
var import_node_crypto18 = require("node:crypto");
|
|
36200
36399
|
var CONTEXT_BUDGET_MS = 2e3;
|
|
36201
|
-
var sha256 = (s) => (0,
|
|
36400
|
+
var sha256 = (s) => (0, import_node_crypto18.createHash)("sha256").update(s).digest("hex");
|
|
36202
36401
|
var TEST_PATH4 = /(^|\/)(tests?|__tests__|spec)\/|\.(test|spec)\.[a-z]+$/;
|
|
36203
36402
|
function slice(content, f, maxLines) {
|
|
36204
36403
|
const all = content.split("\n");
|
|
@@ -36387,7 +36586,7 @@ function workingTreeReader(root) {
|
|
|
36387
36586
|
};
|
|
36388
36587
|
}
|
|
36389
36588
|
function sha256Of(content) {
|
|
36390
|
-
return (0,
|
|
36589
|
+
return (0, import_node_crypto19.createHash)("sha256").update(content).digest("hex");
|
|
36391
36590
|
}
|
|
36392
36591
|
function defaultDeps(opts) {
|
|
36393
36592
|
const env = opts.env ?? process.env;
|
|
@@ -36638,7 +36837,7 @@ async function runFormalPhase(input) {
|
|
|
36638
36837
|
modelName = gen.name;
|
|
36639
36838
|
const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
|
|
36640
36839
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
36641
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
36840
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path46.join)(root, rel);
|
|
36642
36841
|
progress.model = { name: gen.name, file: rel, rounds: round };
|
|
36643
36842
|
progress.step = "check";
|
|
36644
36843
|
report = await deps.check(root, abs);
|
|
@@ -36699,11 +36898,11 @@ async function runFormalPhase(input) {
|
|
|
36699
36898
|
const budget = Math.max(2e4, timeLeft() - 5e3);
|
|
36700
36899
|
const byId = /* @__PURE__ */ new Map();
|
|
36701
36900
|
let stoppedEarly = false;
|
|
36702
|
-
await new Promise((
|
|
36901
|
+
await new Promise((resolve9) => {
|
|
36703
36902
|
let left = toReplay.length;
|
|
36704
|
-
if (left === 0) return
|
|
36903
|
+
if (left === 0) return resolve9();
|
|
36705
36904
|
const settle = () => {
|
|
36706
|
-
if (--left === 0)
|
|
36905
|
+
if (--left === 0) resolve9();
|
|
36707
36906
|
};
|
|
36708
36907
|
for (const p of toReplay) {
|
|
36709
36908
|
void (async () => {
|
|
@@ -36716,7 +36915,7 @@ async function runFormalPhase(input) {
|
|
|
36716
36915
|
if (!stoppedEarly) byId.set(p.id, r);
|
|
36717
36916
|
if (r.verdict === "reproduced" && !stoppedEarly && !isCrash(p)) {
|
|
36718
36917
|
stoppedEarly = true;
|
|
36719
|
-
|
|
36918
|
+
resolve9();
|
|
36720
36919
|
}
|
|
36721
36920
|
})().catch(() => {
|
|
36722
36921
|
byId.set(p.id, null);
|
|
@@ -36760,7 +36959,7 @@ async function runFormalPhase(input) {
|
|
|
36760
36959
|
return done({
|
|
36761
36960
|
status: "checked",
|
|
36762
36961
|
target,
|
|
36763
|
-
model: { name: modelName, file: (0,
|
|
36962
|
+
model: { name: modelName, file: (0, import_node_path46.relative)(root, (0, import_node_path46.join)(root, modelFile)), rounds },
|
|
36764
36963
|
properties: report.properties,
|
|
36765
36964
|
findings
|
|
36766
36965
|
});
|
|
@@ -36823,7 +37022,7 @@ async function generateAndCheck(root, req, opts) {
|
|
|
36823
37022
|
}
|
|
36824
37023
|
const rel = `${dir}/${gen.name}.lean`;
|
|
36825
37024
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
36826
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
37025
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path46.join)(root, rel);
|
|
36827
37026
|
const report = await opts.deps.check(root, abs);
|
|
36828
37027
|
const abstracts = report.header?.abstracts ?? [];
|
|
36829
37028
|
const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
|
|
@@ -36911,10 +37110,10 @@ function runFormalPhaseWithin(input) {
|
|
|
36911
37110
|
if (left <= 0) return Promise.resolve(skippedOutcome("deadline", "no time left"));
|
|
36912
37111
|
const progress = input.progress ?? {};
|
|
36913
37112
|
let timer = null;
|
|
36914
|
-
const cutoff = new Promise((
|
|
37113
|
+
const cutoff = new Promise((resolve9) => {
|
|
36915
37114
|
timer = setTimeout(() => {
|
|
36916
37115
|
progress.cancelled = true;
|
|
36917
|
-
|
|
37116
|
+
resolve9(cutOffOutcome(progress, `hard stop after ${Math.round(left / 1e3)} s during ${progress.step ?? "setup"}`, left));
|
|
36918
37117
|
}, left);
|
|
36919
37118
|
});
|
|
36920
37119
|
return Promise.race([runFormalPhase({ ...input, progress }), cutoff]).finally(() => {
|
|
@@ -36952,12 +37151,12 @@ var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
|
|
|
36952
37151
|
var WRITERS_BUDGET_MS = 1500;
|
|
36953
37152
|
var EXCERPT_MAX_LINES2 = 30;
|
|
36954
37153
|
var GUARD_BLOCK_CAP = 2;
|
|
36955
|
-
var GUARD_ITER_FILE = (0,
|
|
37154
|
+
var GUARD_ITER_FILE = (0, import_node_path47.join)(VERITY_DIR, ".guard-iteration");
|
|
36956
37155
|
function readPreToolUseStdin() {
|
|
36957
37156
|
const empty = { command: "", cwd: null, sessionId: null };
|
|
36958
|
-
return new Promise((
|
|
37157
|
+
return new Promise((resolve9) => {
|
|
36959
37158
|
try {
|
|
36960
|
-
if (process.stdin.isTTY) return
|
|
37159
|
+
if (process.stdin.isTTY) return resolve9(empty);
|
|
36961
37160
|
const chunks = [];
|
|
36962
37161
|
let timer;
|
|
36963
37162
|
let settled = false;
|
|
@@ -36970,7 +37169,7 @@ function readPreToolUseStdin() {
|
|
|
36970
37169
|
process.stdin.removeListener("end", onEnd);
|
|
36971
37170
|
process.stdin.removeListener("error", onError);
|
|
36972
37171
|
process.stdin.pause();
|
|
36973
|
-
|
|
37172
|
+
resolve9(value);
|
|
36974
37173
|
};
|
|
36975
37174
|
const onEnd = () => {
|
|
36976
37175
|
try {
|
|
@@ -36991,13 +37190,13 @@ function readPreToolUseStdin() {
|
|
|
36991
37190
|
process.stdin.on("error", onError);
|
|
36992
37191
|
process.stdin.resume();
|
|
36993
37192
|
} catch {
|
|
36994
|
-
|
|
37193
|
+
resolve9(empty);
|
|
36995
37194
|
}
|
|
36996
37195
|
});
|
|
36997
37196
|
}
|
|
36998
37197
|
function readIterMap() {
|
|
36999
37198
|
try {
|
|
37000
|
-
const raw = JSON.parse((0,
|
|
37199
|
+
const raw = JSON.parse((0, import_node_fs60.readFileSync)(GUARD_ITER_FILE, "utf-8"));
|
|
37001
37200
|
if (raw && typeof raw === "object") {
|
|
37002
37201
|
if (typeof raw.moment === "string" && typeof raw.count === "number") {
|
|
37003
37202
|
return { [raw.moment]: raw.count };
|
|
@@ -37017,10 +37216,10 @@ function readIter(moment) {
|
|
|
37017
37216
|
}
|
|
37018
37217
|
function writeIter(moment, count) {
|
|
37019
37218
|
try {
|
|
37020
|
-
(0,
|
|
37219
|
+
(0, import_node_fs60.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
37021
37220
|
const map = readIterMap();
|
|
37022
37221
|
map[moment] = count;
|
|
37023
|
-
(0,
|
|
37222
|
+
(0, import_node_fs60.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
37024
37223
|
} catch {
|
|
37025
37224
|
}
|
|
37026
37225
|
}
|
|
@@ -37030,10 +37229,10 @@ function resetIter(moment) {
|
|
|
37030
37229
|
if (!(moment in map)) return;
|
|
37031
37230
|
delete map[moment];
|
|
37032
37231
|
if (Object.keys(map).length === 0) {
|
|
37033
|
-
if ((0,
|
|
37232
|
+
if ((0, import_node_fs60.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs60.unlinkSync)(GUARD_ITER_FILE);
|
|
37034
37233
|
} else {
|
|
37035
|
-
(0,
|
|
37036
|
-
(0,
|
|
37234
|
+
(0, import_node_fs60.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
37235
|
+
(0, import_node_fs60.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
37037
37236
|
}
|
|
37038
37237
|
} catch {
|
|
37039
37238
|
}
|
|
@@ -37103,7 +37302,7 @@ function hasBlockingFinding(response, sentFiles) {
|
|
|
37103
37302
|
function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
|
|
37104
37303
|
const analyzable = filterAnalyzable(files);
|
|
37105
37304
|
const securityFiles = filterSecurity(files);
|
|
37106
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0,
|
|
37305
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs60.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
|
|
37107
37306
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
37108
37307
|
const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
|
|
37109
37308
|
const requestBody = {
|
|
@@ -37720,8 +37919,8 @@ function registerIgnoreCommand(program2) {
|
|
|
37720
37919
|
}
|
|
37721
37920
|
|
|
37722
37921
|
// src/commands/waive.ts
|
|
37723
|
-
var
|
|
37724
|
-
var
|
|
37922
|
+
var import_node_crypto20 = require("node:crypto");
|
|
37923
|
+
var import_node_fs61 = require("node:fs");
|
|
37725
37924
|
function registerWaiveCommand(program2) {
|
|
37726
37925
|
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) => {
|
|
37727
37926
|
const globals = program2.opts();
|
|
@@ -37750,7 +37949,7 @@ function registerWaiveCommand(program2) {
|
|
|
37750
37949
|
if (opts.file) {
|
|
37751
37950
|
body2.file = opts.file;
|
|
37752
37951
|
try {
|
|
37753
|
-
body2.file_sha256 = (0,
|
|
37952
|
+
body2.file_sha256 = (0, import_node_crypto20.createHash)("sha256").update((0, import_node_fs61.readFileSync)(opts.file)).digest("hex");
|
|
37754
37953
|
} catch {
|
|
37755
37954
|
printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
|
|
37756
37955
|
process.exit(1);
|
|
@@ -37775,10 +37974,10 @@ function registerWaiveCommand(program2) {
|
|
|
37775
37974
|
}
|
|
37776
37975
|
|
|
37777
37976
|
// src/commands/init.ts
|
|
37778
|
-
var
|
|
37977
|
+
var import_node_fs66 = require("node:fs");
|
|
37779
37978
|
var import_promises20 = require("node:fs/promises");
|
|
37780
37979
|
var import_yaml6 = __toESM2(require_dist());
|
|
37781
|
-
var
|
|
37980
|
+
var import_node_path51 = require("node:path");
|
|
37782
37981
|
var import_node_child_process19 = require("node:child_process");
|
|
37783
37982
|
|
|
37784
37983
|
// src/lib/banner.ts
|
|
@@ -37857,7 +38056,7 @@ function printPhase(n, of, title, subtitle) {
|
|
|
37857
38056
|
}
|
|
37858
38057
|
|
|
37859
38058
|
// src/commands/doctor.ts
|
|
37860
|
-
var
|
|
38059
|
+
var import_node_fs62 = require("node:fs");
|
|
37861
38060
|
|
|
37862
38061
|
// src/lib/prereqs.ts
|
|
37863
38062
|
var import_node_child_process16 = require("node:child_process");
|
|
@@ -37918,13 +38117,13 @@ function checkAnalysisCli() {
|
|
|
37918
38117
|
}
|
|
37919
38118
|
var INSTALL_TIMEOUT_MS = 12e4;
|
|
37920
38119
|
function run3(command, args2, opts = {}) {
|
|
37921
|
-
return new Promise((
|
|
38120
|
+
return new Promise((resolve9) => {
|
|
37922
38121
|
const child = (0, import_node_child_process16.spawn)(command, args2, {
|
|
37923
38122
|
stdio: opts.inherit ? "inherit" : "pipe",
|
|
37924
38123
|
timeout: INSTALL_TIMEOUT_MS
|
|
37925
38124
|
});
|
|
37926
|
-
child.on("error", () =>
|
|
37927
|
-
child.on("close", (code) =>
|
|
38125
|
+
child.on("error", () => resolve9(false));
|
|
38126
|
+
child.on("close", (code) => resolve9(code === 0));
|
|
37928
38127
|
});
|
|
37929
38128
|
}
|
|
37930
38129
|
async function installAnalysisCli() {
|
|
@@ -38065,11 +38264,11 @@ async function buildReport() {
|
|
|
38065
38264
|
const hooks = wiring.status;
|
|
38066
38265
|
const provenance = cliProvenance();
|
|
38067
38266
|
const telemetry = await checkTelemetry();
|
|
38068
|
-
const hasConfig = (0,
|
|
38267
|
+
const hasConfig = (0, import_node_fs62.existsSync)(projectPath(CODACY_CONFIG_FILE));
|
|
38069
38268
|
const artifacts = {
|
|
38070
|
-
standard: (0,
|
|
38269
|
+
standard: (0, import_node_fs62.existsSync)(projectPath(STANDARD_FILE)),
|
|
38071
38270
|
analysisConfig: hasConfig,
|
|
38072
|
-
verityMd: (0,
|
|
38271
|
+
verityMd: (0, import_node_fs62.existsSync)(projectPath(VERITY_MD_FILE)),
|
|
38073
38272
|
analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
|
|
38074
38273
|
};
|
|
38075
38274
|
const next = [];
|
|
@@ -38228,8 +38427,8 @@ function registerDoctorCommand(program2) {
|
|
|
38228
38427
|
}
|
|
38229
38428
|
|
|
38230
38429
|
// src/commands/migrate.ts
|
|
38231
|
-
var
|
|
38232
|
-
var
|
|
38430
|
+
var import_node_fs63 = require("node:fs");
|
|
38431
|
+
var import_node_path48 = require("node:path");
|
|
38233
38432
|
var import_node_child_process17 = require("node:child_process");
|
|
38234
38433
|
var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
|
|
38235
38434
|
function defaultNpmRemover(pkg) {
|
|
@@ -38266,12 +38465,12 @@ async function runMigration(opts = {}) {
|
|
|
38266
38465
|
return { actions, migrated: actions.length > 0 };
|
|
38267
38466
|
}
|
|
38268
38467
|
function migrateProjectDir(root, actions) {
|
|
38269
|
-
const gateDir = (0,
|
|
38270
|
-
const verityDir = (0,
|
|
38271
|
-
if ((0,
|
|
38468
|
+
const gateDir = (0, import_node_path48.join)(root, ".gate");
|
|
38469
|
+
const verityDir = (0, import_node_path48.join)(root, ".verity");
|
|
38470
|
+
if ((0, import_node_fs63.existsSync)(gateDir) && !(0, import_node_fs63.existsSync)(verityDir)) {
|
|
38272
38471
|
return migrateProjectDirRename(root, gateDir, verityDir, actions);
|
|
38273
38472
|
}
|
|
38274
|
-
if ((0,
|
|
38473
|
+
if ((0, import_node_fs63.existsSync)(gateDir) && (0, import_node_fs63.existsSync)(verityDir)) {
|
|
38275
38474
|
return migrateProjectDirCarry(gateDir, verityDir, actions);
|
|
38276
38475
|
}
|
|
38277
38476
|
return false;
|
|
@@ -38292,13 +38491,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
|
|
|
38292
38491
|
}
|
|
38293
38492
|
}
|
|
38294
38493
|
if (moved) {
|
|
38295
|
-
if ((0,
|
|
38494
|
+
if ((0, import_node_fs63.existsSync)(gateDir)) {
|
|
38296
38495
|
const carried = carryLegacyContents(gateDir, verityDir);
|
|
38297
38496
|
if (carried > 0) {
|
|
38298
38497
|
actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
|
|
38299
38498
|
}
|
|
38300
38499
|
try {
|
|
38301
|
-
(0,
|
|
38500
|
+
(0, import_node_fs63.rmSync)(gateDir, { recursive: true, force: true });
|
|
38302
38501
|
} catch {
|
|
38303
38502
|
}
|
|
38304
38503
|
}
|
|
@@ -38314,18 +38513,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
|
|
|
38314
38513
|
actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
|
|
38315
38514
|
}
|
|
38316
38515
|
try {
|
|
38317
|
-
(0,
|
|
38516
|
+
(0, import_node_fs63.rmSync)(gateDir, { recursive: true, force: true });
|
|
38318
38517
|
} catch {
|
|
38319
38518
|
}
|
|
38320
38519
|
return carried > 0;
|
|
38321
38520
|
}
|
|
38322
38521
|
function migrateGlobalCredentials(home, actions) {
|
|
38323
38522
|
if (!home) return;
|
|
38324
|
-
const gateCreds = (0,
|
|
38325
|
-
const verityCreds = (0,
|
|
38326
|
-
if (!(0,
|
|
38327
|
-
if (!(0,
|
|
38328
|
-
(0,
|
|
38523
|
+
const gateCreds = (0, import_node_path48.join)(home, ".gate", "credentials");
|
|
38524
|
+
const verityCreds = (0, import_node_path48.join)(home, ".verity", "credentials");
|
|
38525
|
+
if (!(0, import_node_fs63.existsSync)(gateCreds)) return;
|
|
38526
|
+
if (!(0, import_node_fs63.existsSync)(verityCreds)) {
|
|
38527
|
+
(0, import_node_fs63.mkdirSync)((0, import_node_path48.join)(home, ".verity"), { recursive: true });
|
|
38329
38528
|
moveFile(gateCreds, verityCreds);
|
|
38330
38529
|
actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
|
|
38331
38530
|
return;
|
|
@@ -38347,8 +38546,8 @@ async function migrateLegacyHooks(root, actions) {
|
|
|
38347
38546
|
}
|
|
38348
38547
|
}
|
|
38349
38548
|
async function migrateClaudeMd(root, actions) {
|
|
38350
|
-
const claudeMd = (0,
|
|
38351
|
-
const hadLegacyBlock = (0,
|
|
38549
|
+
const claudeMd = (0, import_node_path48.join)(root, "CLAUDE.md");
|
|
38550
|
+
const hadLegacyBlock = (0, import_node_fs63.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
|
|
38352
38551
|
if (!hadLegacyBlock) return;
|
|
38353
38552
|
try {
|
|
38354
38553
|
await ensureClaudeMdPointer(root);
|
|
@@ -38358,9 +38557,9 @@ async function migrateClaudeMd(root, actions) {
|
|
|
38358
38557
|
}
|
|
38359
38558
|
}
|
|
38360
38559
|
function migrateStandardFile(root, actions) {
|
|
38361
|
-
const gateMd = (0,
|
|
38362
|
-
const verityMd = (0,
|
|
38363
|
-
if (!(0,
|
|
38560
|
+
const gateMd = (0, import_node_path48.join)(root, "GATE.md");
|
|
38561
|
+
const verityMd = (0, import_node_path48.join)(root, "VERITY.md");
|
|
38562
|
+
if (!(0, import_node_fs63.existsSync)(gateMd) || (0, import_node_fs63.existsSync)(verityMd)) return;
|
|
38364
38563
|
let moved = false;
|
|
38365
38564
|
if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
|
|
38366
38565
|
try {
|
|
@@ -38372,12 +38571,12 @@ function migrateStandardFile(root, actions) {
|
|
|
38372
38571
|
if (!moved) moveFile(gateMd, verityMd);
|
|
38373
38572
|
const content = readFileSyncSafe(verityMd);
|
|
38374
38573
|
const refreshed = content.split("GATE.md").join("VERITY.md");
|
|
38375
|
-
if (refreshed !== content) (0,
|
|
38574
|
+
if (refreshed !== content) (0, import_node_fs63.writeFileSync)(verityMd, refreshed);
|
|
38376
38575
|
actions.push("Renamed GATE.md \u2192 VERITY.md");
|
|
38377
38576
|
}
|
|
38378
38577
|
async function migrateTelemetryHeaders(root, actions) {
|
|
38379
|
-
const file = (0,
|
|
38380
|
-
if (!(0,
|
|
38578
|
+
const file = (0, import_node_path48.join)(root, ".claude", "settings.local.json");
|
|
38579
|
+
if (!(0, import_node_fs63.existsSync)(file)) return;
|
|
38381
38580
|
let settings;
|
|
38382
38581
|
try {
|
|
38383
38582
|
settings = JSON.parse(readFileSyncSafe(file) || "{}");
|
|
@@ -38425,14 +38624,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
|
|
|
38425
38624
|
}
|
|
38426
38625
|
if (toAppend.length > 0) {
|
|
38427
38626
|
const sep5 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
|
|
38428
|
-
(0,
|
|
38627
|
+
(0, import_node_fs63.writeFileSync)(verityCreds, verityContent + sep5 + toAppend.join("\n") + "\n");
|
|
38429
38628
|
}
|
|
38430
|
-
(0,
|
|
38629
|
+
(0, import_node_fs63.rmSync)(gateCreds, { force: true });
|
|
38431
38630
|
return toAppend.length;
|
|
38432
38631
|
}
|
|
38433
38632
|
function readFileSyncSafe(path) {
|
|
38434
38633
|
try {
|
|
38435
|
-
return (0,
|
|
38634
|
+
return (0, import_node_fs63.readFileSync)(path, "utf-8");
|
|
38436
38635
|
} catch {
|
|
38437
38636
|
return "";
|
|
38438
38637
|
}
|
|
@@ -38447,35 +38646,35 @@ function hasStagedChanges(root) {
|
|
|
38447
38646
|
}
|
|
38448
38647
|
function moveDir(from, to) {
|
|
38449
38648
|
try {
|
|
38450
|
-
(0,
|
|
38649
|
+
(0, import_node_fs63.renameSync)(from, to);
|
|
38451
38650
|
} catch (err2) {
|
|
38452
38651
|
if (err2.code !== "EXDEV") throw err2;
|
|
38453
|
-
(0,
|
|
38454
|
-
(0,
|
|
38652
|
+
(0, import_node_fs63.cpSync)(from, to, { recursive: true });
|
|
38653
|
+
(0, import_node_fs63.rmSync)(from, { recursive: true, force: true });
|
|
38455
38654
|
}
|
|
38456
38655
|
}
|
|
38457
38656
|
function moveFile(from, to) {
|
|
38458
38657
|
try {
|
|
38459
|
-
(0,
|
|
38658
|
+
(0, import_node_fs63.renameSync)(from, to);
|
|
38460
38659
|
} catch (err2) {
|
|
38461
38660
|
if (err2.code !== "EXDEV") throw err2;
|
|
38462
|
-
(0,
|
|
38463
|
-
(0,
|
|
38661
|
+
(0, import_node_fs63.cpSync)(from, to);
|
|
38662
|
+
(0, import_node_fs63.rmSync)(from, { force: true });
|
|
38464
38663
|
}
|
|
38465
38664
|
}
|
|
38466
38665
|
function carryLegacyContents(gateDir, verityDir) {
|
|
38467
38666
|
let copied = 0;
|
|
38468
38667
|
const walk2 = (relDir) => {
|
|
38469
|
-
const srcDir = (0,
|
|
38470
|
-
for (const entry of (0,
|
|
38471
|
-
const rel = relDir ? (0,
|
|
38472
|
-
const src = (0,
|
|
38473
|
-
const dest = (0,
|
|
38474
|
-
if ((0,
|
|
38668
|
+
const srcDir = (0, import_node_path48.join)(gateDir, relDir);
|
|
38669
|
+
for (const entry of (0, import_node_fs63.readdirSync)(srcDir)) {
|
|
38670
|
+
const rel = relDir ? (0, import_node_path48.join)(relDir, entry) : entry;
|
|
38671
|
+
const src = (0, import_node_path48.join)(gateDir, rel);
|
|
38672
|
+
const dest = (0, import_node_path48.join)(verityDir, rel);
|
|
38673
|
+
if ((0, import_node_fs63.statSync)(src).isDirectory()) {
|
|
38475
38674
|
walk2(rel);
|
|
38476
|
-
} else if (!(0,
|
|
38477
|
-
(0,
|
|
38478
|
-
(0,
|
|
38675
|
+
} else if (!(0, import_node_fs63.existsSync)(dest)) {
|
|
38676
|
+
(0, import_node_fs63.mkdirSync)((0, import_node_path48.dirname)(dest), { recursive: true });
|
|
38677
|
+
(0, import_node_fs63.cpSync)(src, dest);
|
|
38479
38678
|
copied++;
|
|
38480
38679
|
}
|
|
38481
38680
|
}
|
|
@@ -38484,22 +38683,22 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
38484
38683
|
return copied;
|
|
38485
38684
|
}
|
|
38486
38685
|
async function needsMigration(root = repoRoot()) {
|
|
38487
|
-
const gateDir = (0,
|
|
38488
|
-
const verityDir = (0,
|
|
38489
|
-
if ((0,
|
|
38490
|
-
if ((0,
|
|
38491
|
-
if ((0,
|
|
38686
|
+
const gateDir = (0, import_node_path48.join)(root, ".gate");
|
|
38687
|
+
const verityDir = (0, import_node_path48.join)(root, ".verity");
|
|
38688
|
+
if ((0, import_node_fs63.existsSync)(gateDir) && !(0, import_node_fs63.existsSync)(verityDir)) return true;
|
|
38689
|
+
if ((0, import_node_fs63.existsSync)(gateDir) && (0, import_node_fs63.existsSync)(verityDir)) {
|
|
38690
|
+
if ((0, import_node_fs63.existsSync)((0, import_node_path48.join)(gateDir, "credentials")) && !(0, import_node_fs63.existsSync)((0, import_node_path48.join)(verityDir, "credentials"))) {
|
|
38492
38691
|
return true;
|
|
38493
38692
|
}
|
|
38494
|
-
if ((0,
|
|
38693
|
+
if ((0, import_node_fs63.existsSync)((0, import_node_path48.join)(gateDir, "memory")) && !(0, import_node_fs63.existsSync)((0, import_node_path48.join)(verityDir, "memory"))) {
|
|
38495
38694
|
return true;
|
|
38496
38695
|
}
|
|
38497
38696
|
}
|
|
38498
|
-
const claudeMd = (0,
|
|
38499
|
-
if ((0,
|
|
38697
|
+
const claudeMd = (0, import_node_path48.join)(root, "CLAUDE.md");
|
|
38698
|
+
if ((0, import_node_fs63.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
|
|
38500
38699
|
return true;
|
|
38501
38700
|
}
|
|
38502
|
-
if ((0,
|
|
38701
|
+
if ((0, import_node_fs63.existsSync)((0, import_node_path48.join)(root, "GATE.md")) && !(0, import_node_fs63.existsSync)((0, import_node_path48.join)(root, "VERITY.md"))) {
|
|
38503
38702
|
return true;
|
|
38504
38703
|
}
|
|
38505
38704
|
if (await hasLegacyHooksAt(root)) return true;
|
|
@@ -38628,7 +38827,7 @@ function runSelect(opts) {
|
|
|
38628
38827
|
cursor: initialIdx[0] ?? 0,
|
|
38629
38828
|
chosen: new Set(mode2 === "single" ? [initialIdx[0] ?? 0] : initialIdx)
|
|
38630
38829
|
};
|
|
38631
|
-
return new Promise((
|
|
38830
|
+
return new Promise((resolve9) => {
|
|
38632
38831
|
let painted = 0;
|
|
38633
38832
|
let settled = false;
|
|
38634
38833
|
const draw = () => {
|
|
@@ -38676,7 +38875,7 @@ function runSelect(opts) {
|
|
|
38676
38875
|
if (settled) return;
|
|
38677
38876
|
settled = true;
|
|
38678
38877
|
restore();
|
|
38679
|
-
|
|
38878
|
+
resolve9(value);
|
|
38680
38879
|
};
|
|
38681
38880
|
readline2.emitKeypressEvents(input);
|
|
38682
38881
|
input.setRawMode(true);
|
|
@@ -38697,9 +38896,9 @@ async function askLine(question, io = {}) {
|
|
|
38697
38896
|
output: io.output ?? process.stdout
|
|
38698
38897
|
});
|
|
38699
38898
|
try {
|
|
38700
|
-
return await new Promise((
|
|
38701
|
-
rl.question(question).then((a) =>
|
|
38702
|
-
rl.once("close", () => setImmediate(() =>
|
|
38899
|
+
return await new Promise((resolve9) => {
|
|
38900
|
+
rl.question(question).then((a) => resolve9(a.trim())).catch(() => resolve9(null));
|
|
38901
|
+
rl.once("close", () => setImmediate(() => resolve9(null)));
|
|
38703
38902
|
});
|
|
38704
38903
|
} finally {
|
|
38705
38904
|
rl.close();
|
|
@@ -38780,11 +38979,11 @@ async function promptMultiSelect(question, choices, fallback) {
|
|
|
38780
38979
|
}
|
|
38781
38980
|
|
|
38782
38981
|
// src/lib/prove/lean-install.ts
|
|
38783
|
-
var
|
|
38784
|
-
var
|
|
38982
|
+
var import_node_fs64 = require("node:fs");
|
|
38983
|
+
var import_node_crypto21 = require("node:crypto");
|
|
38785
38984
|
var import_node_child_process18 = require("node:child_process");
|
|
38786
38985
|
var import_node_os10 = require("node:os");
|
|
38787
|
-
var
|
|
38986
|
+
var import_node_path49 = require("node:path");
|
|
38788
38987
|
var import_promises18 = require("node:stream/promises");
|
|
38789
38988
|
var import_node_stream = require("node:stream");
|
|
38790
38989
|
var RELEASES = "https://releases.lean-lang.org/lean4";
|
|
@@ -38795,10 +38994,10 @@ function freeBytes(dir) {
|
|
|
38795
38994
|
let d = dir;
|
|
38796
38995
|
for (let i2 = 0; i2 < 64; i2++) {
|
|
38797
38996
|
try {
|
|
38798
|
-
const st = (0,
|
|
38997
|
+
const st = (0, import_node_fs64.statfsSync)(d);
|
|
38799
38998
|
return Number(st.bavail) * Number(st.bsize);
|
|
38800
38999
|
} catch {
|
|
38801
|
-
const up = (0,
|
|
39000
|
+
const up = (0, import_node_path49.join)(d, "..");
|
|
38802
39001
|
if (up === d) return null;
|
|
38803
39002
|
d = up;
|
|
38804
39003
|
}
|
|
@@ -38818,9 +39017,9 @@ function expectedSha256(asset, version = pinnedVersion()) {
|
|
|
38818
39017
|
return LEAN_ASSET_SHA256[version]?.[asset] ?? null;
|
|
38819
39018
|
}
|
|
38820
39019
|
function sha256File(path) {
|
|
38821
|
-
return new Promise((
|
|
38822
|
-
const hash = (0,
|
|
38823
|
-
(0,
|
|
39020
|
+
return new Promise((resolve9, reject) => {
|
|
39021
|
+
const hash = (0, import_node_crypto21.createHash)("sha256");
|
|
39022
|
+
(0, import_node_fs64.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve9(hash.digest("hex"))).on("error", reject);
|
|
38824
39023
|
});
|
|
38825
39024
|
}
|
|
38826
39025
|
async function verifyDownload(zip, asset, version = pinnedVersion()) {
|
|
@@ -38840,7 +39039,7 @@ function leanAssetName(version = pinnedVersion()) {
|
|
|
38840
39039
|
return suffix ? `lean-${v}-${suffix}.zip` : null;
|
|
38841
39040
|
}
|
|
38842
39041
|
function pinnedVersionDir(env = process.env) {
|
|
38843
|
-
return (0,
|
|
39042
|
+
return (0, import_node_path49.join)(verityLeanHome(env), pinnedVersion());
|
|
38844
39043
|
}
|
|
38845
39044
|
function lakeBinary() {
|
|
38846
39045
|
return (0, import_node_os10.platform)() === "win32" ? "lake.exe" : "lake";
|
|
@@ -38851,12 +39050,12 @@ function unzip(zip, dest) {
|
|
|
38851
39050
|
for (const [cmd, args2] of attempts) {
|
|
38852
39051
|
try {
|
|
38853
39052
|
(0, import_node_child_process18.execFileSync)(cmd, args2, { stdio: ["ignore", "ignore", "pipe"], timeout: 15 * 6e4 });
|
|
38854
|
-
if ((0,
|
|
39053
|
+
if ((0, import_node_fs64.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
|
|
38855
39054
|
errors.push(`${cmd}: produced nothing`);
|
|
38856
39055
|
} catch (err2) {
|
|
38857
39056
|
errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
|
|
38858
39057
|
try {
|
|
38859
|
-
for (const e of (0,
|
|
39058
|
+
for (const e of (0, import_node_fs64.readdirSync)(dest)) (0, import_node_fs64.rmSync)((0, import_node_path49.join)(dest, e), { recursive: true, force: true });
|
|
38860
39059
|
} catch {
|
|
38861
39060
|
}
|
|
38862
39061
|
}
|
|
@@ -38882,7 +39081,7 @@ async function download(url, dest, onProgress, stallMs = DOWNLOAD_STALL_MS) {
|
|
|
38882
39081
|
seen += chunk.length;
|
|
38883
39082
|
onProgress(seen, total);
|
|
38884
39083
|
});
|
|
38885
|
-
await (0, import_promises18.pipeline)(stream, (0,
|
|
39084
|
+
await (0, import_promises18.pipeline)(stream, (0, import_node_fs64.createWriteStream)(dest), { signal: ctrl.signal });
|
|
38886
39085
|
} catch (err2) {
|
|
38887
39086
|
if (ctrl.signal.aborted) throw new Error(`download stalled: nothing received for ${Math.round(stallMs / 1e3)} s`);
|
|
38888
39087
|
throw err2;
|
|
@@ -38932,10 +39131,10 @@ async function installLean(opts = {}) {
|
|
|
38932
39131
|
const gb = (n) => (n / 1024 ** 3).toFixed(1);
|
|
38933
39132
|
return { ok: false, error: `not enough disk space for Lean: ${gb(free)} GB free where ${home} lives, needs about ${gb(needed)} GB` };
|
|
38934
39133
|
}
|
|
38935
|
-
const tmp = (0,
|
|
38936
|
-
(0,
|
|
38937
|
-
(0,
|
|
38938
|
-
const zip = (0,
|
|
39134
|
+
const tmp = (0, import_node_path49.join)(home, ".tmp");
|
|
39135
|
+
(0, import_node_fs64.rmSync)(tmp, { recursive: true, force: true });
|
|
39136
|
+
(0, import_node_fs64.mkdirSync)(tmp, { recursive: true });
|
|
39137
|
+
const zip = (0, import_node_path49.join)(tmp, asset);
|
|
38939
39138
|
say(`downloading ${url}`);
|
|
38940
39139
|
let lastPct = -1;
|
|
38941
39140
|
try {
|
|
@@ -38948,40 +39147,40 @@ async function installLean(opts = {}) {
|
|
|
38948
39147
|
}
|
|
38949
39148
|
});
|
|
38950
39149
|
} catch (err2) {
|
|
38951
|
-
(0,
|
|
39150
|
+
(0, import_node_fs64.rmSync)(tmp, { recursive: true, force: true });
|
|
38952
39151
|
return { ok: false, error: err2.message };
|
|
38953
39152
|
}
|
|
38954
39153
|
say("verifying checksum");
|
|
38955
39154
|
const verified = await verifyDownload(zip, asset);
|
|
38956
39155
|
if (!verified.ok) {
|
|
38957
|
-
(0,
|
|
39156
|
+
(0, import_node_fs64.rmSync)(tmp, { recursive: true, force: true });
|
|
38958
39157
|
return { ok: false, error: verified.error };
|
|
38959
39158
|
}
|
|
38960
39159
|
say("unpacking (this takes a minute)");
|
|
38961
|
-
const unpack = (0,
|
|
38962
|
-
(0,
|
|
39160
|
+
const unpack = (0, import_node_path49.join)(tmp, "unpack");
|
|
39161
|
+
(0, import_node_fs64.mkdirSync)(unpack);
|
|
38963
39162
|
const unpacked = unzip(zip, unpack);
|
|
38964
39163
|
if (!unpacked.ok) {
|
|
38965
|
-
(0,
|
|
39164
|
+
(0, import_node_fs64.rmSync)(tmp, { recursive: true, force: true });
|
|
38966
39165
|
return { ok: false, error: `unpack failed: ${unpacked.error}` };
|
|
38967
39166
|
}
|
|
38968
|
-
const entries = (0,
|
|
38969
|
-
const top = entries.length === 1 && (0,
|
|
38970
|
-
if (!(0,
|
|
38971
|
-
(0,
|
|
39167
|
+
const entries = (0, import_node_fs64.readdirSync)(unpack);
|
|
39168
|
+
const top = entries.length === 1 && (0, import_node_fs64.statSync)((0, import_node_path49.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path49.join)(unpack, entries[0]) : unpack;
|
|
39169
|
+
if (!(0, import_node_fs64.existsSync)((0, import_node_path49.join)(top, "bin", lakeBinary()))) {
|
|
39170
|
+
(0, import_node_fs64.rmSync)(tmp, { recursive: true, force: true });
|
|
38972
39171
|
return { ok: false, error: "the archive did not contain bin/lake" };
|
|
38973
39172
|
}
|
|
38974
|
-
(0,
|
|
38975
|
-
(0,
|
|
38976
|
-
(0,
|
|
38977
|
-
(0,
|
|
39173
|
+
(0, import_node_fs64.rmSync)(dir, { recursive: true, force: true });
|
|
39174
|
+
(0, import_node_fs64.mkdirSync)(home, { recursive: true });
|
|
39175
|
+
(0, import_node_fs64.renameSync)(top, dir);
|
|
39176
|
+
(0, import_node_fs64.rmSync)(tmp, { recursive: true, force: true });
|
|
38978
39177
|
return { ok: true, dir };
|
|
38979
39178
|
}
|
|
38980
39179
|
|
|
38981
39180
|
// src/lib/remote-config.ts
|
|
38982
|
-
var
|
|
39181
|
+
var import_node_fs65 = require("node:fs");
|
|
38983
39182
|
var import_promises19 = require("node:fs/promises");
|
|
38984
|
-
var
|
|
39183
|
+
var import_node_path50 = require("node:path");
|
|
38985
39184
|
var import_yaml5 = __toESM2(require_dist());
|
|
38986
39185
|
var IGNORE_RIDER = "verityignore";
|
|
38987
39186
|
async function fetchRemoteSetup(opts) {
|
|
@@ -39026,7 +39225,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
39026
39225
|
written.push(STANDARD_FILE);
|
|
39027
39226
|
if (rider !== null) {
|
|
39028
39227
|
const localIgnore = projectPath(VERITYIGNORE_FILE);
|
|
39029
|
-
if (!(0,
|
|
39228
|
+
if (!(0, import_node_fs65.existsSync)(localIgnore)) {
|
|
39030
39229
|
await writeOut(VERITYIGNORE_FILE, rider);
|
|
39031
39230
|
written.push(VERITYIGNORE_FILE);
|
|
39032
39231
|
} else {
|
|
@@ -39059,7 +39258,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
39059
39258
|
}
|
|
39060
39259
|
async function writeOut(relative6, body2) {
|
|
39061
39260
|
const target = projectPath(relative6);
|
|
39062
|
-
await (0, import_promises19.mkdir)((0,
|
|
39261
|
+
await (0, import_promises19.mkdir)((0, import_node_path50.dirname)(target), { recursive: true });
|
|
39063
39262
|
await (0, import_promises19.writeFile)(target, body2);
|
|
39064
39263
|
}
|
|
39065
39264
|
function describeRemote(found) {
|
|
@@ -39176,15 +39375,15 @@ async function runOptionalAuth(resolution, opts = {}) {
|
|
|
39176
39375
|
}
|
|
39177
39376
|
function resolveDataDir2() {
|
|
39178
39377
|
const candidates2 = [
|
|
39179
|
-
(0,
|
|
39378
|
+
(0, import_node_path51.join)(__dirname, "..", "data"),
|
|
39180
39379
|
// installed: node_modules/@codacy/verity-cli/data
|
|
39181
|
-
(0,
|
|
39380
|
+
(0, import_node_path51.join)(__dirname, "..", "..", "data"),
|
|
39182
39381
|
// edge case: nested resolution
|
|
39183
|
-
(0,
|
|
39382
|
+
(0, import_node_path51.join)(process.cwd(), "cli", "data")
|
|
39184
39383
|
// local dev: running from repo root
|
|
39185
39384
|
];
|
|
39186
39385
|
for (const candidate of candidates2) {
|
|
39187
|
-
if ((0,
|
|
39386
|
+
if ((0, import_node_fs66.existsSync)((0, import_node_path51.join)(candidate, "skills"))) {
|
|
39188
39387
|
return candidate;
|
|
39189
39388
|
}
|
|
39190
39389
|
}
|
|
@@ -39200,9 +39399,9 @@ async function skillIsCurrent(src, dest) {
|
|
|
39200
39399
|
const list2 = (dir) => {
|
|
39201
39400
|
const out2 = [];
|
|
39202
39401
|
const walk2 = (d, prefix) => {
|
|
39203
|
-
for (const e of (0,
|
|
39402
|
+
for (const e of (0, import_node_fs66.readdirSync)(d, { withFileTypes: true })) {
|
|
39204
39403
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
39205
|
-
if (e.isDirectory()) walk2((0,
|
|
39404
|
+
if (e.isDirectory()) walk2((0, import_node_path51.join)(d, e.name), rel);
|
|
39206
39405
|
else if (e.isFile()) out2.push(rel);
|
|
39207
39406
|
}
|
|
39208
39407
|
};
|
|
@@ -39213,8 +39412,8 @@ async function skillIsCurrent(src, dest) {
|
|
|
39213
39412
|
const shipped = list2(src);
|
|
39214
39413
|
if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
|
|
39215
39414
|
for (const rel of shipped) {
|
|
39216
|
-
const a = await (0, import_promises20.readFile)((0,
|
|
39217
|
-
const b = await (0, import_promises20.readFile)((0,
|
|
39415
|
+
const a = await (0, import_promises20.readFile)((0, import_node_path51.join)(src, rel), "utf-8");
|
|
39416
|
+
const b = await (0, import_promises20.readFile)((0, import_node_path51.join)(dest, rel), "utf-8");
|
|
39218
39417
|
if (a !== b) return false;
|
|
39219
39418
|
}
|
|
39220
39419
|
return true;
|
|
@@ -39417,7 +39616,7 @@ async function synthesizeLocally(opts) {
|
|
|
39417
39616
|
async function healStaleAnalysisConfig(globals) {
|
|
39418
39617
|
const configPath = projectPath(CODACY_CONFIG_FILE);
|
|
39419
39618
|
const standardPath = projectPath(STANDARD_FILE);
|
|
39420
|
-
if (!(0,
|
|
39619
|
+
if (!(0, import_node_fs66.existsSync)(configPath) || !(0, import_node_fs66.existsSync)(standardPath)) return;
|
|
39421
39620
|
const validation = validatePatternIds();
|
|
39422
39621
|
if (validation.status !== "invalid") return;
|
|
39423
39622
|
printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
|
|
@@ -39514,17 +39713,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
|
|
|
39514
39713
|
async function installSkills(force, step) {
|
|
39515
39714
|
step("Installing skills");
|
|
39516
39715
|
const dataDir = resolveDataDir2();
|
|
39517
|
-
const skillsSource = (0,
|
|
39716
|
+
const skillsSource = (0, import_node_path51.join)(dataDir, "skills");
|
|
39518
39717
|
const skillsDest = ".claude/skills";
|
|
39519
39718
|
let skillsInstalled = 0;
|
|
39520
39719
|
for (const skill of SKILLS) {
|
|
39521
|
-
const src = (0,
|
|
39522
|
-
const dest = (0,
|
|
39523
|
-
if (!(0,
|
|
39720
|
+
const src = (0, import_node_path51.join)(skillsSource, skill);
|
|
39721
|
+
const dest = (0, import_node_path51.join)(skillsDest, skill);
|
|
39722
|
+
if (!(0, import_node_fs66.existsSync)(src)) {
|
|
39524
39723
|
printWarn(` Skill data not found: ${skill}`);
|
|
39525
39724
|
continue;
|
|
39526
39725
|
}
|
|
39527
|
-
if ((0,
|
|
39726
|
+
if ((0, import_node_fs66.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
|
|
39528
39727
|
skillsInstalled++;
|
|
39529
39728
|
continue;
|
|
39530
39729
|
}
|
|
@@ -39724,7 +39923,7 @@ function registerInitCommand(program2) {
|
|
|
39724
39923
|
const staleMarker = clearStalePluginMarker();
|
|
39725
39924
|
const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
|
|
39726
39925
|
const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
|
|
39727
|
-
const isProject = projectMarkers.some((m) => (0,
|
|
39926
|
+
const isProject = projectMarkers.some((m) => (0, import_node_fs66.existsSync)(m));
|
|
39728
39927
|
if (!isProject) {
|
|
39729
39928
|
printError("No project detected in the current directory.");
|
|
39730
39929
|
printInfo('Run "verity init" from your project root.');
|
|
@@ -39827,7 +40026,7 @@ function registerInitCommand(program2) {
|
|
|
39827
40026
|
untrackMemory: opts.untrackMemory === true,
|
|
39828
40027
|
untrackState: opts.untrackState === true
|
|
39829
40028
|
});
|
|
39830
|
-
const globalVerityDir = (0,
|
|
40029
|
+
const globalVerityDir = (0, import_node_path51.join)(process.env.HOME ?? "", ".verity");
|
|
39831
40030
|
await (0, import_promises20.mkdir)(globalVerityDir, { recursive: true });
|
|
39832
40031
|
console.log("");
|
|
39833
40032
|
step("Wiring Claude Code hooks");
|
|
@@ -39902,7 +40101,7 @@ function registerInitCommand(program2) {
|
|
|
39902
40101
|
}
|
|
39903
40102
|
step("Your project's Standard");
|
|
39904
40103
|
let haveStandard = false;
|
|
39905
|
-
if ((0,
|
|
40104
|
+
if ((0, import_node_fs66.existsSync)(projectPath(STANDARD_FILE))) {
|
|
39906
40105
|
printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
|
|
39907
40106
|
haveStandard = true;
|
|
39908
40107
|
} else {
|
|
@@ -39932,7 +40131,7 @@ function registerInitCommand(program2) {
|
|
|
39932
40131
|
...telemetryChoice ? { telemetry: telemetryChoice } : {},
|
|
39933
40132
|
init: {
|
|
39934
40133
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
39935
|
-
cli_version: true ? "0.34.0-experimental.
|
|
40134
|
+
cli_version: true ? "0.34.0-experimental.380b51f" : "dev"
|
|
39936
40135
|
}
|
|
39937
40136
|
});
|
|
39938
40137
|
} catch (err2) {
|
|
@@ -39982,8 +40181,8 @@ function registerInitCommand(program2) {
|
|
|
39982
40181
|
}
|
|
39983
40182
|
|
|
39984
40183
|
// src/commands/uninstall.ts
|
|
39985
|
-
var
|
|
39986
|
-
var
|
|
40184
|
+
var import_node_fs67 = require("node:fs");
|
|
40185
|
+
var import_node_path52 = require("node:path");
|
|
39987
40186
|
function registerUninstallCommand(program2) {
|
|
39988
40187
|
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
40188
|
const dryRun = opts.dryRun ?? false;
|
|
@@ -39992,11 +40191,11 @@ function registerUninstallCommand(program2) {
|
|
|
39992
40191
|
const actions = [];
|
|
39993
40192
|
const skillsRoot = projectPath(".claude/skills");
|
|
39994
40193
|
for (const name2 of PROJECT_SKILL_NAMES) {
|
|
39995
|
-
const dir = (0,
|
|
39996
|
-
if ((0,
|
|
40194
|
+
const dir = (0, import_node_path52.join)(skillsRoot, name2);
|
|
40195
|
+
if ((0, import_node_fs67.existsSync)(dir)) {
|
|
39997
40196
|
actions.push({
|
|
39998
40197
|
label: `Remove .claude/skills/${name2}/`,
|
|
39999
|
-
apply: () => (0,
|
|
40198
|
+
apply: () => (0, import_node_fs67.rmSync)(dir, { recursive: true, force: true })
|
|
40000
40199
|
});
|
|
40001
40200
|
}
|
|
40002
40201
|
}
|
|
@@ -40010,24 +40209,24 @@ function registerUninstallCommand(program2) {
|
|
|
40010
40209
|
});
|
|
40011
40210
|
}
|
|
40012
40211
|
const verityDir = projectPath(VERITY_DIR);
|
|
40013
|
-
if ((0,
|
|
40212
|
+
if ((0, import_node_fs67.existsSync)(verityDir)) {
|
|
40014
40213
|
actions.push({
|
|
40015
40214
|
label: `Remove ${VERITY_DIR}/`,
|
|
40016
|
-
apply: () => (0,
|
|
40215
|
+
apply: () => (0, import_node_fs67.rmSync)(verityDir, { recursive: true, force: true })
|
|
40017
40216
|
});
|
|
40018
40217
|
}
|
|
40019
40218
|
if (!keepVerityMd) {
|
|
40020
40219
|
const verityMd = projectPath(VERITY_MD_FILE);
|
|
40021
|
-
if ((0,
|
|
40220
|
+
if ((0, import_node_fs67.existsSync)(verityMd)) {
|
|
40022
40221
|
actions.push({
|
|
40023
40222
|
label: `Remove ${VERITY_MD_FILE}`,
|
|
40024
|
-
apply: () => (0,
|
|
40223
|
+
apply: () => (0, import_node_fs67.rmSync)(verityMd, { force: true })
|
|
40025
40224
|
});
|
|
40026
40225
|
}
|
|
40027
40226
|
}
|
|
40028
40227
|
const cleanupEmptyDir = (path) => {
|
|
40029
|
-
if ((0,
|
|
40030
|
-
(0,
|
|
40228
|
+
if ((0, import_node_fs67.existsSync)(path) && (0, import_node_fs67.statSync)(path).isDirectory() && (0, import_node_fs67.readdirSync)(path).length === 0) {
|
|
40229
|
+
(0, import_node_fs67.rmdirSync)(path);
|
|
40031
40230
|
}
|
|
40032
40231
|
};
|
|
40033
40232
|
actions.push({
|
|
@@ -40038,11 +40237,11 @@ function registerUninstallCommand(program2) {
|
|
|
40038
40237
|
}
|
|
40039
40238
|
});
|
|
40040
40239
|
const home = process.env.HOME ?? "";
|
|
40041
|
-
const globalVerityDir = (0,
|
|
40042
|
-
if (purgeGlobal && (0,
|
|
40240
|
+
const globalVerityDir = (0, import_node_path52.join)(home, ".verity");
|
|
40241
|
+
if (purgeGlobal && (0, import_node_fs67.existsSync)(globalVerityDir)) {
|
|
40043
40242
|
actions.push({
|
|
40044
40243
|
label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
|
|
40045
|
-
apply: () => (0,
|
|
40244
|
+
apply: () => (0, import_node_fs67.rmSync)(globalVerityDir, { recursive: true, force: true })
|
|
40046
40245
|
});
|
|
40047
40246
|
}
|
|
40048
40247
|
if (actions.length === 0) {
|
|
@@ -40236,8 +40435,8 @@ function registerTaskCommands(program2) {
|
|
|
40236
40435
|
}
|
|
40237
40436
|
|
|
40238
40437
|
// src/commands/reset.ts
|
|
40239
|
-
var
|
|
40240
|
-
var
|
|
40438
|
+
var import_node_fs68 = require("node:fs");
|
|
40439
|
+
var import_node_path53 = require("node:path");
|
|
40241
40440
|
function registerResetCommand(program2) {
|
|
40242
40441
|
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
40442
|
const globals = program2.opts();
|
|
@@ -40274,11 +40473,11 @@ function registerResetCommand(program2) {
|
|
|
40274
40473
|
}
|
|
40275
40474
|
const cacheDir = projectPath(CACHE_DIR);
|
|
40276
40475
|
let purged = 0;
|
|
40277
|
-
if ((0,
|
|
40278
|
-
for (const entry of (0,
|
|
40476
|
+
if ((0, import_node_fs68.existsSync)(cacheDir)) {
|
|
40477
|
+
for (const entry of (0, import_node_fs68.readdirSync)(cacheDir)) {
|
|
40279
40478
|
if (entry.startsWith("pending-")) {
|
|
40280
40479
|
try {
|
|
40281
|
-
(0,
|
|
40480
|
+
(0, import_node_fs68.unlinkSync)((0, import_node_path53.join)(cacheDir, entry));
|
|
40282
40481
|
purged++;
|
|
40283
40482
|
} catch {
|
|
40284
40483
|
}
|
|
@@ -40293,19 +40492,19 @@ function registerResetCommand(program2) {
|
|
|
40293
40492
|
projectPath(`${VERITY_DIR}/.last-analysis`)
|
|
40294
40493
|
];
|
|
40295
40494
|
for (const file of filesToClear) {
|
|
40296
|
-
if ((0,
|
|
40495
|
+
if ((0, import_node_fs68.existsSync)(file)) {
|
|
40297
40496
|
try {
|
|
40298
|
-
(0,
|
|
40497
|
+
(0, import_node_fs68.writeFileSync)(file, "");
|
|
40299
40498
|
} catch {
|
|
40300
40499
|
}
|
|
40301
40500
|
}
|
|
40302
40501
|
}
|
|
40303
40502
|
if (opts.all) {
|
|
40304
40503
|
const logsDir = projectPath(`${VERITY_DIR}/.logs`);
|
|
40305
|
-
if ((0,
|
|
40306
|
-
for (const entry of (0,
|
|
40504
|
+
if ((0, import_node_fs68.existsSync)(logsDir)) {
|
|
40505
|
+
for (const entry of (0, import_node_fs68.readdirSync)(logsDir)) {
|
|
40307
40506
|
try {
|
|
40308
|
-
(0,
|
|
40507
|
+
(0, import_node_fs68.unlinkSync)((0, import_node_path53.join)(logsDir, entry));
|
|
40309
40508
|
} catch {
|
|
40310
40509
|
}
|
|
40311
40510
|
}
|
|
@@ -40317,7 +40516,7 @@ function registerResetCommand(program2) {
|
|
|
40317
40516
|
}
|
|
40318
40517
|
|
|
40319
40518
|
// src/commands/reflect.ts
|
|
40320
|
-
var
|
|
40519
|
+
var import_node_fs69 = require("node:fs");
|
|
40321
40520
|
|
|
40322
40521
|
// src/lib/reflection-globs.ts
|
|
40323
40522
|
var MAX_GLOBS = 6;
|
|
@@ -40325,7 +40524,7 @@ var PATH_TOKEN = /[A-Za-z0-9_./-]*[A-Za-z0-9_-]\.[A-Za-z0-9]{1,8}(?::\d+(?::\d+)
|
|
|
40325
40524
|
function clean(token) {
|
|
40326
40525
|
return token.replace(/:\d+(?::\d+)?$/, "").replace(/^[`'"(\[]+/, "").replace(/[`'"),\].;!?]+$/, "").replace(/^\.\//, "");
|
|
40327
40526
|
}
|
|
40328
|
-
function
|
|
40527
|
+
function resolve7(token, treePaths) {
|
|
40329
40528
|
if (treePaths.includes(token)) return token;
|
|
40330
40529
|
const suffix = token.startsWith("/") ? token : `/${token}`;
|
|
40331
40530
|
const matches = treePaths.filter((p) => p.endsWith(suffix));
|
|
@@ -40338,7 +40537,7 @@ function deriveFileGlobs(text, treePaths) {
|
|
|
40338
40537
|
for (const raw of text.match(PATH_TOKEN) ?? []) {
|
|
40339
40538
|
const token = clean(raw);
|
|
40340
40539
|
if (!token) continue;
|
|
40341
|
-
const path =
|
|
40540
|
+
const path = resolve7(token, treePaths);
|
|
40342
40541
|
if (!path || seen.has(path)) continue;
|
|
40343
40542
|
seen.add(path);
|
|
40344
40543
|
out2.push(path);
|
|
@@ -40355,14 +40554,19 @@ async function writeNodeToDisk(args2) {
|
|
|
40355
40554
|
{ treePaths: listTrackedFiles(), recordBaseline: false }
|
|
40356
40555
|
);
|
|
40357
40556
|
if (written === 0) return false;
|
|
40358
|
-
return (0,
|
|
40557
|
+
return (0, import_node_fs69.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
|
|
40359
40558
|
} catch {
|
|
40360
40559
|
return false;
|
|
40361
40560
|
}
|
|
40362
40561
|
}
|
|
40363
40562
|
function registerReflectCommand(program2) {
|
|
40364
|
-
program2.command("reflect").description("Capture learnings \u2014 auto-extract or record a reflection").option("--user-input <text>", "The reflection to record (the agent-drafted or user-dictated text)").option("--kind <kind>", "Node kind (decision, gotcha, pattern, security, quality, intent, domain, integration)", "gotcha").option("--task-id <id>", "Task to reflect on (defaults to current task)").option("--confirmed", "The USER authored or confirmed these exact words \u2014 records as human-authored (source: user, confidence 1.0)").option("--file-globs <glob...>", "Files this reflection is about. Without any, the paths cited in the text are used; a reflection matching no file never surfaces in a review").option("--autonomous", "(deprecated, ignored) reflections are always recorded without a confirm step").action(async (opts) => {
|
|
40563
|
+
program2.command("reflect").description("Capture learnings \u2014 auto-extract or record a reflection").option("--user-input <text>", "The reflection to record (the agent-drafted or user-dictated text); - reads it from stdin, so the words never pass through shell quoting").option("--kind <kind>", "Node kind (decision, gotcha, pattern, security, quality, intent, domain, integration)", "gotcha").option("--task-id <id>", "Task to reflect on (defaults to current task)").option("--confirmed", "The USER authored or confirmed these exact words \u2014 records as human-authored (source: user, confidence 1.0)").option("--file-globs <glob...>", "Files this reflection is about. Without any, the paths cited in the text are used; a reflection matching no file never surfaces in a review").option("--autonomous", "(deprecated, ignored) reflections are always recorded without a confirm step").action(async (opts) => {
|
|
40365
40564
|
const globals = program2.opts();
|
|
40565
|
+
const input = readTextInput(opts.userInput, "--user-input");
|
|
40566
|
+
if (!input.ok) {
|
|
40567
|
+
printError(input.error);
|
|
40568
|
+
process.exit(1);
|
|
40569
|
+
}
|
|
40366
40570
|
await ensureMemoryDir();
|
|
40367
40571
|
const tokenResult = await resolveToken(globals.token);
|
|
40368
40572
|
if (!tokenResult.ok) {
|
|
@@ -40423,7 +40627,7 @@ function registerReflectCommand(program2) {
|
|
|
40423
40627
|
taskResolution = "none";
|
|
40424
40628
|
printWarn("No active task found \u2014 saving as an unattached reflection.");
|
|
40425
40629
|
}
|
|
40426
|
-
const userInput =
|
|
40630
|
+
const userInput = input.text;
|
|
40427
40631
|
if (userInput) {
|
|
40428
40632
|
const validKinds = ["decision", "gotcha", "pattern", "security", "quality", "intent", "domain", "integration"];
|
|
40429
40633
|
const kind = validKinds.includes(opts.kind) ? opts.kind : "gotcha";
|
|
@@ -40787,9 +40991,9 @@ function registerRunCommand(program2) {
|
|
|
40787
40991
|
}
|
|
40788
40992
|
|
|
40789
40993
|
// src/commands/telemetry.ts
|
|
40790
|
-
var
|
|
40994
|
+
var import_node_fs70 = require("node:fs");
|
|
40791
40995
|
async function recordTelemetryChoice(choice) {
|
|
40792
|
-
if (!(0,
|
|
40996
|
+
if (!(0, import_node_fs70.existsSync)(projectPath(SETUP_STATE_FILE))) return;
|
|
40793
40997
|
try {
|
|
40794
40998
|
if ((await readSetupState())?.telemetry === choice) return;
|
|
40795
40999
|
await writeSetupState({ telemetry: choice });
|
|
@@ -40866,8 +41070,8 @@ function registerTelemetryCommands(program2) {
|
|
|
40866
41070
|
}
|
|
40867
41071
|
|
|
40868
41072
|
// src/commands/prove.ts
|
|
40869
|
-
var
|
|
40870
|
-
var
|
|
41073
|
+
var import_node_fs71 = require("node:fs");
|
|
41074
|
+
var import_node_path54 = require("node:path");
|
|
40871
41075
|
|
|
40872
41076
|
// src/lib/prove/hint-pool.ts
|
|
40873
41077
|
var STOP2 = /* @__PURE__ */ new Set([
|
|
@@ -40994,7 +41198,13 @@ async function proveAuth(program2) {
|
|
|
40994
41198
|
}
|
|
40995
41199
|
function registerProveCommand(program2) {
|
|
40996
41200
|
const prove = program2.command("prove").description("Formal verification (Lean 4) of small, risky pieces of code \u2014 on demand");
|
|
40997
|
-
prove.command("candidates [paths...]").description("Rank code worth a formal model, from git history and risk signals").option("--since <when>", `git --since window (default: "${DEFAULT_SINCE}")`).option("--limit <n>", "Candidates to show", "10").option("--rank <ranker>", "deterministic | luna | jev (luna and jev need an API key)", "deterministic").option("--hint <text>", "What the user wants checked, in their words (biases the rank; implies --rank luna)").option("--json", "Machine-readable output").action(async (paths, opts) => {
|
|
41201
|
+
prove.command("candidates [paths...]").description("Rank code worth a formal model, from git history and risk signals").option("--since <when>", `git --since window (default: "${DEFAULT_SINCE}")`).option("--limit <n>", "Candidates to show", "10").option("--rank <ranker>", "deterministic | luna | jev (luna and jev need an API key)", "deterministic").option("--hint <text>", "What the user wants checked, in their words (biases the rank; implies --rank luna); - reads it from stdin, so the words never pass through shell quoting").option("--json", "Machine-readable output").action(async (paths, opts) => {
|
|
41202
|
+
const hint = readTextInput(opts.hint, "--hint");
|
|
41203
|
+
if (!hint.ok) {
|
|
41204
|
+
printError(hint.error);
|
|
41205
|
+
process.exit(2);
|
|
41206
|
+
}
|
|
41207
|
+
opts.hint = hint.text;
|
|
40998
41208
|
if (opts.hint && opts.rank === "deterministic") opts.rank = "luna";
|
|
40999
41209
|
const root = repoRoot();
|
|
41000
41210
|
const ranker = RANKERS[opts.rank];
|
|
@@ -41003,7 +41213,7 @@ function registerProveCommand(program2) {
|
|
|
41003
41213
|
process.exit(2);
|
|
41004
41214
|
}
|
|
41005
41215
|
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,
|
|
41216
|
+
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
41217
|
if (opts.hint && paths.length === 0) {
|
|
41008
41218
|
const hit = hintMatches(root, opts.hint);
|
|
41009
41219
|
if (hit.files.length > 0) {
|
|
@@ -41057,7 +41267,7 @@ function registerProveCommand(program2) {
|
|
|
41057
41267
|
});
|
|
41058
41268
|
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
41269
|
const root = repoRoot();
|
|
41060
|
-
if (!(0,
|
|
41270
|
+
if (!(0, import_node_fs71.existsSync)((0, import_node_path54.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41061
41271
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41062
41272
|
process.exit(2);
|
|
41063
41273
|
}
|
|
@@ -41081,7 +41291,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41081
41291
|
const reports = [];
|
|
41082
41292
|
for (const f of files) {
|
|
41083
41293
|
const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
|
|
41084
|
-
report.file = (0,
|
|
41294
|
+
report.file = (0, import_node_path54.relative)(root, f);
|
|
41085
41295
|
reports.push(report);
|
|
41086
41296
|
try {
|
|
41087
41297
|
writeResult(root, report);
|
|
@@ -41119,7 +41329,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41119
41329
|
printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
|
|
41120
41330
|
process.exit(2);
|
|
41121
41331
|
}
|
|
41122
|
-
if (!(0,
|
|
41332
|
+
if (!(0, import_node_fs71.existsSync)((0, import_node_path54.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41123
41333
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41124
41334
|
process.exit(2);
|
|
41125
41335
|
}
|
|
@@ -41150,7 +41360,7 @@ ${report.error ?? ""}`);
|
|
|
41150
41360
|
printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
|
|
41151
41361
|
return;
|
|
41152
41362
|
}
|
|
41153
|
-
const modelSource = readRegularFileInRoot(root, (0,
|
|
41363
|
+
const modelSource = readRegularFileInRoot(root, (0, import_node_path54.relative)(root, file), 512 * 1024);
|
|
41154
41364
|
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
41365
|
const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
|
|
41156
41366
|
const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
|
|
@@ -41170,7 +41380,7 @@ ${report.error ?? ""}`);
|
|
|
41170
41380
|
});
|
|
41171
41381
|
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
41382
|
const root = repoRoot();
|
|
41173
|
-
let files = paths.map((p) => (0,
|
|
41383
|
+
let files = paths.map((p) => (0, import_node_path54.relative)(root, (0, import_node_path54.resolve)(p)));
|
|
41174
41384
|
if (files.length === 0) {
|
|
41175
41385
|
const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
|
|
41176
41386
|
const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
|
|
@@ -41199,7 +41409,19 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41199
41409
|
}
|
|
41200
41410
|
process.exit(outcome.findings.some((f) => f.verdict === "reproduced") ? 1 : 0);
|
|
41201
41411
|
});
|
|
41202
|
-
prove.command("generate <target>").description("Have the Verity service write a Lean model of one symbol (file#symbol), lint it, and check it here \u2014 up to 3 rounds").option("--lines <a-b>", "Model a region of the file (1-based, inclusive) instead of a named symbol").option("--hint <text>", "The user's worry, in their words (may become an intent property)").option("--revise <model>", "Revise this existing model after a diverged replay (with --note)").option("--note <text>", "What the replay showed was different (with --revise)").option("--json", "Machine-readable output").action(async (targetArg, opts) => {
|
|
41412
|
+
prove.command("generate <target>").description("Have the Verity service write a Lean model of one symbol (file#symbol), lint it, and check it here \u2014 up to 3 rounds").option("--lines <a-b>", "Model a region of the file (1-based, inclusive) instead of a named symbol").option("--hint <text>", "The user's worry, in their words (may become an intent property); - reads it from stdin").option("--revise <model>", "Revise this existing model after a diverged replay (with --note)").option("--note <text>", "What the replay showed was different (with --revise); - reads it from stdin").option("--json", "Machine-readable output").action(async (targetArg, opts) => {
|
|
41413
|
+
if (opts.hint === "-" && opts.note === "-") {
|
|
41414
|
+
printError("Only one of --hint and --note can read stdin (-).");
|
|
41415
|
+
process.exit(2);
|
|
41416
|
+
}
|
|
41417
|
+
for (const flag of ["hint", "note"]) {
|
|
41418
|
+
const input = readTextInput(opts[flag], `--${flag}`);
|
|
41419
|
+
if (!input.ok) {
|
|
41420
|
+
printError(input.error);
|
|
41421
|
+
process.exit(2);
|
|
41422
|
+
}
|
|
41423
|
+
opts[flag] = input.text;
|
|
41424
|
+
}
|
|
41203
41425
|
const root = repoRoot();
|
|
41204
41426
|
const auth2 = await proveAuth(program2);
|
|
41205
41427
|
if (!auth2 && !(process.env.VERITY_PROVE_DIRECT === "1" && process.env.OPENAI_API_KEY)) {
|
|
@@ -41230,9 +41452,9 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41230
41452
|
let revise;
|
|
41231
41453
|
if (opts.revise) {
|
|
41232
41454
|
const existing = resolveModelFile(root, opts.revise);
|
|
41233
|
-
const src = existing ? readRegularFileInRoot(root, (0,
|
|
41455
|
+
const src = existing ? readRegularFileInRoot(root, (0, import_node_path54.relative)(root, existing), 64 * 1024) : null;
|
|
41234
41456
|
if (!src || !src.ok || !opts.note) {
|
|
41235
|
-
printError(
|
|
41457
|
+
printError("--revise needs an existing model under Models/ and --note - with what the replay showed on stdin");
|
|
41236
41458
|
process.exit(2);
|
|
41237
41459
|
}
|
|
41238
41460
|
revise = { source: src.content, note: opts.note };
|
|
@@ -41269,8 +41491,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41269
41491
|
});
|
|
41270
41492
|
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
41493
|
const root = repoRoot();
|
|
41272
|
-
const rel0 = (0,
|
|
41273
|
-
const rel = rel0.startsWith("..") || (0,
|
|
41494
|
+
const rel0 = (0, import_node_path54.relative)(root, (0, import_node_path54.isAbsolute)(file) ? file : (0, import_node_path54.join)(root, file)).replace(/\\/g, "/");
|
|
41495
|
+
const rel = rel0.startsWith("..") || (0, import_node_path54.isAbsolute)(rel0) ? null : rel0;
|
|
41274
41496
|
if (!rel) {
|
|
41275
41497
|
printError(`${file} is not inside this repository`);
|
|
41276
41498
|
process.exit(2);
|
|
@@ -41286,8 +41508,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41286
41508
|
});
|
|
41287
41509
|
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
41510
|
const root = repoRoot();
|
|
41289
|
-
const rel = (0,
|
|
41290
|
-
const digest = rel.startsWith("..") || (0,
|
|
41511
|
+
const rel = (0, import_node_path54.relative)(root, (0, import_node_path54.isAbsolute)(file) ? file : (0, import_node_path54.join)(root, file));
|
|
41512
|
+
const digest = rel.startsWith("..") || (0, import_node_path54.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
|
|
41291
41513
|
if (!digest) {
|
|
41292
41514
|
printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
|
|
41293
41515
|
process.exit(2);
|
|
@@ -41321,10 +41543,10 @@ function refreshScaffold(root) {
|
|
|
41321
41543
|
}
|
|
41322
41544
|
|
|
41323
41545
|
// src/commands/lean.ts
|
|
41324
|
-
var
|
|
41546
|
+
var import_node_fs72 = require("node:fs");
|
|
41325
41547
|
var import_node_child_process20 = require("node:child_process");
|
|
41326
41548
|
var import_node_os11 = require("node:os");
|
|
41327
|
-
var
|
|
41549
|
+
var import_node_path55 = require("node:path");
|
|
41328
41550
|
function registerLeanCommand(program2) {
|
|
41329
41551
|
const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
|
|
41330
41552
|
lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
|
|
@@ -41341,7 +41563,7 @@ function registerLeanCommand(program2) {
|
|
|
41341
41563
|
const managed = pinnedVersionDir();
|
|
41342
41564
|
const matches = version ? version.includes(pin) : false;
|
|
41343
41565
|
if (opts.json) {
|
|
41344
|
-
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0,
|
|
41566
|
+
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs72.existsSync)((0, import_node_path55.join)(managed, "bin")), asset: leanAssetName() });
|
|
41345
41567
|
return;
|
|
41346
41568
|
}
|
|
41347
41569
|
printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
|
|
@@ -41359,7 +41581,7 @@ function registerLeanCommand(program2) {
|
|
|
41359
41581
|
process.exit(2);
|
|
41360
41582
|
}
|
|
41361
41583
|
const dir = pinnedVersionDir();
|
|
41362
|
-
if ((0,
|
|
41584
|
+
if ((0, import_node_fs72.existsSync)((0, import_node_path55.join)(dir, "bin", "lake")) && !opts.force) {
|
|
41363
41585
|
printInfo(`already installed at ${dir}`);
|
|
41364
41586
|
return;
|
|
41365
41587
|
}
|
|
@@ -41395,18 +41617,18 @@ function registerLeanCommand(program2) {
|
|
|
41395
41617
|
});
|
|
41396
41618
|
lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
|
|
41397
41619
|
const dir = pinnedVersionDir();
|
|
41398
|
-
if (!(0,
|
|
41620
|
+
if (!(0, import_node_fs72.existsSync)(dir)) {
|
|
41399
41621
|
printInfo("nothing to remove");
|
|
41400
41622
|
return;
|
|
41401
41623
|
}
|
|
41402
|
-
(0,
|
|
41624
|
+
(0, import_node_fs72.rmSync)(dir, { recursive: true, force: true });
|
|
41403
41625
|
printInfo(`removed ${dir}`);
|
|
41404
41626
|
});
|
|
41405
41627
|
}
|
|
41406
41628
|
|
|
41407
41629
|
// 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.
|
|
41630
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.380b51f").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) => {
|
|
41631
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.380b51f");
|
|
41410
41632
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
41411
41633
|
try {
|
|
41412
41634
|
await foldLegacyLocalCredential();
|