@codacy/verity-cli 0.34.0-experimental.5235853 → 0.34.0-experimental.53caba1
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 +1000 -593
- 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]);
|
|
@@ -22965,7 +23100,7 @@ function isIgnored2(path) {
|
|
|
22965
23100
|
}
|
|
22966
23101
|
function listProjectFiles(root) {
|
|
22967
23102
|
try {
|
|
22968
|
-
const out2 = (0, import_node_child_process9.execSync)("git ls-files -z", {
|
|
23103
|
+
const out2 = (0, import_node_child_process9.execSync)("git ls-files -z --cached --others --exclude-standard", {
|
|
22969
23104
|
cwd: root,
|
|
22970
23105
|
encoding: "utf-8",
|
|
22971
23106
|
maxBuffer: 32 * 1024 * 1024,
|
|
@@ -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.53caba1" : "dev";
|
|
27077
27256
|
} catch {
|
|
27078
27257
|
return "dev";
|
|
27079
27258
|
}
|
|
@@ -27114,7 +27293,171 @@ 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");
|
|
27297
|
+
|
|
27298
|
+
// src/lib/environment-globals.ts
|
|
27299
|
+
var NODE = [
|
|
27300
|
+
"process",
|
|
27301
|
+
"Buffer",
|
|
27302
|
+
"global",
|
|
27303
|
+
"require",
|
|
27304
|
+
"module",
|
|
27305
|
+
"exports",
|
|
27306
|
+
"__dirname",
|
|
27307
|
+
"__filename",
|
|
27308
|
+
"console",
|
|
27309
|
+
"setTimeout",
|
|
27310
|
+
"clearTimeout",
|
|
27311
|
+
"setInterval",
|
|
27312
|
+
"clearInterval",
|
|
27313
|
+
"setImmediate",
|
|
27314
|
+
"clearImmediate",
|
|
27315
|
+
"queueMicrotask",
|
|
27316
|
+
"structuredClone",
|
|
27317
|
+
"performance",
|
|
27318
|
+
"fetch",
|
|
27319
|
+
"Request",
|
|
27320
|
+
"Response",
|
|
27321
|
+
"Headers",
|
|
27322
|
+
"FormData",
|
|
27323
|
+
"Blob",
|
|
27324
|
+
"File",
|
|
27325
|
+
"URL",
|
|
27326
|
+
"URLSearchParams",
|
|
27327
|
+
"TextEncoder",
|
|
27328
|
+
"TextDecoder",
|
|
27329
|
+
"TextEncoderStream",
|
|
27330
|
+
"TextDecoderStream",
|
|
27331
|
+
"AbortController",
|
|
27332
|
+
"AbortSignal",
|
|
27333
|
+
"Event",
|
|
27334
|
+
"EventTarget",
|
|
27335
|
+
"CustomEvent",
|
|
27336
|
+
"MessageChannel",
|
|
27337
|
+
"MessagePort",
|
|
27338
|
+
"MessageEvent",
|
|
27339
|
+
"BroadcastChannel",
|
|
27340
|
+
"WebSocket",
|
|
27341
|
+
"WebAssembly",
|
|
27342
|
+
"crypto",
|
|
27343
|
+
"Crypto",
|
|
27344
|
+
"CryptoKey",
|
|
27345
|
+
"SubtleCrypto",
|
|
27346
|
+
"atob",
|
|
27347
|
+
"btoa",
|
|
27348
|
+
"navigator",
|
|
27349
|
+
"DOMException",
|
|
27350
|
+
"ReadableStream",
|
|
27351
|
+
"WritableStream",
|
|
27352
|
+
"TransformStream",
|
|
27353
|
+
"CompressionStream",
|
|
27354
|
+
"DecompressionStream",
|
|
27355
|
+
"ByteLengthQueuingStrategy",
|
|
27356
|
+
"CountQueuingStrategy",
|
|
27357
|
+
"PerformanceObserver",
|
|
27358
|
+
"PerformanceEntry",
|
|
27359
|
+
"PerformanceMark",
|
|
27360
|
+
"PerformanceMeasure"
|
|
27361
|
+
];
|
|
27362
|
+
var BROWSER = [
|
|
27363
|
+
"window",
|
|
27364
|
+
"self",
|
|
27365
|
+
"document",
|
|
27366
|
+
"location",
|
|
27367
|
+
"history",
|
|
27368
|
+
"localStorage",
|
|
27369
|
+
"sessionStorage",
|
|
27370
|
+
"screen",
|
|
27371
|
+
"alert",
|
|
27372
|
+
"confirm",
|
|
27373
|
+
"prompt",
|
|
27374
|
+
"requestAnimationFrame",
|
|
27375
|
+
"cancelAnimationFrame",
|
|
27376
|
+
"requestIdleCallback",
|
|
27377
|
+
"cancelIdleCallback",
|
|
27378
|
+
"getComputedStyle",
|
|
27379
|
+
"matchMedia",
|
|
27380
|
+
"getSelection",
|
|
27381
|
+
"scrollTo",
|
|
27382
|
+
"scrollBy",
|
|
27383
|
+
"innerWidth",
|
|
27384
|
+
"innerHeight",
|
|
27385
|
+
"outerWidth",
|
|
27386
|
+
"outerHeight",
|
|
27387
|
+
"devicePixelRatio",
|
|
27388
|
+
"visualViewport",
|
|
27389
|
+
"postMessage",
|
|
27390
|
+
"addEventListener",
|
|
27391
|
+
"removeEventListener",
|
|
27392
|
+
"dispatchEvent",
|
|
27393
|
+
"customElements",
|
|
27394
|
+
"indexedDB",
|
|
27395
|
+
"IDBKeyRange",
|
|
27396
|
+
"caches",
|
|
27397
|
+
"XMLHttpRequest",
|
|
27398
|
+
"EventSource",
|
|
27399
|
+
"FileReader",
|
|
27400
|
+
"Image",
|
|
27401
|
+
"Audio",
|
|
27402
|
+
"Worker",
|
|
27403
|
+
"SharedWorker",
|
|
27404
|
+
"Notification",
|
|
27405
|
+
"MutationObserver",
|
|
27406
|
+
"IntersectionObserver",
|
|
27407
|
+
"ResizeObserver",
|
|
27408
|
+
"DOMParser",
|
|
27409
|
+
"XMLSerializer",
|
|
27410
|
+
"Node",
|
|
27411
|
+
"Element",
|
|
27412
|
+
"HTMLElement",
|
|
27413
|
+
"SVGElement",
|
|
27414
|
+
"NodeList",
|
|
27415
|
+
"HTMLCollection",
|
|
27416
|
+
"DocumentFragment",
|
|
27417
|
+
"ShadowRoot",
|
|
27418
|
+
"Range",
|
|
27419
|
+
"Selection",
|
|
27420
|
+
"KeyboardEvent",
|
|
27421
|
+
"MouseEvent",
|
|
27422
|
+
"PointerEvent",
|
|
27423
|
+
"FocusEvent",
|
|
27424
|
+
"InputEvent",
|
|
27425
|
+
"TouchEvent",
|
|
27426
|
+
"UIEvent",
|
|
27427
|
+
"ErrorEvent",
|
|
27428
|
+
"ProgressEvent",
|
|
27429
|
+
"StorageEvent",
|
|
27430
|
+
"CloseEvent",
|
|
27431
|
+
"CSS",
|
|
27432
|
+
"CSSStyleSheet",
|
|
27433
|
+
"FontFace",
|
|
27434
|
+
"ImageData",
|
|
27435
|
+
"ImageBitmap",
|
|
27436
|
+
"createImageBitmap",
|
|
27437
|
+
"OffscreenCanvas",
|
|
27438
|
+
"Path2D",
|
|
27439
|
+
"CanvasRenderingContext2D",
|
|
27440
|
+
"AudioContext",
|
|
27441
|
+
"MediaStream",
|
|
27442
|
+
"MediaRecorder",
|
|
27443
|
+
"RTCPeerConnection",
|
|
27444
|
+
"ClipboardItem",
|
|
27445
|
+
"isSecureContext",
|
|
27446
|
+
"crossOriginIsolated",
|
|
27447
|
+
"reportError",
|
|
27448
|
+
"speechSynthesis"
|
|
27449
|
+
];
|
|
27450
|
+
var ENVIRONMENT_GLOBALS = /* @__PURE__ */ new Set([...NODE, ...BROWSER]);
|
|
27451
|
+
var NOT_DEFINED = /^'([^']+)' is not defined\.?$/;
|
|
27452
|
+
var COMMONJS_ONLY = /* @__PURE__ */ new Set(["require", "module", "exports", "__dirname", "__filename"]);
|
|
27453
|
+
function isEnvironmentGlobalNoUndef(ruleId, message, filePath = "") {
|
|
27454
|
+
if (!/(^|_)no-undef$/.test(ruleId)) return false;
|
|
27455
|
+
const name2 = message.trim().match(NOT_DEFINED)?.[1];
|
|
27456
|
+
if (name2 === void 0 || !ENVIRONMENT_GLOBALS.has(name2)) return false;
|
|
27457
|
+
return !(COMMONJS_ONLY.has(name2) && /\.m[jt]s$/.test(filePath));
|
|
27458
|
+
}
|
|
27459
|
+
|
|
27460
|
+
// src/lib/static-analysis.ts
|
|
27118
27461
|
var SEVERITY_ORDER = {
|
|
27119
27462
|
Error: 0,
|
|
27120
27463
|
Critical: 0,
|
|
@@ -27170,7 +27513,7 @@ function runCodacyAnalysis(files) {
|
|
|
27170
27513
|
if (files.length === 0) return empty;
|
|
27171
27514
|
const existingFiles = files.filter((f) => {
|
|
27172
27515
|
try {
|
|
27173
|
-
return (0,
|
|
27516
|
+
return (0, import_node_fs42.existsSync)(f);
|
|
27174
27517
|
} catch {
|
|
27175
27518
|
return false;
|
|
27176
27519
|
}
|
|
@@ -27202,7 +27545,10 @@ function interpretAnalyzerRun(run4) {
|
|
|
27202
27545
|
} catch {
|
|
27203
27546
|
return withFailure("unparseable_output", output);
|
|
27204
27547
|
}
|
|
27205
|
-
const
|
|
27548
|
+
const reported = parsed.issues ?? [];
|
|
27549
|
+
const issues = reported.filter(
|
|
27550
|
+
(i2) => !isEnvironmentGlobalNoUndef(i2.patternId ?? "", i2.message ?? "", i2.filePath ?? "")
|
|
27551
|
+
);
|
|
27206
27552
|
const findings = issues.map((issue) => ({
|
|
27207
27553
|
rule_id: issue.patternId ?? "",
|
|
27208
27554
|
tool: issue.toolId ?? "",
|
|
@@ -27225,7 +27571,7 @@ function interpretAnalyzerRun(run4) {
|
|
|
27225
27571
|
);
|
|
27226
27572
|
const analyzerErrors = parsed.errors ?? [];
|
|
27227
27573
|
let failure;
|
|
27228
|
-
if (
|
|
27574
|
+
if (reported.length === 0) {
|
|
27229
27575
|
if (analyzerErrors.length > 0) {
|
|
27230
27576
|
const first = analyzerErrors[0];
|
|
27231
27577
|
failure = {
|
|
@@ -27439,7 +27785,7 @@ async function scope(run4) {
|
|
|
27439
27785
|
}
|
|
27440
27786
|
|
|
27441
27787
|
// src/lib/specs.ts
|
|
27442
|
-
var
|
|
27788
|
+
var import_node_fs43 = require("node:fs");
|
|
27443
27789
|
var import_node_path32 = require("node:path");
|
|
27444
27790
|
var SPEC_CANDIDATES = [
|
|
27445
27791
|
"CLAUDE.md",
|
|
@@ -27481,7 +27827,7 @@ function discoverSpecs(consulted = []) {
|
|
|
27481
27827
|
const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
|
|
27482
27828
|
if (totalBytes >= totalCap) return false;
|
|
27483
27829
|
if (seen.has(specPath)) return true;
|
|
27484
|
-
if (!(0,
|
|
27830
|
+
if (!(0, import_node_fs43.existsSync)(specPath)) return true;
|
|
27485
27831
|
seen.add(specPath);
|
|
27486
27832
|
const remaining = totalCap - totalBytes;
|
|
27487
27833
|
const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
|
|
@@ -27504,7 +27850,7 @@ function discoverSpecs(consulted = []) {
|
|
|
27504
27850
|
if (!addSpec(candidate)) break;
|
|
27505
27851
|
}
|
|
27506
27852
|
for (const dir of ["spec", "docs"]) {
|
|
27507
|
-
if (!(0,
|
|
27853
|
+
if (!(0, import_node_fs43.existsSync)(dir)) continue;
|
|
27508
27854
|
try {
|
|
27509
27855
|
const mdFiles = findMdFiles(dir, 2).sort();
|
|
27510
27856
|
for (const mdFile of mdFiles) {
|
|
@@ -27519,7 +27865,7 @@ function findMdFiles(dir, maxDepth, depth = 0) {
|
|
|
27519
27865
|
if (depth >= maxDepth) return [];
|
|
27520
27866
|
const result = [];
|
|
27521
27867
|
try {
|
|
27522
|
-
const entries = (0,
|
|
27868
|
+
const entries = (0, import_node_fs43.readdirSync)(dir, { withFileTypes: true });
|
|
27523
27869
|
for (const entry of entries) {
|
|
27524
27870
|
const fullPath = (0, import_node_path32.join)(dir, entry.name);
|
|
27525
27871
|
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -27539,13 +27885,13 @@ function discoverPlans() {
|
|
|
27539
27885
|
if (isRealDirectoryChain(process.cwd(), [".claude", "plans"])) {
|
|
27540
27886
|
sources.push({ root: process.cwd(), prefix: (0, import_node_path32.join)(".claude", "plans") });
|
|
27541
27887
|
}
|
|
27542
|
-
if (home && (0,
|
|
27888
|
+
if (home && (0, import_node_fs43.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
|
|
27543
27889
|
const candidates2 = [];
|
|
27544
27890
|
const seen = /* @__PURE__ */ new Set();
|
|
27545
27891
|
for (const source2 of sources) {
|
|
27546
27892
|
let names2;
|
|
27547
27893
|
try {
|
|
27548
|
-
names2 = (0,
|
|
27894
|
+
names2 = (0, import_node_fs43.readdirSync)(source2.prefix ? (0, import_node_path32.join)(source2.root, source2.prefix) : source2.root);
|
|
27549
27895
|
} catch {
|
|
27550
27896
|
continue;
|
|
27551
27897
|
}
|
|
@@ -27572,7 +27918,7 @@ function isRealDirectoryChain(root, parts2) {
|
|
|
27572
27918
|
for (const part of parts2) {
|
|
27573
27919
|
current = (0, import_node_path32.join)(current, part);
|
|
27574
27920
|
try {
|
|
27575
|
-
if (!(0,
|
|
27921
|
+
if (!(0, import_node_fs43.lstatSync)(current).isDirectory()) return false;
|
|
27576
27922
|
} catch {
|
|
27577
27923
|
return false;
|
|
27578
27924
|
}
|
|
@@ -27587,7 +27933,7 @@ function discoverGuardDocs(rangeFiles2) {
|
|
|
27587
27933
|
if (result.length >= MAX_SPEC_FILES) break;
|
|
27588
27934
|
if (!GUARD_DOC_EXT.test(path)) continue;
|
|
27589
27935
|
if (path.startsWith("/") || path.includes("..")) continue;
|
|
27590
|
-
if (!(0,
|
|
27936
|
+
if (!(0, import_node_fs43.existsSync)(path)) continue;
|
|
27591
27937
|
const opened = openRegularInRoot(process.cwd(), path);
|
|
27592
27938
|
if (!opened.ok) continue;
|
|
27593
27939
|
if (opened.size > MAX_PLAN_FILE_BYTES || totalBytes + opened.size > MAX_TOTAL_SPEC_BYTES) {
|
|
@@ -27773,7 +28119,7 @@ async function mode(run4) {
|
|
|
27773
28119
|
}
|
|
27774
28120
|
|
|
27775
28121
|
// src/lib/fold.ts
|
|
27776
|
-
var
|
|
28122
|
+
var import_node_fs44 = require("node:fs");
|
|
27777
28123
|
var import_node_path33 = require("node:path");
|
|
27778
28124
|
var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
|
|
27779
28125
|
"user",
|
|
@@ -27911,7 +28257,7 @@ function candidateRoots(repoRoot2) {
|
|
|
27911
28257
|
const norm2 = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
27912
28258
|
const out2 = [norm2];
|
|
27913
28259
|
try {
|
|
27914
|
-
const real =
|
|
28260
|
+
const real = import_node_fs44.realpathSync.native(norm2).replace(/\\/g, "/").replace(/\/+$/, "");
|
|
27915
28261
|
if (real !== norm2) out2.push(real);
|
|
27916
28262
|
} catch {
|
|
27917
28263
|
}
|
|
@@ -27999,8 +28345,8 @@ function fold(transcriptPath, opts = {}) {
|
|
|
27999
28345
|
}
|
|
28000
28346
|
};
|
|
28001
28347
|
try {
|
|
28002
|
-
if (!(0,
|
|
28003
|
-
ingest((0,
|
|
28348
|
+
if (!(0, import_node_fs44.existsSync)(transcriptPath)) return result;
|
|
28349
|
+
ingest((0, import_node_fs44.readFileSync)(transcriptPath, "utf8"), "agent");
|
|
28004
28350
|
result.coverage.complete = true;
|
|
28005
28351
|
} catch {
|
|
28006
28352
|
return result;
|
|
@@ -28011,19 +28357,19 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28011
28357
|
(0, import_node_path33.basename)(transcriptPath).replace(/\.jsonl$/, ""),
|
|
28012
28358
|
"subagents"
|
|
28013
28359
|
);
|
|
28014
|
-
if ((0,
|
|
28360
|
+
if ((0, import_node_fs44.existsSync)(sidecarDir)) {
|
|
28015
28361
|
const maxFiles = opts.maxSidecars ?? 200;
|
|
28016
28362
|
const maxBytes = opts.maxSidecarBytes ?? 16 * 1024 * 1024;
|
|
28017
28363
|
const found = [];
|
|
28018
28364
|
const walk2 = (d, depth) => {
|
|
28019
28365
|
if (depth > 4) return;
|
|
28020
|
-
for (const e of (0,
|
|
28366
|
+
for (const e of (0, import_node_fs44.readdirSync)(d, { withFileTypes: true })) {
|
|
28021
28367
|
const p = (0, import_node_path33.join)(d, e.name);
|
|
28022
28368
|
if (e.isDirectory()) {
|
|
28023
28369
|
walk2(p, depth + 1);
|
|
28024
28370
|
} else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
|
|
28025
28371
|
try {
|
|
28026
|
-
const st = (0,
|
|
28372
|
+
const st = (0, import_node_fs44.statSync)(p);
|
|
28027
28373
|
found.push({ path: p, size: st.size, mtimeMs: st.mtimeMs });
|
|
28028
28374
|
} catch {
|
|
28029
28375
|
result.coverage.malformed++;
|
|
@@ -28040,7 +28386,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28040
28386
|
continue;
|
|
28041
28387
|
}
|
|
28042
28388
|
try {
|
|
28043
|
-
ingest((0,
|
|
28389
|
+
ingest((0, import_node_fs44.readFileSync)(f.path, "utf8"), "subagent");
|
|
28044
28390
|
bytes += f.size;
|
|
28045
28391
|
result.coverage.subagentFiles++;
|
|
28046
28392
|
} catch {
|
|
@@ -28075,7 +28421,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28075
28421
|
}
|
|
28076
28422
|
function classifyUnobserved(path) {
|
|
28077
28423
|
try {
|
|
28078
|
-
const st = (0,
|
|
28424
|
+
const st = (0, import_node_fs44.statSync)(path);
|
|
28079
28425
|
if (!st.isFile()) return "unreadable";
|
|
28080
28426
|
} catch {
|
|
28081
28427
|
return "unreadable";
|
|
@@ -28390,20 +28736,20 @@ async function evidence(run4) {
|
|
|
28390
28736
|
}
|
|
28391
28737
|
|
|
28392
28738
|
// src/lib/cache-cleanup.ts
|
|
28393
|
-
var
|
|
28739
|
+
var import_node_fs45 = require("node:fs");
|
|
28394
28740
|
var import_node_path34 = require("node:path");
|
|
28395
28741
|
var CACHE_TTL_DAYS = 7;
|
|
28396
28742
|
function pruneStaleCache() {
|
|
28397
28743
|
try {
|
|
28398
28744
|
const dir = projectPath(CACHE_DIR);
|
|
28399
28745
|
const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
|
|
28400
|
-
for (const entry of (0,
|
|
28746
|
+
for (const entry of (0, import_node_fs45.readdirSync)(dir)) {
|
|
28401
28747
|
if (!entry.startsWith("pending-")) continue;
|
|
28402
28748
|
const path = (0, import_node_path34.join)(dir, entry);
|
|
28403
28749
|
try {
|
|
28404
|
-
const stat3 = (0,
|
|
28750
|
+
const stat3 = (0, import_node_fs45.statSync)(path);
|
|
28405
28751
|
if (stat3.mtimeMs < cutoff) {
|
|
28406
|
-
(0,
|
|
28752
|
+
(0, import_node_fs45.unlinkSync)(path);
|
|
28407
28753
|
logEvent("cache_entry_pruned", {
|
|
28408
28754
|
path: entry,
|
|
28409
28755
|
age_days: Math.round((Date.now() - stat3.mtimeMs) / 864e5)
|
|
@@ -28417,7 +28763,7 @@ function pruneStaleCache() {
|
|
|
28417
28763
|
}
|
|
28418
28764
|
|
|
28419
28765
|
// src/lib/context-files.ts
|
|
28420
|
-
var
|
|
28766
|
+
var import_node_fs46 = require("node:fs");
|
|
28421
28767
|
var import_node_os7 = require("node:os");
|
|
28422
28768
|
var MAX_CONTEXT_FILES = 10;
|
|
28423
28769
|
var MAX_CONTEXT_FILE_BYTES = 10240;
|
|
@@ -28475,7 +28821,7 @@ function gatherContextFiles(contextPaths, deltaFiles, opts) {
|
|
|
28475
28821
|
continue;
|
|
28476
28822
|
}
|
|
28477
28823
|
try {
|
|
28478
|
-
const content = (0,
|
|
28824
|
+
const content = (0, import_node_fs46.readFileSync)(safePath, "utf8");
|
|
28479
28825
|
const bytes = Buffer.byteLength(content);
|
|
28480
28826
|
if (bytes > MAX_CONTEXT_FILE_BYTES) {
|
|
28481
28827
|
logEvent("context_file_skipped", { path: filePath, reason: "too_large", bytes });
|
|
@@ -28541,7 +28887,7 @@ async function contextFiles(run4) {
|
|
|
28541
28887
|
}
|
|
28542
28888
|
|
|
28543
28889
|
// src/lib/code/index.ts
|
|
28544
|
-
var
|
|
28890
|
+
var import_node_crypto13 = require("node:crypto");
|
|
28545
28891
|
|
|
28546
28892
|
// src/lib/code/languages.ts
|
|
28547
28893
|
var JS_LIKE = {
|
|
@@ -28633,7 +28979,7 @@ function languageOf2(path) {
|
|
|
28633
28979
|
}
|
|
28634
28980
|
|
|
28635
28981
|
// src/lib/code/runtime.ts
|
|
28636
|
-
var
|
|
28982
|
+
var import_node_fs47 = require("node:fs");
|
|
28637
28983
|
var import_node_path35 = require("node:path");
|
|
28638
28984
|
var import_web_tree_sitter2 = __toESM2(require_web_tree_sitter2());
|
|
28639
28985
|
|
|
@@ -28705,7 +29051,7 @@ function grammarCandidates(file, pkg, env = process.env) {
|
|
|
28705
29051
|
}
|
|
28706
29052
|
function locateGrammar(id, env = process.env) {
|
|
28707
29053
|
const g = grammars_default[id];
|
|
28708
|
-
return grammarCandidates(g.file, g.package, env).find((p) => (0,
|
|
29054
|
+
return grammarCandidates(g.file, g.package, env).find((p) => (0, import_node_fs47.existsSync)(p)) ?? null;
|
|
28709
29055
|
}
|
|
28710
29056
|
var loading = null;
|
|
28711
29057
|
function loadRuntime(env = process.env) {
|
|
@@ -30319,7 +30665,7 @@ function byPath(fns, name2) {
|
|
|
30319
30665
|
function makeCodeMap(rt) {
|
|
30320
30666
|
const cache = /* @__PURE__ */ new Map();
|
|
30321
30667
|
const outline = (path, content, deadlineAt = Date.now() + DEFAULT_PARSE_MS) => {
|
|
30322
|
-
const key = `${path}\0${(0,
|
|
30668
|
+
const key = `${path}\0${(0, import_node_crypto13.createHash)("sha1").update(content).digest("hex")}`;
|
|
30323
30669
|
const hit = cache.get(key);
|
|
30324
30670
|
if (hit) return { source: "tree-sitter", value: hit, elapsedMs: 0 };
|
|
30325
30671
|
let r;
|
|
@@ -31034,7 +31380,7 @@ async function repoContext(run4) {
|
|
|
31034
31380
|
|
|
31035
31381
|
// src/lib/seed-runner.ts
|
|
31036
31382
|
var import_promises15 = require("node:fs/promises");
|
|
31037
|
-
var
|
|
31383
|
+
var import_node_fs48 = require("node:fs");
|
|
31038
31384
|
var import_node_path36 = require("node:path");
|
|
31039
31385
|
var import_yaml4 = __toESM2(require_dist());
|
|
31040
31386
|
|
|
@@ -31259,7 +31605,7 @@ async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
|
|
|
31259
31605
|
const titles = /* @__PURE__ */ new Set();
|
|
31260
31606
|
for (const dir of NODE_DIRS) {
|
|
31261
31607
|
const full = (0, import_node_path36.join)(memoryDir3, dir);
|
|
31262
|
-
if (!(0,
|
|
31608
|
+
if (!(0, import_node_fs48.existsSync)(full)) continue;
|
|
31263
31609
|
let files;
|
|
31264
31610
|
try {
|
|
31265
31611
|
files = await (0, import_promises15.readdir)(full);
|
|
@@ -31341,7 +31687,7 @@ function renderNodeMarkdown(candidate, nodeId, createdAt) {
|
|
|
31341
31687
|
return fm;
|
|
31342
31688
|
}
|
|
31343
31689
|
async function runSeed(opts) {
|
|
31344
|
-
if (!(0,
|
|
31690
|
+
if (!(0, import_node_fs48.existsSync)(STANDARD_FILE)) {
|
|
31345
31691
|
return { created: 0, existing: 0, failed: 0, skipped: "no_standard", candidates: [] };
|
|
31346
31692
|
}
|
|
31347
31693
|
let standardDoc;
|
|
@@ -31353,7 +31699,7 @@ async function runSeed(opts) {
|
|
|
31353
31699
|
}
|
|
31354
31700
|
const knowledgeSpec = standardDoc.knowledge_spec ?? {};
|
|
31355
31701
|
let readmeContent;
|
|
31356
|
-
if ((0,
|
|
31702
|
+
if ((0, import_node_fs48.existsSync)("README.md")) {
|
|
31357
31703
|
try {
|
|
31358
31704
|
readmeContent = await (0, import_promises15.readFile)("README.md", "utf-8");
|
|
31359
31705
|
} catch {
|
|
@@ -31361,7 +31707,7 @@ async function runSeed(opts) {
|
|
|
31361
31707
|
}
|
|
31362
31708
|
let claudeMdContent;
|
|
31363
31709
|
for (const p of ["CLAUDE.md", ".claude/CLAUDE.md"]) {
|
|
31364
|
-
if ((0,
|
|
31710
|
+
if ((0, import_node_fs48.existsSync)(p)) {
|
|
31365
31711
|
try {
|
|
31366
31712
|
claudeMdContent = await (0, import_promises15.readFile)(p, "utf-8");
|
|
31367
31713
|
break;
|
|
@@ -31441,7 +31787,7 @@ async function runSeed(opts) {
|
|
|
31441
31787
|
continue;
|
|
31442
31788
|
}
|
|
31443
31789
|
const deduplicated = res.data.deduplicated === true;
|
|
31444
|
-
if (deduplicated && (0,
|
|
31790
|
+
if (deduplicated && (0, import_node_fs48.existsSync)(targetPath)) {
|
|
31445
31791
|
existing++;
|
|
31446
31792
|
continue;
|
|
31447
31793
|
}
|
|
@@ -31463,7 +31809,7 @@ async function runSeed(opts) {
|
|
|
31463
31809
|
}
|
|
31464
31810
|
|
|
31465
31811
|
// src/commands/analyze/phases/08-memory-manifest.ts
|
|
31466
|
-
var
|
|
31812
|
+
var import_node_fs49 = require("node:fs");
|
|
31467
31813
|
var import_node_path37 = require("node:path");
|
|
31468
31814
|
async function memoryManifest(run4) {
|
|
31469
31815
|
const { globals } = run4;
|
|
@@ -31475,8 +31821,8 @@ async function memoryManifest(run4) {
|
|
|
31475
31821
|
try {
|
|
31476
31822
|
await ensureMemoryDir();
|
|
31477
31823
|
const seedMarker = (0, import_node_path37.join)(VERITY_DIR, ".seeded");
|
|
31478
|
-
const hasStandard = (0,
|
|
31479
|
-
const alreadyTried = (0,
|
|
31824
|
+
const hasStandard = (0, import_node_fs49.existsSync)(STANDARD_FILE);
|
|
31825
|
+
const alreadyTried = (0, import_node_fs49.existsSync)(seedMarker);
|
|
31480
31826
|
if (hasStandard && !alreadyTried) {
|
|
31481
31827
|
const preManifest = await buildManifest();
|
|
31482
31828
|
if (preManifest.nodes.length === 0) {
|
|
@@ -31489,7 +31835,7 @@ async function memoryManifest(run4) {
|
|
|
31489
31835
|
dryRun: false
|
|
31490
31836
|
});
|
|
31491
31837
|
if (seedResult.created > 0 || seedResult.existing > 0) {
|
|
31492
|
-
(0,
|
|
31838
|
+
(0, import_node_fs49.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created} existing=${seedResult.existing}
|
|
31493
31839
|
`);
|
|
31494
31840
|
if (seedResult.created > 0) {
|
|
31495
31841
|
autoSeedNotice = `Seeded ${seedResult.created} knowledge node(s) from your existing Standard (one-time).`;
|
|
@@ -31500,7 +31846,7 @@ async function memoryManifest(run4) {
|
|
|
31500
31846
|
failed: seedResult.failed
|
|
31501
31847
|
});
|
|
31502
31848
|
} else if (seedResult.skipped === "already_seeded") {
|
|
31503
|
-
(0,
|
|
31849
|
+
(0, import_node_fs49.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
|
|
31504
31850
|
`);
|
|
31505
31851
|
} else {
|
|
31506
31852
|
logEvent("auto_seed_noop", {
|
|
@@ -31705,7 +32051,7 @@ function boundPaths(paths, first, max = MAX_WIRE_PATHS) {
|
|
|
31705
32051
|
}
|
|
31706
32052
|
|
|
31707
32053
|
// src/lib/note-budget.ts
|
|
31708
|
-
var
|
|
32054
|
+
var import_node_fs50 = require("node:fs");
|
|
31709
32055
|
var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
|
|
31710
32056
|
var EPISODE_STALE_SECONDS = 30 * 60;
|
|
31711
32057
|
var FRESH = { delivered: 0, tasksCompleted: 0, ts: 0 };
|
|
@@ -31727,9 +32073,9 @@ function advisoryBudgetSpent(episode, rawDecision) {
|
|
|
31727
32073
|
}
|
|
31728
32074
|
function readAdvisoryEpisode(sessionId) {
|
|
31729
32075
|
const file = scopedFile(ADVISORY_EPISODE_FILE, sessionId);
|
|
31730
|
-
if (!(0,
|
|
32076
|
+
if (!(0, import_node_fs50.existsSync)(file)) return null;
|
|
31731
32077
|
try {
|
|
31732
|
-
const o = JSON.parse((0,
|
|
32078
|
+
const o = JSON.parse((0, import_node_fs50.readFileSync)(file, "utf-8")) ?? {};
|
|
31733
32079
|
const delivered = typeof o.delivered === "number" ? o.delivered : NaN;
|
|
31734
32080
|
if (isNaN(delivered)) return null;
|
|
31735
32081
|
return {
|
|
@@ -31743,8 +32089,8 @@ function readAdvisoryEpisode(sessionId) {
|
|
|
31743
32089
|
}
|
|
31744
32090
|
function writeAdvisoryEpisode(episode, sessionId) {
|
|
31745
32091
|
try {
|
|
31746
|
-
(0,
|
|
31747
|
-
(0,
|
|
32092
|
+
(0, import_node_fs50.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
32093
|
+
(0, import_node_fs50.writeFileSync)(
|
|
31748
32094
|
scopedFile(ADVISORY_EPISODE_FILE, sessionId),
|
|
31749
32095
|
JSON.stringify({ v: 1, ...episode })
|
|
31750
32096
|
);
|
|
@@ -32081,14 +32427,14 @@ async function buildRequest(run4) {
|
|
|
32081
32427
|
}
|
|
32082
32428
|
|
|
32083
32429
|
// src/lib/offline.ts
|
|
32084
|
-
var
|
|
32085
|
-
var
|
|
32430
|
+
var import_node_fs51 = require("node:fs");
|
|
32431
|
+
var import_node_crypto14 = require("node:crypto");
|
|
32086
32432
|
function cacheRequest(body2) {
|
|
32087
32433
|
try {
|
|
32088
|
-
(0,
|
|
32089
|
-
const suffix = (0,
|
|
32434
|
+
(0, import_node_fs51.mkdirSync)(CACHE_DIR, { recursive: true });
|
|
32435
|
+
const suffix = (0, import_node_crypto14.randomBytes)(4).toString("hex");
|
|
32090
32436
|
const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
|
|
32091
|
-
(0,
|
|
32437
|
+
(0, import_node_fs51.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body2)));
|
|
32092
32438
|
} catch {
|
|
32093
32439
|
}
|
|
32094
32440
|
}
|
|
@@ -32210,7 +32556,7 @@ async function transmit(run4) {
|
|
|
32210
32556
|
}
|
|
32211
32557
|
|
|
32212
32558
|
// src/commands/analyze/phases/13-reconcile.ts
|
|
32213
|
-
var
|
|
32559
|
+
var import_node_fs52 = require("node:fs");
|
|
32214
32560
|
var import_node_path39 = require("node:path");
|
|
32215
32561
|
async function reconcile(run4) {
|
|
32216
32562
|
const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory: memory2, memorySession, response, reviewable, securityFiles, turnId } = run4;
|
|
@@ -32240,7 +32586,7 @@ async function reconcile(run4) {
|
|
|
32240
32586
|
const st = foldDossier(memorySession.d);
|
|
32241
32587
|
openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line2) => {
|
|
32242
32588
|
try {
|
|
32243
|
-
const src = (0,
|
|
32589
|
+
const src = (0, import_node_fs52.readFileSync)((0, import_node_path39.join)(repoRoot(), file), "utf8").split("\n");
|
|
32244
32590
|
const at = src[line2 - 1];
|
|
32245
32591
|
return at === void 0 ? null : lineSha(at);
|
|
32246
32592
|
} catch {
|
|
@@ -33062,7 +33408,7 @@ function registerAnalyzeCommand(program2) {
|
|
|
33062
33408
|
var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
|
|
33063
33409
|
async function runAnalyze(opts, globals) {
|
|
33064
33410
|
if (!verityConfigured()) {
|
|
33065
|
-
(0,
|
|
33411
|
+
(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');
|
|
33066
33412
|
process.exit(0);
|
|
33067
33413
|
}
|
|
33068
33414
|
const run4 = createRun(opts, globals);
|
|
@@ -33083,11 +33429,12 @@ async function runAnalyze(opts, globals) {
|
|
|
33083
33429
|
}
|
|
33084
33430
|
|
|
33085
33431
|
// src/commands/baseline.ts
|
|
33086
|
-
var
|
|
33432
|
+
var import_node_fs55 = require("node:fs");
|
|
33433
|
+
var import_node_path42 = require("node:path");
|
|
33087
33434
|
|
|
33088
33435
|
// src/lib/project-skills.ts
|
|
33089
|
-
var
|
|
33090
|
-
var
|
|
33436
|
+
var import_node_fs54 = require("node:fs");
|
|
33437
|
+
var import_node_path41 = require("node:path");
|
|
33091
33438
|
var PROJECT_SKILL_NAMES = [
|
|
33092
33439
|
"verity-setup",
|
|
33093
33440
|
"verity-analyze",
|
|
@@ -33113,14 +33460,14 @@ var LEGACY_SKILL_NAMES = [
|
|
|
33113
33460
|
var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
|
|
33114
33461
|
function staleProjectSkills() {
|
|
33115
33462
|
const root = projectPath(".claude/skills");
|
|
33116
|
-
if (!(0,
|
|
33117
|
-
return ALL.filter((name2) => (0,
|
|
33463
|
+
if (!(0, import_node_fs54.existsSync)(root)) return [];
|
|
33464
|
+
return ALL.filter((name2) => (0, import_node_fs54.existsSync)((0, import_node_path41.join)(root, name2)));
|
|
33118
33465
|
}
|
|
33119
33466
|
function removeProjectSkills() {
|
|
33120
33467
|
const root = projectPath(".claude/skills");
|
|
33121
33468
|
const removed = [];
|
|
33122
33469
|
for (const name2 of staleProjectSkills()) {
|
|
33123
|
-
(0,
|
|
33470
|
+
(0, import_node_fs54.rmSync)((0, import_node_path41.join)(root, name2), { recursive: true, force: true });
|
|
33124
33471
|
removed.push(name2);
|
|
33125
33472
|
}
|
|
33126
33473
|
return removed;
|
|
@@ -33153,6 +33500,7 @@ function registerBaselineCommands(program2) {
|
|
|
33153
33500
|
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;
|
|
33154
33501
|
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;
|
|
33155
33502
|
if (!verityConfigured()) {
|
|
33503
|
+
if (isMachineStore((0, import_node_path42.join)(repoRoot(), VERITY_DIR))) process.exit(0);
|
|
33156
33504
|
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.";
|
|
33157
33505
|
const lines = [
|
|
33158
33506
|
`Verity is installed but this project is not set up yet, so the quality gate will not review anything here. ${how}`
|
|
@@ -33185,13 +33533,13 @@ function registerBaselineCommands(program2) {
|
|
|
33185
33533
|
let memoryMsg = null;
|
|
33186
33534
|
let memoryAgentLine = null;
|
|
33187
33535
|
const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
|
|
33188
|
-
if (realStart && !(0,
|
|
33536
|
+
if (realStart && !(0, import_node_fs55.existsSync)(memoryNotice)) {
|
|
33189
33537
|
const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
|
|
33190
33538
|
if (trackedGraph > 0) {
|
|
33191
33539
|
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.`;
|
|
33192
33540
|
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.`;
|
|
33193
33541
|
try {
|
|
33194
|
-
(0,
|
|
33542
|
+
(0, import_node_fs55.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
|
|
33195
33543
|
} catch {
|
|
33196
33544
|
}
|
|
33197
33545
|
}
|
|
@@ -33292,10 +33640,16 @@ function hookSource(value) {
|
|
|
33292
33640
|
}
|
|
33293
33641
|
|
|
33294
33642
|
// src/commands/review.ts
|
|
33295
|
-
var
|
|
33643
|
+
var import_node_fs56 = require("node:fs");
|
|
33296
33644
|
function registerReviewCommand(program2) {
|
|
33297
|
-
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) => {
|
|
33645
|
+
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) => {
|
|
33298
33646
|
const globals = program2.opts();
|
|
33647
|
+
const intent = readTextInput(opts.intent, "--intent");
|
|
33648
|
+
if (!intent.ok) {
|
|
33649
|
+
printError(intent.error);
|
|
33650
|
+
process.exit(0);
|
|
33651
|
+
}
|
|
33652
|
+
opts.intent = intent.text;
|
|
33299
33653
|
try {
|
|
33300
33654
|
await runReview(opts, globals);
|
|
33301
33655
|
} catch (err2) {
|
|
@@ -33309,7 +33663,7 @@ async function runReview(opts, globals) {
|
|
|
33309
33663
|
const changedFiles = opts.changed ? opts.changed.split(",").map((f) => f.trim()).filter(Boolean) : allFiles;
|
|
33310
33664
|
const analyzable = filterAnalyzable(allFiles);
|
|
33311
33665
|
const securityFiles = filterSecurity(allFiles);
|
|
33312
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0,
|
|
33666
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs56.existsSync)(f) || resolveFile(f) !== null);
|
|
33313
33667
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
33314
33668
|
const codeDelta = collectCodeDelta(allFiles);
|
|
33315
33669
|
const tokenResult = await resolveToken(globals.token);
|
|
@@ -33375,19 +33729,40 @@ async function runReview(opts, globals) {
|
|
|
33375
33729
|
}
|
|
33376
33730
|
|
|
33377
33731
|
// src/commands/guard.ts
|
|
33378
|
-
var
|
|
33379
|
-
var
|
|
33732
|
+
var import_node_fs61 = require("node:fs");
|
|
33733
|
+
var import_node_path48 = require("node:path");
|
|
33380
33734
|
|
|
33381
|
-
// src/lib/
|
|
33382
|
-
var
|
|
33383
|
-
|
|
33384
|
-
|
|
33385
|
-
|
|
33386
|
-
|
|
33735
|
+
// src/lib/vendored.ts
|
|
33736
|
+
var import_node_fs57 = require("node:fs");
|
|
33737
|
+
var import_node_path43 = require("node:path");
|
|
33738
|
+
var INSTALLED_SKILL = /^\.claude\/skills\/(verity-[a-z0-9-]+)\/(.+)$/;
|
|
33739
|
+
function dataDirOrNull() {
|
|
33740
|
+
try {
|
|
33741
|
+
return resolveDataDir();
|
|
33742
|
+
} catch {
|
|
33743
|
+
return null;
|
|
33744
|
+
}
|
|
33387
33745
|
}
|
|
33388
|
-
function
|
|
33389
|
-
const
|
|
33390
|
-
|
|
33746
|
+
function shippedSkillFile(path, dataDir = dataDirOrNull()) {
|
|
33747
|
+
const m = path.replace(/\\/g, "/").match(INSTALLED_SKILL);
|
|
33748
|
+
if (!m || !dataDir) return null;
|
|
33749
|
+
const [, skill, rel] = m;
|
|
33750
|
+
if (rel.split("/").some((seg) => seg === ".." || seg === ".")) return null;
|
|
33751
|
+
try {
|
|
33752
|
+
return (0, import_node_fs57.readFileSync)((0, import_node_path43.join)(dataDir, "skills", skill, rel), "utf8");
|
|
33753
|
+
} catch {
|
|
33754
|
+
return null;
|
|
33755
|
+
}
|
|
33756
|
+
}
|
|
33757
|
+
function partitionVendored(files, read2, dataDir = dataDirOrNull()) {
|
|
33758
|
+
const review = [];
|
|
33759
|
+
const vendored = [];
|
|
33760
|
+
for (const f of files) {
|
|
33761
|
+
const shipped = shippedSkillFile(f, dataDir);
|
|
33762
|
+
if (shipped !== null && read2(f) === shipped) vendored.push(f);
|
|
33763
|
+
else review.push(f);
|
|
33764
|
+
}
|
|
33765
|
+
return { review, vendored };
|
|
33391
33766
|
}
|
|
33392
33767
|
|
|
33393
33768
|
// src/lib/agent-driver.ts
|
|
@@ -33469,7 +33844,7 @@ async function runAgentReview(options) {
|
|
|
33469
33844
|
}
|
|
33470
33845
|
if (!settled) {
|
|
33471
33846
|
const wait = Math.max(0, remaining() - FINISH_TIMEOUT_MS);
|
|
33472
|
-
await Promise.race([oneShotDone, new Promise((
|
|
33847
|
+
await Promise.race([oneShotDone, new Promise((resolve9) => setTimeout(resolve9, wait))]);
|
|
33473
33848
|
}
|
|
33474
33849
|
const finished = await options.http.post(
|
|
33475
33850
|
"/agent-review/finish",
|
|
@@ -33484,8 +33859,8 @@ async function runAgentReview(options) {
|
|
|
33484
33859
|
}
|
|
33485
33860
|
|
|
33486
33861
|
// src/lib/prove/auto.ts
|
|
33487
|
-
var
|
|
33488
|
-
var
|
|
33862
|
+
var import_node_path47 = require("node:path");
|
|
33863
|
+
var import_node_crypto19 = require("node:crypto");
|
|
33489
33864
|
|
|
33490
33865
|
// src/lib/prove/signals.ts
|
|
33491
33866
|
var DEFAULT_SINCE = "180 days ago";
|
|
@@ -35211,18 +35586,18 @@ function renderReplay(model, property, r) {
|
|
|
35211
35586
|
// src/lib/prove/runner.ts
|
|
35212
35587
|
var import_node_child_process15 = require("node:child_process");
|
|
35213
35588
|
var import_node_os8 = require("node:os");
|
|
35214
|
-
var
|
|
35589
|
+
var import_node_fs60 = require("node:fs");
|
|
35215
35590
|
var import_node_os9 = require("node:os");
|
|
35216
|
-
var
|
|
35591
|
+
var import_node_path46 = require("node:path");
|
|
35217
35592
|
|
|
35218
35593
|
// src/lib/prove/scaffold.ts
|
|
35219
|
-
var
|
|
35220
|
-
var
|
|
35594
|
+
var import_node_fs59 = require("node:fs");
|
|
35595
|
+
var import_node_path45 = require("node:path");
|
|
35221
35596
|
|
|
35222
35597
|
// src/lib/prove/safe-write.ts
|
|
35223
|
-
var
|
|
35224
|
-
var
|
|
35225
|
-
var
|
|
35598
|
+
var import_node_fs58 = require("node:fs");
|
|
35599
|
+
var import_node_crypto15 = require("node:crypto");
|
|
35600
|
+
var import_node_path44 = require("node:path");
|
|
35226
35601
|
var SafeWriteError = class extends Error {
|
|
35227
35602
|
constructor(reason, path) {
|
|
35228
35603
|
super(`refusing to write ${path}: ${reason}`);
|
|
@@ -35231,10 +35606,10 @@ var SafeWriteError = class extends Error {
|
|
|
35231
35606
|
this.name = "SafeWriteError";
|
|
35232
35607
|
}
|
|
35233
35608
|
};
|
|
35234
|
-
var FLAGS3 =
|
|
35609
|
+
var FLAGS3 = import_node_fs58.constants;
|
|
35235
35610
|
var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
|
|
35236
35611
|
function assertPlainRelative(rel) {
|
|
35237
|
-
if (!rel || (0,
|
|
35612
|
+
if (!rel || (0, import_node_path44.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
|
|
35238
35613
|
for (const part of rel.split(/[\\/]/)) {
|
|
35239
35614
|
if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
|
|
35240
35615
|
}
|
|
@@ -35243,34 +35618,34 @@ function ensureDirsNoFollow(root, rel) {
|
|
|
35243
35618
|
const parts2 = rel.split(/[\\/]/);
|
|
35244
35619
|
let cur = root;
|
|
35245
35620
|
for (const part of parts2.slice(0, -1)) {
|
|
35246
|
-
cur = (0,
|
|
35621
|
+
cur = (0, import_node_path44.join)(cur, part);
|
|
35247
35622
|
let st;
|
|
35248
35623
|
try {
|
|
35249
|
-
st = (0,
|
|
35624
|
+
st = (0, import_node_fs58.lstatSync)(cur);
|
|
35250
35625
|
} catch {
|
|
35251
|
-
(0,
|
|
35626
|
+
(0, import_node_fs58.mkdirSync)(cur);
|
|
35252
35627
|
continue;
|
|
35253
35628
|
}
|
|
35254
35629
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
|
|
35255
35630
|
if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
|
|
35256
35631
|
}
|
|
35257
|
-
return (0,
|
|
35632
|
+
return (0, import_node_path44.join)(root, rel);
|
|
35258
35633
|
}
|
|
35259
35634
|
function insideRoot(realRoot, realPath) {
|
|
35260
|
-
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(
|
|
35635
|
+
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path44.sep) ? realRoot : realRoot + import_node_path44.sep);
|
|
35261
35636
|
}
|
|
35262
35637
|
function removeQuietly(path) {
|
|
35263
35638
|
try {
|
|
35264
|
-
(0,
|
|
35639
|
+
(0, import_node_fs58.unlinkSync)(path);
|
|
35265
35640
|
} catch {
|
|
35266
35641
|
}
|
|
35267
35642
|
}
|
|
35268
35643
|
function writeFileInRootNoFollow(root, rel, content) {
|
|
35269
35644
|
assertPlainRelative(rel);
|
|
35270
35645
|
const dest = ensureDirsNoFollow(root, rel);
|
|
35271
|
-
const dir = (0,
|
|
35646
|
+
const dir = (0, import_node_path44.dirname)(dest);
|
|
35272
35647
|
try {
|
|
35273
|
-
const st = (0,
|
|
35648
|
+
const st = (0, import_node_fs58.lstatSync)(dest);
|
|
35274
35649
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
|
|
35275
35650
|
if (!st.isFile()) throw new SafeWriteError("not-regular", dest);
|
|
35276
35651
|
} catch (err2) {
|
|
@@ -35278,41 +35653,41 @@ function writeFileInRootNoFollow(root, rel, content) {
|
|
|
35278
35653
|
}
|
|
35279
35654
|
let realRoot;
|
|
35280
35655
|
try {
|
|
35281
|
-
realRoot = (0,
|
|
35656
|
+
realRoot = (0, import_node_fs58.realpathSync)(root);
|
|
35282
35657
|
} catch {
|
|
35283
35658
|
throw new SafeWriteError("unwritable", root);
|
|
35284
35659
|
}
|
|
35285
|
-
const tmp = (0,
|
|
35660
|
+
const tmp = (0, import_node_path44.join)(dir, `.${(0, import_node_path44.basename)(dest)}.${(0, import_node_crypto15.randomBytes)(6).toString("hex")}.tmp`);
|
|
35286
35661
|
let fd;
|
|
35287
35662
|
try {
|
|
35288
|
-
fd = (0,
|
|
35663
|
+
fd = (0, import_node_fs58.openSync)(tmp, import_node_fs58.constants.O_WRONLY | import_node_fs58.constants.O_CREAT | import_node_fs58.constants.O_EXCL | NOFOLLOW2, 420);
|
|
35289
35664
|
} catch {
|
|
35290
35665
|
throw new SafeWriteError("unwritable", tmp);
|
|
35291
35666
|
}
|
|
35292
35667
|
try {
|
|
35293
|
-
const opened = (0,
|
|
35668
|
+
const opened = (0, import_node_fs58.fstatSync)(fd, { bigint: true });
|
|
35294
35669
|
let realTmp;
|
|
35295
35670
|
try {
|
|
35296
|
-
realTmp = (0,
|
|
35671
|
+
realTmp = (0, import_node_fs58.realpathSync)(tmp);
|
|
35297
35672
|
} catch {
|
|
35298
35673
|
throw new SafeWriteError("escaped", tmp);
|
|
35299
35674
|
}
|
|
35300
|
-
const there = (0,
|
|
35675
|
+
const there = (0, import_node_fs58.lstatSync)(realTmp, { bigint: true });
|
|
35301
35676
|
if (!opened.isFile() || there.ino !== opened.ino || there.dev !== opened.dev || !insideRoot(realRoot, realTmp)) {
|
|
35302
35677
|
throw new SafeWriteError("escaped", tmp);
|
|
35303
35678
|
}
|
|
35304
35679
|
const buf = Buffer.from(content, "utf-8");
|
|
35305
35680
|
let off = 0;
|
|
35306
|
-
while (off < buf.length) off += (0,
|
|
35681
|
+
while (off < buf.length) off += (0, import_node_fs58.writeSync)(fd, buf, off, buf.length - off);
|
|
35307
35682
|
} catch (err2) {
|
|
35308
|
-
(0,
|
|
35683
|
+
(0, import_node_fs58.closeSync)(fd);
|
|
35309
35684
|
removeQuietly(tmp);
|
|
35310
35685
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", tmp);
|
|
35311
35686
|
}
|
|
35312
|
-
(0,
|
|
35687
|
+
(0, import_node_fs58.closeSync)(fd);
|
|
35313
35688
|
try {
|
|
35314
|
-
if (!insideRoot(realRoot, (0,
|
|
35315
|
-
(0,
|
|
35689
|
+
if (!insideRoot(realRoot, (0, import_node_fs58.realpathSync)(dir)) || (0, import_node_fs58.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
|
|
35690
|
+
(0, import_node_fs58.renameSync)(tmp, dest);
|
|
35316
35691
|
} catch (err2) {
|
|
35317
35692
|
removeQuietly(tmp);
|
|
35318
35693
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", dest);
|
|
@@ -35326,9 +35701,9 @@ function pathHasNoLink(root, rel) {
|
|
|
35326
35701
|
}
|
|
35327
35702
|
let cur = root;
|
|
35328
35703
|
for (const part of rel.split(/[\\/]/)) {
|
|
35329
|
-
cur = cur +
|
|
35704
|
+
cur = cur + import_node_path44.sep + part;
|
|
35330
35705
|
try {
|
|
35331
|
-
if ((0,
|
|
35706
|
+
if ((0, import_node_fs58.lstatSync)(cur).isSymbolicLink()) return false;
|
|
35332
35707
|
} catch {
|
|
35333
35708
|
return true;
|
|
35334
35709
|
}
|
|
@@ -35638,20 +36013,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
|
|
|
35638
36013
|
never committed; what reaches the team is the bug report and the fix.
|
|
35639
36014
|
`;
|
|
35640
36015
|
function scaffoldProofs(root) {
|
|
35641
|
-
const proofsDir = (0,
|
|
36016
|
+
const proofsDir = (0, import_node_path45.join)(root, PROOFS_DIR);
|
|
35642
36017
|
const written = [];
|
|
35643
36018
|
const kept = [];
|
|
35644
36019
|
for (const stray of ["lakefile.lean"]) {
|
|
35645
36020
|
const rel = `${PROOFS_DIR}/${stray}`;
|
|
35646
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
36021
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
|
|
35647
36022
|
try {
|
|
35648
|
-
(0,
|
|
36023
|
+
(0, import_node_fs59.rmSync)((0, import_node_path45.join)(root, rel), { force: true });
|
|
35649
36024
|
} catch {
|
|
35650
36025
|
}
|
|
35651
36026
|
}
|
|
35652
36027
|
for (const f of PROOFS_TEMPLATE_FILES) {
|
|
35653
36028
|
const rel = `${PROOFS_DIR}/${f.path}`;
|
|
35654
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
36029
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
|
|
35655
36030
|
const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
|
|
35656
36031
|
if (current.ok && current.content === f.content) {
|
|
35657
36032
|
kept.push(rel);
|
|
@@ -35664,8 +36039,8 @@ function scaffoldProofs(root) {
|
|
|
35664
36039
|
[`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
|
|
35665
36040
|
[`${MODELS_DIR}/README.md`, MODELS_README]
|
|
35666
36041
|
]) {
|
|
35667
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35668
|
-
if (existsNoFollow((0,
|
|
36042
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
|
|
36043
|
+
if (existsNoFollow((0, import_node_path45.join)(root, rel))) {
|
|
35669
36044
|
kept.push(rel);
|
|
35670
36045
|
continue;
|
|
35671
36046
|
}
|
|
@@ -35676,7 +36051,7 @@ function scaffoldProofs(root) {
|
|
|
35676
36051
|
}
|
|
35677
36052
|
function existsNoFollow(abs) {
|
|
35678
36053
|
try {
|
|
35679
|
-
(0,
|
|
36054
|
+
(0, import_node_fs59.lstatSync)(abs);
|
|
35680
36055
|
return true;
|
|
35681
36056
|
} catch {
|
|
35682
36057
|
return false;
|
|
@@ -35684,7 +36059,7 @@ function existsNoFollow(abs) {
|
|
|
35684
36059
|
}
|
|
35685
36060
|
|
|
35686
36061
|
// src/lib/prove/report.ts
|
|
35687
|
-
var
|
|
36062
|
+
var import_node_crypto16 = require("node:crypto");
|
|
35688
36063
|
var IDENT2 = /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$/;
|
|
35689
36064
|
var SHA256 = /^(sha256:)?[0-9a-f]{64}$/;
|
|
35690
36065
|
var KINDS2 = /* @__PURE__ */ new Set(["structural", "intent"]);
|
|
@@ -35832,7 +36207,7 @@ function sha256InRoot(root, file) {
|
|
|
35832
36207
|
const opened = openRegularInRoot(root, file);
|
|
35833
36208
|
if (!opened.ok) return null;
|
|
35834
36209
|
try {
|
|
35835
|
-
return (0,
|
|
36210
|
+
return (0, import_node_crypto16.createHash)("sha256").update(readOpened(opened.fd, opened.size)).digest("hex");
|
|
35836
36211
|
} catch {
|
|
35837
36212
|
return null;
|
|
35838
36213
|
}
|
|
@@ -35934,17 +36309,17 @@ function renderReport(r) {
|
|
|
35934
36309
|
|
|
35935
36310
|
// src/lib/prove/runner.ts
|
|
35936
36311
|
function verityLeanHome(env = process.env) {
|
|
35937
|
-
return env.VERITY_LEAN_HOME ?? (0,
|
|
36312
|
+
return env.VERITY_LEAN_HOME ?? (0, import_node_path46.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
|
|
35938
36313
|
}
|
|
35939
36314
|
function findToolchain(env = process.env) {
|
|
35940
|
-
const managedBin = (0,
|
|
35941
|
-
const elanBin = (0,
|
|
35942
|
-
const elanHas = (0,
|
|
35943
|
-
const userPath = (env.PATH ?? "").split(
|
|
35944
|
-
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(
|
|
36315
|
+
const managedBin = (0, import_node_path46.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
|
|
36316
|
+
const elanBin = (0, import_node_path46.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
|
|
36317
|
+
const elanHas = (0, import_node_fs60.existsSync)((0, import_node_path46.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
|
|
36318
|
+
const userPath = (env.PATH ?? "").split(import_node_path46.delimiter).filter((d) => d && (elanHas || (0, import_node_path46.resolve)(d) !== (0, import_node_path46.resolve)(elanBin)));
|
|
36319
|
+
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path46.delimiter);
|
|
35945
36320
|
const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
|
|
35946
36321
|
const exe = process.platform === "win32" ? "lake.exe" : "lake";
|
|
35947
|
-
const candidates2 = [(0,
|
|
36322
|
+
const candidates2 = [(0, import_node_path46.join)(managedBin, exe), ...elanHas ? [(0, import_node_path46.join)(elanBin, exe)] : [], exe];
|
|
35948
36323
|
for (const candidate of candidates2) {
|
|
35949
36324
|
try {
|
|
35950
36325
|
(0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
|
|
@@ -35982,7 +36357,7 @@ function run2(tc, cwd, args2, timeoutMs) {
|
|
|
35982
36357
|
function runAsync(tc, cwd, args2, timeoutMs) {
|
|
35983
36358
|
const started = Date.now();
|
|
35984
36359
|
const MAX = 16 * 1024 * 1024;
|
|
35985
|
-
return new Promise((
|
|
36360
|
+
return new Promise((resolve9) => {
|
|
35986
36361
|
const posix = (0, import_node_os8.platform)() !== "win32";
|
|
35987
36362
|
const child = (0, import_node_child_process15.spawn)(tc.lake, args2, { cwd, env: tc.env, stdio: ["ignore", "pipe", "pipe"], detached: posix });
|
|
35988
36363
|
let stdout = "";
|
|
@@ -36010,8 +36385,8 @@ function runAsync(tc, cwd, args2, timeoutMs) {
|
|
|
36010
36385
|
if (settled) return;
|
|
36011
36386
|
settled = true;
|
|
36012
36387
|
clearTimeout(timer);
|
|
36013
|
-
if (ok)
|
|
36014
|
-
else
|
|
36388
|
+
if (ok) resolve9({ ok: true, stdout, stderr: "", durationMs: Date.now() - started, timedOut: false });
|
|
36389
|
+
else resolve9({ ok: false, stdout, stderr: stderr || message || "", durationMs: Date.now() - started, timedOut });
|
|
36015
36390
|
};
|
|
36016
36391
|
child.on("error", (err2) => finish(false, err2.message));
|
|
36017
36392
|
child.on("close", (code) => finish(code === 0 && !timedOut));
|
|
@@ -36023,7 +36398,7 @@ function proofsWorkspaceProblem(root) {
|
|
|
36023
36398
|
for (const rel of [".verity", PROOFS_DIR, `${PROOFS_DIR}/.lake`]) {
|
|
36024
36399
|
let st;
|
|
36025
36400
|
try {
|
|
36026
|
-
st = (0,
|
|
36401
|
+
st = (0, import_node_fs60.lstatSync)((0, import_node_path46.join)(root, rel));
|
|
36027
36402
|
} catch {
|
|
36028
36403
|
break;
|
|
36029
36404
|
}
|
|
@@ -36043,44 +36418,44 @@ function refused(problem) {
|
|
|
36043
36418
|
function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
36044
36419
|
const problem = proofsWorkspaceProblem(root);
|
|
36045
36420
|
if (problem) return refused(problem);
|
|
36046
|
-
return run2(tc, (0,
|
|
36421
|
+
return run2(tc, (0, import_node_path46.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36047
36422
|
}
|
|
36048
36423
|
async function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
36049
36424
|
const problem = proofsWorkspaceProblem(root);
|
|
36050
36425
|
if (problem) return refused(problem);
|
|
36051
|
-
return runAsync(tc, (0,
|
|
36426
|
+
return runAsync(tc, (0, import_node_path46.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36052
36427
|
}
|
|
36053
36428
|
function isModelInRoot(modelsAbs, rel) {
|
|
36054
|
-
if (!rel.endsWith(".lean") || (0,
|
|
36429
|
+
if (!rel.endsWith(".lean") || (0, import_node_path46.isAbsolute)(rel) || rel.startsWith("..")) return false;
|
|
36055
36430
|
return statRegularInRoot(modelsAbs, rel).ok;
|
|
36056
36431
|
}
|
|
36057
36432
|
function resolveModelFile(root, arg) {
|
|
36058
|
-
const modelsAbs = (0,
|
|
36059
|
-
const asPath = (0,
|
|
36433
|
+
const modelsAbs = (0, import_node_path46.join)(root, MODELS_DIR);
|
|
36434
|
+
const asPath = (0, import_node_path46.relative)(modelsAbs, (0, import_node_path46.isAbsolute)(arg) ? arg : (0, import_node_path46.resolve)(root, arg));
|
|
36060
36435
|
const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
|
|
36061
36436
|
for (const rel of candidates2) {
|
|
36062
|
-
if (isModelInRoot(modelsAbs, rel)) return (0,
|
|
36437
|
+
if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path46.join)(modelsAbs, rel);
|
|
36063
36438
|
}
|
|
36064
36439
|
return null;
|
|
36065
36440
|
}
|
|
36066
36441
|
function listModelFiles(root) {
|
|
36067
|
-
const modelsAbs = (0,
|
|
36068
|
-
if (!(0,
|
|
36069
|
-
return (0,
|
|
36442
|
+
const modelsAbs = (0, import_node_path46.join)(root, MODELS_DIR);
|
|
36443
|
+
if (!(0, import_node_fs60.existsSync)(modelsAbs)) return [];
|
|
36444
|
+
return (0, import_node_fs60.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path46.join)(modelsAbs, f));
|
|
36070
36445
|
}
|
|
36071
36446
|
function trimDiagnostics(text) {
|
|
36072
36447
|
return text.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
|
|
36073
36448
|
}
|
|
36074
36449
|
function checkModel(tc, root, modelFile, opts = {}) {
|
|
36075
|
-
const proofsAbs = (0,
|
|
36076
|
-
const rel = (0,
|
|
36450
|
+
const proofsAbs = (0, import_node_path46.join)(root, PROOFS_DIR);
|
|
36451
|
+
const rel = (0, import_node_path46.relative)(proofsAbs, modelFile);
|
|
36077
36452
|
const problem = proofsWorkspaceProblem(root);
|
|
36078
36453
|
const res = problem ? refused(problem) : run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36079
36454
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36080
36455
|
}
|
|
36081
36456
|
async function checkModelAsync(tc, root, modelFile, opts = {}) {
|
|
36082
|
-
const proofsAbs = (0,
|
|
36083
|
-
const rel = (0,
|
|
36457
|
+
const proofsAbs = (0, import_node_path46.join)(root, PROOFS_DIR);
|
|
36458
|
+
const rel = (0, import_node_path46.relative)(proofsAbs, modelFile);
|
|
36084
36459
|
const problem = proofsWorkspaceProblem(root);
|
|
36085
36460
|
const res = problem ? refused(problem) : await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36086
36461
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
@@ -36089,10 +36464,10 @@ function toReport(res, root, modelFile, timeoutMs) {
|
|
|
36089
36464
|
const parsed = parseVerityLines(res.stdout);
|
|
36090
36465
|
const combined = `${res.stdout}
|
|
36091
36466
|
${res.stderr}`;
|
|
36092
|
-
const name2 = parsed.header?.model ?? (0,
|
|
36467
|
+
const name2 = parsed.header?.model ?? (0, import_node_path46.basename)(modelFile, ".lean");
|
|
36093
36468
|
const report = {
|
|
36094
36469
|
model: name2,
|
|
36095
|
-
file: (0,
|
|
36470
|
+
file: (0, import_node_path46.relative)(root, modelFile),
|
|
36096
36471
|
ok: res.ok,
|
|
36097
36472
|
header: parsed.header,
|
|
36098
36473
|
properties: parsed.properties,
|
|
@@ -36167,7 +36542,7 @@ function mergeFormalFindings(response, outcome, pushedFiles) {
|
|
|
36167
36542
|
}
|
|
36168
36543
|
|
|
36169
36544
|
// src/lib/prove/scalpel.ts
|
|
36170
|
-
var
|
|
36545
|
+
var import_node_crypto17 = require("node:crypto");
|
|
36171
36546
|
var ARITHMETIC = /Math\.(?:round|floor|ceil|trunc)\(|\bround\(|\bdivmod\(|[\w)\]]\s*(?:\*|\/(?!\/)|%)\s*[\w(]/;
|
|
36172
36547
|
function functionHazard(numbered2) {
|
|
36173
36548
|
const sites = effectSites(numbered2);
|
|
@@ -36197,7 +36572,7 @@ function semanticFingerprint(numbered2) {
|
|
|
36197
36572
|
if (LOG_LINE.test(t)) continue;
|
|
36198
36573
|
kept.push(t.replace(/\s+/g, " "));
|
|
36199
36574
|
}
|
|
36200
|
-
return (0,
|
|
36575
|
+
return (0, import_node_crypto17.createHash)("sha256").update(kept.join("\n")).digest("hex");
|
|
36201
36576
|
}
|
|
36202
36577
|
function readVerified(root, now = Date.now()) {
|
|
36203
36578
|
const read2 = readRegularFileInRoot(root, VERIFIED_FILE, 256 * 1024);
|
|
@@ -36220,9 +36595,9 @@ function recordVerified(root, rec, now = Date.now()) {
|
|
|
36220
36595
|
}
|
|
36221
36596
|
|
|
36222
36597
|
// src/lib/prove/context.ts
|
|
36223
|
-
var
|
|
36598
|
+
var import_node_crypto18 = require("node:crypto");
|
|
36224
36599
|
var CONTEXT_BUDGET_MS = 2e3;
|
|
36225
|
-
var sha256 = (s) => (0,
|
|
36600
|
+
var sha256 = (s) => (0, import_node_crypto18.createHash)("sha256").update(s).digest("hex");
|
|
36226
36601
|
var TEST_PATH4 = /(^|\/)(tests?|__tests__|spec)\/|\.(test|spec)\.[a-z]+$/;
|
|
36227
36602
|
function slice(content, f, maxLines) {
|
|
36228
36603
|
const all = content.split("\n");
|
|
@@ -36411,7 +36786,7 @@ function workingTreeReader(root) {
|
|
|
36411
36786
|
};
|
|
36412
36787
|
}
|
|
36413
36788
|
function sha256Of(content) {
|
|
36414
|
-
return (0,
|
|
36789
|
+
return (0, import_node_crypto19.createHash)("sha256").update(content).digest("hex");
|
|
36415
36790
|
}
|
|
36416
36791
|
function defaultDeps(opts) {
|
|
36417
36792
|
const env = opts.env ?? process.env;
|
|
@@ -36662,7 +37037,7 @@ async function runFormalPhase(input) {
|
|
|
36662
37037
|
modelName = gen.name;
|
|
36663
37038
|
const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
|
|
36664
37039
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
36665
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
37040
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path47.join)(root, rel);
|
|
36666
37041
|
progress.model = { name: gen.name, file: rel, rounds: round };
|
|
36667
37042
|
progress.step = "check";
|
|
36668
37043
|
report = await deps.check(root, abs);
|
|
@@ -36723,11 +37098,11 @@ async function runFormalPhase(input) {
|
|
|
36723
37098
|
const budget = Math.max(2e4, timeLeft() - 5e3);
|
|
36724
37099
|
const byId = /* @__PURE__ */ new Map();
|
|
36725
37100
|
let stoppedEarly = false;
|
|
36726
|
-
await new Promise((
|
|
37101
|
+
await new Promise((resolve9) => {
|
|
36727
37102
|
let left = toReplay.length;
|
|
36728
|
-
if (left === 0) return
|
|
37103
|
+
if (left === 0) return resolve9();
|
|
36729
37104
|
const settle = () => {
|
|
36730
|
-
if (--left === 0)
|
|
37105
|
+
if (--left === 0) resolve9();
|
|
36731
37106
|
};
|
|
36732
37107
|
for (const p of toReplay) {
|
|
36733
37108
|
void (async () => {
|
|
@@ -36740,7 +37115,7 @@ async function runFormalPhase(input) {
|
|
|
36740
37115
|
if (!stoppedEarly) byId.set(p.id, r);
|
|
36741
37116
|
if (r.verdict === "reproduced" && !stoppedEarly && !isCrash(p)) {
|
|
36742
37117
|
stoppedEarly = true;
|
|
36743
|
-
|
|
37118
|
+
resolve9();
|
|
36744
37119
|
}
|
|
36745
37120
|
})().catch(() => {
|
|
36746
37121
|
byId.set(p.id, null);
|
|
@@ -36784,7 +37159,7 @@ async function runFormalPhase(input) {
|
|
|
36784
37159
|
return done({
|
|
36785
37160
|
status: "checked",
|
|
36786
37161
|
target,
|
|
36787
|
-
model: { name: modelName, file: (0,
|
|
37162
|
+
model: { name: modelName, file: (0, import_node_path47.relative)(root, (0, import_node_path47.join)(root, modelFile)), rounds },
|
|
36788
37163
|
properties: report.properties,
|
|
36789
37164
|
findings
|
|
36790
37165
|
});
|
|
@@ -36847,7 +37222,7 @@ async function generateAndCheck(root, req, opts) {
|
|
|
36847
37222
|
}
|
|
36848
37223
|
const rel = `${dir}/${gen.name}.lean`;
|
|
36849
37224
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
36850
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
37225
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path47.join)(root, rel);
|
|
36851
37226
|
const report = await opts.deps.check(root, abs);
|
|
36852
37227
|
const abstracts = report.header?.abstracts ?? [];
|
|
36853
37228
|
const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
|
|
@@ -36935,10 +37310,10 @@ function runFormalPhaseWithin(input) {
|
|
|
36935
37310
|
if (left <= 0) return Promise.resolve(skippedOutcome("deadline", "no time left"));
|
|
36936
37311
|
const progress = input.progress ?? {};
|
|
36937
37312
|
let timer = null;
|
|
36938
|
-
const cutoff = new Promise((
|
|
37313
|
+
const cutoff = new Promise((resolve9) => {
|
|
36939
37314
|
timer = setTimeout(() => {
|
|
36940
37315
|
progress.cancelled = true;
|
|
36941
|
-
|
|
37316
|
+
resolve9(cutOffOutcome(progress, `hard stop after ${Math.round(left / 1e3)} s during ${progress.step ?? "setup"}`, left));
|
|
36942
37317
|
}, left);
|
|
36943
37318
|
});
|
|
36944
37319
|
return Promise.race([runFormalPhase({ ...input, progress }), cutoff]).finally(() => {
|
|
@@ -36975,13 +37350,14 @@ function describeFormalOutcome(o) {
|
|
|
36975
37350
|
var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
|
|
36976
37351
|
var WRITERS_BUDGET_MS = 1500;
|
|
36977
37352
|
var EXCERPT_MAX_LINES2 = 30;
|
|
37353
|
+
var VENDORED_READ_MAX_BYTES = 256 * 1024;
|
|
36978
37354
|
var GUARD_BLOCK_CAP = 2;
|
|
36979
|
-
var GUARD_ITER_FILE = (0,
|
|
37355
|
+
var GUARD_ITER_FILE = (0, import_node_path48.join)(VERITY_DIR, ".guard-iteration");
|
|
36980
37356
|
function readPreToolUseStdin() {
|
|
36981
37357
|
const empty = { command: "", cwd: null, sessionId: null };
|
|
36982
|
-
return new Promise((
|
|
37358
|
+
return new Promise((resolve9) => {
|
|
36983
37359
|
try {
|
|
36984
|
-
if (process.stdin.isTTY) return
|
|
37360
|
+
if (process.stdin.isTTY) return resolve9(empty);
|
|
36985
37361
|
const chunks = [];
|
|
36986
37362
|
let timer;
|
|
36987
37363
|
let settled = false;
|
|
@@ -36994,7 +37370,7 @@ function readPreToolUseStdin() {
|
|
|
36994
37370
|
process.stdin.removeListener("end", onEnd);
|
|
36995
37371
|
process.stdin.removeListener("error", onError);
|
|
36996
37372
|
process.stdin.pause();
|
|
36997
|
-
|
|
37373
|
+
resolve9(value);
|
|
36998
37374
|
};
|
|
36999
37375
|
const onEnd = () => {
|
|
37000
37376
|
try {
|
|
@@ -37015,13 +37391,13 @@ function readPreToolUseStdin() {
|
|
|
37015
37391
|
process.stdin.on("error", onError);
|
|
37016
37392
|
process.stdin.resume();
|
|
37017
37393
|
} catch {
|
|
37018
|
-
|
|
37394
|
+
resolve9(empty);
|
|
37019
37395
|
}
|
|
37020
37396
|
});
|
|
37021
37397
|
}
|
|
37022
37398
|
function readIterMap() {
|
|
37023
37399
|
try {
|
|
37024
|
-
const raw = JSON.parse((0,
|
|
37400
|
+
const raw = JSON.parse((0, import_node_fs61.readFileSync)(GUARD_ITER_FILE, "utf-8"));
|
|
37025
37401
|
if (raw && typeof raw === "object") {
|
|
37026
37402
|
if (typeof raw.moment === "string" && typeof raw.count === "number") {
|
|
37027
37403
|
return { [raw.moment]: raw.count };
|
|
@@ -37041,10 +37417,10 @@ function readIter(moment) {
|
|
|
37041
37417
|
}
|
|
37042
37418
|
function writeIter(moment, count) {
|
|
37043
37419
|
try {
|
|
37044
|
-
(0,
|
|
37420
|
+
(0, import_node_fs61.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
37045
37421
|
const map = readIterMap();
|
|
37046
37422
|
map[moment] = count;
|
|
37047
|
-
(0,
|
|
37423
|
+
(0, import_node_fs61.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
37048
37424
|
} catch {
|
|
37049
37425
|
}
|
|
37050
37426
|
}
|
|
@@ -37054,10 +37430,10 @@ function resetIter(moment) {
|
|
|
37054
37430
|
if (!(moment in map)) return;
|
|
37055
37431
|
delete map[moment];
|
|
37056
37432
|
if (Object.keys(map).length === 0) {
|
|
37057
|
-
if ((0,
|
|
37433
|
+
if ((0, import_node_fs61.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs61.unlinkSync)(GUARD_ITER_FILE);
|
|
37058
37434
|
} else {
|
|
37059
|
-
(0,
|
|
37060
|
-
(0,
|
|
37435
|
+
(0, import_node_fs61.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
37436
|
+
(0, import_node_fs61.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
37061
37437
|
}
|
|
37062
37438
|
} catch {
|
|
37063
37439
|
}
|
|
@@ -37127,7 +37503,7 @@ function hasBlockingFinding(response, sentFiles) {
|
|
|
37127
37503
|
function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
|
|
37128
37504
|
const analyzable = filterAnalyzable(files);
|
|
37129
37505
|
const securityFiles = filterSecurity(files);
|
|
37130
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0,
|
|
37506
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs61.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
|
|
37131
37507
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
37132
37508
|
const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
|
|
37133
37509
|
const requestBody = {
|
|
@@ -37364,7 +37740,15 @@ async function runGuard(opts, globals) {
|
|
|
37364
37740
|
`Verity ${moment}: this command stages files as it runs and the resulting set could not be resolved (${range.refusal}); the ${verb} was allowed WITHOUT a Verity review. Stage first (\`git add \u2026\`) and re-run the ${verb} to have it reviewed.`
|
|
37365
37741
|
);
|
|
37366
37742
|
}
|
|
37367
|
-
const
|
|
37743
|
+
const committed = revisionSource(
|
|
37744
|
+
frame.worktreeRoot ?? process.cwd(),
|
|
37745
|
+
range.kind === "push" && range.head !== "INDEX" ? range.head : null
|
|
37746
|
+
);
|
|
37747
|
+
const { review: files, vendored } = partitionVendored(rangeFiles(frame, range), (p) => {
|
|
37748
|
+
const read2 = committed.read(p, VENDORED_READ_MAX_BYTES);
|
|
37749
|
+
return read2.ok ? read2.content : null;
|
|
37750
|
+
});
|
|
37751
|
+
if (vendored.length > 0) logEvent("guard_vendored", { moment, n: vendored.length, paths: vendored.slice(0, 20) });
|
|
37368
37752
|
if (files.length === 0) process.exit(0);
|
|
37369
37753
|
const tokenResult = await resolveToken(globals.token);
|
|
37370
37754
|
const urlResult = await resolveServiceUrl(globals.serviceUrl);
|
|
@@ -37744,8 +38128,8 @@ function registerIgnoreCommand(program2) {
|
|
|
37744
38128
|
}
|
|
37745
38129
|
|
|
37746
38130
|
// src/commands/waive.ts
|
|
37747
|
-
var
|
|
37748
|
-
var
|
|
38131
|
+
var import_node_crypto20 = require("node:crypto");
|
|
38132
|
+
var import_node_fs62 = require("node:fs");
|
|
37749
38133
|
function registerWaiveCommand(program2) {
|
|
37750
38134
|
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) => {
|
|
37751
38135
|
const globals = program2.opts();
|
|
@@ -37774,7 +38158,7 @@ function registerWaiveCommand(program2) {
|
|
|
37774
38158
|
if (opts.file) {
|
|
37775
38159
|
body2.file = opts.file;
|
|
37776
38160
|
try {
|
|
37777
|
-
body2.file_sha256 = (0,
|
|
38161
|
+
body2.file_sha256 = (0, import_node_crypto20.createHash)("sha256").update((0, import_node_fs62.readFileSync)(opts.file)).digest("hex");
|
|
37778
38162
|
} catch {
|
|
37779
38163
|
printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
|
|
37780
38164
|
process.exit(1);
|
|
@@ -37799,10 +38183,10 @@ function registerWaiveCommand(program2) {
|
|
|
37799
38183
|
}
|
|
37800
38184
|
|
|
37801
38185
|
// src/commands/init.ts
|
|
37802
|
-
var
|
|
38186
|
+
var import_node_fs67 = require("node:fs");
|
|
37803
38187
|
var import_promises20 = require("node:fs/promises");
|
|
37804
38188
|
var import_yaml6 = __toESM2(require_dist());
|
|
37805
|
-
var
|
|
38189
|
+
var import_node_path52 = require("node:path");
|
|
37806
38190
|
var import_node_child_process19 = require("node:child_process");
|
|
37807
38191
|
|
|
37808
38192
|
// src/lib/banner.ts
|
|
@@ -37881,7 +38265,7 @@ function printPhase(n, of, title, subtitle) {
|
|
|
37881
38265
|
}
|
|
37882
38266
|
|
|
37883
38267
|
// src/commands/doctor.ts
|
|
37884
|
-
var
|
|
38268
|
+
var import_node_fs63 = require("node:fs");
|
|
37885
38269
|
|
|
37886
38270
|
// src/lib/prereqs.ts
|
|
37887
38271
|
var import_node_child_process16 = require("node:child_process");
|
|
@@ -37942,13 +38326,13 @@ function checkAnalysisCli() {
|
|
|
37942
38326
|
}
|
|
37943
38327
|
var INSTALL_TIMEOUT_MS = 12e4;
|
|
37944
38328
|
function run3(command, args2, opts = {}) {
|
|
37945
|
-
return new Promise((
|
|
38329
|
+
return new Promise((resolve9) => {
|
|
37946
38330
|
const child = (0, import_node_child_process16.spawn)(command, args2, {
|
|
37947
38331
|
stdio: opts.inherit ? "inherit" : "pipe",
|
|
37948
38332
|
timeout: INSTALL_TIMEOUT_MS
|
|
37949
38333
|
});
|
|
37950
|
-
child.on("error", () =>
|
|
37951
|
-
child.on("close", (code) =>
|
|
38334
|
+
child.on("error", () => resolve9(false));
|
|
38335
|
+
child.on("close", (code) => resolve9(code === 0));
|
|
37952
38336
|
});
|
|
37953
38337
|
}
|
|
37954
38338
|
async function installAnalysisCli() {
|
|
@@ -38089,11 +38473,11 @@ async function buildReport() {
|
|
|
38089
38473
|
const hooks = wiring.status;
|
|
38090
38474
|
const provenance = cliProvenance();
|
|
38091
38475
|
const telemetry = await checkTelemetry();
|
|
38092
|
-
const hasConfig = (0,
|
|
38476
|
+
const hasConfig = (0, import_node_fs63.existsSync)(projectPath(CODACY_CONFIG_FILE));
|
|
38093
38477
|
const artifacts = {
|
|
38094
|
-
standard: (0,
|
|
38478
|
+
standard: (0, import_node_fs63.existsSync)(projectPath(STANDARD_FILE)),
|
|
38095
38479
|
analysisConfig: hasConfig,
|
|
38096
|
-
verityMd: (0,
|
|
38480
|
+
verityMd: (0, import_node_fs63.existsSync)(projectPath(VERITY_MD_FILE)),
|
|
38097
38481
|
analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
|
|
38098
38482
|
};
|
|
38099
38483
|
const next = [];
|
|
@@ -38252,8 +38636,8 @@ function registerDoctorCommand(program2) {
|
|
|
38252
38636
|
}
|
|
38253
38637
|
|
|
38254
38638
|
// src/commands/migrate.ts
|
|
38255
|
-
var
|
|
38256
|
-
var
|
|
38639
|
+
var import_node_fs64 = require("node:fs");
|
|
38640
|
+
var import_node_path49 = require("node:path");
|
|
38257
38641
|
var import_node_child_process17 = require("node:child_process");
|
|
38258
38642
|
var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
|
|
38259
38643
|
function defaultNpmRemover(pkg) {
|
|
@@ -38290,12 +38674,12 @@ async function runMigration(opts = {}) {
|
|
|
38290
38674
|
return { actions, migrated: actions.length > 0 };
|
|
38291
38675
|
}
|
|
38292
38676
|
function migrateProjectDir(root, actions) {
|
|
38293
|
-
const gateDir = (0,
|
|
38294
|
-
const verityDir = (0,
|
|
38295
|
-
if ((0,
|
|
38677
|
+
const gateDir = (0, import_node_path49.join)(root, ".gate");
|
|
38678
|
+
const verityDir = (0, import_node_path49.join)(root, ".verity");
|
|
38679
|
+
if ((0, import_node_fs64.existsSync)(gateDir) && !(0, import_node_fs64.existsSync)(verityDir)) {
|
|
38296
38680
|
return migrateProjectDirRename(root, gateDir, verityDir, actions);
|
|
38297
38681
|
}
|
|
38298
|
-
if ((0,
|
|
38682
|
+
if ((0, import_node_fs64.existsSync)(gateDir) && (0, import_node_fs64.existsSync)(verityDir)) {
|
|
38299
38683
|
return migrateProjectDirCarry(gateDir, verityDir, actions);
|
|
38300
38684
|
}
|
|
38301
38685
|
return false;
|
|
@@ -38316,13 +38700,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
|
|
|
38316
38700
|
}
|
|
38317
38701
|
}
|
|
38318
38702
|
if (moved) {
|
|
38319
|
-
if ((0,
|
|
38703
|
+
if ((0, import_node_fs64.existsSync)(gateDir)) {
|
|
38320
38704
|
const carried = carryLegacyContents(gateDir, verityDir);
|
|
38321
38705
|
if (carried > 0) {
|
|
38322
38706
|
actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
|
|
38323
38707
|
}
|
|
38324
38708
|
try {
|
|
38325
|
-
(0,
|
|
38709
|
+
(0, import_node_fs64.rmSync)(gateDir, { recursive: true, force: true });
|
|
38326
38710
|
} catch {
|
|
38327
38711
|
}
|
|
38328
38712
|
}
|
|
@@ -38338,18 +38722,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
|
|
|
38338
38722
|
actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
|
|
38339
38723
|
}
|
|
38340
38724
|
try {
|
|
38341
|
-
(0,
|
|
38725
|
+
(0, import_node_fs64.rmSync)(gateDir, { recursive: true, force: true });
|
|
38342
38726
|
} catch {
|
|
38343
38727
|
}
|
|
38344
38728
|
return carried > 0;
|
|
38345
38729
|
}
|
|
38346
38730
|
function migrateGlobalCredentials(home, actions) {
|
|
38347
38731
|
if (!home) return;
|
|
38348
|
-
const gateCreds = (0,
|
|
38349
|
-
const verityCreds = (0,
|
|
38350
|
-
if (!(0,
|
|
38351
|
-
if (!(0,
|
|
38352
|
-
(0,
|
|
38732
|
+
const gateCreds = (0, import_node_path49.join)(home, ".gate", "credentials");
|
|
38733
|
+
const verityCreds = (0, import_node_path49.join)(home, ".verity", "credentials");
|
|
38734
|
+
if (!(0, import_node_fs64.existsSync)(gateCreds)) return;
|
|
38735
|
+
if (!(0, import_node_fs64.existsSync)(verityCreds)) {
|
|
38736
|
+
(0, import_node_fs64.mkdirSync)((0, import_node_path49.join)(home, ".verity"), { recursive: true });
|
|
38353
38737
|
moveFile(gateCreds, verityCreds);
|
|
38354
38738
|
actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
|
|
38355
38739
|
return;
|
|
@@ -38371,8 +38755,8 @@ async function migrateLegacyHooks(root, actions) {
|
|
|
38371
38755
|
}
|
|
38372
38756
|
}
|
|
38373
38757
|
async function migrateClaudeMd(root, actions) {
|
|
38374
|
-
const claudeMd = (0,
|
|
38375
|
-
const hadLegacyBlock = (0,
|
|
38758
|
+
const claudeMd = (0, import_node_path49.join)(root, "CLAUDE.md");
|
|
38759
|
+
const hadLegacyBlock = (0, import_node_fs64.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
|
|
38376
38760
|
if (!hadLegacyBlock) return;
|
|
38377
38761
|
try {
|
|
38378
38762
|
await ensureClaudeMdPointer(root);
|
|
@@ -38382,9 +38766,9 @@ async function migrateClaudeMd(root, actions) {
|
|
|
38382
38766
|
}
|
|
38383
38767
|
}
|
|
38384
38768
|
function migrateStandardFile(root, actions) {
|
|
38385
|
-
const gateMd = (0,
|
|
38386
|
-
const verityMd = (0,
|
|
38387
|
-
if (!(0,
|
|
38769
|
+
const gateMd = (0, import_node_path49.join)(root, "GATE.md");
|
|
38770
|
+
const verityMd = (0, import_node_path49.join)(root, "VERITY.md");
|
|
38771
|
+
if (!(0, import_node_fs64.existsSync)(gateMd) || (0, import_node_fs64.existsSync)(verityMd)) return;
|
|
38388
38772
|
let moved = false;
|
|
38389
38773
|
if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
|
|
38390
38774
|
try {
|
|
@@ -38396,12 +38780,12 @@ function migrateStandardFile(root, actions) {
|
|
|
38396
38780
|
if (!moved) moveFile(gateMd, verityMd);
|
|
38397
38781
|
const content = readFileSyncSafe(verityMd);
|
|
38398
38782
|
const refreshed = content.split("GATE.md").join("VERITY.md");
|
|
38399
|
-
if (refreshed !== content) (0,
|
|
38783
|
+
if (refreshed !== content) (0, import_node_fs64.writeFileSync)(verityMd, refreshed);
|
|
38400
38784
|
actions.push("Renamed GATE.md \u2192 VERITY.md");
|
|
38401
38785
|
}
|
|
38402
38786
|
async function migrateTelemetryHeaders(root, actions) {
|
|
38403
|
-
const file = (0,
|
|
38404
|
-
if (!(0,
|
|
38787
|
+
const file = (0, import_node_path49.join)(root, ".claude", "settings.local.json");
|
|
38788
|
+
if (!(0, import_node_fs64.existsSync)(file)) return;
|
|
38405
38789
|
let settings;
|
|
38406
38790
|
try {
|
|
38407
38791
|
settings = JSON.parse(readFileSyncSafe(file) || "{}");
|
|
@@ -38449,14 +38833,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
|
|
|
38449
38833
|
}
|
|
38450
38834
|
if (toAppend.length > 0) {
|
|
38451
38835
|
const sep5 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
|
|
38452
|
-
(0,
|
|
38836
|
+
(0, import_node_fs64.writeFileSync)(verityCreds, verityContent + sep5 + toAppend.join("\n") + "\n");
|
|
38453
38837
|
}
|
|
38454
|
-
(0,
|
|
38838
|
+
(0, import_node_fs64.rmSync)(gateCreds, { force: true });
|
|
38455
38839
|
return toAppend.length;
|
|
38456
38840
|
}
|
|
38457
38841
|
function readFileSyncSafe(path) {
|
|
38458
38842
|
try {
|
|
38459
|
-
return (0,
|
|
38843
|
+
return (0, import_node_fs64.readFileSync)(path, "utf-8");
|
|
38460
38844
|
} catch {
|
|
38461
38845
|
return "";
|
|
38462
38846
|
}
|
|
@@ -38471,35 +38855,35 @@ function hasStagedChanges(root) {
|
|
|
38471
38855
|
}
|
|
38472
38856
|
function moveDir(from, to) {
|
|
38473
38857
|
try {
|
|
38474
|
-
(0,
|
|
38858
|
+
(0, import_node_fs64.renameSync)(from, to);
|
|
38475
38859
|
} catch (err2) {
|
|
38476
38860
|
if (err2.code !== "EXDEV") throw err2;
|
|
38477
|
-
(0,
|
|
38478
|
-
(0,
|
|
38861
|
+
(0, import_node_fs64.cpSync)(from, to, { recursive: true });
|
|
38862
|
+
(0, import_node_fs64.rmSync)(from, { recursive: true, force: true });
|
|
38479
38863
|
}
|
|
38480
38864
|
}
|
|
38481
38865
|
function moveFile(from, to) {
|
|
38482
38866
|
try {
|
|
38483
|
-
(0,
|
|
38867
|
+
(0, import_node_fs64.renameSync)(from, to);
|
|
38484
38868
|
} catch (err2) {
|
|
38485
38869
|
if (err2.code !== "EXDEV") throw err2;
|
|
38486
|
-
(0,
|
|
38487
|
-
(0,
|
|
38870
|
+
(0, import_node_fs64.cpSync)(from, to);
|
|
38871
|
+
(0, import_node_fs64.rmSync)(from, { force: true });
|
|
38488
38872
|
}
|
|
38489
38873
|
}
|
|
38490
38874
|
function carryLegacyContents(gateDir, verityDir) {
|
|
38491
38875
|
let copied = 0;
|
|
38492
38876
|
const walk2 = (relDir) => {
|
|
38493
|
-
const srcDir = (0,
|
|
38494
|
-
for (const entry of (0,
|
|
38495
|
-
const rel = relDir ? (0,
|
|
38496
|
-
const src = (0,
|
|
38497
|
-
const dest = (0,
|
|
38498
|
-
if ((0,
|
|
38877
|
+
const srcDir = (0, import_node_path49.join)(gateDir, relDir);
|
|
38878
|
+
for (const entry of (0, import_node_fs64.readdirSync)(srcDir)) {
|
|
38879
|
+
const rel = relDir ? (0, import_node_path49.join)(relDir, entry) : entry;
|
|
38880
|
+
const src = (0, import_node_path49.join)(gateDir, rel);
|
|
38881
|
+
const dest = (0, import_node_path49.join)(verityDir, rel);
|
|
38882
|
+
if ((0, import_node_fs64.statSync)(src).isDirectory()) {
|
|
38499
38883
|
walk2(rel);
|
|
38500
|
-
} else if (!(0,
|
|
38501
|
-
(0,
|
|
38502
|
-
(0,
|
|
38884
|
+
} else if (!(0, import_node_fs64.existsSync)(dest)) {
|
|
38885
|
+
(0, import_node_fs64.mkdirSync)((0, import_node_path49.dirname)(dest), { recursive: true });
|
|
38886
|
+
(0, import_node_fs64.cpSync)(src, dest);
|
|
38503
38887
|
copied++;
|
|
38504
38888
|
}
|
|
38505
38889
|
}
|
|
@@ -38508,22 +38892,22 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
38508
38892
|
return copied;
|
|
38509
38893
|
}
|
|
38510
38894
|
async function needsMigration(root = repoRoot()) {
|
|
38511
|
-
const gateDir = (0,
|
|
38512
|
-
const verityDir = (0,
|
|
38513
|
-
if ((0,
|
|
38514
|
-
if ((0,
|
|
38515
|
-
if ((0,
|
|
38895
|
+
const gateDir = (0, import_node_path49.join)(root, ".gate");
|
|
38896
|
+
const verityDir = (0, import_node_path49.join)(root, ".verity");
|
|
38897
|
+
if ((0, import_node_fs64.existsSync)(gateDir) && !(0, import_node_fs64.existsSync)(verityDir)) return true;
|
|
38898
|
+
if ((0, import_node_fs64.existsSync)(gateDir) && (0, import_node_fs64.existsSync)(verityDir)) {
|
|
38899
|
+
if ((0, import_node_fs64.existsSync)((0, import_node_path49.join)(gateDir, "credentials")) && !(0, import_node_fs64.existsSync)((0, import_node_path49.join)(verityDir, "credentials"))) {
|
|
38516
38900
|
return true;
|
|
38517
38901
|
}
|
|
38518
|
-
if ((0,
|
|
38902
|
+
if ((0, import_node_fs64.existsSync)((0, import_node_path49.join)(gateDir, "memory")) && !(0, import_node_fs64.existsSync)((0, import_node_path49.join)(verityDir, "memory"))) {
|
|
38519
38903
|
return true;
|
|
38520
38904
|
}
|
|
38521
38905
|
}
|
|
38522
|
-
const claudeMd = (0,
|
|
38523
|
-
if ((0,
|
|
38906
|
+
const claudeMd = (0, import_node_path49.join)(root, "CLAUDE.md");
|
|
38907
|
+
if ((0, import_node_fs64.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
|
|
38524
38908
|
return true;
|
|
38525
38909
|
}
|
|
38526
|
-
if ((0,
|
|
38910
|
+
if ((0, import_node_fs64.existsSync)((0, import_node_path49.join)(root, "GATE.md")) && !(0, import_node_fs64.existsSync)((0, import_node_path49.join)(root, "VERITY.md"))) {
|
|
38527
38911
|
return true;
|
|
38528
38912
|
}
|
|
38529
38913
|
if (await hasLegacyHooksAt(root)) return true;
|
|
@@ -38652,7 +39036,7 @@ function runSelect(opts) {
|
|
|
38652
39036
|
cursor: initialIdx[0] ?? 0,
|
|
38653
39037
|
chosen: new Set(mode2 === "single" ? [initialIdx[0] ?? 0] : initialIdx)
|
|
38654
39038
|
};
|
|
38655
|
-
return new Promise((
|
|
39039
|
+
return new Promise((resolve9) => {
|
|
38656
39040
|
let painted = 0;
|
|
38657
39041
|
let settled = false;
|
|
38658
39042
|
const draw = () => {
|
|
@@ -38700,7 +39084,7 @@ function runSelect(opts) {
|
|
|
38700
39084
|
if (settled) return;
|
|
38701
39085
|
settled = true;
|
|
38702
39086
|
restore();
|
|
38703
|
-
|
|
39087
|
+
resolve9(value);
|
|
38704
39088
|
};
|
|
38705
39089
|
readline2.emitKeypressEvents(input);
|
|
38706
39090
|
input.setRawMode(true);
|
|
@@ -38721,9 +39105,9 @@ async function askLine(question, io = {}) {
|
|
|
38721
39105
|
output: io.output ?? process.stdout
|
|
38722
39106
|
});
|
|
38723
39107
|
try {
|
|
38724
|
-
return await new Promise((
|
|
38725
|
-
rl.question(question).then((a) =>
|
|
38726
|
-
rl.once("close", () => setImmediate(() =>
|
|
39108
|
+
return await new Promise((resolve9) => {
|
|
39109
|
+
rl.question(question).then((a) => resolve9(a.trim())).catch(() => resolve9(null));
|
|
39110
|
+
rl.once("close", () => setImmediate(() => resolve9(null)));
|
|
38727
39111
|
});
|
|
38728
39112
|
} finally {
|
|
38729
39113
|
rl.close();
|
|
@@ -38804,11 +39188,11 @@ async function promptMultiSelect(question, choices, fallback) {
|
|
|
38804
39188
|
}
|
|
38805
39189
|
|
|
38806
39190
|
// src/lib/prove/lean-install.ts
|
|
38807
|
-
var
|
|
38808
|
-
var
|
|
39191
|
+
var import_node_fs65 = require("node:fs");
|
|
39192
|
+
var import_node_crypto21 = require("node:crypto");
|
|
38809
39193
|
var import_node_child_process18 = require("node:child_process");
|
|
38810
39194
|
var import_node_os10 = require("node:os");
|
|
38811
|
-
var
|
|
39195
|
+
var import_node_path50 = require("node:path");
|
|
38812
39196
|
var import_promises18 = require("node:stream/promises");
|
|
38813
39197
|
var import_node_stream = require("node:stream");
|
|
38814
39198
|
var RELEASES = "https://releases.lean-lang.org/lean4";
|
|
@@ -38819,10 +39203,10 @@ function freeBytes(dir) {
|
|
|
38819
39203
|
let d = dir;
|
|
38820
39204
|
for (let i2 = 0; i2 < 64; i2++) {
|
|
38821
39205
|
try {
|
|
38822
|
-
const st = (0,
|
|
39206
|
+
const st = (0, import_node_fs65.statfsSync)(d);
|
|
38823
39207
|
return Number(st.bavail) * Number(st.bsize);
|
|
38824
39208
|
} catch {
|
|
38825
|
-
const up = (0,
|
|
39209
|
+
const up = (0, import_node_path50.join)(d, "..");
|
|
38826
39210
|
if (up === d) return null;
|
|
38827
39211
|
d = up;
|
|
38828
39212
|
}
|
|
@@ -38842,9 +39226,9 @@ function expectedSha256(asset, version = pinnedVersion()) {
|
|
|
38842
39226
|
return LEAN_ASSET_SHA256[version]?.[asset] ?? null;
|
|
38843
39227
|
}
|
|
38844
39228
|
function sha256File(path) {
|
|
38845
|
-
return new Promise((
|
|
38846
|
-
const hash = (0,
|
|
38847
|
-
(0,
|
|
39229
|
+
return new Promise((resolve9, reject) => {
|
|
39230
|
+
const hash = (0, import_node_crypto21.createHash)("sha256");
|
|
39231
|
+
(0, import_node_fs65.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve9(hash.digest("hex"))).on("error", reject);
|
|
38848
39232
|
});
|
|
38849
39233
|
}
|
|
38850
39234
|
async function verifyDownload(zip, asset, version = pinnedVersion()) {
|
|
@@ -38864,7 +39248,7 @@ function leanAssetName(version = pinnedVersion()) {
|
|
|
38864
39248
|
return suffix ? `lean-${v}-${suffix}.zip` : null;
|
|
38865
39249
|
}
|
|
38866
39250
|
function pinnedVersionDir(env = process.env) {
|
|
38867
|
-
return (0,
|
|
39251
|
+
return (0, import_node_path50.join)(verityLeanHome(env), pinnedVersion());
|
|
38868
39252
|
}
|
|
38869
39253
|
function lakeBinary() {
|
|
38870
39254
|
return (0, import_node_os10.platform)() === "win32" ? "lake.exe" : "lake";
|
|
@@ -38875,12 +39259,12 @@ function unzip(zip, dest) {
|
|
|
38875
39259
|
for (const [cmd, args2] of attempts) {
|
|
38876
39260
|
try {
|
|
38877
39261
|
(0, import_node_child_process18.execFileSync)(cmd, args2, { stdio: ["ignore", "ignore", "pipe"], timeout: 15 * 6e4 });
|
|
38878
|
-
if ((0,
|
|
39262
|
+
if ((0, import_node_fs65.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
|
|
38879
39263
|
errors.push(`${cmd}: produced nothing`);
|
|
38880
39264
|
} catch (err2) {
|
|
38881
39265
|
errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
|
|
38882
39266
|
try {
|
|
38883
|
-
for (const e of (0,
|
|
39267
|
+
for (const e of (0, import_node_fs65.readdirSync)(dest)) (0, import_node_fs65.rmSync)((0, import_node_path50.join)(dest, e), { recursive: true, force: true });
|
|
38884
39268
|
} catch {
|
|
38885
39269
|
}
|
|
38886
39270
|
}
|
|
@@ -38906,7 +39290,7 @@ async function download(url, dest, onProgress, stallMs = DOWNLOAD_STALL_MS) {
|
|
|
38906
39290
|
seen += chunk.length;
|
|
38907
39291
|
onProgress(seen, total);
|
|
38908
39292
|
});
|
|
38909
|
-
await (0, import_promises18.pipeline)(stream, (0,
|
|
39293
|
+
await (0, import_promises18.pipeline)(stream, (0, import_node_fs65.createWriteStream)(dest), { signal: ctrl.signal });
|
|
38910
39294
|
} catch (err2) {
|
|
38911
39295
|
if (ctrl.signal.aborted) throw new Error(`download stalled: nothing received for ${Math.round(stallMs / 1e3)} s`);
|
|
38912
39296
|
throw err2;
|
|
@@ -38956,10 +39340,10 @@ async function installLean(opts = {}) {
|
|
|
38956
39340
|
const gb = (n) => (n / 1024 ** 3).toFixed(1);
|
|
38957
39341
|
return { ok: false, error: `not enough disk space for Lean: ${gb(free)} GB free where ${home} lives, needs about ${gb(needed)} GB` };
|
|
38958
39342
|
}
|
|
38959
|
-
const tmp = (0,
|
|
38960
|
-
(0,
|
|
38961
|
-
(0,
|
|
38962
|
-
const zip = (0,
|
|
39343
|
+
const tmp = (0, import_node_path50.join)(home, ".tmp");
|
|
39344
|
+
(0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
|
|
39345
|
+
(0, import_node_fs65.mkdirSync)(tmp, { recursive: true });
|
|
39346
|
+
const zip = (0, import_node_path50.join)(tmp, asset);
|
|
38963
39347
|
say(`downloading ${url}`);
|
|
38964
39348
|
let lastPct = -1;
|
|
38965
39349
|
try {
|
|
@@ -38972,40 +39356,40 @@ async function installLean(opts = {}) {
|
|
|
38972
39356
|
}
|
|
38973
39357
|
});
|
|
38974
39358
|
} catch (err2) {
|
|
38975
|
-
(0,
|
|
39359
|
+
(0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
|
|
38976
39360
|
return { ok: false, error: err2.message };
|
|
38977
39361
|
}
|
|
38978
39362
|
say("verifying checksum");
|
|
38979
39363
|
const verified = await verifyDownload(zip, asset);
|
|
38980
39364
|
if (!verified.ok) {
|
|
38981
|
-
(0,
|
|
39365
|
+
(0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
|
|
38982
39366
|
return { ok: false, error: verified.error };
|
|
38983
39367
|
}
|
|
38984
39368
|
say("unpacking (this takes a minute)");
|
|
38985
|
-
const unpack = (0,
|
|
38986
|
-
(0,
|
|
39369
|
+
const unpack = (0, import_node_path50.join)(tmp, "unpack");
|
|
39370
|
+
(0, import_node_fs65.mkdirSync)(unpack);
|
|
38987
39371
|
const unpacked = unzip(zip, unpack);
|
|
38988
39372
|
if (!unpacked.ok) {
|
|
38989
|
-
(0,
|
|
39373
|
+
(0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
|
|
38990
39374
|
return { ok: false, error: `unpack failed: ${unpacked.error}` };
|
|
38991
39375
|
}
|
|
38992
|
-
const entries = (0,
|
|
38993
|
-
const top = entries.length === 1 && (0,
|
|
38994
|
-
if (!(0,
|
|
38995
|
-
(0,
|
|
39376
|
+
const entries = (0, import_node_fs65.readdirSync)(unpack);
|
|
39377
|
+
const top = entries.length === 1 && (0, import_node_fs65.statSync)((0, import_node_path50.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path50.join)(unpack, entries[0]) : unpack;
|
|
39378
|
+
if (!(0, import_node_fs65.existsSync)((0, import_node_path50.join)(top, "bin", lakeBinary()))) {
|
|
39379
|
+
(0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
|
|
38996
39380
|
return { ok: false, error: "the archive did not contain bin/lake" };
|
|
38997
39381
|
}
|
|
38998
|
-
(0,
|
|
38999
|
-
(0,
|
|
39000
|
-
(0,
|
|
39001
|
-
(0,
|
|
39382
|
+
(0, import_node_fs65.rmSync)(dir, { recursive: true, force: true });
|
|
39383
|
+
(0, import_node_fs65.mkdirSync)(home, { recursive: true });
|
|
39384
|
+
(0, import_node_fs65.renameSync)(top, dir);
|
|
39385
|
+
(0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
|
|
39002
39386
|
return { ok: true, dir };
|
|
39003
39387
|
}
|
|
39004
39388
|
|
|
39005
39389
|
// src/lib/remote-config.ts
|
|
39006
|
-
var
|
|
39390
|
+
var import_node_fs66 = require("node:fs");
|
|
39007
39391
|
var import_promises19 = require("node:fs/promises");
|
|
39008
|
-
var
|
|
39392
|
+
var import_node_path51 = require("node:path");
|
|
39009
39393
|
var import_yaml5 = __toESM2(require_dist());
|
|
39010
39394
|
var IGNORE_RIDER = "verityignore";
|
|
39011
39395
|
async function fetchRemoteSetup(opts) {
|
|
@@ -39050,7 +39434,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
39050
39434
|
written.push(STANDARD_FILE);
|
|
39051
39435
|
if (rider !== null) {
|
|
39052
39436
|
const localIgnore = projectPath(VERITYIGNORE_FILE);
|
|
39053
|
-
if (!(0,
|
|
39437
|
+
if (!(0, import_node_fs66.existsSync)(localIgnore)) {
|
|
39054
39438
|
await writeOut(VERITYIGNORE_FILE, rider);
|
|
39055
39439
|
written.push(VERITYIGNORE_FILE);
|
|
39056
39440
|
} else {
|
|
@@ -39083,7 +39467,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
39083
39467
|
}
|
|
39084
39468
|
async function writeOut(relative6, body2) {
|
|
39085
39469
|
const target = projectPath(relative6);
|
|
39086
|
-
await (0, import_promises19.mkdir)((0,
|
|
39470
|
+
await (0, import_promises19.mkdir)((0, import_node_path51.dirname)(target), { recursive: true });
|
|
39087
39471
|
await (0, import_promises19.writeFile)(target, body2);
|
|
39088
39472
|
}
|
|
39089
39473
|
function describeRemote(found) {
|
|
@@ -39200,15 +39584,15 @@ async function runOptionalAuth(resolution, opts = {}) {
|
|
|
39200
39584
|
}
|
|
39201
39585
|
function resolveDataDir2() {
|
|
39202
39586
|
const candidates2 = [
|
|
39203
|
-
(0,
|
|
39587
|
+
(0, import_node_path52.join)(__dirname, "..", "data"),
|
|
39204
39588
|
// installed: node_modules/@codacy/verity-cli/data
|
|
39205
|
-
(0,
|
|
39589
|
+
(0, import_node_path52.join)(__dirname, "..", "..", "data"),
|
|
39206
39590
|
// edge case: nested resolution
|
|
39207
|
-
(0,
|
|
39591
|
+
(0, import_node_path52.join)(process.cwd(), "cli", "data")
|
|
39208
39592
|
// local dev: running from repo root
|
|
39209
39593
|
];
|
|
39210
39594
|
for (const candidate of candidates2) {
|
|
39211
|
-
if ((0,
|
|
39595
|
+
if ((0, import_node_fs67.existsSync)((0, import_node_path52.join)(candidate, "skills"))) {
|
|
39212
39596
|
return candidate;
|
|
39213
39597
|
}
|
|
39214
39598
|
}
|
|
@@ -39224,9 +39608,9 @@ async function skillIsCurrent(src, dest) {
|
|
|
39224
39608
|
const list2 = (dir) => {
|
|
39225
39609
|
const out2 = [];
|
|
39226
39610
|
const walk2 = (d, prefix) => {
|
|
39227
|
-
for (const e of (0,
|
|
39611
|
+
for (const e of (0, import_node_fs67.readdirSync)(d, { withFileTypes: true })) {
|
|
39228
39612
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
39229
|
-
if (e.isDirectory()) walk2((0,
|
|
39613
|
+
if (e.isDirectory()) walk2((0, import_node_path52.join)(d, e.name), rel);
|
|
39230
39614
|
else if (e.isFile()) out2.push(rel);
|
|
39231
39615
|
}
|
|
39232
39616
|
};
|
|
@@ -39237,8 +39621,8 @@ async function skillIsCurrent(src, dest) {
|
|
|
39237
39621
|
const shipped = list2(src);
|
|
39238
39622
|
if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
|
|
39239
39623
|
for (const rel of shipped) {
|
|
39240
|
-
const a = await (0, import_promises20.readFile)((0,
|
|
39241
|
-
const b = await (0, import_promises20.readFile)((0,
|
|
39624
|
+
const a = await (0, import_promises20.readFile)((0, import_node_path52.join)(src, rel), "utf-8");
|
|
39625
|
+
const b = await (0, import_promises20.readFile)((0, import_node_path52.join)(dest, rel), "utf-8");
|
|
39242
39626
|
if (a !== b) return false;
|
|
39243
39627
|
}
|
|
39244
39628
|
return true;
|
|
@@ -39441,7 +39825,7 @@ async function synthesizeLocally(opts) {
|
|
|
39441
39825
|
async function healStaleAnalysisConfig(globals) {
|
|
39442
39826
|
const configPath = projectPath(CODACY_CONFIG_FILE);
|
|
39443
39827
|
const standardPath = projectPath(STANDARD_FILE);
|
|
39444
|
-
if (!(0,
|
|
39828
|
+
if (!(0, import_node_fs67.existsSync)(configPath) || !(0, import_node_fs67.existsSync)(standardPath)) return;
|
|
39445
39829
|
const validation = validatePatternIds();
|
|
39446
39830
|
if (validation.status !== "invalid") return;
|
|
39447
39831
|
printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
|
|
@@ -39538,17 +39922,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
|
|
|
39538
39922
|
async function installSkills(force, step) {
|
|
39539
39923
|
step("Installing skills");
|
|
39540
39924
|
const dataDir = resolveDataDir2();
|
|
39541
|
-
const skillsSource = (0,
|
|
39925
|
+
const skillsSource = (0, import_node_path52.join)(dataDir, "skills");
|
|
39542
39926
|
const skillsDest = ".claude/skills";
|
|
39543
39927
|
let skillsInstalled = 0;
|
|
39544
39928
|
for (const skill of SKILLS) {
|
|
39545
|
-
const src = (0,
|
|
39546
|
-
const dest = (0,
|
|
39547
|
-
if (!(0,
|
|
39929
|
+
const src = (0, import_node_path52.join)(skillsSource, skill);
|
|
39930
|
+
const dest = (0, import_node_path52.join)(skillsDest, skill);
|
|
39931
|
+
if (!(0, import_node_fs67.existsSync)(src)) {
|
|
39548
39932
|
printWarn(` Skill data not found: ${skill}`);
|
|
39549
39933
|
continue;
|
|
39550
39934
|
}
|
|
39551
|
-
if ((0,
|
|
39935
|
+
if ((0, import_node_fs67.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
|
|
39552
39936
|
skillsInstalled++;
|
|
39553
39937
|
continue;
|
|
39554
39938
|
}
|
|
@@ -39748,7 +40132,7 @@ function registerInitCommand(program2) {
|
|
|
39748
40132
|
const staleMarker = clearStalePluginMarker();
|
|
39749
40133
|
const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
|
|
39750
40134
|
const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
|
|
39751
|
-
const isProject = projectMarkers.some((m) => (0,
|
|
40135
|
+
const isProject = projectMarkers.some((m) => (0, import_node_fs67.existsSync)(m));
|
|
39752
40136
|
if (!isProject) {
|
|
39753
40137
|
printError("No project detected in the current directory.");
|
|
39754
40138
|
printInfo('Run "verity init" from your project root.');
|
|
@@ -39851,7 +40235,7 @@ function registerInitCommand(program2) {
|
|
|
39851
40235
|
untrackMemory: opts.untrackMemory === true,
|
|
39852
40236
|
untrackState: opts.untrackState === true
|
|
39853
40237
|
});
|
|
39854
|
-
const globalVerityDir = (0,
|
|
40238
|
+
const globalVerityDir = (0, import_node_path52.join)(process.env.HOME ?? "", ".verity");
|
|
39855
40239
|
await (0, import_promises20.mkdir)(globalVerityDir, { recursive: true });
|
|
39856
40240
|
console.log("");
|
|
39857
40241
|
step("Wiring Claude Code hooks");
|
|
@@ -39926,7 +40310,7 @@ function registerInitCommand(program2) {
|
|
|
39926
40310
|
}
|
|
39927
40311
|
step("Your project's Standard");
|
|
39928
40312
|
let haveStandard = false;
|
|
39929
|
-
if ((0,
|
|
40313
|
+
if ((0, import_node_fs67.existsSync)(projectPath(STANDARD_FILE))) {
|
|
39930
40314
|
printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
|
|
39931
40315
|
haveStandard = true;
|
|
39932
40316
|
} else {
|
|
@@ -39956,7 +40340,7 @@ function registerInitCommand(program2) {
|
|
|
39956
40340
|
...telemetryChoice ? { telemetry: telemetryChoice } : {},
|
|
39957
40341
|
init: {
|
|
39958
40342
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
39959
|
-
cli_version: true ? "0.34.0-experimental.
|
|
40343
|
+
cli_version: true ? "0.34.0-experimental.53caba1" : "dev"
|
|
39960
40344
|
}
|
|
39961
40345
|
});
|
|
39962
40346
|
} catch (err2) {
|
|
@@ -40006,8 +40390,8 @@ function registerInitCommand(program2) {
|
|
|
40006
40390
|
}
|
|
40007
40391
|
|
|
40008
40392
|
// src/commands/uninstall.ts
|
|
40009
|
-
var
|
|
40010
|
-
var
|
|
40393
|
+
var import_node_fs68 = require("node:fs");
|
|
40394
|
+
var import_node_path53 = require("node:path");
|
|
40011
40395
|
function registerUninstallCommand(program2) {
|
|
40012
40396
|
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) => {
|
|
40013
40397
|
const dryRun = opts.dryRun ?? false;
|
|
@@ -40016,11 +40400,11 @@ function registerUninstallCommand(program2) {
|
|
|
40016
40400
|
const actions = [];
|
|
40017
40401
|
const skillsRoot = projectPath(".claude/skills");
|
|
40018
40402
|
for (const name2 of PROJECT_SKILL_NAMES) {
|
|
40019
|
-
const dir = (0,
|
|
40020
|
-
if ((0,
|
|
40403
|
+
const dir = (0, import_node_path53.join)(skillsRoot, name2);
|
|
40404
|
+
if ((0, import_node_fs68.existsSync)(dir)) {
|
|
40021
40405
|
actions.push({
|
|
40022
40406
|
label: `Remove .claude/skills/${name2}/`,
|
|
40023
|
-
apply: () => (0,
|
|
40407
|
+
apply: () => (0, import_node_fs68.rmSync)(dir, { recursive: true, force: true })
|
|
40024
40408
|
});
|
|
40025
40409
|
}
|
|
40026
40410
|
}
|
|
@@ -40034,24 +40418,24 @@ function registerUninstallCommand(program2) {
|
|
|
40034
40418
|
});
|
|
40035
40419
|
}
|
|
40036
40420
|
const verityDir = projectPath(VERITY_DIR);
|
|
40037
|
-
if ((0,
|
|
40421
|
+
if ((0, import_node_fs68.existsSync)(verityDir)) {
|
|
40038
40422
|
actions.push({
|
|
40039
40423
|
label: `Remove ${VERITY_DIR}/`,
|
|
40040
|
-
apply: () => (0,
|
|
40424
|
+
apply: () => (0, import_node_fs68.rmSync)(verityDir, { recursive: true, force: true })
|
|
40041
40425
|
});
|
|
40042
40426
|
}
|
|
40043
40427
|
if (!keepVerityMd) {
|
|
40044
40428
|
const verityMd = projectPath(VERITY_MD_FILE);
|
|
40045
|
-
if ((0,
|
|
40429
|
+
if ((0, import_node_fs68.existsSync)(verityMd)) {
|
|
40046
40430
|
actions.push({
|
|
40047
40431
|
label: `Remove ${VERITY_MD_FILE}`,
|
|
40048
|
-
apply: () => (0,
|
|
40432
|
+
apply: () => (0, import_node_fs68.rmSync)(verityMd, { force: true })
|
|
40049
40433
|
});
|
|
40050
40434
|
}
|
|
40051
40435
|
}
|
|
40052
40436
|
const cleanupEmptyDir = (path) => {
|
|
40053
|
-
if ((0,
|
|
40054
|
-
(0,
|
|
40437
|
+
if ((0, import_node_fs68.existsSync)(path) && (0, import_node_fs68.statSync)(path).isDirectory() && (0, import_node_fs68.readdirSync)(path).length === 0) {
|
|
40438
|
+
(0, import_node_fs68.rmdirSync)(path);
|
|
40055
40439
|
}
|
|
40056
40440
|
};
|
|
40057
40441
|
actions.push({
|
|
@@ -40062,11 +40446,11 @@ function registerUninstallCommand(program2) {
|
|
|
40062
40446
|
}
|
|
40063
40447
|
});
|
|
40064
40448
|
const home = process.env.HOME ?? "";
|
|
40065
|
-
const globalVerityDir = (0,
|
|
40066
|
-
if (purgeGlobal && (0,
|
|
40449
|
+
const globalVerityDir = (0, import_node_path53.join)(home, ".verity");
|
|
40450
|
+
if (purgeGlobal && (0, import_node_fs68.existsSync)(globalVerityDir)) {
|
|
40067
40451
|
actions.push({
|
|
40068
40452
|
label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
|
|
40069
|
-
apply: () => (0,
|
|
40453
|
+
apply: () => (0, import_node_fs68.rmSync)(globalVerityDir, { recursive: true, force: true })
|
|
40070
40454
|
});
|
|
40071
40455
|
}
|
|
40072
40456
|
if (actions.length === 0) {
|
|
@@ -40260,8 +40644,8 @@ function registerTaskCommands(program2) {
|
|
|
40260
40644
|
}
|
|
40261
40645
|
|
|
40262
40646
|
// src/commands/reset.ts
|
|
40263
|
-
var
|
|
40264
|
-
var
|
|
40647
|
+
var import_node_fs69 = require("node:fs");
|
|
40648
|
+
var import_node_path54 = require("node:path");
|
|
40265
40649
|
function registerResetCommand(program2) {
|
|
40266
40650
|
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) => {
|
|
40267
40651
|
const globals = program2.opts();
|
|
@@ -40298,11 +40682,11 @@ function registerResetCommand(program2) {
|
|
|
40298
40682
|
}
|
|
40299
40683
|
const cacheDir = projectPath(CACHE_DIR);
|
|
40300
40684
|
let purged = 0;
|
|
40301
|
-
if ((0,
|
|
40302
|
-
for (const entry of (0,
|
|
40685
|
+
if ((0, import_node_fs69.existsSync)(cacheDir)) {
|
|
40686
|
+
for (const entry of (0, import_node_fs69.readdirSync)(cacheDir)) {
|
|
40303
40687
|
if (entry.startsWith("pending-")) {
|
|
40304
40688
|
try {
|
|
40305
|
-
(0,
|
|
40689
|
+
(0, import_node_fs69.unlinkSync)((0, import_node_path54.join)(cacheDir, entry));
|
|
40306
40690
|
purged++;
|
|
40307
40691
|
} catch {
|
|
40308
40692
|
}
|
|
@@ -40317,19 +40701,19 @@ function registerResetCommand(program2) {
|
|
|
40317
40701
|
projectPath(`${VERITY_DIR}/.last-analysis`)
|
|
40318
40702
|
];
|
|
40319
40703
|
for (const file of filesToClear) {
|
|
40320
|
-
if ((0,
|
|
40704
|
+
if ((0, import_node_fs69.existsSync)(file)) {
|
|
40321
40705
|
try {
|
|
40322
|
-
(0,
|
|
40706
|
+
(0, import_node_fs69.writeFileSync)(file, "");
|
|
40323
40707
|
} catch {
|
|
40324
40708
|
}
|
|
40325
40709
|
}
|
|
40326
40710
|
}
|
|
40327
40711
|
if (opts.all) {
|
|
40328
40712
|
const logsDir = projectPath(`${VERITY_DIR}/.logs`);
|
|
40329
|
-
if ((0,
|
|
40330
|
-
for (const entry of (0,
|
|
40713
|
+
if ((0, import_node_fs69.existsSync)(logsDir)) {
|
|
40714
|
+
for (const entry of (0, import_node_fs69.readdirSync)(logsDir)) {
|
|
40331
40715
|
try {
|
|
40332
|
-
(0,
|
|
40716
|
+
(0, import_node_fs69.unlinkSync)((0, import_node_path54.join)(logsDir, entry));
|
|
40333
40717
|
} catch {
|
|
40334
40718
|
}
|
|
40335
40719
|
}
|
|
@@ -40341,7 +40725,7 @@ function registerResetCommand(program2) {
|
|
|
40341
40725
|
}
|
|
40342
40726
|
|
|
40343
40727
|
// src/commands/reflect.ts
|
|
40344
|
-
var
|
|
40728
|
+
var import_node_fs70 = require("node:fs");
|
|
40345
40729
|
|
|
40346
40730
|
// src/lib/reflection-globs.ts
|
|
40347
40731
|
var MAX_GLOBS = 6;
|
|
@@ -40349,7 +40733,7 @@ var PATH_TOKEN = /[A-Za-z0-9_./-]*[A-Za-z0-9_-]\.[A-Za-z0-9]{1,8}(?::\d+(?::\d+)
|
|
|
40349
40733
|
function clean(token) {
|
|
40350
40734
|
return token.replace(/:\d+(?::\d+)?$/, "").replace(/^[`'"(\[]+/, "").replace(/[`'"),\].;!?]+$/, "").replace(/^\.\//, "");
|
|
40351
40735
|
}
|
|
40352
|
-
function
|
|
40736
|
+
function resolve7(token, treePaths) {
|
|
40353
40737
|
if (treePaths.includes(token)) return token;
|
|
40354
40738
|
const suffix = token.startsWith("/") ? token : `/${token}`;
|
|
40355
40739
|
const matches = treePaths.filter((p) => p.endsWith(suffix));
|
|
@@ -40362,7 +40746,7 @@ function deriveFileGlobs(text, treePaths) {
|
|
|
40362
40746
|
for (const raw of text.match(PATH_TOKEN) ?? []) {
|
|
40363
40747
|
const token = clean(raw);
|
|
40364
40748
|
if (!token) continue;
|
|
40365
|
-
const path =
|
|
40749
|
+
const path = resolve7(token, treePaths);
|
|
40366
40750
|
if (!path || seen.has(path)) continue;
|
|
40367
40751
|
seen.add(path);
|
|
40368
40752
|
out2.push(path);
|
|
@@ -40379,14 +40763,19 @@ async function writeNodeToDisk(args2) {
|
|
|
40379
40763
|
{ treePaths: listTrackedFiles(), recordBaseline: false }
|
|
40380
40764
|
);
|
|
40381
40765
|
if (written === 0) return false;
|
|
40382
|
-
return (0,
|
|
40766
|
+
return (0, import_node_fs70.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
|
|
40383
40767
|
} catch {
|
|
40384
40768
|
return false;
|
|
40385
40769
|
}
|
|
40386
40770
|
}
|
|
40387
40771
|
function registerReflectCommand(program2) {
|
|
40388
|
-
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) => {
|
|
40772
|
+
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) => {
|
|
40389
40773
|
const globals = program2.opts();
|
|
40774
|
+
const input = readTextInput(opts.userInput, "--user-input");
|
|
40775
|
+
if (!input.ok) {
|
|
40776
|
+
printError(input.error);
|
|
40777
|
+
process.exit(1);
|
|
40778
|
+
}
|
|
40390
40779
|
await ensureMemoryDir();
|
|
40391
40780
|
const tokenResult = await resolveToken(globals.token);
|
|
40392
40781
|
if (!tokenResult.ok) {
|
|
@@ -40447,7 +40836,7 @@ function registerReflectCommand(program2) {
|
|
|
40447
40836
|
taskResolution = "none";
|
|
40448
40837
|
printWarn("No active task found \u2014 saving as an unattached reflection.");
|
|
40449
40838
|
}
|
|
40450
|
-
const userInput =
|
|
40839
|
+
const userInput = input.text;
|
|
40451
40840
|
if (userInput) {
|
|
40452
40841
|
const validKinds = ["decision", "gotcha", "pattern", "security", "quality", "intent", "domain", "integration"];
|
|
40453
40842
|
const kind = validKinds.includes(opts.kind) ? opts.kind : "gotcha";
|
|
@@ -40811,9 +41200,9 @@ function registerRunCommand(program2) {
|
|
|
40811
41200
|
}
|
|
40812
41201
|
|
|
40813
41202
|
// src/commands/telemetry.ts
|
|
40814
|
-
var
|
|
41203
|
+
var import_node_fs71 = require("node:fs");
|
|
40815
41204
|
async function recordTelemetryChoice(choice) {
|
|
40816
|
-
if (!(0,
|
|
41205
|
+
if (!(0, import_node_fs71.existsSync)(projectPath(SETUP_STATE_FILE))) return;
|
|
40817
41206
|
try {
|
|
40818
41207
|
if ((await readSetupState())?.telemetry === choice) return;
|
|
40819
41208
|
await writeSetupState({ telemetry: choice });
|
|
@@ -40890,8 +41279,8 @@ function registerTelemetryCommands(program2) {
|
|
|
40890
41279
|
}
|
|
40891
41280
|
|
|
40892
41281
|
// src/commands/prove.ts
|
|
40893
|
-
var
|
|
40894
|
-
var
|
|
41282
|
+
var import_node_fs72 = require("node:fs");
|
|
41283
|
+
var import_node_path55 = require("node:path");
|
|
40895
41284
|
|
|
40896
41285
|
// src/lib/prove/hint-pool.ts
|
|
40897
41286
|
var STOP2 = /* @__PURE__ */ new Set([
|
|
@@ -41018,7 +41407,13 @@ async function proveAuth(program2) {
|
|
|
41018
41407
|
}
|
|
41019
41408
|
function registerProveCommand(program2) {
|
|
41020
41409
|
const prove = program2.command("prove").description("Formal verification (Lean 4) of small, risky pieces of code \u2014 on demand");
|
|
41021
|
-
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) => {
|
|
41410
|
+
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) => {
|
|
41411
|
+
const hint = readTextInput(opts.hint, "--hint");
|
|
41412
|
+
if (!hint.ok) {
|
|
41413
|
+
printError(hint.error);
|
|
41414
|
+
process.exit(2);
|
|
41415
|
+
}
|
|
41416
|
+
opts.hint = hint.text;
|
|
41022
41417
|
if (opts.hint && opts.rank === "deterministic") opts.rank = "luna";
|
|
41023
41418
|
const root = repoRoot();
|
|
41024
41419
|
const ranker = RANKERS[opts.rank];
|
|
@@ -41027,7 +41422,7 @@ function registerProveCommand(program2) {
|
|
|
41027
41422
|
process.exit(2);
|
|
41028
41423
|
}
|
|
41029
41424
|
const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
|
|
41030
|
-
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0,
|
|
41425
|
+
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path55.relative)(root, (0, import_node_path55.resolve)(p)) || ".") });
|
|
41031
41426
|
if (opts.hint && paths.length === 0) {
|
|
41032
41427
|
const hit = hintMatches(root, opts.hint);
|
|
41033
41428
|
if (hit.files.length > 0) {
|
|
@@ -41081,7 +41476,7 @@ function registerProveCommand(program2) {
|
|
|
41081
41476
|
});
|
|
41082
41477
|
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) => {
|
|
41083
41478
|
const root = repoRoot();
|
|
41084
|
-
if (!(0,
|
|
41479
|
+
if (!(0, import_node_fs72.existsSync)((0, import_node_path55.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41085
41480
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41086
41481
|
process.exit(2);
|
|
41087
41482
|
}
|
|
@@ -41105,7 +41500,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41105
41500
|
const reports = [];
|
|
41106
41501
|
for (const f of files) {
|
|
41107
41502
|
const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
|
|
41108
|
-
report.file = (0,
|
|
41503
|
+
report.file = (0, import_node_path55.relative)(root, f);
|
|
41109
41504
|
reports.push(report);
|
|
41110
41505
|
try {
|
|
41111
41506
|
writeResult(root, report);
|
|
@@ -41143,7 +41538,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41143
41538
|
printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
|
|
41144
41539
|
process.exit(2);
|
|
41145
41540
|
}
|
|
41146
|
-
if (!(0,
|
|
41541
|
+
if (!(0, import_node_fs72.existsSync)((0, import_node_path55.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41147
41542
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41148
41543
|
process.exit(2);
|
|
41149
41544
|
}
|
|
@@ -41174,7 +41569,7 @@ ${report.error ?? ""}`);
|
|
|
41174
41569
|
printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
|
|
41175
41570
|
return;
|
|
41176
41571
|
}
|
|
41177
|
-
const modelSource = readRegularFileInRoot(root, (0,
|
|
41572
|
+
const modelSource = readRegularFileInRoot(root, (0, import_node_path55.relative)(root, file), 512 * 1024);
|
|
41178
41573
|
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`);
|
|
41179
41574
|
const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
|
|
41180
41575
|
const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
|
|
@@ -41194,7 +41589,7 @@ ${report.error ?? ""}`);
|
|
|
41194
41589
|
});
|
|
41195
41590
|
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) => {
|
|
41196
41591
|
const root = repoRoot();
|
|
41197
|
-
let files = paths.map((p) => (0,
|
|
41592
|
+
let files = paths.map((p) => (0, import_node_path55.relative)(root, (0, import_node_path55.resolve)(p)));
|
|
41198
41593
|
if (files.length === 0) {
|
|
41199
41594
|
const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
|
|
41200
41595
|
const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
|
|
@@ -41223,7 +41618,19 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41223
41618
|
}
|
|
41224
41619
|
process.exit(outcome.findings.some((f) => f.verdict === "reproduced") ? 1 : 0);
|
|
41225
41620
|
});
|
|
41226
|
-
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) => {
|
|
41621
|
+
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) => {
|
|
41622
|
+
if (opts.hint === "-" && opts.note === "-") {
|
|
41623
|
+
printError("Only one of --hint and --note can read stdin (-).");
|
|
41624
|
+
process.exit(2);
|
|
41625
|
+
}
|
|
41626
|
+
for (const flag of ["hint", "note"]) {
|
|
41627
|
+
const input = readTextInput(opts[flag], `--${flag}`);
|
|
41628
|
+
if (!input.ok) {
|
|
41629
|
+
printError(input.error);
|
|
41630
|
+
process.exit(2);
|
|
41631
|
+
}
|
|
41632
|
+
opts[flag] = input.text;
|
|
41633
|
+
}
|
|
41227
41634
|
const root = repoRoot();
|
|
41228
41635
|
const auth2 = await proveAuth(program2);
|
|
41229
41636
|
if (!auth2 && !(process.env.VERITY_PROVE_DIRECT === "1" && process.env.OPENAI_API_KEY)) {
|
|
@@ -41254,9 +41661,9 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41254
41661
|
let revise;
|
|
41255
41662
|
if (opts.revise) {
|
|
41256
41663
|
const existing = resolveModelFile(root, opts.revise);
|
|
41257
|
-
const src = existing ? readRegularFileInRoot(root, (0,
|
|
41664
|
+
const src = existing ? readRegularFileInRoot(root, (0, import_node_path55.relative)(root, existing), 64 * 1024) : null;
|
|
41258
41665
|
if (!src || !src.ok || !opts.note) {
|
|
41259
|
-
printError(
|
|
41666
|
+
printError("--revise needs an existing model under Models/ and --note - with what the replay showed on stdin");
|
|
41260
41667
|
process.exit(2);
|
|
41261
41668
|
}
|
|
41262
41669
|
revise = { source: src.content, note: opts.note };
|
|
@@ -41293,8 +41700,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41293
41700
|
});
|
|
41294
41701
|
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) => {
|
|
41295
41702
|
const root = repoRoot();
|
|
41296
|
-
const rel0 = (0,
|
|
41297
|
-
const rel = rel0.startsWith("..") || (0,
|
|
41703
|
+
const rel0 = (0, import_node_path55.relative)(root, (0, import_node_path55.isAbsolute)(file) ? file : (0, import_node_path55.join)(root, file)).replace(/\\/g, "/");
|
|
41704
|
+
const rel = rel0.startsWith("..") || (0, import_node_path55.isAbsolute)(rel0) ? null : rel0;
|
|
41298
41705
|
if (!rel) {
|
|
41299
41706
|
printError(`${file} is not inside this repository`);
|
|
41300
41707
|
process.exit(2);
|
|
@@ -41310,8 +41717,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41310
41717
|
});
|
|
41311
41718
|
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) => {
|
|
41312
41719
|
const root = repoRoot();
|
|
41313
|
-
const rel = (0,
|
|
41314
|
-
const digest = rel.startsWith("..") || (0,
|
|
41720
|
+
const rel = (0, import_node_path55.relative)(root, (0, import_node_path55.isAbsolute)(file) ? file : (0, import_node_path55.join)(root, file));
|
|
41721
|
+
const digest = rel.startsWith("..") || (0, import_node_path55.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
|
|
41315
41722
|
if (!digest) {
|
|
41316
41723
|
printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
|
|
41317
41724
|
process.exit(2);
|
|
@@ -41345,10 +41752,10 @@ function refreshScaffold(root) {
|
|
|
41345
41752
|
}
|
|
41346
41753
|
|
|
41347
41754
|
// src/commands/lean.ts
|
|
41348
|
-
var
|
|
41755
|
+
var import_node_fs73 = require("node:fs");
|
|
41349
41756
|
var import_node_child_process20 = require("node:child_process");
|
|
41350
41757
|
var import_node_os11 = require("node:os");
|
|
41351
|
-
var
|
|
41758
|
+
var import_node_path56 = require("node:path");
|
|
41352
41759
|
function registerLeanCommand(program2) {
|
|
41353
41760
|
const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
|
|
41354
41761
|
lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
|
|
@@ -41365,7 +41772,7 @@ function registerLeanCommand(program2) {
|
|
|
41365
41772
|
const managed = pinnedVersionDir();
|
|
41366
41773
|
const matches = version ? version.includes(pin) : false;
|
|
41367
41774
|
if (opts.json) {
|
|
41368
|
-
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0,
|
|
41775
|
+
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs73.existsSync)((0, import_node_path56.join)(managed, "bin")), asset: leanAssetName() });
|
|
41369
41776
|
return;
|
|
41370
41777
|
}
|
|
41371
41778
|
printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
|
|
@@ -41383,7 +41790,7 @@ function registerLeanCommand(program2) {
|
|
|
41383
41790
|
process.exit(2);
|
|
41384
41791
|
}
|
|
41385
41792
|
const dir = pinnedVersionDir();
|
|
41386
|
-
if ((0,
|
|
41793
|
+
if ((0, import_node_fs73.existsSync)((0, import_node_path56.join)(dir, "bin", "lake")) && !opts.force) {
|
|
41387
41794
|
printInfo(`already installed at ${dir}`);
|
|
41388
41795
|
return;
|
|
41389
41796
|
}
|
|
@@ -41419,18 +41826,18 @@ function registerLeanCommand(program2) {
|
|
|
41419
41826
|
});
|
|
41420
41827
|
lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
|
|
41421
41828
|
const dir = pinnedVersionDir();
|
|
41422
|
-
if (!(0,
|
|
41829
|
+
if (!(0, import_node_fs73.existsSync)(dir)) {
|
|
41423
41830
|
printInfo("nothing to remove");
|
|
41424
41831
|
return;
|
|
41425
41832
|
}
|
|
41426
|
-
(0,
|
|
41833
|
+
(0, import_node_fs73.rmSync)(dir, { recursive: true, force: true });
|
|
41427
41834
|
printInfo(`removed ${dir}`);
|
|
41428
41835
|
});
|
|
41429
41836
|
}
|
|
41430
41837
|
|
|
41431
41838
|
// src/cli.ts
|
|
41432
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.
|
|
41433
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.
|
|
41839
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.53caba1").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) => {
|
|
41840
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.53caba1");
|
|
41434
41841
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
41435
41842
|
try {
|
|
41436
41843
|
await foldLegacyLocalCredential();
|