@codacy/verity-cli 0.34.0-experimental.afcb0e6 → 0.34.0-experimental.ba15b96
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 +0 -2
- package/bin/verity.js +597 -861
- package/data/skills/verity-analyze/SKILL.md +5 -17
- package/data/skills/verity-feedback/SKILL.md +3 -19
- package/data/skills/verity-learn/SKILL.md +7 -19
- package/data/skills/verity-memory/SKILL.md +8 -21
- package/data/skills/verity-prove/SKILL.md +9 -35
- package/data/skills/verity-reflect/SKILL.md +3 -16
- 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((resolve8, 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
|
+
resolve8(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((resolve8, reject) => {
|
|
10638
10638
|
Module["instantiateWasm"](info2, (mod, inst) => {
|
|
10639
|
-
|
|
10639
|
+
resolve8(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((resolve8, reject) => {
|
|
11973
|
+
readyPromiseResolve = resolve8;
|
|
11974
11974
|
readyPromiseReject = reject;
|
|
11975
11975
|
});
|
|
11976
11976
|
}
|
|
@@ -14447,87 +14447,8 @@ 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");
|
|
14455
14450
|
var import_node_fs = require("node:fs");
|
|
14456
|
-
var import_node_os = require("node:os");
|
|
14457
14451
|
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
|
|
14531
14452
|
var _repoRoot = null;
|
|
14532
14453
|
function repoRoot() {
|
|
14533
14454
|
if (_repoRoot === null) {
|
|
@@ -14555,36 +14476,17 @@ function mainWorktreeRoot() {
|
|
|
14555
14476
|
_mainRoot = null;
|
|
14556
14477
|
return _mainRoot;
|
|
14557
14478
|
}
|
|
14558
|
-
const abs = common.startsWith("/") ? common : (0,
|
|
14559
|
-
_mainRoot = (0,
|
|
14479
|
+
const abs = common.startsWith("/") ? common : (0, import_node_path.join)(repoRoot(), common);
|
|
14480
|
+
_mainRoot = (0, import_node_path.dirname)(abs);
|
|
14560
14481
|
} catch {
|
|
14561
14482
|
_mainRoot = null;
|
|
14562
14483
|
}
|
|
14563
14484
|
return _mainRoot;
|
|
14564
14485
|
}
|
|
14565
14486
|
function verityConfigured() {
|
|
14566
|
-
if (
|
|
14487
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(repoRoot(), VERITY_DIR))) return true;
|
|
14567
14488
|
const main = mainWorktreeRoot();
|
|
14568
|
-
return !!main &&
|
|
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
|
-
}
|
|
14489
|
+
return !!main && (0, import_node_fs.existsSync)((0, import_node_path.join)(main, VERITY_DIR));
|
|
14588
14490
|
}
|
|
14589
14491
|
var VERITY_DIR = ".verity";
|
|
14590
14492
|
var CREDENTIALS_FILE = `${VERITY_DIR}/credentials`;
|
|
@@ -14605,7 +14507,7 @@ var MEMORY_DIR = `${VERITY_DIR}/memory`;
|
|
|
14605
14507
|
var CODACY_CONFIG_FILE = ".codacy/codacy.config.json";
|
|
14606
14508
|
var VERITYIGNORE_FILE = ".verityignore";
|
|
14607
14509
|
function projectPath(relativePath) {
|
|
14608
|
-
return (0,
|
|
14510
|
+
return (0, import_node_path.join)(repoRoot(), relativePath);
|
|
14609
14511
|
}
|
|
14610
14512
|
var MAX_DELTA_BYTES = 194560;
|
|
14611
14513
|
var MAX_FILES = 40;
|
|
@@ -14779,7 +14681,7 @@ function printVerbose(msg, verbose) {
|
|
|
14779
14681
|
}
|
|
14780
14682
|
|
|
14781
14683
|
// src/lib/debug-log.ts
|
|
14782
|
-
var
|
|
14684
|
+
var import_node_fs2 = require("node:fs");
|
|
14783
14685
|
function isDebugEnabled() {
|
|
14784
14686
|
const v = process.env.VERITY_DEBUG;
|
|
14785
14687
|
if (v === "0" || v === "false" || v === "off") return false;
|
|
@@ -14797,24 +14699,24 @@ function writeLine(obj) {
|
|
|
14797
14699
|
try {
|
|
14798
14700
|
const dir = projectPath(DEBUG_LOG_DIR);
|
|
14799
14701
|
const file = projectPath(DEBUG_LOG_FILE);
|
|
14800
|
-
(0,
|
|
14702
|
+
(0, import_node_fs2.mkdirSync)(dir, { recursive: true });
|
|
14801
14703
|
rotateIfNeeded(file);
|
|
14802
|
-
(0,
|
|
14704
|
+
(0, import_node_fs2.appendFileSync)(file, JSON.stringify(obj) + "\n");
|
|
14803
14705
|
} catch {
|
|
14804
14706
|
}
|
|
14805
14707
|
}
|
|
14806
14708
|
function rotateIfNeeded(file) {
|
|
14807
14709
|
try {
|
|
14808
|
-
const s = (0,
|
|
14710
|
+
const s = (0, import_node_fs2.statSync)(file);
|
|
14809
14711
|
if (s.size < DEBUG_LOG_MAX_BYTES) return;
|
|
14810
|
-
(0,
|
|
14712
|
+
(0, import_node_fs2.renameSync)(file, `${file}.1`);
|
|
14811
14713
|
} catch {
|
|
14812
14714
|
}
|
|
14813
14715
|
}
|
|
14814
14716
|
|
|
14815
14717
|
// src/lib/credentials.ts
|
|
14816
14718
|
var import_promises = require("node:fs/promises");
|
|
14817
|
-
var
|
|
14719
|
+
var import_node_path2 = require("node:path");
|
|
14818
14720
|
var import_node_child_process2 = require("node:child_process");
|
|
14819
14721
|
function globalCredentialsPath() {
|
|
14820
14722
|
return `${process.env.HOME}/.verity/credentials`;
|
|
@@ -14889,7 +14791,7 @@ async function readGlobalCredential(remote) {
|
|
|
14889
14791
|
}
|
|
14890
14792
|
async function upsertGlobalCredential(remote, rec) {
|
|
14891
14793
|
const path = globalCredentialsPath();
|
|
14892
|
-
await (0, import_promises.mkdir)((0,
|
|
14794
|
+
await (0, import_promises.mkdir)((0, import_node_path2.dirname)(path), { recursive: true });
|
|
14893
14795
|
let content = "";
|
|
14894
14796
|
try {
|
|
14895
14797
|
content = await (0, import_promises.readFile)(path, "utf-8");
|
|
@@ -15033,10 +14935,10 @@ async function foldLegacyLocalCredential(remoteArg) {
|
|
|
15033
14935
|
|
|
15034
14936
|
// src/lib/git.ts
|
|
15035
14937
|
var import_node_child_process3 = require("node:child_process");
|
|
15036
|
-
var
|
|
15037
|
-
var
|
|
14938
|
+
var import_node_fs3 = require("node:fs");
|
|
14939
|
+
var import_node_path3 = require("node:path");
|
|
15038
14940
|
function resolveFile(relpath) {
|
|
15039
|
-
return (0,
|
|
14941
|
+
return (0, import_node_fs3.existsSync)(relpath) ? relpath : null;
|
|
15040
14942
|
}
|
|
15041
14943
|
function execGit(cmd) {
|
|
15042
14944
|
try {
|
|
@@ -15054,7 +14956,7 @@ function readBaselineSha() {
|
|
|
15054
14956
|
if (sha === null) return null;
|
|
15055
14957
|
if (!commitResolves(sha)) {
|
|
15056
14958
|
try {
|
|
15057
|
-
(0,
|
|
14959
|
+
(0, import_node_fs3.unlinkSync)(BASELINE_SHA_FILE);
|
|
15058
14960
|
} catch {
|
|
15059
14961
|
}
|
|
15060
14962
|
return null;
|
|
@@ -15062,10 +14964,10 @@ function readBaselineSha() {
|
|
|
15062
14964
|
return sha;
|
|
15063
14965
|
}
|
|
15064
14966
|
function readRawBaselineSha() {
|
|
15065
|
-
if (!(0,
|
|
14967
|
+
if (!(0, import_node_fs3.existsSync)(BASELINE_SHA_FILE)) return null;
|
|
15066
14968
|
let sha;
|
|
15067
14969
|
try {
|
|
15068
|
-
sha = (0,
|
|
14970
|
+
sha = (0, import_node_fs3.readFileSync)(BASELINE_SHA_FILE, "utf-8").trim();
|
|
15069
14971
|
} catch {
|
|
15070
14972
|
return null;
|
|
15071
14973
|
}
|
|
@@ -15074,8 +14976,8 @@ function readRawBaselineSha() {
|
|
|
15074
14976
|
function writeBaselineSha(sha) {
|
|
15075
14977
|
if (!SHA_RE.test(sha)) return;
|
|
15076
14978
|
try {
|
|
15077
|
-
(0,
|
|
15078
|
-
(0,
|
|
14979
|
+
(0, import_node_fs3.mkdirSync)((0, import_node_path3.dirname)(BASELINE_SHA_FILE), { recursive: true });
|
|
14980
|
+
(0, import_node_fs3.writeFileSync)(BASELINE_SHA_FILE, sha);
|
|
15079
14981
|
} catch {
|
|
15080
14982
|
}
|
|
15081
14983
|
}
|
|
@@ -15163,17 +15065,17 @@ function showContentAtRef(ref, repoRelPath) {
|
|
|
15163
15065
|
}
|
|
15164
15066
|
function filterAnalyzable(files) {
|
|
15165
15067
|
return files.filter((f) => {
|
|
15166
|
-
const ext = (0,
|
|
15068
|
+
const ext = (0, import_node_path3.extname)(f).slice(1);
|
|
15167
15069
|
return ANALYZABLE_EXTENSIONS.has(ext);
|
|
15168
15070
|
});
|
|
15169
15071
|
}
|
|
15170
15072
|
function filterReviewable(files) {
|
|
15171
15073
|
return files.filter((f) => {
|
|
15172
|
-
const ext = (0,
|
|
15074
|
+
const ext = (0, import_node_path3.extname)(f).slice(1);
|
|
15173
15075
|
if (ANALYZABLE_EXTENSIONS.has(ext)) return false;
|
|
15174
15076
|
if (REVIEWABLE_EXTENSIONS.has(ext)) return true;
|
|
15175
|
-
const
|
|
15176
|
-
if (REVIEWABLE_FILENAMES.has(
|
|
15077
|
+
const basename8 = f.split("/").pop() ?? "";
|
|
15078
|
+
if (REVIEWABLE_FILENAMES.has(basename8)) return true;
|
|
15177
15079
|
if (REVIEWABLE_PATH_PATTERNS.some((p) => p.test(f))) return true;
|
|
15178
15080
|
return false;
|
|
15179
15081
|
});
|
|
@@ -15648,7 +15550,7 @@ async function maybeHealServiceUrl(resolution, verbose) {
|
|
|
15648
15550
|
|
|
15649
15551
|
// src/lib/register.ts
|
|
15650
15552
|
var readline = __toESM2(require("node:readline/promises"));
|
|
15651
|
-
var
|
|
15553
|
+
var import_node_os = require("node:os");
|
|
15652
15554
|
|
|
15653
15555
|
// src/lib/spinner.ts
|
|
15654
15556
|
var FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
@@ -15736,7 +15638,7 @@ function startSpinner(label2, opts = {}) {
|
|
|
15736
15638
|
}
|
|
15737
15639
|
|
|
15738
15640
|
// src/lib/provider-auth.ts
|
|
15739
|
-
var sleep = (ms) => new Promise((
|
|
15641
|
+
var sleep = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
15740
15642
|
var form = (fields) => new URLSearchParams(fields).toString();
|
|
15741
15643
|
async function githubAccountId(owner) {
|
|
15742
15644
|
try {
|
|
@@ -16001,7 +15903,7 @@ function deviceLabel() {
|
|
|
16001
15903
|
const override = process.env.VERITY_DEVICE_LABEL?.trim();
|
|
16002
15904
|
if (override) return override;
|
|
16003
15905
|
try {
|
|
16004
|
-
return (0,
|
|
15906
|
+
return (0, import_node_os.hostname)() || void 0;
|
|
16005
15907
|
} catch {
|
|
16006
15908
|
return void 0;
|
|
16007
15909
|
}
|
|
@@ -16159,8 +16061,8 @@ function registerAuthCommands(program2) {
|
|
|
16159
16061
|
}
|
|
16160
16062
|
|
|
16161
16063
|
// src/lib/pending-login.ts
|
|
16162
|
-
var
|
|
16163
|
-
var
|
|
16064
|
+
var import_node_fs4 = require("node:fs");
|
|
16065
|
+
var import_node_path4 = require("node:path");
|
|
16164
16066
|
function pendingLoginPath() {
|
|
16165
16067
|
return `${process.env.HOME}/.verity/pending-login.json`;
|
|
16166
16068
|
}
|
|
@@ -16176,26 +16078,26 @@ function savePendingLogin(dc, serviceUrl, now = Date.now()) {
|
|
|
16176
16078
|
created_at: new Date(now).toISOString()
|
|
16177
16079
|
};
|
|
16178
16080
|
const path = pendingLoginPath();
|
|
16179
|
-
(0,
|
|
16081
|
+
(0, import_node_fs4.mkdirSync)((0, import_node_path4.dirname)(path), { recursive: true });
|
|
16180
16082
|
clearPendingLogin();
|
|
16181
|
-
(0,
|
|
16083
|
+
(0, import_node_fs4.writeFileSync)(path, JSON.stringify(record, null, 2) + "\n", { mode: 384, flag: "wx" });
|
|
16182
16084
|
try {
|
|
16183
|
-
(0,
|
|
16085
|
+
(0, import_node_fs4.chmodSync)(path, 384);
|
|
16184
16086
|
} catch {
|
|
16185
16087
|
}
|
|
16186
16088
|
return record;
|
|
16187
16089
|
}
|
|
16188
16090
|
function readPendingLogin(now = Date.now()) {
|
|
16189
16091
|
const path = pendingLoginPath();
|
|
16190
|
-
if (!(0,
|
|
16092
|
+
if (!(0, import_node_fs4.existsSync)(path)) return { status: "none" };
|
|
16191
16093
|
try {
|
|
16192
|
-
if ((0,
|
|
16094
|
+
if ((0, import_node_fs4.lstatSync)(path).isSymbolicLink()) return { status: "invalid", reason: "it is a symlink" };
|
|
16193
16095
|
} catch {
|
|
16194
16096
|
return { status: "none" };
|
|
16195
16097
|
}
|
|
16196
16098
|
let parsed;
|
|
16197
16099
|
try {
|
|
16198
|
-
parsed = JSON.parse((0,
|
|
16100
|
+
parsed = JSON.parse((0, import_node_fs4.readFileSync)(path, "utf-8"));
|
|
16199
16101
|
} catch {
|
|
16200
16102
|
return { status: "invalid", reason: "it is not valid JSON" };
|
|
16201
16103
|
}
|
|
@@ -16216,7 +16118,7 @@ function readPendingLogin(now = Date.now()) {
|
|
|
16216
16118
|
}
|
|
16217
16119
|
function clearPendingLogin() {
|
|
16218
16120
|
try {
|
|
16219
|
-
(0,
|
|
16121
|
+
(0, import_node_fs4.unlinkSync)(pendingLoginPath());
|
|
16220
16122
|
return true;
|
|
16221
16123
|
} catch {
|
|
16222
16124
|
return false;
|
|
@@ -16772,11 +16674,11 @@ function registerLogoutCommand(program2) {
|
|
|
16772
16674
|
|
|
16773
16675
|
// src/lib/hooks.ts
|
|
16774
16676
|
var import_promises4 = require("node:fs/promises");
|
|
16775
|
-
var
|
|
16677
|
+
var import_node_path6 = require("node:path");
|
|
16776
16678
|
|
|
16777
16679
|
// src/lib/json-file.ts
|
|
16778
16680
|
var import_promises3 = require("node:fs/promises");
|
|
16779
|
-
var
|
|
16681
|
+
var import_node_path5 = require("node:path");
|
|
16780
16682
|
function jsonSemanticEqual(a, b) {
|
|
16781
16683
|
if (a === b) return true;
|
|
16782
16684
|
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
|
|
@@ -16822,7 +16724,7 @@ async function writeJsonFilePreservingStyle(file, value) {
|
|
|
16822
16724
|
const indent = currentRaw !== null ? detectJsonIndent(currentRaw) : 2;
|
|
16823
16725
|
const next = JSON.stringify(value, null, indent) + "\n";
|
|
16824
16726
|
if (next === currentRaw) return false;
|
|
16825
|
-
await (0, import_promises3.mkdir)((0,
|
|
16727
|
+
await (0, import_promises3.mkdir)((0, import_node_path5.dirname)(file), { recursive: true });
|
|
16826
16728
|
await (0, import_promises3.writeFile)(file, next);
|
|
16827
16729
|
return true;
|
|
16828
16730
|
}
|
|
@@ -17007,13 +16909,13 @@ async function writeSettings(settings) {
|
|
|
17007
16909
|
}
|
|
17008
16910
|
async function readSettingsAt(root) {
|
|
17009
16911
|
try {
|
|
17010
|
-
return JSON.parse(await (0, import_promises4.readFile)((0,
|
|
16912
|
+
return JSON.parse(await (0, import_promises4.readFile)((0, import_node_path6.join)(root, CLAUDE_SETTINGS_FILE), "utf-8"));
|
|
17011
16913
|
} catch {
|
|
17012
16914
|
return {};
|
|
17013
16915
|
}
|
|
17014
16916
|
}
|
|
17015
16917
|
async function writeSettingsAt(root, settings) {
|
|
17016
|
-
await writeJsonFilePreservingStyle((0,
|
|
16918
|
+
await writeJsonFilePreservingStyle((0, import_node_path6.join)(root, CLAUDE_SETTINGS_FILE), settings);
|
|
17017
16919
|
}
|
|
17018
16920
|
async function hasLegacyHooksAt(root) {
|
|
17019
16921
|
const settings = await readSettingsAt(root);
|
|
@@ -17202,13 +17104,13 @@ async function applyMomentSelection(moments) {
|
|
|
17202
17104
|
}
|
|
17203
17105
|
|
|
17204
17106
|
// src/lib/project-config.ts
|
|
17205
|
-
var import_node_fs7 = require("node:fs");
|
|
17206
|
-
var import_node_path9 = require("node:path");
|
|
17207
|
-
|
|
17208
|
-
// src/lib/repo-controlled.ts
|
|
17209
17107
|
var import_node_fs6 = require("node:fs");
|
|
17210
17108
|
var import_node_path8 = require("node:path");
|
|
17211
17109
|
|
|
17110
|
+
// src/lib/repo-controlled.ts
|
|
17111
|
+
var import_node_fs5 = require("node:fs");
|
|
17112
|
+
var import_node_path7 = require("node:path");
|
|
17113
|
+
|
|
17212
17114
|
// src/lib/hardened-git.ts
|
|
17213
17115
|
var import_node_child_process5 = require("node:child_process");
|
|
17214
17116
|
var HARDENED_CONFIG_ARGS = [
|
|
@@ -17288,7 +17190,7 @@ function repoControlled(worktree, rel) {
|
|
|
17288
17190
|
for (let i2 = 1; i2 <= parts2.length; i2++) {
|
|
17289
17191
|
let st;
|
|
17290
17192
|
try {
|
|
17291
|
-
st = (0,
|
|
17193
|
+
st = (0, import_node_fs5.lstatSync)((0, import_node_path7.join)(worktree, ...parts2.slice(0, i2)));
|
|
17292
17194
|
} catch (err2) {
|
|
17293
17195
|
const code = err2?.code;
|
|
17294
17196
|
if (code === "ENOENT" || code === "ENOTDIR") return null;
|
|
@@ -17312,8 +17214,8 @@ function parseMoments(raw) {
|
|
|
17312
17214
|
}
|
|
17313
17215
|
function readConfigFile(path) {
|
|
17314
17216
|
try {
|
|
17315
|
-
if (!(0,
|
|
17316
|
-
const raw = JSON.parse((0,
|
|
17217
|
+
if (!(0, import_node_fs6.existsSync)(path)) return null;
|
|
17218
|
+
const raw = JSON.parse((0, import_node_fs6.readFileSync)(path, "utf-8"));
|
|
17317
17219
|
const moments = Array.isArray(raw.git_moments) ? raw.git_moments.filter(isMoment) : [];
|
|
17318
17220
|
const source2 = raw.git_moments_source === "user" || raw.git_moments_source === "init" ? raw.git_moments_source : void 0;
|
|
17319
17221
|
return {
|
|
@@ -17330,13 +17232,13 @@ function candidates() {
|
|
|
17330
17232
|
const out2 = [{ path: local, source: "local" }];
|
|
17331
17233
|
const main = mainWorktreeRoot();
|
|
17332
17234
|
if (main) {
|
|
17333
|
-
const inherited = (0,
|
|
17235
|
+
const inherited = (0, import_node_path8.join)(main, PROJECT_CONFIG_FILE);
|
|
17334
17236
|
if (inherited !== local) out2.push({ path: inherited, source: "main-worktree" });
|
|
17335
17237
|
}
|
|
17336
17238
|
return out2;
|
|
17337
17239
|
}
|
|
17338
17240
|
function formalRefusal(path) {
|
|
17339
|
-
return repoControlled((0,
|
|
17241
|
+
return repoControlled((0, import_node_path8.dirname)((0, import_node_path8.dirname)(path)), PROJECT_CONFIG_FILE);
|
|
17340
17242
|
}
|
|
17341
17243
|
function readProjectConfigRaw() {
|
|
17342
17244
|
for (const { path, source: source2 } of candidates()) {
|
|
@@ -17372,8 +17274,8 @@ function writeProjectConfig(patch) {
|
|
|
17372
17274
|
...patch
|
|
17373
17275
|
};
|
|
17374
17276
|
const target = projectPath(PROJECT_CONFIG_FILE);
|
|
17375
|
-
(0,
|
|
17376
|
-
(0,
|
|
17277
|
+
(0, import_node_fs6.mkdirSync)((0, import_node_path8.dirname)(target), { recursive: true });
|
|
17278
|
+
(0, import_node_fs6.writeFileSync)(target, JSON.stringify(next, null, 2) + "\n");
|
|
17377
17279
|
return next;
|
|
17378
17280
|
}
|
|
17379
17281
|
function resolveGuardMoments(explicit) {
|
|
@@ -17382,11 +17284,11 @@ function resolveGuardMoments(explicit) {
|
|
|
17382
17284
|
}
|
|
17383
17285
|
|
|
17384
17286
|
// src/lib/plugin-ownership.ts
|
|
17385
|
-
var
|
|
17287
|
+
var import_node_fs9 = require("node:fs");
|
|
17386
17288
|
|
|
17387
17289
|
// src/lib/which.ts
|
|
17388
|
-
var
|
|
17389
|
-
var
|
|
17290
|
+
var import_node_fs7 = require("node:fs");
|
|
17291
|
+
var import_node_path9 = require("node:path");
|
|
17390
17292
|
function executableExtensions(platform4, pathext) {
|
|
17391
17293
|
if (platform4 !== "win32") return [""];
|
|
17392
17294
|
const raw = (pathext ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean);
|
|
@@ -17404,14 +17306,14 @@ function whichSync(bin, opts = {}) {
|
|
|
17404
17306
|
if (!rawPath) return null;
|
|
17405
17307
|
const exts = executableExtensions(platform4, opts.pathext ?? process.env.PATHEXT);
|
|
17406
17308
|
const real = opts.real ?? true;
|
|
17407
|
-
for (const dir of rawPath.split(
|
|
17309
|
+
for (const dir of rawPath.split(import_node_path9.delimiter)) {
|
|
17408
17310
|
if (!dir) continue;
|
|
17409
17311
|
for (const ext of exts) {
|
|
17410
|
-
const candidate = (0,
|
|
17312
|
+
const candidate = (0, import_node_path9.join)(dir, bin + ext);
|
|
17411
17313
|
try {
|
|
17412
|
-
if (!(0,
|
|
17413
|
-
if (platform4 !== "win32") (0,
|
|
17414
|
-
return real ? (0,
|
|
17314
|
+
if (!(0, import_node_fs7.statSync)(candidate).isFile()) continue;
|
|
17315
|
+
if (platform4 !== "win32") (0, import_node_fs7.accessSync)(candidate, import_node_fs7.constants.X_OK);
|
|
17316
|
+
return real ? (0, import_node_fs7.realpathSync)(candidate) : candidate;
|
|
17415
17317
|
} catch {
|
|
17416
17318
|
continue;
|
|
17417
17319
|
}
|
|
@@ -17421,11 +17323,11 @@ function whichSync(bin, opts = {}) {
|
|
|
17421
17323
|
}
|
|
17422
17324
|
|
|
17423
17325
|
// src/lib/plugin-ownership.ts
|
|
17424
|
-
var
|
|
17425
|
-
var
|
|
17326
|
+
var import_node_os2 = require("node:os");
|
|
17327
|
+
var import_node_path10 = require("node:path");
|
|
17426
17328
|
|
|
17427
17329
|
// src/lib/stderr-log.ts
|
|
17428
|
-
var
|
|
17330
|
+
var import_node_fs8 = require("node:fs");
|
|
17429
17331
|
var TOKEN_RE2 = /verity_[0-9a-f]{16,}/g;
|
|
17430
17332
|
var ANSI_RE = /\u001b\[[0-?]*[ -/]*[@-~]/g;
|
|
17431
17333
|
function scrub(s) {
|
|
@@ -17438,9 +17340,9 @@ function append(text) {
|
|
|
17438
17340
|
try {
|
|
17439
17341
|
const dir = projectPath(DEBUG_LOG_DIR);
|
|
17440
17342
|
const file = projectPath(STDERR_LOG_FILE);
|
|
17441
|
-
(0,
|
|
17343
|
+
(0, import_node_fs8.mkdirSync)(dir, { recursive: true });
|
|
17442
17344
|
rotateIfNeeded(file);
|
|
17443
|
-
(0,
|
|
17345
|
+
(0, import_node_fs8.appendFileSync)(file, text);
|
|
17444
17346
|
} catch {
|
|
17445
17347
|
}
|
|
17446
17348
|
}
|
|
@@ -17488,8 +17390,8 @@ function markerPath() {
|
|
|
17488
17390
|
}
|
|
17489
17391
|
function readMarker() {
|
|
17490
17392
|
try {
|
|
17491
|
-
if (!(0,
|
|
17492
|
-
const raw = JSON.parse((0,
|
|
17393
|
+
if (!(0, import_node_fs9.existsSync)(markerPath())) return null;
|
|
17394
|
+
const raw = JSON.parse((0, import_node_fs9.readFileSync)(markerPath(), "utf-8"));
|
|
17493
17395
|
const pluginRoot = typeof raw.plugin_root === "string" ? raw.plugin_root : "";
|
|
17494
17396
|
if (!pluginRoot || CONTROL_CHARS2.test(pluginRoot)) return null;
|
|
17495
17397
|
const version = typeof raw.version === "string" && !CONTROL_CHARS2.test(raw.version) ? raw.version : null;
|
|
@@ -17507,23 +17409,23 @@ function recordPluginOwnership(sessionId) {
|
|
|
17507
17409
|
const pluginRoot = process.env.VERITY_PLUGIN_ROOT;
|
|
17508
17410
|
if (!pluginRoot) return;
|
|
17509
17411
|
try {
|
|
17510
|
-
(0,
|
|
17412
|
+
(0, import_node_fs9.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
|
|
17511
17413
|
const marker = {
|
|
17512
17414
|
session_id: sessionId,
|
|
17513
17415
|
plugin_root: pluginRoot,
|
|
17514
17416
|
version: process.env.VERITY_PLUGIN_VERSION || null,
|
|
17515
17417
|
ts: Math.floor(Date.now() / 1e3)
|
|
17516
17418
|
};
|
|
17517
|
-
(0,
|
|
17419
|
+
(0, import_node_fs9.writeFileSync)(markerPath(), JSON.stringify(marker));
|
|
17518
17420
|
} catch {
|
|
17519
17421
|
}
|
|
17520
17422
|
}
|
|
17521
17423
|
function claudeConfigDir() {
|
|
17522
|
-
return process.env.CLAUDE_CONFIG_DIR || (0,
|
|
17424
|
+
return process.env.CLAUDE_CONFIG_DIR || (0, import_node_path10.join)((0, import_node_os2.homedir)(), ".claude");
|
|
17523
17425
|
}
|
|
17524
17426
|
function readJsonFile(path) {
|
|
17525
17427
|
try {
|
|
17526
|
-
const parsed = JSON.parse((0,
|
|
17428
|
+
const parsed = JSON.parse((0, import_node_fs9.readFileSync)(path, "utf-8"));
|
|
17527
17429
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
17528
17430
|
} catch {
|
|
17529
17431
|
return null;
|
|
@@ -17531,9 +17433,9 @@ function readJsonFile(path) {
|
|
|
17531
17433
|
}
|
|
17532
17434
|
function enabledPluginSetting(key) {
|
|
17533
17435
|
const files = [
|
|
17534
|
-
projectPath((0,
|
|
17535
|
-
projectPath((0,
|
|
17536
|
-
(0,
|
|
17436
|
+
projectPath((0, import_node_path10.join)(".claude", "settings.local.json")),
|
|
17437
|
+
projectPath((0, import_node_path10.join)(".claude", "settings.json")),
|
|
17438
|
+
(0, import_node_path10.join)(claudeConfigDir(), "settings.json")
|
|
17537
17439
|
];
|
|
17538
17440
|
for (const file of files) {
|
|
17539
17441
|
const map = readJsonFile(file)?.enabledPlugins;
|
|
@@ -17545,11 +17447,11 @@ function enabledPluginSetting(key) {
|
|
|
17545
17447
|
}
|
|
17546
17448
|
function marketplaceLocations() {
|
|
17547
17449
|
const out2 = /* @__PURE__ */ new Map();
|
|
17548
|
-
const known = readJsonFile((0,
|
|
17450
|
+
const known = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
|
|
17549
17451
|
if (!known) return out2;
|
|
17550
17452
|
for (const [name2, entry] of Object.entries(known)) {
|
|
17551
17453
|
const loc2 = entry?.installLocation;
|
|
17552
|
-
if (typeof loc2 === "string" && loc2) out2.set(name2, (0,
|
|
17454
|
+
if (typeof loc2 === "string" && loc2) out2.set(name2, (0, import_node_path10.resolve)(loc2));
|
|
17553
17455
|
}
|
|
17554
17456
|
return out2;
|
|
17555
17457
|
}
|
|
@@ -17563,7 +17465,7 @@ function globalVerityVersion() {
|
|
|
17563
17465
|
const entry = verityPathEntry();
|
|
17564
17466
|
if (!entry) return null;
|
|
17565
17467
|
try {
|
|
17566
|
-
const pkg = readJsonFile((0,
|
|
17468
|
+
const pkg = readJsonFile((0, import_node_path10.join)((0, import_node_path10.dirname)((0, import_node_fs9.realpathSync)(entry)), "..", "package.json"));
|
|
17567
17469
|
if (pkg?.name !== "@codacy/verity-cli" || typeof pkg.version !== "string") return null;
|
|
17568
17470
|
return pkg.version;
|
|
17569
17471
|
} catch {
|
|
@@ -17580,7 +17482,7 @@ var VERITY_MARKETPLACE_REPO = "codacy/verity";
|
|
|
17580
17482
|
function marketplaceConflict() {
|
|
17581
17483
|
const wanted = VERITY_MARKETPLACE;
|
|
17582
17484
|
for (const file of ["settings.json", "settings.local.json"]) {
|
|
17583
|
-
const path = (0,
|
|
17485
|
+
const path = (0, import_node_path10.join)(claudeConfigDir(), file);
|
|
17584
17486
|
const declared = readJsonFile(path)?.extraKnownMarketplaces ?? null;
|
|
17585
17487
|
const entry2 = declared && typeof declared === "object" ? declared[wanted] : void 0;
|
|
17586
17488
|
if (entry2 && typeof entry2 === "object") {
|
|
@@ -17590,7 +17492,7 @@ function marketplaceConflict() {
|
|
|
17590
17492
|
}
|
|
17591
17493
|
}
|
|
17592
17494
|
}
|
|
17593
|
-
const known = readJsonFile((0,
|
|
17495
|
+
const known = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
|
|
17594
17496
|
const entry = known?.[wanted];
|
|
17595
17497
|
if (entry && typeof entry === "object" && !pointsAtVerity(entry.source)) {
|
|
17596
17498
|
return { name: wanted, declaredAs: describeSource(entry.source) };
|
|
@@ -17611,7 +17513,7 @@ function describeSource(src) {
|
|
|
17611
17513
|
return target ? `${kind} \u2192 ${target}` : kind;
|
|
17612
17514
|
}
|
|
17613
17515
|
function legacyMarketplaceInstall() {
|
|
17614
|
-
const plugins = readJsonFile((0,
|
|
17516
|
+
const plugins = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17615
17517
|
if (!plugins || typeof plugins !== "object") return null;
|
|
17616
17518
|
for (const key of Object.keys(plugins)) {
|
|
17617
17519
|
const at = key.lastIndexOf("@");
|
|
@@ -17623,13 +17525,13 @@ function legacyMarketplaceInstall() {
|
|
|
17623
17525
|
}
|
|
17624
17526
|
function realpathOr(p) {
|
|
17625
17527
|
try {
|
|
17626
|
-
return
|
|
17528
|
+
return import_node_fs9.realpathSync.native(p);
|
|
17627
17529
|
} catch {
|
|
17628
|
-
return (0,
|
|
17530
|
+
return (0, import_node_path10.resolve)(p);
|
|
17629
17531
|
}
|
|
17630
17532
|
}
|
|
17631
17533
|
function isWithin(want, dir) {
|
|
17632
|
-
return want === dir || want.startsWith(dir +
|
|
17534
|
+
return want === dir || want.startsWith(dir + import_node_path10.sep);
|
|
17633
17535
|
}
|
|
17634
17536
|
function entryAppliesHere(entry, here) {
|
|
17635
17537
|
const e = entry;
|
|
@@ -17639,9 +17541,9 @@ function entryAppliesHere(entry, here) {
|
|
|
17639
17541
|
return forProject === here;
|
|
17640
17542
|
}
|
|
17641
17543
|
function registrySays(pluginRoot) {
|
|
17642
|
-
const plugins = readJsonFile((0,
|
|
17544
|
+
const plugins = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17643
17545
|
if (!plugins || typeof plugins !== "object") return "unverified";
|
|
17644
|
-
const want = (0,
|
|
17546
|
+
const want = (0, import_node_path10.resolve)(pluginRoot);
|
|
17645
17547
|
const here = realpathOr(repoRoot());
|
|
17646
17548
|
const markets = marketplaceLocations();
|
|
17647
17549
|
for (const [key, value] of Object.entries(plugins)) {
|
|
@@ -17650,15 +17552,15 @@ function registrySays(pluginRoot) {
|
|
|
17650
17552
|
const applicable = (Array.isArray(value) ? value : []).filter((entry) => entryAppliesHere(entry, here));
|
|
17651
17553
|
const claims = applicable.some((entry) => {
|
|
17652
17554
|
const installPath = entry?.installPath;
|
|
17653
|
-
return typeof installPath === "string" && (0,
|
|
17555
|
+
return typeof installPath === "string" && (0, import_node_path10.resolve)(installPath) === want;
|
|
17654
17556
|
}) || source2 !== void 0 && applicable.length > 0 && isWithin(want, source2);
|
|
17655
17557
|
if (claims) {
|
|
17656
17558
|
if (enabledPluginSetting(key) === false) return "gone";
|
|
17657
|
-
return (0,
|
|
17559
|
+
return (0, import_node_fs9.existsSync)(pluginRoot) ? "live" : "gone";
|
|
17658
17560
|
}
|
|
17659
17561
|
}
|
|
17660
|
-
const managed = (0,
|
|
17661
|
-
return want === managed || want.startsWith(managed +
|
|
17562
|
+
const managed = (0, import_node_path10.resolve)((0, import_node_path10.join)(claudeConfigDir(), "plugins", "cache"));
|
|
17563
|
+
return want === managed || want.startsWith(managed + import_node_path10.sep) ? "gone" : "unverified";
|
|
17662
17564
|
}
|
|
17663
17565
|
var _live = /* @__PURE__ */ new Map();
|
|
17664
17566
|
function pluginLiveness(pluginRoot) {
|
|
@@ -17672,7 +17574,7 @@ function clearStalePluginMarker() {
|
|
|
17672
17574
|
const marker = readMarker();
|
|
17673
17575
|
if (!marker || pluginLiveness(marker.plugin_root) !== "gone") return null;
|
|
17674
17576
|
try {
|
|
17675
|
-
(0,
|
|
17577
|
+
(0, import_node_fs9.rmSync)(markerPath(), { force: true });
|
|
17676
17578
|
} catch {
|
|
17677
17579
|
return null;
|
|
17678
17580
|
}
|
|
@@ -17700,7 +17602,7 @@ function pluginActiveHere() {
|
|
|
17700
17602
|
return activePluginInstall() !== null;
|
|
17701
17603
|
}
|
|
17702
17604
|
function registeredVerityPlugin() {
|
|
17703
|
-
const plugins = readJsonFile((0,
|
|
17605
|
+
const plugins = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17704
17606
|
if (!plugins || typeof plugins !== "object") return null;
|
|
17705
17607
|
const here = realpathOr(repoRoot());
|
|
17706
17608
|
for (const [key, value] of Object.entries(plugins)) {
|
|
@@ -17710,7 +17612,7 @@ function registeredVerityPlugin() {
|
|
|
17710
17612
|
for (const entry of Array.isArray(value) ? value : []) {
|
|
17711
17613
|
const e = entry;
|
|
17712
17614
|
const installPath = typeof e.installPath === "string" ? e.installPath : "";
|
|
17713
|
-
if (!installPath || !(0,
|
|
17615
|
+
if (!installPath || !(0, import_node_fs9.existsSync)(installPath)) continue;
|
|
17714
17616
|
if (!entryAppliesHere(entry, here)) continue;
|
|
17715
17617
|
return { pluginRoot: installPath, version: typeof e.version === "string" ? e.version : null };
|
|
17716
17618
|
}
|
|
@@ -17762,28 +17664,28 @@ async function resolveHookWiring() {
|
|
|
17762
17664
|
}
|
|
17763
17665
|
|
|
17764
17666
|
// src/lib/cli-provenance.ts
|
|
17765
|
-
var
|
|
17766
|
-
var
|
|
17767
|
-
var
|
|
17667
|
+
var import_node_fs10 = require("node:fs");
|
|
17668
|
+
var import_node_os3 = require("node:os");
|
|
17669
|
+
var import_node_path11 = require("node:path");
|
|
17768
17670
|
var CLI_PACKAGE = "@codacy/verity-cli";
|
|
17769
|
-
var CLI_ENTRY = (0,
|
|
17671
|
+
var CLI_ENTRY = (0, import_node_path11.join)("node_modules", CLI_PACKAGE, "bin", "verity.js");
|
|
17770
17672
|
function readJson(path) {
|
|
17771
17673
|
try {
|
|
17772
|
-
const parsed = JSON.parse((0,
|
|
17674
|
+
const parsed = JSON.parse((0, import_node_fs10.readFileSync)(path, "utf-8"));
|
|
17773
17675
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
17774
17676
|
} catch {
|
|
17775
17677
|
return null;
|
|
17776
17678
|
}
|
|
17777
17679
|
}
|
|
17778
17680
|
function versionUnder(base) {
|
|
17779
|
-
const entry = (0,
|
|
17780
|
-
if (!(0,
|
|
17781
|
-
const pkg = readJson((0,
|
|
17681
|
+
const entry = (0, import_node_path11.join)(base, CLI_ENTRY);
|
|
17682
|
+
if (!(0, import_node_fs10.existsSync)(entry)) return null;
|
|
17683
|
+
const pkg = readJson((0, import_node_path11.join)(base, "node_modules", CLI_PACKAGE, "package.json"));
|
|
17782
17684
|
return typeof pkg?.version === "string" ? pkg.version : null;
|
|
17783
17685
|
}
|
|
17784
17686
|
function versionForEntry(entry) {
|
|
17785
17687
|
try {
|
|
17786
|
-
const pkg = readJson((0,
|
|
17688
|
+
const pkg = readJson((0, import_node_path11.join)((0, import_node_path11.dirname)((0, import_node_fs10.realpathSync)(entry)), "..", "package.json"));
|
|
17787
17689
|
return typeof pkg?.version === "string" ? pkg.version : null;
|
|
17788
17690
|
} catch {
|
|
17789
17691
|
return null;
|
|
@@ -17791,16 +17693,16 @@ function versionForEntry(entry) {
|
|
|
17791
17693
|
}
|
|
17792
17694
|
function resolveHooksCli(pluginRoot) {
|
|
17793
17695
|
const override = process.env.VERITY_CLI_PATH;
|
|
17794
|
-
if (override && (0,
|
|
17696
|
+
if (override && (0, import_node_fs10.existsSync)(override)) {
|
|
17795
17697
|
return { version: versionForEntry(override), rung: "override" };
|
|
17796
17698
|
}
|
|
17797
17699
|
const fromPlugin = versionUnder(pluginRoot);
|
|
17798
17700
|
if (fromPlugin !== null) return { version: fromPlugin, rung: "plugin" };
|
|
17799
|
-
if ((0,
|
|
17800
|
-
const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0,
|
|
17701
|
+
if ((0, import_node_fs10.existsSync)((0, import_node_path11.join)(pluginRoot, CLI_ENTRY))) return { version: null, rung: "plugin" };
|
|
17702
|
+
const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0, import_node_path11.join)((0, import_node_os3.homedir)(), ".verity", "plugin-cli");
|
|
17801
17703
|
const fromData = versionUnder(dataDir);
|
|
17802
17704
|
if (fromData !== null) return { version: fromData, rung: "plugin-data" };
|
|
17803
|
-
if ((0,
|
|
17705
|
+
if ((0, import_node_fs10.existsSync)((0, import_node_path11.join)(dataDir, CLI_ENTRY))) return { version: null, rung: "plugin-data" };
|
|
17804
17706
|
const global = globalVerityVersion();
|
|
17805
17707
|
if (global !== null) return { version: global, rung: "global" };
|
|
17806
17708
|
return null;
|
|
@@ -17902,7 +17804,7 @@ function pluginCliInvocation() {
|
|
|
17902
17804
|
return resolverCommand(root);
|
|
17903
17805
|
}
|
|
17904
17806
|
function resolverCommand(root) {
|
|
17905
|
-
return `node ${JSON.stringify((0,
|
|
17807
|
+
return `node ${JSON.stringify((0, import_node_path11.join)(root, "scripts", "verity.mjs"))}`;
|
|
17906
17808
|
}
|
|
17907
17809
|
|
|
17908
17810
|
// src/commands/hooks.ts
|
|
@@ -18038,18 +17940,18 @@ function registerHooksCommands(program2) {
|
|
|
18038
17940
|
}
|
|
18039
17941
|
|
|
18040
17942
|
// src/commands/intent.ts
|
|
18041
|
-
var
|
|
17943
|
+
var import_node_crypto9 = require("node:crypto");
|
|
18042
17944
|
|
|
18043
17945
|
// src/lib/conversation-buffer.ts
|
|
18044
17946
|
var import_promises5 = require("node:fs/promises");
|
|
18045
|
-
var
|
|
17947
|
+
var import_node_fs11 = require("node:fs");
|
|
18046
17948
|
var import_node_child_process6 = require("node:child_process");
|
|
18047
|
-
var
|
|
17949
|
+
var import_node_crypto = require("node:crypto");
|
|
18048
17950
|
function stripImageReferences(text) {
|
|
18049
17951
|
return text.replace(/\[Image #\d+\]/g, "[screenshot \u2014 not available for review]");
|
|
18050
17952
|
}
|
|
18051
17953
|
function bufferTmpPath() {
|
|
18052
|
-
return `${CONVERSATION_BUFFER_FILE}.${process.pid}.${(0,
|
|
17954
|
+
return `${CONVERSATION_BUFFER_FILE}.${process.pid}.${(0, import_node_crypto.randomBytes)(4).toString("hex")}.tmp`;
|
|
18053
17955
|
}
|
|
18054
17956
|
async function appendToConversationBuffer(prompt, sessionId) {
|
|
18055
17957
|
try {
|
|
@@ -18078,7 +17980,7 @@ async function appendToConversationBuffer(prompt, sessionId) {
|
|
|
18078
17980
|
}
|
|
18079
17981
|
async function readAndClearConversationBuffer(currentSessionId) {
|
|
18080
17982
|
try {
|
|
18081
|
-
if ((0,
|
|
17983
|
+
if ((0, import_node_fs11.existsSync)(CONVERSATION_BUFFER_FILE)) {
|
|
18082
17984
|
const entries = await readBufferEntries();
|
|
18083
17985
|
let mine = entries;
|
|
18084
17986
|
let others = [];
|
|
@@ -18102,7 +18004,7 @@ async function readAndClearConversationBuffer(currentSessionId) {
|
|
|
18102
18004
|
};
|
|
18103
18005
|
}
|
|
18104
18006
|
}
|
|
18105
|
-
if ((0,
|
|
18007
|
+
if ((0, import_node_fs11.existsSync)(INTENT_FILE)) {
|
|
18106
18008
|
try {
|
|
18107
18009
|
const content = await (0, import_promises5.readFile)(INTENT_FILE, "utf-8");
|
|
18108
18010
|
await (0, import_promises5.unlink)(INTENT_FILE).catch(() => {
|
|
@@ -18393,6 +18295,83 @@ function isCommandOnlyTurn(input) {
|
|
|
18393
18295
|
return commands.every(isNonAuthoringCommand);
|
|
18394
18296
|
}
|
|
18395
18297
|
|
|
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
|
+
|
|
18396
18375
|
// src/lib/task-context-buffer.ts
|
|
18397
18376
|
var import_promises6 = require("node:fs/promises");
|
|
18398
18377
|
var import_node_fs13 = require("node:fs");
|
|
@@ -20058,97 +20037,6 @@ var LEGACY_MD_END = "<!-- gate-memory:end -->";
|
|
|
20058
20037
|
var LEGACY_PRESERVE_START = "<!-- gate-memory:preserve -->";
|
|
20059
20038
|
var LEGACY_PRESERVE_END = "<!-- /gate-memory:preserve -->";
|
|
20060
20039
|
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 = [
|
|
20152
20040
|
"## Project Memory",
|
|
20153
20041
|
"",
|
|
20154
20042
|
"This project has a knowledge graph maintained at `.verity/memory/`. Before starting",
|
|
@@ -20590,7 +20478,6 @@ function stripKnownProse(interior) {
|
|
|
20590
20478
|
const trimmed = interior.replace(/^\n+/, "");
|
|
20591
20479
|
for (const prose of [
|
|
20592
20480
|
CLAUDE_MD_PROSE,
|
|
20593
|
-
CLAUDE_MD_PROSE_PRE_STDIN,
|
|
20594
20481
|
CLAUDE_MD_PROSE_PRE_ORG,
|
|
20595
20482
|
CLAUDE_MD_PROSE_PRE_AUTORECORD,
|
|
20596
20483
|
CLAUDE_MD_PROSE_PRE_REFLECT,
|
|
@@ -20657,7 +20544,7 @@ Body content (\u22648KB). Use [[node-id]] wikilinks for cross-references.
|
|
|
20657
20544
|
|
|
20658
20545
|
// src/lib/dossier-session.ts
|
|
20659
20546
|
var import_node_fs26 = require("node:fs");
|
|
20660
|
-
var
|
|
20547
|
+
var import_node_crypto8 = require("node:crypto");
|
|
20661
20548
|
var import_node_path22 = require("node:path");
|
|
20662
20549
|
|
|
20663
20550
|
// src/lib/pending-repeat.ts
|
|
@@ -20734,7 +20621,6 @@ function isRepeatOfAny(text, priorFingerprints, threshold = REPEAT_THRESHOLD) {
|
|
|
20734
20621
|
}
|
|
20735
20622
|
|
|
20736
20623
|
// src/lib/dossier/bounds.ts
|
|
20737
|
-
var import_node_crypto5 = require("node:crypto");
|
|
20738
20624
|
var MAX_LINE_BYTES = 4096;
|
|
20739
20625
|
var MAX_GOAL_CHARS = 2e3;
|
|
20740
20626
|
var GOAL_KEEP = 8;
|
|
@@ -20746,17 +20632,10 @@ var NOT_MINE_CAP = 300;
|
|
|
20746
20632
|
var STATEMENTS_OPEN_CAP = 40;
|
|
20747
20633
|
var COMMANDS_CAP = 12;
|
|
20748
20634
|
var DIVERGENCE_CAP = 10;
|
|
20749
|
-
var
|
|
20750
|
-
var DIVERGENCE_KEYS_PER_LINE = 200;
|
|
20635
|
+
var DIVERGENCE_SEEN_CAP = 300;
|
|
20751
20636
|
function divergenceKey(path, hash) {
|
|
20752
20637
|
return `${path}@${hash ?? "unknown"}`;
|
|
20753
20638
|
}
|
|
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
|
-
}
|
|
20760
20639
|
var MARKS_CAP = 50;
|
|
20761
20640
|
var ROTATE_BYTES = 1048576;
|
|
20762
20641
|
var ROTATE_KEEP = 2;
|
|
@@ -20770,7 +20649,7 @@ function statementAnchorKey(file, patternId) {
|
|
|
20770
20649
|
}
|
|
20771
20650
|
|
|
20772
20651
|
// src/lib/dossier/log.ts
|
|
20773
|
-
var
|
|
20652
|
+
var import_node_crypto5 = require("node:crypto");
|
|
20774
20653
|
var import_node_fs22 = require("node:fs");
|
|
20775
20654
|
var import_node_path20 = require("node:path");
|
|
20776
20655
|
var CRC_TABLE = (() => {
|
|
@@ -20812,7 +20691,7 @@ function nextSeq() {
|
|
|
20812
20691
|
function encodeEvent(ev) {
|
|
20813
20692
|
const full = {
|
|
20814
20693
|
v: 1,
|
|
20815
|
-
id: (0,
|
|
20694
|
+
id: (0, import_node_crypto5.randomBytes)(4).toString("hex"),
|
|
20816
20695
|
...ev
|
|
20817
20696
|
};
|
|
20818
20697
|
let body2 = JSON.stringify(full);
|
|
@@ -20883,7 +20762,7 @@ function rotateIfNeeded2(d) {
|
|
|
20883
20762
|
}
|
|
20884
20763
|
|
|
20885
20764
|
// src/lib/dossier/fold-dossier.ts
|
|
20886
|
-
var
|
|
20765
|
+
var import_node_crypto6 = require("node:crypto");
|
|
20887
20766
|
var import_node_fs23 = require("node:fs");
|
|
20888
20767
|
var import_node_path21 = require("node:path");
|
|
20889
20768
|
var EMPTY_CAPABILITIES = () => ({
|
|
@@ -20975,7 +20854,7 @@ function reduce(state, events, now) {
|
|
|
20975
20854
|
state.meta.seq = Math.max(state.meta.seq, ev.seq);
|
|
20976
20855
|
switch (ev.k) {
|
|
20977
20856
|
case "goal": {
|
|
20978
|
-
const hash = (0,
|
|
20857
|
+
const hash = (0, import_node_crypto6.createHash)("sha256").update(ev.text).digest("hex").slice(0, 16);
|
|
20979
20858
|
const prev = state.goal[state.goal.length - 1];
|
|
20980
20859
|
if (prev && prev.hash === hash) {
|
|
20981
20860
|
prev.repeats = (prev.repeats ?? 0) + 1;
|
|
@@ -21103,13 +20982,12 @@ function reduce(state, events, now) {
|
|
|
21103
20982
|
break;
|
|
21104
20983
|
}
|
|
21105
20984
|
case "divergence": {
|
|
20985
|
+
state.divergence.counts[ev.kind] = (state.divergence.counts[ev.kind] ?? 0) + 1;
|
|
21106
20986
|
state.divergence.events.push({ kind: ev.kind, path: ev.path, at: ev.at });
|
|
21107
|
-
const
|
|
21108
|
-
|
|
21109
|
-
if (seenDivergence.has(key)) continue;
|
|
20987
|
+
const key = divergenceKey(ev.path, ev.hash ?? null);
|
|
20988
|
+
if (!seenDivergence.has(key)) {
|
|
21110
20989
|
seenDivergence.add(key);
|
|
21111
|
-
state.divergence.seen.push(key);
|
|
21112
|
-
state.divergence.counts[ev.kind] = (state.divergence.counts[ev.kind] ?? 0) + 1;
|
|
20990
|
+
if (state.divergence.seen.length < DIVERGENCE_SEEN_CAP) state.divergence.seen.push(key);
|
|
21113
20991
|
}
|
|
21114
20992
|
break;
|
|
21115
20993
|
}
|
|
@@ -21416,14 +21294,14 @@ function assessContinuity(i2) {
|
|
|
21416
21294
|
}
|
|
21417
21295
|
|
|
21418
21296
|
// src/lib/dossier/reanchor.ts
|
|
21419
|
-
var
|
|
21297
|
+
var import_node_crypto7 = require("node:crypto");
|
|
21420
21298
|
var import_node_fs25 = require("node:fs");
|
|
21421
21299
|
function lineSha(text) {
|
|
21422
|
-
return (0,
|
|
21300
|
+
return (0, import_node_crypto7.createHash)("sha256").update(text.trim()).digest("hex").slice(0, HASH_WIDTH);
|
|
21423
21301
|
}
|
|
21424
21302
|
function fileHash(path) {
|
|
21425
21303
|
try {
|
|
21426
|
-
return (0,
|
|
21304
|
+
return (0, import_node_crypto7.createHash)("sha256").update((0, import_node_fs25.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
|
|
21427
21305
|
} catch {
|
|
21428
21306
|
return null;
|
|
21429
21307
|
}
|
|
@@ -21920,7 +21798,7 @@ function recordTurn(d, t) {
|
|
|
21920
21798
|
// Identity is the COMMAND, not its category — otherwise `npm test -- a` and
|
|
21921
21799
|
// `npm test -- b` are one row and the streak counts two different commands
|
|
21922
21800
|
// as a run of one.
|
|
21923
|
-
cmd_hash: (0,
|
|
21801
|
+
cmd_hash: (0, import_node_crypto8.createHash)("sha256").update(c.head || c.class).digest("hex").slice(0, 12),
|
|
21924
21802
|
head: c.head || c.class,
|
|
21925
21803
|
status: toStatus(c.last_status)
|
|
21926
21804
|
});
|
|
@@ -21938,23 +21816,10 @@ function recordTurn(d, t) {
|
|
|
21938
21816
|
}
|
|
21939
21817
|
}
|
|
21940
21818
|
const seenDivergence = t.known?.divergence ?? /* @__PURE__ */ new Set();
|
|
21941
|
-
const fresh = [];
|
|
21942
21819
|
for (const u of t.unobserved) {
|
|
21943
21820
|
const hash = fileHash((0, import_node_path22.join)(root, u.p));
|
|
21944
|
-
|
|
21945
|
-
|
|
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
|
-
}
|
|
21821
|
+
if (seenDivergence.has(divergenceKey(u.p, hash))) continue;
|
|
21822
|
+
appendEvent(d, { k: "divergence", kind: "external_mutation", path: u.p, hash });
|
|
21958
21823
|
}
|
|
21959
21824
|
const newCompactions = (t.compactions ?? 0) - (t.known?.compactions ?? 0);
|
|
21960
21825
|
for (let i2 = 0; i2 < newCompactions; i2++) {
|
|
@@ -22219,7 +22084,7 @@ async function fireClassify(prompt, sessionId, globals) {
|
|
|
22219
22084
|
logEvent("classify_skipped", { reason: "no_service_url", detail: urlResult.error });
|
|
22220
22085
|
return;
|
|
22221
22086
|
}
|
|
22222
|
-
const promptHash = (0,
|
|
22087
|
+
const promptHash = (0, import_node_crypto9.createHash)("sha256").update(prompt).digest("hex");
|
|
22223
22088
|
const result = await apiRequest({
|
|
22224
22089
|
method: "POST",
|
|
22225
22090
|
path: "/classify-task",
|
|
@@ -22263,7 +22128,7 @@ var import_node_path26 = require("node:path");
|
|
|
22263
22128
|
// src/lib/baseline.ts
|
|
22264
22129
|
var import_node_fs28 = require("node:fs");
|
|
22265
22130
|
var import_node_path25 = require("node:path");
|
|
22266
|
-
var
|
|
22131
|
+
var import_node_crypto10 = require("node:crypto");
|
|
22267
22132
|
|
|
22268
22133
|
// src/lib/snapshot.ts
|
|
22269
22134
|
var import_node_fs27 = require("node:fs");
|
|
@@ -22532,7 +22397,7 @@ var MIRROR_MAX_BYTES = 2 * 1024 * 1024;
|
|
|
22532
22397
|
var DEFAULT_SESSION_KEY = "_default";
|
|
22533
22398
|
function sessionKey(sessionId) {
|
|
22534
22399
|
if (!sessionId) return DEFAULT_SESSION_KEY;
|
|
22535
|
-
return (0,
|
|
22400
|
+
return (0, import_node_crypto10.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
|
|
22536
22401
|
}
|
|
22537
22402
|
function sessionDir(key) {
|
|
22538
22403
|
return (0, import_node_path25.join)(projectPath(BASELINE_DIR), key);
|
|
@@ -22994,17 +22859,17 @@ async function readHookStdin() {
|
|
|
22994
22859
|
try {
|
|
22995
22860
|
if (process.stdin.isTTY) return {};
|
|
22996
22861
|
const chunks = [];
|
|
22997
|
-
const timeout = new Promise((
|
|
22998
|
-
const read2 = new Promise((
|
|
22862
|
+
const timeout = new Promise((resolve8) => setTimeout(() => resolve8({}), 500));
|
|
22863
|
+
const read2 = new Promise((resolve8) => {
|
|
22999
22864
|
process.stdin.on("data", (c) => chunks.push(c));
|
|
23000
22865
|
process.stdin.on("end", () => {
|
|
23001
22866
|
try {
|
|
23002
|
-
|
|
22867
|
+
resolve8(JSON.parse(Buffer.concat(chunks).toString("utf-8").trim() || "{}"));
|
|
23003
22868
|
} catch {
|
|
23004
|
-
|
|
22869
|
+
resolve8({});
|
|
23005
22870
|
}
|
|
23006
22871
|
});
|
|
23007
|
-
process.stdin.on("error", () =>
|
|
22872
|
+
process.stdin.on("error", () => resolve8({}));
|
|
23008
22873
|
process.stdin.resume();
|
|
23009
22874
|
});
|
|
23010
22875
|
return await Promise.race([read2, timeout]);
|
|
@@ -23100,7 +22965,7 @@ function isIgnored2(path) {
|
|
|
23100
22965
|
}
|
|
23101
22966
|
function listProjectFiles(root) {
|
|
23102
22967
|
try {
|
|
23103
|
-
const out2 = (0, import_node_child_process9.execSync)("git ls-files -z
|
|
22968
|
+
const out2 = (0, import_node_child_process9.execSync)("git ls-files -z", {
|
|
23104
22969
|
cwd: root,
|
|
23105
22970
|
encoding: "utf-8",
|
|
23106
22971
|
maxBuffer: 32 * 1024 * 1024,
|
|
@@ -24452,10 +24317,10 @@ var import_node_fs38 = require("node:fs");
|
|
|
24452
24317
|
|
|
24453
24318
|
// src/lib/debounce.ts
|
|
24454
24319
|
var import_node_fs37 = require("node:fs");
|
|
24455
|
-
var
|
|
24320
|
+
var import_node_crypto11 = require("node:crypto");
|
|
24456
24321
|
function scopedFile(base, sessionId) {
|
|
24457
24322
|
if (!sessionId) return base;
|
|
24458
|
-
return `${base}.${(0,
|
|
24323
|
+
return `${base}.${(0, import_node_crypto11.createHash)("sha1").update(sessionId).digest("hex").slice(0, 12)}`;
|
|
24459
24324
|
}
|
|
24460
24325
|
function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
|
|
24461
24326
|
const file = scopedFile(DEBOUNCE_FILE, sessionId);
|
|
@@ -24496,7 +24361,7 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
|
|
|
24496
24361
|
return "No files modified since last analysis";
|
|
24497
24362
|
}
|
|
24498
24363
|
function computeContentHash(files) {
|
|
24499
|
-
const hash = (0,
|
|
24364
|
+
const hash = (0, import_node_crypto11.createHash)("sha1");
|
|
24500
24365
|
const sorted = [...files].sort();
|
|
24501
24366
|
for (const f of sorted) {
|
|
24502
24367
|
const resolved = resolveFile(f) ?? f;
|
|
@@ -24952,56 +24817,20 @@ function registerStatusCommand(program2) {
|
|
|
24952
24817
|
});
|
|
24953
24818
|
}
|
|
24954
24819
|
|
|
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
|
-
|
|
24986
24820
|
// src/commands/feedback.ts
|
|
24987
24821
|
function registerFeedbackCommand(program2) {
|
|
24988
24822
|
const feedbackCmd = program2.command("feedback").description("Send feedback to the Verity team");
|
|
24989
|
-
feedbackCmd.command("message <text>").description("Send general feedback
|
|
24990
|
-
|
|
24823
|
+
feedbackCmd.command("message <text>").description("Send general feedback").option("--session-id <id>", "Session identifier").option("--model <name>", "Agent model name").action(async (message, opts) => {
|
|
24824
|
+
const globals = program2.opts();
|
|
24825
|
+
await sendGeneralFeedback(message, opts, globals);
|
|
24991
24826
|
});
|
|
24992
|
-
feedbackCmd.command("finding <run-id> <pattern-id> <action> [note]").description("Submit per-finding feedback (false_positive, acknowledged, useful, etc.)
|
|
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, note, opts) => {
|
|
24993
24828
|
const globals = program2.opts();
|
|
24994
24829
|
const validActions = ["false_positive", "acknowledged", "will_fix_later", "wrong_severity", "useful"];
|
|
24995
24830
|
if (!validActions.includes(action)) {
|
|
24996
24831
|
printError(`Invalid action "${action}". Must be one of: ${validActions.join(", ")}`);
|
|
24997
24832
|
process.exit(1);
|
|
24998
24833
|
}
|
|
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;
|
|
25005
24834
|
const tokenResult = await resolveToken(globals.token);
|
|
25006
24835
|
if (!tokenResult.ok) {
|
|
25007
24836
|
printError(tokenResult.error);
|
|
@@ -25037,28 +24866,21 @@ function registerFeedbackCommand(program2) {
|
|
|
25037
24866
|
});
|
|
25038
24867
|
feedbackCmd.argument("[message]", "Feedback message (for backwards compat)").option("--session-id <id>", "Session identifier").option("--model <name>", "Agent model name").action(async (message, opts) => {
|
|
25039
24868
|
if (!message) return;
|
|
25040
|
-
|
|
24869
|
+
const globals = program2.opts();
|
|
24870
|
+
await sendGeneralFeedback(message, opts, globals);
|
|
25041
24871
|
});
|
|
25042
24872
|
}
|
|
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
|
-
}
|
|
25051
24873
|
async function sendGeneralFeedback(message, opts, globals) {
|
|
25052
24874
|
const tokenResult = await resolveToken(globals.token);
|
|
25053
24875
|
if (!tokenResult.ok) {
|
|
25054
24876
|
printError(tokenResult.error);
|
|
25055
|
-
printInfo(`Your message: ${
|
|
24877
|
+
printInfo(`Your message: ${message}`);
|
|
25056
24878
|
process.exit(1);
|
|
25057
24879
|
}
|
|
25058
24880
|
const urlResult = await resolveServiceUrl(globals.serviceUrl);
|
|
25059
24881
|
if (!urlResult.ok) {
|
|
25060
24882
|
printError(urlResult.error);
|
|
25061
|
-
printInfo(`Your message: ${
|
|
24883
|
+
printInfo(`Your message: ${message}`);
|
|
25062
24884
|
process.exit(1);
|
|
25063
24885
|
}
|
|
25064
24886
|
const body2 = { message };
|
|
@@ -25076,7 +24898,7 @@ async function sendGeneralFeedback(message, opts, globals) {
|
|
|
25076
24898
|
});
|
|
25077
24899
|
if (!result.ok) {
|
|
25078
24900
|
printError(`Couldn't send feedback: ${result.error}`);
|
|
25079
|
-
printInfo(`Your message: ${
|
|
24901
|
+
printInfo(`Your message: ${message}`);
|
|
25080
24902
|
process.exit(1);
|
|
25081
24903
|
}
|
|
25082
24904
|
printInfo("Thanks, feedback sent!");
|
|
@@ -25161,8 +24983,7 @@ function createRun(opts, globals) {
|
|
|
25161
24983
|
}
|
|
25162
24984
|
|
|
25163
24985
|
// src/commands/analyze/index.ts
|
|
25164
|
-
var
|
|
25165
|
-
var import_node_path40 = require("node:path");
|
|
24986
|
+
var import_node_fs52 = require("node:fs");
|
|
25166
24987
|
|
|
25167
24988
|
// src/lib/repo-context.ts
|
|
25168
24989
|
var import_node_child_process11 = require("node:child_process");
|
|
@@ -26126,7 +25947,7 @@ function installRunEvidence(run4) {
|
|
|
26126
25947
|
}
|
|
26127
25948
|
|
|
26128
25949
|
// src/lib/git-frame.ts
|
|
26129
|
-
var
|
|
25950
|
+
var import_node_fs39 = require("node:fs");
|
|
26130
25951
|
var import_node_os6 = require("node:os");
|
|
26131
25952
|
var import_node_path30 = require("node:path");
|
|
26132
25953
|
var import_node_path31 = require("node:path");
|
|
@@ -26296,14 +26117,14 @@ function gitAt(dir, args2) {
|
|
|
26296
26117
|
}
|
|
26297
26118
|
function realpathOr2(p) {
|
|
26298
26119
|
try {
|
|
26299
|
-
return
|
|
26120
|
+
return import_node_fs39.realpathSync.native(p);
|
|
26300
26121
|
} catch {
|
|
26301
26122
|
return (0, import_node_path30.resolve)(p);
|
|
26302
26123
|
}
|
|
26303
26124
|
}
|
|
26304
26125
|
function resolveFrame(input) {
|
|
26305
26126
|
const found = findMomentSegment(input.command, input.on);
|
|
26306
|
-
const hookDirUsable = !!input.hookCwd && (0,
|
|
26127
|
+
const hookDirUsable = !!input.hookCwd && (0, import_node_fs39.existsSync)(input.hookCwd);
|
|
26307
26128
|
const baseDir = hookDirUsable ? input.hookCwd : process.cwd();
|
|
26308
26129
|
let anchor = hookDirUsable ? "hook-cwd" : "process-cwd";
|
|
26309
26130
|
const refuse = (refusal) => ({
|
|
@@ -26326,7 +26147,7 @@ function resolveFrame(input) {
|
|
|
26326
26147
|
if (dirs.size > 1) return refuse(`target:multiple ${found.moment} targets in one command`);
|
|
26327
26148
|
const targetDir = dirs.size === 1 ? [...dirs][0] : baseDir;
|
|
26328
26149
|
if (targetDir !== baseDir) {
|
|
26329
|
-
if (!(0,
|
|
26150
|
+
if (!(0, import_node_fs39.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
|
|
26330
26151
|
dir = targetDir;
|
|
26331
26152
|
}
|
|
26332
26153
|
}
|
|
@@ -26513,7 +26334,7 @@ function stagedRange(frame, command) {
|
|
|
26513
26334
|
return { kind: "staged", base: "HEAD", head: "INDEX", via: "staged-in-command", refusal: plan.reason };
|
|
26514
26335
|
}
|
|
26515
26336
|
const mergeHead = frame.gitDir ? (0, import_node_path31.join)(frame.gitDir, "MERGE_HEAD") : null;
|
|
26516
|
-
if (mergeHead && (0,
|
|
26337
|
+
if (mergeHead && (0, import_node_fs39.existsSync)(mergeHead)) {
|
|
26517
26338
|
const vsHead = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "HEAD"]).split("\n").filter(Boolean));
|
|
26518
26339
|
const vsMerge = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "MERGE_HEAD"]).split("\n").filter(Boolean));
|
|
26519
26340
|
const resolutions = new Set([...vsHead].filter((f) => vsMerge.has(f) && !isVerityOwnedPath(f)));
|
|
@@ -26647,7 +26468,7 @@ function truthy(v) {
|
|
|
26647
26468
|
}
|
|
26648
26469
|
|
|
26649
26470
|
// src/lib/transcript.ts
|
|
26650
|
-
var
|
|
26471
|
+
var import_node_fs40 = require("node:fs");
|
|
26651
26472
|
var MAX_READ_BYTES = 256 * 1024;
|
|
26652
26473
|
var SMALL_FILE_BYTES = 64 * 1024;
|
|
26653
26474
|
var MAX_FILES_LIST = 20;
|
|
@@ -26674,7 +26495,7 @@ async function extractActionSummary(transcriptPath) {
|
|
|
26674
26495
|
function readTurnLines(transcriptPath) {
|
|
26675
26496
|
let size;
|
|
26676
26497
|
try {
|
|
26677
|
-
size = (0,
|
|
26498
|
+
size = (0, import_node_fs40.statSync)(transcriptPath).size;
|
|
26678
26499
|
} catch {
|
|
26679
26500
|
return null;
|
|
26680
26501
|
}
|
|
@@ -26682,7 +26503,7 @@ function readTurnLines(transcriptPath) {
|
|
|
26682
26503
|
let raw;
|
|
26683
26504
|
let windowed = false;
|
|
26684
26505
|
if (size <= SMALL_FILE_BYTES) {
|
|
26685
|
-
raw = (0,
|
|
26506
|
+
raw = (0, import_node_fs40.readFileSync)(transcriptPath, "utf-8");
|
|
26686
26507
|
} else {
|
|
26687
26508
|
windowed = true;
|
|
26688
26509
|
const buf = Buffer.alloc(Math.min(MAX_READ_BYTES, size));
|
|
@@ -26965,28 +26786,28 @@ async function readStopHookStdin() {
|
|
|
26965
26786
|
try {
|
|
26966
26787
|
if (process.stdin.isTTY) return empty;
|
|
26967
26788
|
const chunks = [];
|
|
26968
|
-
const timeout = new Promise((
|
|
26969
|
-
const read2 = new Promise((
|
|
26789
|
+
const timeout = new Promise((resolve8) => setTimeout(() => resolve8(empty), 500));
|
|
26790
|
+
const read2 = new Promise((resolve8) => {
|
|
26970
26791
|
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
26971
26792
|
process.stdin.on("end", () => {
|
|
26972
26793
|
const raw = Buffer.concat(chunks).toString("utf-8").trim();
|
|
26973
26794
|
if (!raw) {
|
|
26974
|
-
|
|
26795
|
+
resolve8(empty);
|
|
26975
26796
|
return;
|
|
26976
26797
|
}
|
|
26977
26798
|
try {
|
|
26978
26799
|
const data = JSON.parse(raw);
|
|
26979
|
-
|
|
26800
|
+
resolve8({
|
|
26980
26801
|
assistantMessage: typeof data.last_assistant_message === "string" ? data.last_assistant_message : null,
|
|
26981
26802
|
stopReason: typeof data.stop_reason === "string" ? data.stop_reason : null,
|
|
26982
26803
|
transcriptPath: typeof data.transcript_path === "string" ? data.transcript_path : null,
|
|
26983
26804
|
sessionId: typeof data.session_id === "string" ? data.session_id : null
|
|
26984
26805
|
});
|
|
26985
26806
|
} catch {
|
|
26986
|
-
|
|
26807
|
+
resolve8(empty);
|
|
26987
26808
|
}
|
|
26988
26809
|
});
|
|
26989
|
-
process.stdin.on("error", () =>
|
|
26810
|
+
process.stdin.on("error", () => resolve8(empty));
|
|
26990
26811
|
process.stdin.resume();
|
|
26991
26812
|
});
|
|
26992
26813
|
return await Promise.race([read2, timeout]);
|
|
@@ -27252,7 +27073,7 @@ function channelSilence(input) {
|
|
|
27252
27073
|
// src/lib/cli-version.ts
|
|
27253
27074
|
function cliVersion() {
|
|
27254
27075
|
try {
|
|
27255
|
-
return true ? "0.34.0-experimental.
|
|
27076
|
+
return true ? "0.34.0-experimental.ba15b96" : "dev";
|
|
27256
27077
|
} catch {
|
|
27257
27078
|
return "dev";
|
|
27258
27079
|
}
|
|
@@ -27293,7 +27114,7 @@ async function sendSkipBeacon(ctx, reason) {
|
|
|
27293
27114
|
|
|
27294
27115
|
// src/lib/static-analysis.ts
|
|
27295
27116
|
var import_node_child_process12 = require("node:child_process");
|
|
27296
|
-
var
|
|
27117
|
+
var import_node_fs41 = require("node:fs");
|
|
27297
27118
|
var SEVERITY_ORDER = {
|
|
27298
27119
|
Error: 0,
|
|
27299
27120
|
Critical: 0,
|
|
@@ -27349,7 +27170,7 @@ function runCodacyAnalysis(files) {
|
|
|
27349
27170
|
if (files.length === 0) return empty;
|
|
27350
27171
|
const existingFiles = files.filter((f) => {
|
|
27351
27172
|
try {
|
|
27352
|
-
return (0,
|
|
27173
|
+
return (0, import_node_fs41.existsSync)(f);
|
|
27353
27174
|
} catch {
|
|
27354
27175
|
return false;
|
|
27355
27176
|
}
|
|
@@ -27618,7 +27439,7 @@ async function scope(run4) {
|
|
|
27618
27439
|
}
|
|
27619
27440
|
|
|
27620
27441
|
// src/lib/specs.ts
|
|
27621
|
-
var
|
|
27442
|
+
var import_node_fs42 = require("node:fs");
|
|
27622
27443
|
var import_node_path32 = require("node:path");
|
|
27623
27444
|
var SPEC_CANDIDATES = [
|
|
27624
27445
|
"CLAUDE.md",
|
|
@@ -27660,7 +27481,7 @@ function discoverSpecs(consulted = []) {
|
|
|
27660
27481
|
const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
|
|
27661
27482
|
if (totalBytes >= totalCap) return false;
|
|
27662
27483
|
if (seen.has(specPath)) return true;
|
|
27663
|
-
if (!(0,
|
|
27484
|
+
if (!(0, import_node_fs42.existsSync)(specPath)) return true;
|
|
27664
27485
|
seen.add(specPath);
|
|
27665
27486
|
const remaining = totalCap - totalBytes;
|
|
27666
27487
|
const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
|
|
@@ -27683,7 +27504,7 @@ function discoverSpecs(consulted = []) {
|
|
|
27683
27504
|
if (!addSpec(candidate)) break;
|
|
27684
27505
|
}
|
|
27685
27506
|
for (const dir of ["spec", "docs"]) {
|
|
27686
|
-
if (!(0,
|
|
27507
|
+
if (!(0, import_node_fs42.existsSync)(dir)) continue;
|
|
27687
27508
|
try {
|
|
27688
27509
|
const mdFiles = findMdFiles(dir, 2).sort();
|
|
27689
27510
|
for (const mdFile of mdFiles) {
|
|
@@ -27698,7 +27519,7 @@ function findMdFiles(dir, maxDepth, depth = 0) {
|
|
|
27698
27519
|
if (depth >= maxDepth) return [];
|
|
27699
27520
|
const result = [];
|
|
27700
27521
|
try {
|
|
27701
|
-
const entries = (0,
|
|
27522
|
+
const entries = (0, import_node_fs42.readdirSync)(dir, { withFileTypes: true });
|
|
27702
27523
|
for (const entry of entries) {
|
|
27703
27524
|
const fullPath = (0, import_node_path32.join)(dir, entry.name);
|
|
27704
27525
|
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -27718,13 +27539,13 @@ function discoverPlans() {
|
|
|
27718
27539
|
if (isRealDirectoryChain(process.cwd(), [".claude", "plans"])) {
|
|
27719
27540
|
sources.push({ root: process.cwd(), prefix: (0, import_node_path32.join)(".claude", "plans") });
|
|
27720
27541
|
}
|
|
27721
|
-
if (home && (0,
|
|
27542
|
+
if (home && (0, import_node_fs42.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
|
|
27722
27543
|
const candidates2 = [];
|
|
27723
27544
|
const seen = /* @__PURE__ */ new Set();
|
|
27724
27545
|
for (const source2 of sources) {
|
|
27725
27546
|
let names2;
|
|
27726
27547
|
try {
|
|
27727
|
-
names2 = (0,
|
|
27548
|
+
names2 = (0, import_node_fs42.readdirSync)(source2.prefix ? (0, import_node_path32.join)(source2.root, source2.prefix) : source2.root);
|
|
27728
27549
|
} catch {
|
|
27729
27550
|
continue;
|
|
27730
27551
|
}
|
|
@@ -27751,7 +27572,7 @@ function isRealDirectoryChain(root, parts2) {
|
|
|
27751
27572
|
for (const part of parts2) {
|
|
27752
27573
|
current = (0, import_node_path32.join)(current, part);
|
|
27753
27574
|
try {
|
|
27754
|
-
if (!(0,
|
|
27575
|
+
if (!(0, import_node_fs42.lstatSync)(current).isDirectory()) return false;
|
|
27755
27576
|
} catch {
|
|
27756
27577
|
return false;
|
|
27757
27578
|
}
|
|
@@ -27766,7 +27587,7 @@ function discoverGuardDocs(rangeFiles2) {
|
|
|
27766
27587
|
if (result.length >= MAX_SPEC_FILES) break;
|
|
27767
27588
|
if (!GUARD_DOC_EXT.test(path)) continue;
|
|
27768
27589
|
if (path.startsWith("/") || path.includes("..")) continue;
|
|
27769
|
-
if (!(0,
|
|
27590
|
+
if (!(0, import_node_fs42.existsSync)(path)) continue;
|
|
27770
27591
|
const opened = openRegularInRoot(process.cwd(), path);
|
|
27771
27592
|
if (!opened.ok) continue;
|
|
27772
27593
|
if (opened.size > MAX_PLAN_FILE_BYTES || totalBytes + opened.size > MAX_TOTAL_SPEC_BYTES) {
|
|
@@ -27952,7 +27773,7 @@ async function mode(run4) {
|
|
|
27952
27773
|
}
|
|
27953
27774
|
|
|
27954
27775
|
// src/lib/fold.ts
|
|
27955
|
-
var
|
|
27776
|
+
var import_node_fs43 = require("node:fs");
|
|
27956
27777
|
var import_node_path33 = require("node:path");
|
|
27957
27778
|
var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
|
|
27958
27779
|
"user",
|
|
@@ -28090,7 +27911,7 @@ function candidateRoots(repoRoot2) {
|
|
|
28090
27911
|
const norm2 = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
28091
27912
|
const out2 = [norm2];
|
|
28092
27913
|
try {
|
|
28093
|
-
const real =
|
|
27914
|
+
const real = import_node_fs43.realpathSync.native(norm2).replace(/\\/g, "/").replace(/\/+$/, "");
|
|
28094
27915
|
if (real !== norm2) out2.push(real);
|
|
28095
27916
|
} catch {
|
|
28096
27917
|
}
|
|
@@ -28178,8 +27999,8 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28178
27999
|
}
|
|
28179
28000
|
};
|
|
28180
28001
|
try {
|
|
28181
|
-
if (!(0,
|
|
28182
|
-
ingest((0,
|
|
28002
|
+
if (!(0, import_node_fs43.existsSync)(transcriptPath)) return result;
|
|
28003
|
+
ingest((0, import_node_fs43.readFileSync)(transcriptPath, "utf8"), "agent");
|
|
28183
28004
|
result.coverage.complete = true;
|
|
28184
28005
|
} catch {
|
|
28185
28006
|
return result;
|
|
@@ -28190,19 +28011,19 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28190
28011
|
(0, import_node_path33.basename)(transcriptPath).replace(/\.jsonl$/, ""),
|
|
28191
28012
|
"subagents"
|
|
28192
28013
|
);
|
|
28193
|
-
if ((0,
|
|
28014
|
+
if ((0, import_node_fs43.existsSync)(sidecarDir)) {
|
|
28194
28015
|
const maxFiles = opts.maxSidecars ?? 200;
|
|
28195
28016
|
const maxBytes = opts.maxSidecarBytes ?? 16 * 1024 * 1024;
|
|
28196
28017
|
const found = [];
|
|
28197
28018
|
const walk2 = (d, depth) => {
|
|
28198
28019
|
if (depth > 4) return;
|
|
28199
|
-
for (const e of (0,
|
|
28020
|
+
for (const e of (0, import_node_fs43.readdirSync)(d, { withFileTypes: true })) {
|
|
28200
28021
|
const p = (0, import_node_path33.join)(d, e.name);
|
|
28201
28022
|
if (e.isDirectory()) {
|
|
28202
28023
|
walk2(p, depth + 1);
|
|
28203
28024
|
} else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
|
|
28204
28025
|
try {
|
|
28205
|
-
const st = (0,
|
|
28026
|
+
const st = (0, import_node_fs43.statSync)(p);
|
|
28206
28027
|
found.push({ path: p, size: st.size, mtimeMs: st.mtimeMs });
|
|
28207
28028
|
} catch {
|
|
28208
28029
|
result.coverage.malformed++;
|
|
@@ -28219,7 +28040,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28219
28040
|
continue;
|
|
28220
28041
|
}
|
|
28221
28042
|
try {
|
|
28222
|
-
ingest((0,
|
|
28043
|
+
ingest((0, import_node_fs43.readFileSync)(f.path, "utf8"), "subagent");
|
|
28223
28044
|
bytes += f.size;
|
|
28224
28045
|
result.coverage.subagentFiles++;
|
|
28225
28046
|
} catch {
|
|
@@ -28254,7 +28075,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28254
28075
|
}
|
|
28255
28076
|
function classifyUnobserved(path) {
|
|
28256
28077
|
try {
|
|
28257
|
-
const st = (0,
|
|
28078
|
+
const st = (0, import_node_fs43.statSync)(path);
|
|
28258
28079
|
if (!st.isFile()) return "unreadable";
|
|
28259
28080
|
} catch {
|
|
28260
28081
|
return "unreadable";
|
|
@@ -28569,20 +28390,20 @@ async function evidence(run4) {
|
|
|
28569
28390
|
}
|
|
28570
28391
|
|
|
28571
28392
|
// src/lib/cache-cleanup.ts
|
|
28572
|
-
var
|
|
28393
|
+
var import_node_fs44 = require("node:fs");
|
|
28573
28394
|
var import_node_path34 = require("node:path");
|
|
28574
28395
|
var CACHE_TTL_DAYS = 7;
|
|
28575
28396
|
function pruneStaleCache() {
|
|
28576
28397
|
try {
|
|
28577
28398
|
const dir = projectPath(CACHE_DIR);
|
|
28578
28399
|
const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
|
|
28579
|
-
for (const entry of (0,
|
|
28400
|
+
for (const entry of (0, import_node_fs44.readdirSync)(dir)) {
|
|
28580
28401
|
if (!entry.startsWith("pending-")) continue;
|
|
28581
28402
|
const path = (0, import_node_path34.join)(dir, entry);
|
|
28582
28403
|
try {
|
|
28583
|
-
const stat3 = (0,
|
|
28404
|
+
const stat3 = (0, import_node_fs44.statSync)(path);
|
|
28584
28405
|
if (stat3.mtimeMs < cutoff) {
|
|
28585
|
-
(0,
|
|
28406
|
+
(0, import_node_fs44.unlinkSync)(path);
|
|
28586
28407
|
logEvent("cache_entry_pruned", {
|
|
28587
28408
|
path: entry,
|
|
28588
28409
|
age_days: Math.round((Date.now() - stat3.mtimeMs) / 864e5)
|
|
@@ -28596,7 +28417,7 @@ function pruneStaleCache() {
|
|
|
28596
28417
|
}
|
|
28597
28418
|
|
|
28598
28419
|
// src/lib/context-files.ts
|
|
28599
|
-
var
|
|
28420
|
+
var import_node_fs45 = require("node:fs");
|
|
28600
28421
|
var import_node_os7 = require("node:os");
|
|
28601
28422
|
var MAX_CONTEXT_FILES = 10;
|
|
28602
28423
|
var MAX_CONTEXT_FILE_BYTES = 10240;
|
|
@@ -28654,7 +28475,7 @@ function gatherContextFiles(contextPaths, deltaFiles, opts) {
|
|
|
28654
28475
|
continue;
|
|
28655
28476
|
}
|
|
28656
28477
|
try {
|
|
28657
|
-
const content = (0,
|
|
28478
|
+
const content = (0, import_node_fs45.readFileSync)(safePath, "utf8");
|
|
28658
28479
|
const bytes = Buffer.byteLength(content);
|
|
28659
28480
|
if (bytes > MAX_CONTEXT_FILE_BYTES) {
|
|
28660
28481
|
logEvent("context_file_skipped", { path: filePath, reason: "too_large", bytes });
|
|
@@ -28720,7 +28541,7 @@ async function contextFiles(run4) {
|
|
|
28720
28541
|
}
|
|
28721
28542
|
|
|
28722
28543
|
// src/lib/code/index.ts
|
|
28723
|
-
var
|
|
28544
|
+
var import_node_crypto12 = require("node:crypto");
|
|
28724
28545
|
|
|
28725
28546
|
// src/lib/code/languages.ts
|
|
28726
28547
|
var JS_LIKE = {
|
|
@@ -28812,7 +28633,7 @@ function languageOf2(path) {
|
|
|
28812
28633
|
}
|
|
28813
28634
|
|
|
28814
28635
|
// src/lib/code/runtime.ts
|
|
28815
|
-
var
|
|
28636
|
+
var import_node_fs46 = require("node:fs");
|
|
28816
28637
|
var import_node_path35 = require("node:path");
|
|
28817
28638
|
var import_web_tree_sitter2 = __toESM2(require_web_tree_sitter2());
|
|
28818
28639
|
|
|
@@ -28884,7 +28705,7 @@ function grammarCandidates(file, pkg, env = process.env) {
|
|
|
28884
28705
|
}
|
|
28885
28706
|
function locateGrammar(id, env = process.env) {
|
|
28886
28707
|
const g = grammars_default[id];
|
|
28887
|
-
return grammarCandidates(g.file, g.package, env).find((p) => (0,
|
|
28708
|
+
return grammarCandidates(g.file, g.package, env).find((p) => (0, import_node_fs46.existsSync)(p)) ?? null;
|
|
28888
28709
|
}
|
|
28889
28710
|
var loading = null;
|
|
28890
28711
|
function loadRuntime(env = process.env) {
|
|
@@ -30498,7 +30319,7 @@ function byPath(fns, name2) {
|
|
|
30498
30319
|
function makeCodeMap(rt) {
|
|
30499
30320
|
const cache = /* @__PURE__ */ new Map();
|
|
30500
30321
|
const outline = (path, content, deadlineAt = Date.now() + DEFAULT_PARSE_MS) => {
|
|
30501
|
-
const key = `${path}\0${(0,
|
|
30322
|
+
const key = `${path}\0${(0, import_node_crypto12.createHash)("sha1").update(content).digest("hex")}`;
|
|
30502
30323
|
const hit = cache.get(key);
|
|
30503
30324
|
if (hit) return { source: "tree-sitter", value: hit, elapsedMs: 0 };
|
|
30504
30325
|
let r;
|
|
@@ -31213,7 +31034,7 @@ async function repoContext(run4) {
|
|
|
31213
31034
|
|
|
31214
31035
|
// src/lib/seed-runner.ts
|
|
31215
31036
|
var import_promises15 = require("node:fs/promises");
|
|
31216
|
-
var
|
|
31037
|
+
var import_node_fs47 = require("node:fs");
|
|
31217
31038
|
var import_node_path36 = require("node:path");
|
|
31218
31039
|
var import_yaml4 = __toESM2(require_dist());
|
|
31219
31040
|
|
|
@@ -31438,7 +31259,7 @@ async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
|
|
|
31438
31259
|
const titles = /* @__PURE__ */ new Set();
|
|
31439
31260
|
for (const dir of NODE_DIRS) {
|
|
31440
31261
|
const full = (0, import_node_path36.join)(memoryDir3, dir);
|
|
31441
|
-
if (!(0,
|
|
31262
|
+
if (!(0, import_node_fs47.existsSync)(full)) continue;
|
|
31442
31263
|
let files;
|
|
31443
31264
|
try {
|
|
31444
31265
|
files = await (0, import_promises15.readdir)(full);
|
|
@@ -31520,7 +31341,7 @@ function renderNodeMarkdown(candidate, nodeId, createdAt) {
|
|
|
31520
31341
|
return fm;
|
|
31521
31342
|
}
|
|
31522
31343
|
async function runSeed(opts) {
|
|
31523
|
-
if (!(0,
|
|
31344
|
+
if (!(0, import_node_fs47.existsSync)(STANDARD_FILE)) {
|
|
31524
31345
|
return { created: 0, existing: 0, failed: 0, skipped: "no_standard", candidates: [] };
|
|
31525
31346
|
}
|
|
31526
31347
|
let standardDoc;
|
|
@@ -31532,7 +31353,7 @@ async function runSeed(opts) {
|
|
|
31532
31353
|
}
|
|
31533
31354
|
const knowledgeSpec = standardDoc.knowledge_spec ?? {};
|
|
31534
31355
|
let readmeContent;
|
|
31535
|
-
if ((0,
|
|
31356
|
+
if ((0, import_node_fs47.existsSync)("README.md")) {
|
|
31536
31357
|
try {
|
|
31537
31358
|
readmeContent = await (0, import_promises15.readFile)("README.md", "utf-8");
|
|
31538
31359
|
} catch {
|
|
@@ -31540,7 +31361,7 @@ async function runSeed(opts) {
|
|
|
31540
31361
|
}
|
|
31541
31362
|
let claudeMdContent;
|
|
31542
31363
|
for (const p of ["CLAUDE.md", ".claude/CLAUDE.md"]) {
|
|
31543
|
-
if ((0,
|
|
31364
|
+
if ((0, import_node_fs47.existsSync)(p)) {
|
|
31544
31365
|
try {
|
|
31545
31366
|
claudeMdContent = await (0, import_promises15.readFile)(p, "utf-8");
|
|
31546
31367
|
break;
|
|
@@ -31620,7 +31441,7 @@ async function runSeed(opts) {
|
|
|
31620
31441
|
continue;
|
|
31621
31442
|
}
|
|
31622
31443
|
const deduplicated = res.data.deduplicated === true;
|
|
31623
|
-
if (deduplicated && (0,
|
|
31444
|
+
if (deduplicated && (0, import_node_fs47.existsSync)(targetPath)) {
|
|
31624
31445
|
existing++;
|
|
31625
31446
|
continue;
|
|
31626
31447
|
}
|
|
@@ -31642,7 +31463,7 @@ async function runSeed(opts) {
|
|
|
31642
31463
|
}
|
|
31643
31464
|
|
|
31644
31465
|
// src/commands/analyze/phases/08-memory-manifest.ts
|
|
31645
|
-
var
|
|
31466
|
+
var import_node_fs48 = require("node:fs");
|
|
31646
31467
|
var import_node_path37 = require("node:path");
|
|
31647
31468
|
async function memoryManifest(run4) {
|
|
31648
31469
|
const { globals } = run4;
|
|
@@ -31654,8 +31475,8 @@ async function memoryManifest(run4) {
|
|
|
31654
31475
|
try {
|
|
31655
31476
|
await ensureMemoryDir();
|
|
31656
31477
|
const seedMarker = (0, import_node_path37.join)(VERITY_DIR, ".seeded");
|
|
31657
|
-
const hasStandard = (0,
|
|
31658
|
-
const alreadyTried = (0,
|
|
31478
|
+
const hasStandard = (0, import_node_fs48.existsSync)(STANDARD_FILE);
|
|
31479
|
+
const alreadyTried = (0, import_node_fs48.existsSync)(seedMarker);
|
|
31659
31480
|
if (hasStandard && !alreadyTried) {
|
|
31660
31481
|
const preManifest = await buildManifest();
|
|
31661
31482
|
if (preManifest.nodes.length === 0) {
|
|
@@ -31668,7 +31489,7 @@ async function memoryManifest(run4) {
|
|
|
31668
31489
|
dryRun: false
|
|
31669
31490
|
});
|
|
31670
31491
|
if (seedResult.created > 0 || seedResult.existing > 0) {
|
|
31671
|
-
(0,
|
|
31492
|
+
(0, import_node_fs48.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created} existing=${seedResult.existing}
|
|
31672
31493
|
`);
|
|
31673
31494
|
if (seedResult.created > 0) {
|
|
31674
31495
|
autoSeedNotice = `Seeded ${seedResult.created} knowledge node(s) from your existing Standard (one-time).`;
|
|
@@ -31679,7 +31500,7 @@ async function memoryManifest(run4) {
|
|
|
31679
31500
|
failed: seedResult.failed
|
|
31680
31501
|
});
|
|
31681
31502
|
} else if (seedResult.skipped === "already_seeded") {
|
|
31682
|
-
(0,
|
|
31503
|
+
(0, import_node_fs48.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
|
|
31683
31504
|
`);
|
|
31684
31505
|
} else {
|
|
31685
31506
|
logEvent("auto_seed_noop", {
|
|
@@ -31867,24 +31688,8 @@ async function workingMemory(run4) {
|
|
|
31867
31688
|
Object.assign(run4, { incrementReport, memory: memory2, memorySession, reachability });
|
|
31868
31689
|
}
|
|
31869
31690
|
|
|
31870
|
-
// src/lib/payload-bounds.ts
|
|
31871
|
-
var MAX_WIRE_PATHS = 500;
|
|
31872
|
-
function boundPaths(paths, first, max = MAX_WIRE_PATHS) {
|
|
31873
|
-
if (paths.length <= max) return [...paths];
|
|
31874
|
-
const present = new Set(paths);
|
|
31875
|
-
const kept = /* @__PURE__ */ new Set();
|
|
31876
|
-
const out2 = [];
|
|
31877
|
-
for (const p of [...first, ...paths]) {
|
|
31878
|
-
if (out2.length >= max) break;
|
|
31879
|
-
if (!present.has(p) || kept.has(p)) continue;
|
|
31880
|
-
kept.add(p);
|
|
31881
|
-
out2.push(p);
|
|
31882
|
-
}
|
|
31883
|
-
return out2;
|
|
31884
|
-
}
|
|
31885
|
-
|
|
31886
31691
|
// src/lib/note-budget.ts
|
|
31887
|
-
var
|
|
31692
|
+
var import_node_fs49 = require("node:fs");
|
|
31888
31693
|
var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
|
|
31889
31694
|
var EPISODE_STALE_SECONDS = 30 * 60;
|
|
31890
31695
|
var FRESH = { delivered: 0, tasksCompleted: 0, ts: 0 };
|
|
@@ -31906,9 +31711,9 @@ function advisoryBudgetSpent(episode, rawDecision) {
|
|
|
31906
31711
|
}
|
|
31907
31712
|
function readAdvisoryEpisode(sessionId) {
|
|
31908
31713
|
const file = scopedFile(ADVISORY_EPISODE_FILE, sessionId);
|
|
31909
|
-
if (!(0,
|
|
31714
|
+
if (!(0, import_node_fs49.existsSync)(file)) return null;
|
|
31910
31715
|
try {
|
|
31911
|
-
const o = JSON.parse((0,
|
|
31716
|
+
const o = JSON.parse((0, import_node_fs49.readFileSync)(file, "utf-8")) ?? {};
|
|
31912
31717
|
const delivered = typeof o.delivered === "number" ? o.delivered : NaN;
|
|
31913
31718
|
if (isNaN(delivered)) return null;
|
|
31914
31719
|
return {
|
|
@@ -31922,8 +31727,8 @@ function readAdvisoryEpisode(sessionId) {
|
|
|
31922
31727
|
}
|
|
31923
31728
|
function writeAdvisoryEpisode(episode, sessionId) {
|
|
31924
31729
|
try {
|
|
31925
|
-
(0,
|
|
31926
|
-
(0,
|
|
31730
|
+
(0, import_node_fs49.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
31731
|
+
(0, import_node_fs49.writeFileSync)(
|
|
31927
31732
|
scopedFile(ADVISORY_EPISODE_FILE, sessionId),
|
|
31928
31733
|
JSON.stringify({ v: 1, ...episode })
|
|
31929
31734
|
);
|
|
@@ -31997,7 +31802,6 @@ async function buildRequest(run4) {
|
|
|
31997
31802
|
(conversation?.prompts?.length ?? 0) > 0
|
|
31998
31803
|
);
|
|
31999
31804
|
const noteConfirmation = peekNoteOutcome();
|
|
32000
|
-
const unobserved = foldResult?.unobserved ?? [];
|
|
32001
31805
|
const excludedByReason = {};
|
|
32002
31806
|
for (const e of codeDelta.excluded ?? []) {
|
|
32003
31807
|
excludedByReason[e.reason] = (excludedByReason[e.reason] ?? 0) + 1;
|
|
@@ -32042,9 +31846,7 @@ async function buildRequest(run4) {
|
|
|
32042
31846
|
coverage_telemetry: coverageTelemetry,
|
|
32043
31847
|
static_results: staticResults,
|
|
32044
31848
|
code_delta: codeDelta,
|
|
32045
|
-
|
|
32046
|
-
// full count is `coverage_telemetry.for_review`. VRT-242.
|
|
32047
|
-
changed_files: boundPaths(allForReview, codeDelta.files.map((f) => f.path)),
|
|
31849
|
+
changed_files: allForReview,
|
|
32048
31850
|
standard_version: "latest",
|
|
32049
31851
|
analysis_mode: analysisMode,
|
|
32050
31852
|
plan_only: analysisMode === "plan",
|
|
@@ -32095,9 +31897,7 @@ async function buildRequest(run4) {
|
|
|
32095
31897
|
// `hash_at_last_verdict` is frozen at each verdict and `hash_now` tracks
|
|
32096
31898
|
// disk, so their inequality IS "changed since we last spoke".
|
|
32097
31899
|
authored_since_verdict: memorySession ? foldDossier(memorySession.d).authored_all.filter((a) => a.hash_now !== a.hash_at_last_verdict).map((a) => a.path) : [],
|
|
32098
|
-
|
|
32099
|
-
unobserved: unobserved.slice(0, MAX_WIRE_PATHS),
|
|
32100
|
-
...unobserved.length > MAX_WIRE_PATHS && { unobserved_total: unobserved.length },
|
|
31900
|
+
unobserved: foldResult?.unobserved ?? [],
|
|
32101
31901
|
commands: foldResult?.commands ?? [],
|
|
32102
31902
|
tools: foldResult?.tools ?? [],
|
|
32103
31903
|
tasks: foldResult?.tasks ?? [],
|
|
@@ -32260,14 +32060,14 @@ async function buildRequest(run4) {
|
|
|
32260
32060
|
}
|
|
32261
32061
|
|
|
32262
32062
|
// src/lib/offline.ts
|
|
32263
|
-
var
|
|
32264
|
-
var
|
|
32063
|
+
var import_node_fs50 = require("node:fs");
|
|
32064
|
+
var import_node_crypto13 = require("node:crypto");
|
|
32265
32065
|
function cacheRequest(body2) {
|
|
32266
32066
|
try {
|
|
32267
|
-
(0,
|
|
32268
|
-
const suffix = (0,
|
|
32067
|
+
(0, import_node_fs50.mkdirSync)(CACHE_DIR, { recursive: true });
|
|
32068
|
+
const suffix = (0, import_node_crypto13.randomBytes)(4).toString("hex");
|
|
32269
32069
|
const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
|
|
32270
|
-
(0,
|
|
32070
|
+
(0, import_node_fs50.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body2)));
|
|
32271
32071
|
} catch {
|
|
32272
32072
|
}
|
|
32273
32073
|
}
|
|
@@ -32308,10 +32108,8 @@ function buildOfflineFallback(reason, staticResults) {
|
|
|
32308
32108
|
}
|
|
32309
32109
|
|
|
32310
32110
|
// src/lib/retry.ts
|
|
32311
|
-
var WORKER_RESOURCE_LIMIT = 546;
|
|
32312
32111
|
function shouldWarmRetryAnalyze(result) {
|
|
32313
32112
|
if (result.ok) return false;
|
|
32314
|
-
if (result.http_status === WORKER_RESOURCE_LIMIT) return false;
|
|
32315
32113
|
if (result.category === "network" || result.category === "timeout") return true;
|
|
32316
32114
|
if (result.category === "http_5xx") return true;
|
|
32317
32115
|
if (result.category === "invalid_json" && (result.http_status ?? 0) >= 500) return true;
|
|
@@ -32321,7 +32119,7 @@ function shouldWarmRetryAnalyze(result) {
|
|
|
32321
32119
|
// src/commands/analyze/phases/12-transmit.ts
|
|
32322
32120
|
async function transmit(run4) {
|
|
32323
32121
|
const { globals } = run4;
|
|
32324
|
-
const { requestBody, serviceUrl, staticResults, token } = run4;
|
|
32122
|
+
const { codeDelta, requestBody, serviceUrl, staticResults, token } = run4;
|
|
32325
32123
|
const ANALYZE_TIMEOUT_MS = 1e5;
|
|
32326
32124
|
let result = await analyzeRequest({
|
|
32327
32125
|
serviceUrl,
|
|
@@ -32358,12 +32156,11 @@ async function transmit(run4) {
|
|
|
32358
32156
|
}
|
|
32359
32157
|
if (!result.ok) {
|
|
32360
32158
|
cacheRequest(requestBody);
|
|
32361
|
-
const sentKb = () => Math.round(Buffer.byteLength(JSON.stringify(requestBody)) / 1024);
|
|
32362
32159
|
let message;
|
|
32363
32160
|
if (result.http_status === 413) {
|
|
32364
|
-
|
|
32365
|
-
|
|
32366
|
-
message = `Verity:
|
|
32161
|
+
const totalBytes = codeDelta.files.reduce((sum, f) => sum + f.content.length, 0);
|
|
32162
|
+
const kb = Math.round(totalBytes / 1024);
|
|
32163
|
+
message = `Verity: request rejected \u2014 payload too large (${kb}KB over the 190KB cap). Commit or stash pre-existing changes, or run with --mode skip if you didn't intend to submit code this turn.`;
|
|
32367
32164
|
} else if (result.category === "network" || result.category === "timeout") {
|
|
32368
32165
|
message = `Verity offline \u2014 ${result.error}`;
|
|
32369
32166
|
} else if (result.error.startsWith("STALE_VERIFICATION")) {
|
|
@@ -32389,7 +32186,7 @@ async function transmit(run4) {
|
|
|
32389
32186
|
}
|
|
32390
32187
|
|
|
32391
32188
|
// src/commands/analyze/phases/13-reconcile.ts
|
|
32392
|
-
var
|
|
32189
|
+
var import_node_fs51 = require("node:fs");
|
|
32393
32190
|
var import_node_path39 = require("node:path");
|
|
32394
32191
|
async function reconcile(run4) {
|
|
32395
32192
|
const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory: memory2, memorySession, response, reviewable, securityFiles, turnId } = run4;
|
|
@@ -32419,7 +32216,7 @@ async function reconcile(run4) {
|
|
|
32419
32216
|
const st = foldDossier(memorySession.d);
|
|
32420
32217
|
openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line2) => {
|
|
32421
32218
|
try {
|
|
32422
|
-
const src = (0,
|
|
32219
|
+
const src = (0, import_node_fs51.readFileSync)((0, import_node_path39.join)(repoRoot(), file), "utf8").split("\n");
|
|
32423
32220
|
const at = src[line2 - 1];
|
|
32424
32221
|
return at === void 0 ? null : lineSha(at);
|
|
32425
32222
|
} catch {
|
|
@@ -33241,7 +33038,7 @@ function registerAnalyzeCommand(program2) {
|
|
|
33241
33038
|
var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
|
|
33242
33039
|
async function runAnalyze(opts, globals) {
|
|
33243
33040
|
if (!verityConfigured()) {
|
|
33244
|
-
(0,
|
|
33041
|
+
(0, import_node_fs52.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
|
|
33245
33042
|
process.exit(0);
|
|
33246
33043
|
}
|
|
33247
33044
|
const run4 = createRun(opts, globals);
|
|
@@ -33262,12 +33059,11 @@ async function runAnalyze(opts, globals) {
|
|
|
33262
33059
|
}
|
|
33263
33060
|
|
|
33264
33061
|
// src/commands/baseline.ts
|
|
33265
|
-
var
|
|
33266
|
-
var import_node_path42 = require("node:path");
|
|
33062
|
+
var import_node_fs54 = require("node:fs");
|
|
33267
33063
|
|
|
33268
33064
|
// src/lib/project-skills.ts
|
|
33269
|
-
var
|
|
33270
|
-
var
|
|
33065
|
+
var import_node_fs53 = require("node:fs");
|
|
33066
|
+
var import_node_path40 = require("node:path");
|
|
33271
33067
|
var PROJECT_SKILL_NAMES = [
|
|
33272
33068
|
"verity-setup",
|
|
33273
33069
|
"verity-analyze",
|
|
@@ -33293,14 +33089,14 @@ var LEGACY_SKILL_NAMES = [
|
|
|
33293
33089
|
var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
|
|
33294
33090
|
function staleProjectSkills() {
|
|
33295
33091
|
const root = projectPath(".claude/skills");
|
|
33296
|
-
if (!(0,
|
|
33297
|
-
return ALL.filter((name2) => (0,
|
|
33092
|
+
if (!(0, import_node_fs53.existsSync)(root)) return [];
|
|
33093
|
+
return ALL.filter((name2) => (0, import_node_fs53.existsSync)((0, import_node_path40.join)(root, name2)));
|
|
33298
33094
|
}
|
|
33299
33095
|
function removeProjectSkills() {
|
|
33300
33096
|
const root = projectPath(".claude/skills");
|
|
33301
33097
|
const removed = [];
|
|
33302
33098
|
for (const name2 of staleProjectSkills()) {
|
|
33303
|
-
(0,
|
|
33099
|
+
(0, import_node_fs53.rmSync)((0, import_node_path40.join)(root, name2), { recursive: true, force: true });
|
|
33304
33100
|
removed.push(name2);
|
|
33305
33101
|
}
|
|
33306
33102
|
return removed;
|
|
@@ -33333,7 +33129,6 @@ function registerBaselineCommands(program2) {
|
|
|
33333
33129
|
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;
|
|
33334
33130
|
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;
|
|
33335
33131
|
if (!verityConfigured()) {
|
|
33336
|
-
if (isMachineStore((0, import_node_path42.join)(repoRoot(), VERITY_DIR))) process.exit(0);
|
|
33337
33132
|
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.";
|
|
33338
33133
|
const lines = [
|
|
33339
33134
|
`Verity is installed but this project is not set up yet, so the quality gate will not review anything here. ${how}`
|
|
@@ -33366,13 +33161,13 @@ function registerBaselineCommands(program2) {
|
|
|
33366
33161
|
let memoryMsg = null;
|
|
33367
33162
|
let memoryAgentLine = null;
|
|
33368
33163
|
const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
|
|
33369
|
-
if (realStart && !(0,
|
|
33164
|
+
if (realStart && !(0, import_node_fs54.existsSync)(memoryNotice)) {
|
|
33370
33165
|
const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
|
|
33371
33166
|
if (trackedGraph > 0) {
|
|
33372
33167
|
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.`;
|
|
33373
33168
|
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.`;
|
|
33374
33169
|
try {
|
|
33375
|
-
(0,
|
|
33170
|
+
(0, import_node_fs54.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
|
|
33376
33171
|
} catch {
|
|
33377
33172
|
}
|
|
33378
33173
|
}
|
|
@@ -33473,16 +33268,10 @@ function hookSource(value) {
|
|
|
33473
33268
|
}
|
|
33474
33269
|
|
|
33475
33270
|
// src/commands/review.ts
|
|
33476
|
-
var
|
|
33271
|
+
var import_node_fs55 = require("node:fs");
|
|
33477
33272
|
function registerReviewCommand(program2) {
|
|
33478
|
-
program2.command("review").description("Run on-demand Verity analysis (advisory, never blocks)").requiredOption("--files <paths>", "Comma-separated file list").option("--changed <paths>", "Subset of --files that were modified").option("--intent <text>", "User intent description (max 2000 chars)
|
|
33273
|
+
program2.command("review").description("Run on-demand Verity analysis (advisory, never blocks)").requiredOption("--files <paths>", "Comma-separated file list").option("--changed <paths>", "Subset of --files that were modified").option("--intent <text>", "User intent description (max 2000 chars)").option("--specs <paths>", "Comma-separated spec file paths").option("--json", "Output raw JSON response").action(async (opts) => {
|
|
33479
33274
|
const globals = program2.opts();
|
|
33480
|
-
const intent = readTextInput(opts.intent, "--intent");
|
|
33481
|
-
if (!intent.ok) {
|
|
33482
|
-
printError(intent.error);
|
|
33483
|
-
process.exit(0);
|
|
33484
|
-
}
|
|
33485
|
-
opts.intent = intent.text;
|
|
33486
33275
|
try {
|
|
33487
33276
|
await runReview(opts, globals);
|
|
33488
33277
|
} catch (err2) {
|
|
@@ -33496,7 +33285,7 @@ async function runReview(opts, globals) {
|
|
|
33496
33285
|
const changedFiles = opts.changed ? opts.changed.split(",").map((f) => f.trim()).filter(Boolean) : allFiles;
|
|
33497
33286
|
const analyzable = filterAnalyzable(allFiles);
|
|
33498
33287
|
const securityFiles = filterSecurity(allFiles);
|
|
33499
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0,
|
|
33288
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs55.existsSync)(f) || resolveFile(f) !== null);
|
|
33500
33289
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
33501
33290
|
const codeDelta = collectCodeDelta(allFiles);
|
|
33502
33291
|
const tokenResult = await resolveToken(globals.token);
|
|
@@ -33562,40 +33351,19 @@ async function runReview(opts, globals) {
|
|
|
33562
33351
|
}
|
|
33563
33352
|
|
|
33564
33353
|
// src/commands/guard.ts
|
|
33565
|
-
var
|
|
33566
|
-
var
|
|
33354
|
+
var import_node_fs59 = require("node:fs");
|
|
33355
|
+
var import_node_path45 = require("node:path");
|
|
33567
33356
|
|
|
33568
|
-
// src/lib/
|
|
33569
|
-
var
|
|
33570
|
-
|
|
33571
|
-
|
|
33572
|
-
|
|
33573
|
-
|
|
33574
|
-
return resolveDataDir();
|
|
33575
|
-
} catch {
|
|
33576
|
-
return null;
|
|
33577
|
-
}
|
|
33578
|
-
}
|
|
33579
|
-
function shippedSkillFile(path, dataDir = dataDirOrNull()) {
|
|
33580
|
-
const m = path.replace(/\\/g, "/").match(INSTALLED_SKILL);
|
|
33581
|
-
if (!m || !dataDir) return null;
|
|
33582
|
-
const [, skill, rel] = m;
|
|
33583
|
-
if (rel.split("/").some((seg) => seg === ".." || seg === ".")) return null;
|
|
33584
|
-
try {
|
|
33585
|
-
return (0, import_node_fs57.readFileSync)((0, import_node_path43.join)(dataDir, "skills", skill, rel), "utf8");
|
|
33586
|
-
} catch {
|
|
33587
|
-
return null;
|
|
33588
|
-
}
|
|
33357
|
+
// src/lib/terminal-text.ts
|
|
33358
|
+
var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/g;
|
|
33359
|
+
function terminalText(value, max = 4e3) {
|
|
33360
|
+
if (typeof value !== "string") return "";
|
|
33361
|
+
const clean2 = value.replace(CONTROL, "");
|
|
33362
|
+
return clean2.length > max ? `${clean2.slice(0, max - 1)}\u2026` : clean2;
|
|
33589
33363
|
}
|
|
33590
|
-
function
|
|
33591
|
-
const
|
|
33592
|
-
|
|
33593
|
-
for (const f of files) {
|
|
33594
|
-
const shipped = shippedSkillFile(f, dataDir);
|
|
33595
|
-
if (shipped !== null && read2(f) === shipped) vendored.push(f);
|
|
33596
|
-
else review.push(f);
|
|
33597
|
-
}
|
|
33598
|
-
return { review, vendored };
|
|
33364
|
+
function terminalUrl(value) {
|
|
33365
|
+
const clean2 = terminalText(value, 2e3);
|
|
33366
|
+
return /^https?:\/\/\S+$/.test(clean2) ? clean2 : "";
|
|
33599
33367
|
}
|
|
33600
33368
|
|
|
33601
33369
|
// src/lib/agent-driver.ts
|
|
@@ -33677,7 +33445,7 @@ async function runAgentReview(options) {
|
|
|
33677
33445
|
}
|
|
33678
33446
|
if (!settled) {
|
|
33679
33447
|
const wait = Math.max(0, remaining() - FINISH_TIMEOUT_MS);
|
|
33680
|
-
await Promise.race([oneShotDone, new Promise((
|
|
33448
|
+
await Promise.race([oneShotDone, new Promise((resolve8) => setTimeout(resolve8, wait))]);
|
|
33681
33449
|
}
|
|
33682
33450
|
const finished = await options.http.post(
|
|
33683
33451
|
"/agent-review/finish",
|
|
@@ -33692,8 +33460,8 @@ async function runAgentReview(options) {
|
|
|
33692
33460
|
}
|
|
33693
33461
|
|
|
33694
33462
|
// src/lib/prove/auto.ts
|
|
33695
|
-
var
|
|
33696
|
-
var
|
|
33463
|
+
var import_node_path44 = require("node:path");
|
|
33464
|
+
var import_node_crypto18 = require("node:crypto");
|
|
33697
33465
|
|
|
33698
33466
|
// src/lib/prove/signals.ts
|
|
33699
33467
|
var DEFAULT_SINCE = "180 days ago";
|
|
@@ -35419,18 +35187,18 @@ function renderReplay(model, property, r) {
|
|
|
35419
35187
|
// src/lib/prove/runner.ts
|
|
35420
35188
|
var import_node_child_process15 = require("node:child_process");
|
|
35421
35189
|
var import_node_os8 = require("node:os");
|
|
35422
|
-
var
|
|
35190
|
+
var import_node_fs58 = require("node:fs");
|
|
35423
35191
|
var import_node_os9 = require("node:os");
|
|
35424
|
-
var
|
|
35192
|
+
var import_node_path43 = require("node:path");
|
|
35425
35193
|
|
|
35426
35194
|
// src/lib/prove/scaffold.ts
|
|
35427
|
-
var
|
|
35428
|
-
var
|
|
35195
|
+
var import_node_fs57 = require("node:fs");
|
|
35196
|
+
var import_node_path42 = require("node:path");
|
|
35429
35197
|
|
|
35430
35198
|
// src/lib/prove/safe-write.ts
|
|
35431
|
-
var
|
|
35432
|
-
var
|
|
35433
|
-
var
|
|
35199
|
+
var import_node_fs56 = require("node:fs");
|
|
35200
|
+
var import_node_crypto14 = require("node:crypto");
|
|
35201
|
+
var import_node_path41 = require("node:path");
|
|
35434
35202
|
var SafeWriteError = class extends Error {
|
|
35435
35203
|
constructor(reason, path) {
|
|
35436
35204
|
super(`refusing to write ${path}: ${reason}`);
|
|
@@ -35439,10 +35207,10 @@ var SafeWriteError = class extends Error {
|
|
|
35439
35207
|
this.name = "SafeWriteError";
|
|
35440
35208
|
}
|
|
35441
35209
|
};
|
|
35442
|
-
var FLAGS3 =
|
|
35210
|
+
var FLAGS3 = import_node_fs56.constants;
|
|
35443
35211
|
var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
|
|
35444
35212
|
function assertPlainRelative(rel) {
|
|
35445
|
-
if (!rel || (0,
|
|
35213
|
+
if (!rel || (0, import_node_path41.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
|
|
35446
35214
|
for (const part of rel.split(/[\\/]/)) {
|
|
35447
35215
|
if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
|
|
35448
35216
|
}
|
|
@@ -35451,34 +35219,34 @@ function ensureDirsNoFollow(root, rel) {
|
|
|
35451
35219
|
const parts2 = rel.split(/[\\/]/);
|
|
35452
35220
|
let cur = root;
|
|
35453
35221
|
for (const part of parts2.slice(0, -1)) {
|
|
35454
|
-
cur = (0,
|
|
35222
|
+
cur = (0, import_node_path41.join)(cur, part);
|
|
35455
35223
|
let st;
|
|
35456
35224
|
try {
|
|
35457
|
-
st = (0,
|
|
35225
|
+
st = (0, import_node_fs56.lstatSync)(cur);
|
|
35458
35226
|
} catch {
|
|
35459
|
-
(0,
|
|
35227
|
+
(0, import_node_fs56.mkdirSync)(cur);
|
|
35460
35228
|
continue;
|
|
35461
35229
|
}
|
|
35462
35230
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
|
|
35463
35231
|
if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
|
|
35464
35232
|
}
|
|
35465
|
-
return (0,
|
|
35233
|
+
return (0, import_node_path41.join)(root, rel);
|
|
35466
35234
|
}
|
|
35467
35235
|
function insideRoot(realRoot, realPath) {
|
|
35468
|
-
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(
|
|
35236
|
+
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path41.sep) ? realRoot : realRoot + import_node_path41.sep);
|
|
35469
35237
|
}
|
|
35470
35238
|
function removeQuietly(path) {
|
|
35471
35239
|
try {
|
|
35472
|
-
(0,
|
|
35240
|
+
(0, import_node_fs56.unlinkSync)(path);
|
|
35473
35241
|
} catch {
|
|
35474
35242
|
}
|
|
35475
35243
|
}
|
|
35476
35244
|
function writeFileInRootNoFollow(root, rel, content) {
|
|
35477
35245
|
assertPlainRelative(rel);
|
|
35478
35246
|
const dest = ensureDirsNoFollow(root, rel);
|
|
35479
|
-
const dir = (0,
|
|
35247
|
+
const dir = (0, import_node_path41.dirname)(dest);
|
|
35480
35248
|
try {
|
|
35481
|
-
const st = (0,
|
|
35249
|
+
const st = (0, import_node_fs56.lstatSync)(dest);
|
|
35482
35250
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
|
|
35483
35251
|
if (!st.isFile()) throw new SafeWriteError("not-regular", dest);
|
|
35484
35252
|
} catch (err2) {
|
|
@@ -35486,41 +35254,41 @@ function writeFileInRootNoFollow(root, rel, content) {
|
|
|
35486
35254
|
}
|
|
35487
35255
|
let realRoot;
|
|
35488
35256
|
try {
|
|
35489
|
-
realRoot = (0,
|
|
35257
|
+
realRoot = (0, import_node_fs56.realpathSync)(root);
|
|
35490
35258
|
} catch {
|
|
35491
35259
|
throw new SafeWriteError("unwritable", root);
|
|
35492
35260
|
}
|
|
35493
|
-
const tmp = (0,
|
|
35261
|
+
const tmp = (0, import_node_path41.join)(dir, `.${(0, import_node_path41.basename)(dest)}.${(0, import_node_crypto14.randomBytes)(6).toString("hex")}.tmp`);
|
|
35494
35262
|
let fd;
|
|
35495
35263
|
try {
|
|
35496
|
-
fd = (0,
|
|
35264
|
+
fd = (0, import_node_fs56.openSync)(tmp, import_node_fs56.constants.O_WRONLY | import_node_fs56.constants.O_CREAT | import_node_fs56.constants.O_EXCL | NOFOLLOW2, 420);
|
|
35497
35265
|
} catch {
|
|
35498
35266
|
throw new SafeWriteError("unwritable", tmp);
|
|
35499
35267
|
}
|
|
35500
35268
|
try {
|
|
35501
|
-
const opened = (0,
|
|
35269
|
+
const opened = (0, import_node_fs56.fstatSync)(fd, { bigint: true });
|
|
35502
35270
|
let realTmp;
|
|
35503
35271
|
try {
|
|
35504
|
-
realTmp = (0,
|
|
35272
|
+
realTmp = (0, import_node_fs56.realpathSync)(tmp);
|
|
35505
35273
|
} catch {
|
|
35506
35274
|
throw new SafeWriteError("escaped", tmp);
|
|
35507
35275
|
}
|
|
35508
|
-
const there = (0,
|
|
35276
|
+
const there = (0, import_node_fs56.lstatSync)(realTmp, { bigint: true });
|
|
35509
35277
|
if (!opened.isFile() || there.ino !== opened.ino || there.dev !== opened.dev || !insideRoot(realRoot, realTmp)) {
|
|
35510
35278
|
throw new SafeWriteError("escaped", tmp);
|
|
35511
35279
|
}
|
|
35512
35280
|
const buf = Buffer.from(content, "utf-8");
|
|
35513
35281
|
let off = 0;
|
|
35514
|
-
while (off < buf.length) off += (0,
|
|
35282
|
+
while (off < buf.length) off += (0, import_node_fs56.writeSync)(fd, buf, off, buf.length - off);
|
|
35515
35283
|
} catch (err2) {
|
|
35516
|
-
(0,
|
|
35284
|
+
(0, import_node_fs56.closeSync)(fd);
|
|
35517
35285
|
removeQuietly(tmp);
|
|
35518
35286
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", tmp);
|
|
35519
35287
|
}
|
|
35520
|
-
(0,
|
|
35288
|
+
(0, import_node_fs56.closeSync)(fd);
|
|
35521
35289
|
try {
|
|
35522
|
-
if (!insideRoot(realRoot, (0,
|
|
35523
|
-
(0,
|
|
35290
|
+
if (!insideRoot(realRoot, (0, import_node_fs56.realpathSync)(dir)) || (0, import_node_fs56.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
|
|
35291
|
+
(0, import_node_fs56.renameSync)(tmp, dest);
|
|
35524
35292
|
} catch (err2) {
|
|
35525
35293
|
removeQuietly(tmp);
|
|
35526
35294
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", dest);
|
|
@@ -35534,9 +35302,9 @@ function pathHasNoLink(root, rel) {
|
|
|
35534
35302
|
}
|
|
35535
35303
|
let cur = root;
|
|
35536
35304
|
for (const part of rel.split(/[\\/]/)) {
|
|
35537
|
-
cur = cur +
|
|
35305
|
+
cur = cur + import_node_path41.sep + part;
|
|
35538
35306
|
try {
|
|
35539
|
-
if ((0,
|
|
35307
|
+
if ((0, import_node_fs56.lstatSync)(cur).isSymbolicLink()) return false;
|
|
35540
35308
|
} catch {
|
|
35541
35309
|
return true;
|
|
35542
35310
|
}
|
|
@@ -35846,20 +35614,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
|
|
|
35846
35614
|
never committed; what reaches the team is the bug report and the fix.
|
|
35847
35615
|
`;
|
|
35848
35616
|
function scaffoldProofs(root) {
|
|
35849
|
-
const proofsDir = (0,
|
|
35617
|
+
const proofsDir = (0, import_node_path42.join)(root, PROOFS_DIR);
|
|
35850
35618
|
const written = [];
|
|
35851
35619
|
const kept = [];
|
|
35852
35620
|
for (const stray of ["lakefile.lean"]) {
|
|
35853
35621
|
const rel = `${PROOFS_DIR}/${stray}`;
|
|
35854
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35622
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path42.join)(root, rel));
|
|
35855
35623
|
try {
|
|
35856
|
-
(0,
|
|
35624
|
+
(0, import_node_fs57.rmSync)((0, import_node_path42.join)(root, rel), { force: true });
|
|
35857
35625
|
} catch {
|
|
35858
35626
|
}
|
|
35859
35627
|
}
|
|
35860
35628
|
for (const f of PROOFS_TEMPLATE_FILES) {
|
|
35861
35629
|
const rel = `${PROOFS_DIR}/${f.path}`;
|
|
35862
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35630
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path42.join)(root, rel));
|
|
35863
35631
|
const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
|
|
35864
35632
|
if (current.ok && current.content === f.content) {
|
|
35865
35633
|
kept.push(rel);
|
|
@@ -35872,8 +35640,8 @@ function scaffoldProofs(root) {
|
|
|
35872
35640
|
[`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
|
|
35873
35641
|
[`${MODELS_DIR}/README.md`, MODELS_README]
|
|
35874
35642
|
]) {
|
|
35875
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35876
|
-
if (existsNoFollow((0,
|
|
35643
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path42.join)(root, rel));
|
|
35644
|
+
if (existsNoFollow((0, import_node_path42.join)(root, rel))) {
|
|
35877
35645
|
kept.push(rel);
|
|
35878
35646
|
continue;
|
|
35879
35647
|
}
|
|
@@ -35884,7 +35652,7 @@ function scaffoldProofs(root) {
|
|
|
35884
35652
|
}
|
|
35885
35653
|
function existsNoFollow(abs) {
|
|
35886
35654
|
try {
|
|
35887
|
-
(0,
|
|
35655
|
+
(0, import_node_fs57.lstatSync)(abs);
|
|
35888
35656
|
return true;
|
|
35889
35657
|
} catch {
|
|
35890
35658
|
return false;
|
|
@@ -35892,7 +35660,7 @@ function existsNoFollow(abs) {
|
|
|
35892
35660
|
}
|
|
35893
35661
|
|
|
35894
35662
|
// src/lib/prove/report.ts
|
|
35895
|
-
var
|
|
35663
|
+
var import_node_crypto15 = require("node:crypto");
|
|
35896
35664
|
var IDENT2 = /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$/;
|
|
35897
35665
|
var SHA256 = /^(sha256:)?[0-9a-f]{64}$/;
|
|
35898
35666
|
var KINDS2 = /* @__PURE__ */ new Set(["structural", "intent"]);
|
|
@@ -36040,7 +35808,7 @@ function sha256InRoot(root, file) {
|
|
|
36040
35808
|
const opened = openRegularInRoot(root, file);
|
|
36041
35809
|
if (!opened.ok) return null;
|
|
36042
35810
|
try {
|
|
36043
|
-
return (0,
|
|
35811
|
+
return (0, import_node_crypto15.createHash)("sha256").update(readOpened(opened.fd, opened.size)).digest("hex");
|
|
36044
35812
|
} catch {
|
|
36045
35813
|
return null;
|
|
36046
35814
|
}
|
|
@@ -36142,17 +35910,17 @@ function renderReport(r) {
|
|
|
36142
35910
|
|
|
36143
35911
|
// src/lib/prove/runner.ts
|
|
36144
35912
|
function verityLeanHome(env = process.env) {
|
|
36145
|
-
return env.VERITY_LEAN_HOME ?? (0,
|
|
35913
|
+
return env.VERITY_LEAN_HOME ?? (0, import_node_path43.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
|
|
36146
35914
|
}
|
|
36147
35915
|
function findToolchain(env = process.env) {
|
|
36148
|
-
const managedBin = (0,
|
|
36149
|
-
const elanBin = (0,
|
|
36150
|
-
const elanHas = (0,
|
|
36151
|
-
const userPath = (env.PATH ?? "").split(
|
|
36152
|
-
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(
|
|
35916
|
+
const managedBin = (0, import_node_path43.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
|
|
35917
|
+
const elanBin = (0, import_node_path43.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
|
|
35918
|
+
const elanHas = (0, import_node_fs58.existsSync)((0, import_node_path43.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
|
|
35919
|
+
const userPath = (env.PATH ?? "").split(import_node_path43.delimiter).filter((d) => d && (elanHas || (0, import_node_path43.resolve)(d) !== (0, import_node_path43.resolve)(elanBin)));
|
|
35920
|
+
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path43.delimiter);
|
|
36153
35921
|
const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
|
|
36154
35922
|
const exe = process.platform === "win32" ? "lake.exe" : "lake";
|
|
36155
|
-
const candidates2 = [(0,
|
|
35923
|
+
const candidates2 = [(0, import_node_path43.join)(managedBin, exe), ...elanHas ? [(0, import_node_path43.join)(elanBin, exe)] : [], exe];
|
|
36156
35924
|
for (const candidate of candidates2) {
|
|
36157
35925
|
try {
|
|
36158
35926
|
(0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
|
|
@@ -36190,7 +35958,7 @@ function run2(tc, cwd, args2, timeoutMs) {
|
|
|
36190
35958
|
function runAsync(tc, cwd, args2, timeoutMs) {
|
|
36191
35959
|
const started = Date.now();
|
|
36192
35960
|
const MAX = 16 * 1024 * 1024;
|
|
36193
|
-
return new Promise((
|
|
35961
|
+
return new Promise((resolve8) => {
|
|
36194
35962
|
const posix = (0, import_node_os8.platform)() !== "win32";
|
|
36195
35963
|
const child = (0, import_node_child_process15.spawn)(tc.lake, args2, { cwd, env: tc.env, stdio: ["ignore", "pipe", "pipe"], detached: posix });
|
|
36196
35964
|
let stdout = "";
|
|
@@ -36218,8 +35986,8 @@ function runAsync(tc, cwd, args2, timeoutMs) {
|
|
|
36218
35986
|
if (settled) return;
|
|
36219
35987
|
settled = true;
|
|
36220
35988
|
clearTimeout(timer);
|
|
36221
|
-
if (ok)
|
|
36222
|
-
else
|
|
35989
|
+
if (ok) resolve8({ ok: true, stdout, stderr: "", durationMs: Date.now() - started, timedOut: false });
|
|
35990
|
+
else resolve8({ ok: false, stdout, stderr: stderr || message || "", durationMs: Date.now() - started, timedOut });
|
|
36223
35991
|
};
|
|
36224
35992
|
child.on("error", (err2) => finish(false, err2.message));
|
|
36225
35993
|
child.on("close", (code) => finish(code === 0 && !timedOut));
|
|
@@ -36231,7 +35999,7 @@ function proofsWorkspaceProblem(root) {
|
|
|
36231
35999
|
for (const rel of [".verity", PROOFS_DIR, `${PROOFS_DIR}/.lake`]) {
|
|
36232
36000
|
let st;
|
|
36233
36001
|
try {
|
|
36234
|
-
st = (0,
|
|
36002
|
+
st = (0, import_node_fs58.lstatSync)((0, import_node_path43.join)(root, rel));
|
|
36235
36003
|
} catch {
|
|
36236
36004
|
break;
|
|
36237
36005
|
}
|
|
@@ -36251,44 +36019,44 @@ function refused(problem) {
|
|
|
36251
36019
|
function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
36252
36020
|
const problem = proofsWorkspaceProblem(root);
|
|
36253
36021
|
if (problem) return refused(problem);
|
|
36254
|
-
return run2(tc, (0,
|
|
36022
|
+
return run2(tc, (0, import_node_path43.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36255
36023
|
}
|
|
36256
36024
|
async function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
36257
36025
|
const problem = proofsWorkspaceProblem(root);
|
|
36258
36026
|
if (problem) return refused(problem);
|
|
36259
|
-
return runAsync(tc, (0,
|
|
36027
|
+
return runAsync(tc, (0, import_node_path43.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36260
36028
|
}
|
|
36261
36029
|
function isModelInRoot(modelsAbs, rel) {
|
|
36262
|
-
if (!rel.endsWith(".lean") || (0,
|
|
36030
|
+
if (!rel.endsWith(".lean") || (0, import_node_path43.isAbsolute)(rel) || rel.startsWith("..")) return false;
|
|
36263
36031
|
return statRegularInRoot(modelsAbs, rel).ok;
|
|
36264
36032
|
}
|
|
36265
36033
|
function resolveModelFile(root, arg) {
|
|
36266
|
-
const modelsAbs = (0,
|
|
36267
|
-
const asPath = (0,
|
|
36034
|
+
const modelsAbs = (0, import_node_path43.join)(root, MODELS_DIR);
|
|
36035
|
+
const asPath = (0, import_node_path43.relative)(modelsAbs, (0, import_node_path43.isAbsolute)(arg) ? arg : (0, import_node_path43.resolve)(root, arg));
|
|
36268
36036
|
const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
|
|
36269
36037
|
for (const rel of candidates2) {
|
|
36270
|
-
if (isModelInRoot(modelsAbs, rel)) return (0,
|
|
36038
|
+
if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path43.join)(modelsAbs, rel);
|
|
36271
36039
|
}
|
|
36272
36040
|
return null;
|
|
36273
36041
|
}
|
|
36274
36042
|
function listModelFiles(root) {
|
|
36275
|
-
const modelsAbs = (0,
|
|
36276
|
-
if (!(0,
|
|
36277
|
-
return (0,
|
|
36043
|
+
const modelsAbs = (0, import_node_path43.join)(root, MODELS_DIR);
|
|
36044
|
+
if (!(0, import_node_fs58.existsSync)(modelsAbs)) return [];
|
|
36045
|
+
return (0, import_node_fs58.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path43.join)(modelsAbs, f));
|
|
36278
36046
|
}
|
|
36279
36047
|
function trimDiagnostics(text) {
|
|
36280
36048
|
return text.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
|
|
36281
36049
|
}
|
|
36282
36050
|
function checkModel(tc, root, modelFile, opts = {}) {
|
|
36283
|
-
const proofsAbs = (0,
|
|
36284
|
-
const rel = (0,
|
|
36051
|
+
const proofsAbs = (0, import_node_path43.join)(root, PROOFS_DIR);
|
|
36052
|
+
const rel = (0, import_node_path43.relative)(proofsAbs, modelFile);
|
|
36285
36053
|
const problem = proofsWorkspaceProblem(root);
|
|
36286
36054
|
const res = problem ? refused(problem) : run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36287
36055
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36288
36056
|
}
|
|
36289
36057
|
async function checkModelAsync(tc, root, modelFile, opts = {}) {
|
|
36290
|
-
const proofsAbs = (0,
|
|
36291
|
-
const rel = (0,
|
|
36058
|
+
const proofsAbs = (0, import_node_path43.join)(root, PROOFS_DIR);
|
|
36059
|
+
const rel = (0, import_node_path43.relative)(proofsAbs, modelFile);
|
|
36292
36060
|
const problem = proofsWorkspaceProblem(root);
|
|
36293
36061
|
const res = problem ? refused(problem) : await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36294
36062
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
@@ -36297,10 +36065,10 @@ function toReport(res, root, modelFile, timeoutMs) {
|
|
|
36297
36065
|
const parsed = parseVerityLines(res.stdout);
|
|
36298
36066
|
const combined = `${res.stdout}
|
|
36299
36067
|
${res.stderr}`;
|
|
36300
|
-
const name2 = parsed.header?.model ?? (0,
|
|
36068
|
+
const name2 = parsed.header?.model ?? (0, import_node_path43.basename)(modelFile, ".lean");
|
|
36301
36069
|
const report = {
|
|
36302
36070
|
model: name2,
|
|
36303
|
-
file: (0,
|
|
36071
|
+
file: (0, import_node_path43.relative)(root, modelFile),
|
|
36304
36072
|
ok: res.ok,
|
|
36305
36073
|
header: parsed.header,
|
|
36306
36074
|
properties: parsed.properties,
|
|
@@ -36375,7 +36143,7 @@ function mergeFormalFindings(response, outcome, pushedFiles) {
|
|
|
36375
36143
|
}
|
|
36376
36144
|
|
|
36377
36145
|
// src/lib/prove/scalpel.ts
|
|
36378
|
-
var
|
|
36146
|
+
var import_node_crypto16 = require("node:crypto");
|
|
36379
36147
|
var ARITHMETIC = /Math\.(?:round|floor|ceil|trunc)\(|\bround\(|\bdivmod\(|[\w)\]]\s*(?:\*|\/(?!\/)|%)\s*[\w(]/;
|
|
36380
36148
|
function functionHazard(numbered2) {
|
|
36381
36149
|
const sites = effectSites(numbered2);
|
|
@@ -36405,7 +36173,7 @@ function semanticFingerprint(numbered2) {
|
|
|
36405
36173
|
if (LOG_LINE.test(t)) continue;
|
|
36406
36174
|
kept.push(t.replace(/\s+/g, " "));
|
|
36407
36175
|
}
|
|
36408
|
-
return (0,
|
|
36176
|
+
return (0, import_node_crypto16.createHash)("sha256").update(kept.join("\n")).digest("hex");
|
|
36409
36177
|
}
|
|
36410
36178
|
function readVerified(root, now = Date.now()) {
|
|
36411
36179
|
const read2 = readRegularFileInRoot(root, VERIFIED_FILE, 256 * 1024);
|
|
@@ -36428,9 +36196,9 @@ function recordVerified(root, rec, now = Date.now()) {
|
|
|
36428
36196
|
}
|
|
36429
36197
|
|
|
36430
36198
|
// src/lib/prove/context.ts
|
|
36431
|
-
var
|
|
36199
|
+
var import_node_crypto17 = require("node:crypto");
|
|
36432
36200
|
var CONTEXT_BUDGET_MS = 2e3;
|
|
36433
|
-
var sha256 = (s) => (0,
|
|
36201
|
+
var sha256 = (s) => (0, import_node_crypto17.createHash)("sha256").update(s).digest("hex");
|
|
36434
36202
|
var TEST_PATH4 = /(^|\/)(tests?|__tests__|spec)\/|\.(test|spec)\.[a-z]+$/;
|
|
36435
36203
|
function slice(content, f, maxLines) {
|
|
36436
36204
|
const all = content.split("\n");
|
|
@@ -36619,7 +36387,7 @@ function workingTreeReader(root) {
|
|
|
36619
36387
|
};
|
|
36620
36388
|
}
|
|
36621
36389
|
function sha256Of(content) {
|
|
36622
|
-
return (0,
|
|
36390
|
+
return (0, import_node_crypto18.createHash)("sha256").update(content).digest("hex");
|
|
36623
36391
|
}
|
|
36624
36392
|
function defaultDeps(opts) {
|
|
36625
36393
|
const env = opts.env ?? process.env;
|
|
@@ -36870,7 +36638,7 @@ async function runFormalPhase(input) {
|
|
|
36870
36638
|
modelName = gen.name;
|
|
36871
36639
|
const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
|
|
36872
36640
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
36873
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
36641
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path44.join)(root, rel);
|
|
36874
36642
|
progress.model = { name: gen.name, file: rel, rounds: round };
|
|
36875
36643
|
progress.step = "check";
|
|
36876
36644
|
report = await deps.check(root, abs);
|
|
@@ -36931,11 +36699,11 @@ async function runFormalPhase(input) {
|
|
|
36931
36699
|
const budget = Math.max(2e4, timeLeft() - 5e3);
|
|
36932
36700
|
const byId = /* @__PURE__ */ new Map();
|
|
36933
36701
|
let stoppedEarly = false;
|
|
36934
|
-
await new Promise((
|
|
36702
|
+
await new Promise((resolve8) => {
|
|
36935
36703
|
let left = toReplay.length;
|
|
36936
|
-
if (left === 0) return
|
|
36704
|
+
if (left === 0) return resolve8();
|
|
36937
36705
|
const settle = () => {
|
|
36938
|
-
if (--left === 0)
|
|
36706
|
+
if (--left === 0) resolve8();
|
|
36939
36707
|
};
|
|
36940
36708
|
for (const p of toReplay) {
|
|
36941
36709
|
void (async () => {
|
|
@@ -36948,7 +36716,7 @@ async function runFormalPhase(input) {
|
|
|
36948
36716
|
if (!stoppedEarly) byId.set(p.id, r);
|
|
36949
36717
|
if (r.verdict === "reproduced" && !stoppedEarly && !isCrash(p)) {
|
|
36950
36718
|
stoppedEarly = true;
|
|
36951
|
-
|
|
36719
|
+
resolve8();
|
|
36952
36720
|
}
|
|
36953
36721
|
})().catch(() => {
|
|
36954
36722
|
byId.set(p.id, null);
|
|
@@ -36992,7 +36760,7 @@ async function runFormalPhase(input) {
|
|
|
36992
36760
|
return done({
|
|
36993
36761
|
status: "checked",
|
|
36994
36762
|
target,
|
|
36995
|
-
model: { name: modelName, file: (0,
|
|
36763
|
+
model: { name: modelName, file: (0, import_node_path44.relative)(root, (0, import_node_path44.join)(root, modelFile)), rounds },
|
|
36996
36764
|
properties: report.properties,
|
|
36997
36765
|
findings
|
|
36998
36766
|
});
|
|
@@ -37055,7 +36823,7 @@ async function generateAndCheck(root, req, opts) {
|
|
|
37055
36823
|
}
|
|
37056
36824
|
const rel = `${dir}/${gen.name}.lean`;
|
|
37057
36825
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
37058
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
36826
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path44.join)(root, rel);
|
|
37059
36827
|
const report = await opts.deps.check(root, abs);
|
|
37060
36828
|
const abstracts = report.header?.abstracts ?? [];
|
|
37061
36829
|
const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
|
|
@@ -37143,10 +36911,10 @@ function runFormalPhaseWithin(input) {
|
|
|
37143
36911
|
if (left <= 0) return Promise.resolve(skippedOutcome("deadline", "no time left"));
|
|
37144
36912
|
const progress = input.progress ?? {};
|
|
37145
36913
|
let timer = null;
|
|
37146
|
-
const cutoff = new Promise((
|
|
36914
|
+
const cutoff = new Promise((resolve8) => {
|
|
37147
36915
|
timer = setTimeout(() => {
|
|
37148
36916
|
progress.cancelled = true;
|
|
37149
|
-
|
|
36917
|
+
resolve8(cutOffOutcome(progress, `hard stop after ${Math.round(left / 1e3)} s during ${progress.step ?? "setup"}`, left));
|
|
37150
36918
|
}, left);
|
|
37151
36919
|
});
|
|
37152
36920
|
return Promise.race([runFormalPhase({ ...input, progress }), cutoff]).finally(() => {
|
|
@@ -37183,14 +36951,13 @@ function describeFormalOutcome(o) {
|
|
|
37183
36951
|
var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
|
|
37184
36952
|
var WRITERS_BUDGET_MS = 1500;
|
|
37185
36953
|
var EXCERPT_MAX_LINES2 = 30;
|
|
37186
|
-
var VENDORED_READ_MAX_BYTES = 256 * 1024;
|
|
37187
36954
|
var GUARD_BLOCK_CAP = 2;
|
|
37188
|
-
var GUARD_ITER_FILE = (0,
|
|
36955
|
+
var GUARD_ITER_FILE = (0, import_node_path45.join)(VERITY_DIR, ".guard-iteration");
|
|
37189
36956
|
function readPreToolUseStdin() {
|
|
37190
36957
|
const empty = { command: "", cwd: null, sessionId: null };
|
|
37191
|
-
return new Promise((
|
|
36958
|
+
return new Promise((resolve8) => {
|
|
37192
36959
|
try {
|
|
37193
|
-
if (process.stdin.isTTY) return
|
|
36960
|
+
if (process.stdin.isTTY) return resolve8(empty);
|
|
37194
36961
|
const chunks = [];
|
|
37195
36962
|
let timer;
|
|
37196
36963
|
let settled = false;
|
|
@@ -37203,7 +36970,7 @@ function readPreToolUseStdin() {
|
|
|
37203
36970
|
process.stdin.removeListener("end", onEnd);
|
|
37204
36971
|
process.stdin.removeListener("error", onError);
|
|
37205
36972
|
process.stdin.pause();
|
|
37206
|
-
|
|
36973
|
+
resolve8(value);
|
|
37207
36974
|
};
|
|
37208
36975
|
const onEnd = () => {
|
|
37209
36976
|
try {
|
|
@@ -37224,13 +36991,13 @@ function readPreToolUseStdin() {
|
|
|
37224
36991
|
process.stdin.on("error", onError);
|
|
37225
36992
|
process.stdin.resume();
|
|
37226
36993
|
} catch {
|
|
37227
|
-
|
|
36994
|
+
resolve8(empty);
|
|
37228
36995
|
}
|
|
37229
36996
|
});
|
|
37230
36997
|
}
|
|
37231
36998
|
function readIterMap() {
|
|
37232
36999
|
try {
|
|
37233
|
-
const raw = JSON.parse((0,
|
|
37000
|
+
const raw = JSON.parse((0, import_node_fs59.readFileSync)(GUARD_ITER_FILE, "utf-8"));
|
|
37234
37001
|
if (raw && typeof raw === "object") {
|
|
37235
37002
|
if (typeof raw.moment === "string" && typeof raw.count === "number") {
|
|
37236
37003
|
return { [raw.moment]: raw.count };
|
|
@@ -37250,10 +37017,10 @@ function readIter(moment) {
|
|
|
37250
37017
|
}
|
|
37251
37018
|
function writeIter(moment, count) {
|
|
37252
37019
|
try {
|
|
37253
|
-
(0,
|
|
37020
|
+
(0, import_node_fs59.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
37254
37021
|
const map = readIterMap();
|
|
37255
37022
|
map[moment] = count;
|
|
37256
|
-
(0,
|
|
37023
|
+
(0, import_node_fs59.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
37257
37024
|
} catch {
|
|
37258
37025
|
}
|
|
37259
37026
|
}
|
|
@@ -37263,10 +37030,10 @@ function resetIter(moment) {
|
|
|
37263
37030
|
if (!(moment in map)) return;
|
|
37264
37031
|
delete map[moment];
|
|
37265
37032
|
if (Object.keys(map).length === 0) {
|
|
37266
|
-
if ((0,
|
|
37033
|
+
if ((0, import_node_fs59.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs59.unlinkSync)(GUARD_ITER_FILE);
|
|
37267
37034
|
} else {
|
|
37268
|
-
(0,
|
|
37269
|
-
(0,
|
|
37035
|
+
(0, import_node_fs59.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
37036
|
+
(0, import_node_fs59.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
37270
37037
|
}
|
|
37271
37038
|
} catch {
|
|
37272
37039
|
}
|
|
@@ -37336,7 +37103,7 @@ function hasBlockingFinding(response, sentFiles) {
|
|
|
37336
37103
|
function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
|
|
37337
37104
|
const analyzable = filterAnalyzable(files);
|
|
37338
37105
|
const securityFiles = filterSecurity(files);
|
|
37339
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0,
|
|
37106
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs59.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
|
|
37340
37107
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
37341
37108
|
const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
|
|
37342
37109
|
const requestBody = {
|
|
@@ -37573,15 +37340,7 @@ async function runGuard(opts, globals) {
|
|
|
37573
37340
|
`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.`
|
|
37574
37341
|
);
|
|
37575
37342
|
}
|
|
37576
|
-
const
|
|
37577
|
-
frame.worktreeRoot ?? process.cwd(),
|
|
37578
|
-
range.kind === "push" && range.head !== "INDEX" ? range.head : null
|
|
37579
|
-
);
|
|
37580
|
-
const { review: files, vendored } = partitionVendored(rangeFiles(frame, range), (p) => {
|
|
37581
|
-
const read2 = committed.read(p, VENDORED_READ_MAX_BYTES);
|
|
37582
|
-
return read2.ok ? read2.content : null;
|
|
37583
|
-
});
|
|
37584
|
-
if (vendored.length > 0) logEvent("guard_vendored", { moment, n: vendored.length, paths: vendored.slice(0, 20) });
|
|
37343
|
+
const files = rangeFiles(frame, range);
|
|
37585
37344
|
if (files.length === 0) process.exit(0);
|
|
37586
37345
|
const tokenResult = await resolveToken(globals.token);
|
|
37587
37346
|
const urlResult = await resolveServiceUrl(globals.serviceUrl);
|
|
@@ -37961,8 +37720,8 @@ function registerIgnoreCommand(program2) {
|
|
|
37961
37720
|
}
|
|
37962
37721
|
|
|
37963
37722
|
// src/commands/waive.ts
|
|
37964
|
-
var
|
|
37965
|
-
var
|
|
37723
|
+
var import_node_crypto19 = require("node:crypto");
|
|
37724
|
+
var import_node_fs60 = require("node:fs");
|
|
37966
37725
|
function registerWaiveCommand(program2) {
|
|
37967
37726
|
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) => {
|
|
37968
37727
|
const globals = program2.opts();
|
|
@@ -37991,7 +37750,7 @@ function registerWaiveCommand(program2) {
|
|
|
37991
37750
|
if (opts.file) {
|
|
37992
37751
|
body2.file = opts.file;
|
|
37993
37752
|
try {
|
|
37994
|
-
body2.file_sha256 = (0,
|
|
37753
|
+
body2.file_sha256 = (0, import_node_crypto19.createHash)("sha256").update((0, import_node_fs60.readFileSync)(opts.file)).digest("hex");
|
|
37995
37754
|
} catch {
|
|
37996
37755
|
printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
|
|
37997
37756
|
process.exit(1);
|
|
@@ -38016,10 +37775,10 @@ function registerWaiveCommand(program2) {
|
|
|
38016
37775
|
}
|
|
38017
37776
|
|
|
38018
37777
|
// src/commands/init.ts
|
|
38019
|
-
var
|
|
37778
|
+
var import_node_fs65 = require("node:fs");
|
|
38020
37779
|
var import_promises20 = require("node:fs/promises");
|
|
38021
37780
|
var import_yaml6 = __toESM2(require_dist());
|
|
38022
|
-
var
|
|
37781
|
+
var import_node_path49 = require("node:path");
|
|
38023
37782
|
var import_node_child_process19 = require("node:child_process");
|
|
38024
37783
|
|
|
38025
37784
|
// src/lib/banner.ts
|
|
@@ -38098,7 +37857,7 @@ function printPhase(n, of, title, subtitle) {
|
|
|
38098
37857
|
}
|
|
38099
37858
|
|
|
38100
37859
|
// src/commands/doctor.ts
|
|
38101
|
-
var
|
|
37860
|
+
var import_node_fs61 = require("node:fs");
|
|
38102
37861
|
|
|
38103
37862
|
// src/lib/prereqs.ts
|
|
38104
37863
|
var import_node_child_process16 = require("node:child_process");
|
|
@@ -38159,13 +37918,13 @@ function checkAnalysisCli() {
|
|
|
38159
37918
|
}
|
|
38160
37919
|
var INSTALL_TIMEOUT_MS = 12e4;
|
|
38161
37920
|
function run3(command, args2, opts = {}) {
|
|
38162
|
-
return new Promise((
|
|
37921
|
+
return new Promise((resolve8) => {
|
|
38163
37922
|
const child = (0, import_node_child_process16.spawn)(command, args2, {
|
|
38164
37923
|
stdio: opts.inherit ? "inherit" : "pipe",
|
|
38165
37924
|
timeout: INSTALL_TIMEOUT_MS
|
|
38166
37925
|
});
|
|
38167
|
-
child.on("error", () =>
|
|
38168
|
-
child.on("close", (code) =>
|
|
37926
|
+
child.on("error", () => resolve8(false));
|
|
37927
|
+
child.on("close", (code) => resolve8(code === 0));
|
|
38169
37928
|
});
|
|
38170
37929
|
}
|
|
38171
37930
|
async function installAnalysisCli() {
|
|
@@ -38306,11 +38065,11 @@ async function buildReport() {
|
|
|
38306
38065
|
const hooks = wiring.status;
|
|
38307
38066
|
const provenance = cliProvenance();
|
|
38308
38067
|
const telemetry = await checkTelemetry();
|
|
38309
|
-
const hasConfig = (0,
|
|
38068
|
+
const hasConfig = (0, import_node_fs61.existsSync)(projectPath(CODACY_CONFIG_FILE));
|
|
38310
38069
|
const artifacts = {
|
|
38311
|
-
standard: (0,
|
|
38070
|
+
standard: (0, import_node_fs61.existsSync)(projectPath(STANDARD_FILE)),
|
|
38312
38071
|
analysisConfig: hasConfig,
|
|
38313
|
-
verityMd: (0,
|
|
38072
|
+
verityMd: (0, import_node_fs61.existsSync)(projectPath(VERITY_MD_FILE)),
|
|
38314
38073
|
analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
|
|
38315
38074
|
};
|
|
38316
38075
|
const next = [];
|
|
@@ -38469,8 +38228,8 @@ function registerDoctorCommand(program2) {
|
|
|
38469
38228
|
}
|
|
38470
38229
|
|
|
38471
38230
|
// src/commands/migrate.ts
|
|
38472
|
-
var
|
|
38473
|
-
var
|
|
38231
|
+
var import_node_fs62 = require("node:fs");
|
|
38232
|
+
var import_node_path46 = require("node:path");
|
|
38474
38233
|
var import_node_child_process17 = require("node:child_process");
|
|
38475
38234
|
var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
|
|
38476
38235
|
function defaultNpmRemover(pkg) {
|
|
@@ -38507,12 +38266,12 @@ async function runMigration(opts = {}) {
|
|
|
38507
38266
|
return { actions, migrated: actions.length > 0 };
|
|
38508
38267
|
}
|
|
38509
38268
|
function migrateProjectDir(root, actions) {
|
|
38510
|
-
const gateDir = (0,
|
|
38511
|
-
const verityDir = (0,
|
|
38512
|
-
if ((0,
|
|
38269
|
+
const gateDir = (0, import_node_path46.join)(root, ".gate");
|
|
38270
|
+
const verityDir = (0, import_node_path46.join)(root, ".verity");
|
|
38271
|
+
if ((0, import_node_fs62.existsSync)(gateDir) && !(0, import_node_fs62.existsSync)(verityDir)) {
|
|
38513
38272
|
return migrateProjectDirRename(root, gateDir, verityDir, actions);
|
|
38514
38273
|
}
|
|
38515
|
-
if ((0,
|
|
38274
|
+
if ((0, import_node_fs62.existsSync)(gateDir) && (0, import_node_fs62.existsSync)(verityDir)) {
|
|
38516
38275
|
return migrateProjectDirCarry(gateDir, verityDir, actions);
|
|
38517
38276
|
}
|
|
38518
38277
|
return false;
|
|
@@ -38533,13 +38292,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
|
|
|
38533
38292
|
}
|
|
38534
38293
|
}
|
|
38535
38294
|
if (moved) {
|
|
38536
|
-
if ((0,
|
|
38295
|
+
if ((0, import_node_fs62.existsSync)(gateDir)) {
|
|
38537
38296
|
const carried = carryLegacyContents(gateDir, verityDir);
|
|
38538
38297
|
if (carried > 0) {
|
|
38539
38298
|
actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
|
|
38540
38299
|
}
|
|
38541
38300
|
try {
|
|
38542
|
-
(0,
|
|
38301
|
+
(0, import_node_fs62.rmSync)(gateDir, { recursive: true, force: true });
|
|
38543
38302
|
} catch {
|
|
38544
38303
|
}
|
|
38545
38304
|
}
|
|
@@ -38555,18 +38314,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
|
|
|
38555
38314
|
actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
|
|
38556
38315
|
}
|
|
38557
38316
|
try {
|
|
38558
|
-
(0,
|
|
38317
|
+
(0, import_node_fs62.rmSync)(gateDir, { recursive: true, force: true });
|
|
38559
38318
|
} catch {
|
|
38560
38319
|
}
|
|
38561
38320
|
return carried > 0;
|
|
38562
38321
|
}
|
|
38563
38322
|
function migrateGlobalCredentials(home, actions) {
|
|
38564
38323
|
if (!home) return;
|
|
38565
|
-
const gateCreds = (0,
|
|
38566
|
-
const verityCreds = (0,
|
|
38567
|
-
if (!(0,
|
|
38568
|
-
if (!(0,
|
|
38569
|
-
(0,
|
|
38324
|
+
const gateCreds = (0, import_node_path46.join)(home, ".gate", "credentials");
|
|
38325
|
+
const verityCreds = (0, import_node_path46.join)(home, ".verity", "credentials");
|
|
38326
|
+
if (!(0, import_node_fs62.existsSync)(gateCreds)) return;
|
|
38327
|
+
if (!(0, import_node_fs62.existsSync)(verityCreds)) {
|
|
38328
|
+
(0, import_node_fs62.mkdirSync)((0, import_node_path46.join)(home, ".verity"), { recursive: true });
|
|
38570
38329
|
moveFile(gateCreds, verityCreds);
|
|
38571
38330
|
actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
|
|
38572
38331
|
return;
|
|
@@ -38588,8 +38347,8 @@ async function migrateLegacyHooks(root, actions) {
|
|
|
38588
38347
|
}
|
|
38589
38348
|
}
|
|
38590
38349
|
async function migrateClaudeMd(root, actions) {
|
|
38591
|
-
const claudeMd = (0,
|
|
38592
|
-
const hadLegacyBlock = (0,
|
|
38350
|
+
const claudeMd = (0, import_node_path46.join)(root, "CLAUDE.md");
|
|
38351
|
+
const hadLegacyBlock = (0, import_node_fs62.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
|
|
38593
38352
|
if (!hadLegacyBlock) return;
|
|
38594
38353
|
try {
|
|
38595
38354
|
await ensureClaudeMdPointer(root);
|
|
@@ -38599,9 +38358,9 @@ async function migrateClaudeMd(root, actions) {
|
|
|
38599
38358
|
}
|
|
38600
38359
|
}
|
|
38601
38360
|
function migrateStandardFile(root, actions) {
|
|
38602
|
-
const gateMd = (0,
|
|
38603
|
-
const verityMd = (0,
|
|
38604
|
-
if (!(0,
|
|
38361
|
+
const gateMd = (0, import_node_path46.join)(root, "GATE.md");
|
|
38362
|
+
const verityMd = (0, import_node_path46.join)(root, "VERITY.md");
|
|
38363
|
+
if (!(0, import_node_fs62.existsSync)(gateMd) || (0, import_node_fs62.existsSync)(verityMd)) return;
|
|
38605
38364
|
let moved = false;
|
|
38606
38365
|
if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
|
|
38607
38366
|
try {
|
|
@@ -38613,12 +38372,12 @@ function migrateStandardFile(root, actions) {
|
|
|
38613
38372
|
if (!moved) moveFile(gateMd, verityMd);
|
|
38614
38373
|
const content = readFileSyncSafe(verityMd);
|
|
38615
38374
|
const refreshed = content.split("GATE.md").join("VERITY.md");
|
|
38616
|
-
if (refreshed !== content) (0,
|
|
38375
|
+
if (refreshed !== content) (0, import_node_fs62.writeFileSync)(verityMd, refreshed);
|
|
38617
38376
|
actions.push("Renamed GATE.md \u2192 VERITY.md");
|
|
38618
38377
|
}
|
|
38619
38378
|
async function migrateTelemetryHeaders(root, actions) {
|
|
38620
|
-
const file = (0,
|
|
38621
|
-
if (!(0,
|
|
38379
|
+
const file = (0, import_node_path46.join)(root, ".claude", "settings.local.json");
|
|
38380
|
+
if (!(0, import_node_fs62.existsSync)(file)) return;
|
|
38622
38381
|
let settings;
|
|
38623
38382
|
try {
|
|
38624
38383
|
settings = JSON.parse(readFileSyncSafe(file) || "{}");
|
|
@@ -38666,14 +38425,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
|
|
|
38666
38425
|
}
|
|
38667
38426
|
if (toAppend.length > 0) {
|
|
38668
38427
|
const sep5 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
|
|
38669
|
-
(0,
|
|
38428
|
+
(0, import_node_fs62.writeFileSync)(verityCreds, verityContent + sep5 + toAppend.join("\n") + "\n");
|
|
38670
38429
|
}
|
|
38671
|
-
(0,
|
|
38430
|
+
(0, import_node_fs62.rmSync)(gateCreds, { force: true });
|
|
38672
38431
|
return toAppend.length;
|
|
38673
38432
|
}
|
|
38674
38433
|
function readFileSyncSafe(path) {
|
|
38675
38434
|
try {
|
|
38676
|
-
return (0,
|
|
38435
|
+
return (0, import_node_fs62.readFileSync)(path, "utf-8");
|
|
38677
38436
|
} catch {
|
|
38678
38437
|
return "";
|
|
38679
38438
|
}
|
|
@@ -38688,35 +38447,35 @@ function hasStagedChanges(root) {
|
|
|
38688
38447
|
}
|
|
38689
38448
|
function moveDir(from, to) {
|
|
38690
38449
|
try {
|
|
38691
|
-
(0,
|
|
38450
|
+
(0, import_node_fs62.renameSync)(from, to);
|
|
38692
38451
|
} catch (err2) {
|
|
38693
38452
|
if (err2.code !== "EXDEV") throw err2;
|
|
38694
|
-
(0,
|
|
38695
|
-
(0,
|
|
38453
|
+
(0, import_node_fs62.cpSync)(from, to, { recursive: true });
|
|
38454
|
+
(0, import_node_fs62.rmSync)(from, { recursive: true, force: true });
|
|
38696
38455
|
}
|
|
38697
38456
|
}
|
|
38698
38457
|
function moveFile(from, to) {
|
|
38699
38458
|
try {
|
|
38700
|
-
(0,
|
|
38459
|
+
(0, import_node_fs62.renameSync)(from, to);
|
|
38701
38460
|
} catch (err2) {
|
|
38702
38461
|
if (err2.code !== "EXDEV") throw err2;
|
|
38703
|
-
(0,
|
|
38704
|
-
(0,
|
|
38462
|
+
(0, import_node_fs62.cpSync)(from, to);
|
|
38463
|
+
(0, import_node_fs62.rmSync)(from, { force: true });
|
|
38705
38464
|
}
|
|
38706
38465
|
}
|
|
38707
38466
|
function carryLegacyContents(gateDir, verityDir) {
|
|
38708
38467
|
let copied = 0;
|
|
38709
38468
|
const walk2 = (relDir) => {
|
|
38710
|
-
const srcDir = (0,
|
|
38711
|
-
for (const entry of (0,
|
|
38712
|
-
const rel = relDir ? (0,
|
|
38713
|
-
const src = (0,
|
|
38714
|
-
const dest = (0,
|
|
38715
|
-
if ((0,
|
|
38469
|
+
const srcDir = (0, import_node_path46.join)(gateDir, relDir);
|
|
38470
|
+
for (const entry of (0, import_node_fs62.readdirSync)(srcDir)) {
|
|
38471
|
+
const rel = relDir ? (0, import_node_path46.join)(relDir, entry) : entry;
|
|
38472
|
+
const src = (0, import_node_path46.join)(gateDir, rel);
|
|
38473
|
+
const dest = (0, import_node_path46.join)(verityDir, rel);
|
|
38474
|
+
if ((0, import_node_fs62.statSync)(src).isDirectory()) {
|
|
38716
38475
|
walk2(rel);
|
|
38717
|
-
} else if (!(0,
|
|
38718
|
-
(0,
|
|
38719
|
-
(0,
|
|
38476
|
+
} else if (!(0, import_node_fs62.existsSync)(dest)) {
|
|
38477
|
+
(0, import_node_fs62.mkdirSync)((0, import_node_path46.dirname)(dest), { recursive: true });
|
|
38478
|
+
(0, import_node_fs62.cpSync)(src, dest);
|
|
38720
38479
|
copied++;
|
|
38721
38480
|
}
|
|
38722
38481
|
}
|
|
@@ -38725,22 +38484,22 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
38725
38484
|
return copied;
|
|
38726
38485
|
}
|
|
38727
38486
|
async function needsMigration(root = repoRoot()) {
|
|
38728
|
-
const gateDir = (0,
|
|
38729
|
-
const verityDir = (0,
|
|
38730
|
-
if ((0,
|
|
38731
|
-
if ((0,
|
|
38732
|
-
if ((0,
|
|
38487
|
+
const gateDir = (0, import_node_path46.join)(root, ".gate");
|
|
38488
|
+
const verityDir = (0, import_node_path46.join)(root, ".verity");
|
|
38489
|
+
if ((0, import_node_fs62.existsSync)(gateDir) && !(0, import_node_fs62.existsSync)(verityDir)) return true;
|
|
38490
|
+
if ((0, import_node_fs62.existsSync)(gateDir) && (0, import_node_fs62.existsSync)(verityDir)) {
|
|
38491
|
+
if ((0, import_node_fs62.existsSync)((0, import_node_path46.join)(gateDir, "credentials")) && !(0, import_node_fs62.existsSync)((0, import_node_path46.join)(verityDir, "credentials"))) {
|
|
38733
38492
|
return true;
|
|
38734
38493
|
}
|
|
38735
|
-
if ((0,
|
|
38494
|
+
if ((0, import_node_fs62.existsSync)((0, import_node_path46.join)(gateDir, "memory")) && !(0, import_node_fs62.existsSync)((0, import_node_path46.join)(verityDir, "memory"))) {
|
|
38736
38495
|
return true;
|
|
38737
38496
|
}
|
|
38738
38497
|
}
|
|
38739
|
-
const claudeMd = (0,
|
|
38740
|
-
if ((0,
|
|
38498
|
+
const claudeMd = (0, import_node_path46.join)(root, "CLAUDE.md");
|
|
38499
|
+
if ((0, import_node_fs62.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
|
|
38741
38500
|
return true;
|
|
38742
38501
|
}
|
|
38743
|
-
if ((0,
|
|
38502
|
+
if ((0, import_node_fs62.existsSync)((0, import_node_path46.join)(root, "GATE.md")) && !(0, import_node_fs62.existsSync)((0, import_node_path46.join)(root, "VERITY.md"))) {
|
|
38744
38503
|
return true;
|
|
38745
38504
|
}
|
|
38746
38505
|
if (await hasLegacyHooksAt(root)) return true;
|
|
@@ -38869,7 +38628,7 @@ function runSelect(opts) {
|
|
|
38869
38628
|
cursor: initialIdx[0] ?? 0,
|
|
38870
38629
|
chosen: new Set(mode2 === "single" ? [initialIdx[0] ?? 0] : initialIdx)
|
|
38871
38630
|
};
|
|
38872
|
-
return new Promise((
|
|
38631
|
+
return new Promise((resolve8) => {
|
|
38873
38632
|
let painted = 0;
|
|
38874
38633
|
let settled = false;
|
|
38875
38634
|
const draw = () => {
|
|
@@ -38917,7 +38676,7 @@ function runSelect(opts) {
|
|
|
38917
38676
|
if (settled) return;
|
|
38918
38677
|
settled = true;
|
|
38919
38678
|
restore();
|
|
38920
|
-
|
|
38679
|
+
resolve8(value);
|
|
38921
38680
|
};
|
|
38922
38681
|
readline2.emitKeypressEvents(input);
|
|
38923
38682
|
input.setRawMode(true);
|
|
@@ -38938,9 +38697,9 @@ async function askLine(question, io = {}) {
|
|
|
38938
38697
|
output: io.output ?? process.stdout
|
|
38939
38698
|
});
|
|
38940
38699
|
try {
|
|
38941
|
-
return await new Promise((
|
|
38942
|
-
rl.question(question).then((a) =>
|
|
38943
|
-
rl.once("close", () => setImmediate(() =>
|
|
38700
|
+
return await new Promise((resolve8) => {
|
|
38701
|
+
rl.question(question).then((a) => resolve8(a.trim())).catch(() => resolve8(null));
|
|
38702
|
+
rl.once("close", () => setImmediate(() => resolve8(null)));
|
|
38944
38703
|
});
|
|
38945
38704
|
} finally {
|
|
38946
38705
|
rl.close();
|
|
@@ -39021,11 +38780,11 @@ async function promptMultiSelect(question, choices, fallback) {
|
|
|
39021
38780
|
}
|
|
39022
38781
|
|
|
39023
38782
|
// src/lib/prove/lean-install.ts
|
|
39024
|
-
var
|
|
39025
|
-
var
|
|
38783
|
+
var import_node_fs63 = require("node:fs");
|
|
38784
|
+
var import_node_crypto20 = require("node:crypto");
|
|
39026
38785
|
var import_node_child_process18 = require("node:child_process");
|
|
39027
38786
|
var import_node_os10 = require("node:os");
|
|
39028
|
-
var
|
|
38787
|
+
var import_node_path47 = require("node:path");
|
|
39029
38788
|
var import_promises18 = require("node:stream/promises");
|
|
39030
38789
|
var import_node_stream = require("node:stream");
|
|
39031
38790
|
var RELEASES = "https://releases.lean-lang.org/lean4";
|
|
@@ -39036,10 +38795,10 @@ function freeBytes(dir) {
|
|
|
39036
38795
|
let d = dir;
|
|
39037
38796
|
for (let i2 = 0; i2 < 64; i2++) {
|
|
39038
38797
|
try {
|
|
39039
|
-
const st = (0,
|
|
38798
|
+
const st = (0, import_node_fs63.statfsSync)(d);
|
|
39040
38799
|
return Number(st.bavail) * Number(st.bsize);
|
|
39041
38800
|
} catch {
|
|
39042
|
-
const up = (0,
|
|
38801
|
+
const up = (0, import_node_path47.join)(d, "..");
|
|
39043
38802
|
if (up === d) return null;
|
|
39044
38803
|
d = up;
|
|
39045
38804
|
}
|
|
@@ -39059,9 +38818,9 @@ function expectedSha256(asset, version = pinnedVersion()) {
|
|
|
39059
38818
|
return LEAN_ASSET_SHA256[version]?.[asset] ?? null;
|
|
39060
38819
|
}
|
|
39061
38820
|
function sha256File(path) {
|
|
39062
|
-
return new Promise((
|
|
39063
|
-
const hash = (0,
|
|
39064
|
-
(0,
|
|
38821
|
+
return new Promise((resolve8, reject) => {
|
|
38822
|
+
const hash = (0, import_node_crypto20.createHash)("sha256");
|
|
38823
|
+
(0, import_node_fs63.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve8(hash.digest("hex"))).on("error", reject);
|
|
39065
38824
|
});
|
|
39066
38825
|
}
|
|
39067
38826
|
async function verifyDownload(zip, asset, version = pinnedVersion()) {
|
|
@@ -39081,7 +38840,7 @@ function leanAssetName(version = pinnedVersion()) {
|
|
|
39081
38840
|
return suffix ? `lean-${v}-${suffix}.zip` : null;
|
|
39082
38841
|
}
|
|
39083
38842
|
function pinnedVersionDir(env = process.env) {
|
|
39084
|
-
return (0,
|
|
38843
|
+
return (0, import_node_path47.join)(verityLeanHome(env), pinnedVersion());
|
|
39085
38844
|
}
|
|
39086
38845
|
function lakeBinary() {
|
|
39087
38846
|
return (0, import_node_os10.platform)() === "win32" ? "lake.exe" : "lake";
|
|
@@ -39092,12 +38851,12 @@ function unzip(zip, dest) {
|
|
|
39092
38851
|
for (const [cmd, args2] of attempts) {
|
|
39093
38852
|
try {
|
|
39094
38853
|
(0, import_node_child_process18.execFileSync)(cmd, args2, { stdio: ["ignore", "ignore", "pipe"], timeout: 15 * 6e4 });
|
|
39095
|
-
if ((0,
|
|
38854
|
+
if ((0, import_node_fs63.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
|
|
39096
38855
|
errors.push(`${cmd}: produced nothing`);
|
|
39097
38856
|
} catch (err2) {
|
|
39098
38857
|
errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
|
|
39099
38858
|
try {
|
|
39100
|
-
for (const e of (0,
|
|
38859
|
+
for (const e of (0, import_node_fs63.readdirSync)(dest)) (0, import_node_fs63.rmSync)((0, import_node_path47.join)(dest, e), { recursive: true, force: true });
|
|
39101
38860
|
} catch {
|
|
39102
38861
|
}
|
|
39103
38862
|
}
|
|
@@ -39123,7 +38882,7 @@ async function download(url, dest, onProgress, stallMs = DOWNLOAD_STALL_MS) {
|
|
|
39123
38882
|
seen += chunk.length;
|
|
39124
38883
|
onProgress(seen, total);
|
|
39125
38884
|
});
|
|
39126
|
-
await (0, import_promises18.pipeline)(stream, (0,
|
|
38885
|
+
await (0, import_promises18.pipeline)(stream, (0, import_node_fs63.createWriteStream)(dest), { signal: ctrl.signal });
|
|
39127
38886
|
} catch (err2) {
|
|
39128
38887
|
if (ctrl.signal.aborted) throw new Error(`download stalled: nothing received for ${Math.round(stallMs / 1e3)} s`);
|
|
39129
38888
|
throw err2;
|
|
@@ -39173,10 +38932,10 @@ async function installLean(opts = {}) {
|
|
|
39173
38932
|
const gb = (n) => (n / 1024 ** 3).toFixed(1);
|
|
39174
38933
|
return { ok: false, error: `not enough disk space for Lean: ${gb(free)} GB free where ${home} lives, needs about ${gb(needed)} GB` };
|
|
39175
38934
|
}
|
|
39176
|
-
const tmp = (0,
|
|
39177
|
-
(0,
|
|
39178
|
-
(0,
|
|
39179
|
-
const zip = (0,
|
|
38935
|
+
const tmp = (0, import_node_path47.join)(home, ".tmp");
|
|
38936
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
38937
|
+
(0, import_node_fs63.mkdirSync)(tmp, { recursive: true });
|
|
38938
|
+
const zip = (0, import_node_path47.join)(tmp, asset);
|
|
39180
38939
|
say(`downloading ${url}`);
|
|
39181
38940
|
let lastPct = -1;
|
|
39182
38941
|
try {
|
|
@@ -39189,40 +38948,40 @@ async function installLean(opts = {}) {
|
|
|
39189
38948
|
}
|
|
39190
38949
|
});
|
|
39191
38950
|
} catch (err2) {
|
|
39192
|
-
(0,
|
|
38951
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
39193
38952
|
return { ok: false, error: err2.message };
|
|
39194
38953
|
}
|
|
39195
38954
|
say("verifying checksum");
|
|
39196
38955
|
const verified = await verifyDownload(zip, asset);
|
|
39197
38956
|
if (!verified.ok) {
|
|
39198
|
-
(0,
|
|
38957
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
39199
38958
|
return { ok: false, error: verified.error };
|
|
39200
38959
|
}
|
|
39201
38960
|
say("unpacking (this takes a minute)");
|
|
39202
|
-
const unpack = (0,
|
|
39203
|
-
(0,
|
|
38961
|
+
const unpack = (0, import_node_path47.join)(tmp, "unpack");
|
|
38962
|
+
(0, import_node_fs63.mkdirSync)(unpack);
|
|
39204
38963
|
const unpacked = unzip(zip, unpack);
|
|
39205
38964
|
if (!unpacked.ok) {
|
|
39206
|
-
(0,
|
|
38965
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
39207
38966
|
return { ok: false, error: `unpack failed: ${unpacked.error}` };
|
|
39208
38967
|
}
|
|
39209
|
-
const entries = (0,
|
|
39210
|
-
const top = entries.length === 1 && (0,
|
|
39211
|
-
if (!(0,
|
|
39212
|
-
(0,
|
|
38968
|
+
const entries = (0, import_node_fs63.readdirSync)(unpack);
|
|
38969
|
+
const top = entries.length === 1 && (0, import_node_fs63.statSync)((0, import_node_path47.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path47.join)(unpack, entries[0]) : unpack;
|
|
38970
|
+
if (!(0, import_node_fs63.existsSync)((0, import_node_path47.join)(top, "bin", lakeBinary()))) {
|
|
38971
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
39213
38972
|
return { ok: false, error: "the archive did not contain bin/lake" };
|
|
39214
38973
|
}
|
|
39215
|
-
(0,
|
|
39216
|
-
(0,
|
|
39217
|
-
(0,
|
|
39218
|
-
(0,
|
|
38974
|
+
(0, import_node_fs63.rmSync)(dir, { recursive: true, force: true });
|
|
38975
|
+
(0, import_node_fs63.mkdirSync)(home, { recursive: true });
|
|
38976
|
+
(0, import_node_fs63.renameSync)(top, dir);
|
|
38977
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
39219
38978
|
return { ok: true, dir };
|
|
39220
38979
|
}
|
|
39221
38980
|
|
|
39222
38981
|
// src/lib/remote-config.ts
|
|
39223
|
-
var
|
|
38982
|
+
var import_node_fs64 = require("node:fs");
|
|
39224
38983
|
var import_promises19 = require("node:fs/promises");
|
|
39225
|
-
var
|
|
38984
|
+
var import_node_path48 = require("node:path");
|
|
39226
38985
|
var import_yaml5 = __toESM2(require_dist());
|
|
39227
38986
|
var IGNORE_RIDER = "verityignore";
|
|
39228
38987
|
async function fetchRemoteSetup(opts) {
|
|
@@ -39267,7 +39026,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
39267
39026
|
written.push(STANDARD_FILE);
|
|
39268
39027
|
if (rider !== null) {
|
|
39269
39028
|
const localIgnore = projectPath(VERITYIGNORE_FILE);
|
|
39270
|
-
if (!(0,
|
|
39029
|
+
if (!(0, import_node_fs64.existsSync)(localIgnore)) {
|
|
39271
39030
|
await writeOut(VERITYIGNORE_FILE, rider);
|
|
39272
39031
|
written.push(VERITYIGNORE_FILE);
|
|
39273
39032
|
} else {
|
|
@@ -39300,7 +39059,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
39300
39059
|
}
|
|
39301
39060
|
async function writeOut(relative6, body2) {
|
|
39302
39061
|
const target = projectPath(relative6);
|
|
39303
|
-
await (0, import_promises19.mkdir)((0,
|
|
39062
|
+
await (0, import_promises19.mkdir)((0, import_node_path48.dirname)(target), { recursive: true });
|
|
39304
39063
|
await (0, import_promises19.writeFile)(target, body2);
|
|
39305
39064
|
}
|
|
39306
39065
|
function describeRemote(found) {
|
|
@@ -39417,15 +39176,15 @@ async function runOptionalAuth(resolution, opts = {}) {
|
|
|
39417
39176
|
}
|
|
39418
39177
|
function resolveDataDir2() {
|
|
39419
39178
|
const candidates2 = [
|
|
39420
|
-
(0,
|
|
39179
|
+
(0, import_node_path49.join)(__dirname, "..", "data"),
|
|
39421
39180
|
// installed: node_modules/@codacy/verity-cli/data
|
|
39422
|
-
(0,
|
|
39181
|
+
(0, import_node_path49.join)(__dirname, "..", "..", "data"),
|
|
39423
39182
|
// edge case: nested resolution
|
|
39424
|
-
(0,
|
|
39183
|
+
(0, import_node_path49.join)(process.cwd(), "cli", "data")
|
|
39425
39184
|
// local dev: running from repo root
|
|
39426
39185
|
];
|
|
39427
39186
|
for (const candidate of candidates2) {
|
|
39428
|
-
if ((0,
|
|
39187
|
+
if ((0, import_node_fs65.existsSync)((0, import_node_path49.join)(candidate, "skills"))) {
|
|
39429
39188
|
return candidate;
|
|
39430
39189
|
}
|
|
39431
39190
|
}
|
|
@@ -39441,9 +39200,9 @@ async function skillIsCurrent(src, dest) {
|
|
|
39441
39200
|
const list2 = (dir) => {
|
|
39442
39201
|
const out2 = [];
|
|
39443
39202
|
const walk2 = (d, prefix) => {
|
|
39444
|
-
for (const e of (0,
|
|
39203
|
+
for (const e of (0, import_node_fs65.readdirSync)(d, { withFileTypes: true })) {
|
|
39445
39204
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
39446
|
-
if (e.isDirectory()) walk2((0,
|
|
39205
|
+
if (e.isDirectory()) walk2((0, import_node_path49.join)(d, e.name), rel);
|
|
39447
39206
|
else if (e.isFile()) out2.push(rel);
|
|
39448
39207
|
}
|
|
39449
39208
|
};
|
|
@@ -39454,8 +39213,8 @@ async function skillIsCurrent(src, dest) {
|
|
|
39454
39213
|
const shipped = list2(src);
|
|
39455
39214
|
if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
|
|
39456
39215
|
for (const rel of shipped) {
|
|
39457
|
-
const a = await (0, import_promises20.readFile)((0,
|
|
39458
|
-
const b = await (0, import_promises20.readFile)((0,
|
|
39216
|
+
const a = await (0, import_promises20.readFile)((0, import_node_path49.join)(src, rel), "utf-8");
|
|
39217
|
+
const b = await (0, import_promises20.readFile)((0, import_node_path49.join)(dest, rel), "utf-8");
|
|
39459
39218
|
if (a !== b) return false;
|
|
39460
39219
|
}
|
|
39461
39220
|
return true;
|
|
@@ -39658,7 +39417,7 @@ async function synthesizeLocally(opts) {
|
|
|
39658
39417
|
async function healStaleAnalysisConfig(globals) {
|
|
39659
39418
|
const configPath = projectPath(CODACY_CONFIG_FILE);
|
|
39660
39419
|
const standardPath = projectPath(STANDARD_FILE);
|
|
39661
|
-
if (!(0,
|
|
39420
|
+
if (!(0, import_node_fs65.existsSync)(configPath) || !(0, import_node_fs65.existsSync)(standardPath)) return;
|
|
39662
39421
|
const validation = validatePatternIds();
|
|
39663
39422
|
if (validation.status !== "invalid") return;
|
|
39664
39423
|
printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
|
|
@@ -39755,17 +39514,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
|
|
|
39755
39514
|
async function installSkills(force, step) {
|
|
39756
39515
|
step("Installing skills");
|
|
39757
39516
|
const dataDir = resolveDataDir2();
|
|
39758
|
-
const skillsSource = (0,
|
|
39517
|
+
const skillsSource = (0, import_node_path49.join)(dataDir, "skills");
|
|
39759
39518
|
const skillsDest = ".claude/skills";
|
|
39760
39519
|
let skillsInstalled = 0;
|
|
39761
39520
|
for (const skill of SKILLS) {
|
|
39762
|
-
const src = (0,
|
|
39763
|
-
const dest = (0,
|
|
39764
|
-
if (!(0,
|
|
39521
|
+
const src = (0, import_node_path49.join)(skillsSource, skill);
|
|
39522
|
+
const dest = (0, import_node_path49.join)(skillsDest, skill);
|
|
39523
|
+
if (!(0, import_node_fs65.existsSync)(src)) {
|
|
39765
39524
|
printWarn(` Skill data not found: ${skill}`);
|
|
39766
39525
|
continue;
|
|
39767
39526
|
}
|
|
39768
|
-
if ((0,
|
|
39527
|
+
if ((0, import_node_fs65.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
|
|
39769
39528
|
skillsInstalled++;
|
|
39770
39529
|
continue;
|
|
39771
39530
|
}
|
|
@@ -39965,7 +39724,7 @@ function registerInitCommand(program2) {
|
|
|
39965
39724
|
const staleMarker = clearStalePluginMarker();
|
|
39966
39725
|
const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
|
|
39967
39726
|
const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
|
|
39968
|
-
const isProject = projectMarkers.some((m) => (0,
|
|
39727
|
+
const isProject = projectMarkers.some((m) => (0, import_node_fs65.existsSync)(m));
|
|
39969
39728
|
if (!isProject) {
|
|
39970
39729
|
printError("No project detected in the current directory.");
|
|
39971
39730
|
printInfo('Run "verity init" from your project root.');
|
|
@@ -40068,7 +39827,7 @@ function registerInitCommand(program2) {
|
|
|
40068
39827
|
untrackMemory: opts.untrackMemory === true,
|
|
40069
39828
|
untrackState: opts.untrackState === true
|
|
40070
39829
|
});
|
|
40071
|
-
const globalVerityDir = (0,
|
|
39830
|
+
const globalVerityDir = (0, import_node_path49.join)(process.env.HOME ?? "", ".verity");
|
|
40072
39831
|
await (0, import_promises20.mkdir)(globalVerityDir, { recursive: true });
|
|
40073
39832
|
console.log("");
|
|
40074
39833
|
step("Wiring Claude Code hooks");
|
|
@@ -40143,7 +39902,7 @@ function registerInitCommand(program2) {
|
|
|
40143
39902
|
}
|
|
40144
39903
|
step("Your project's Standard");
|
|
40145
39904
|
let haveStandard = false;
|
|
40146
|
-
if ((0,
|
|
39905
|
+
if ((0, import_node_fs65.existsSync)(projectPath(STANDARD_FILE))) {
|
|
40147
39906
|
printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
|
|
40148
39907
|
haveStandard = true;
|
|
40149
39908
|
} else {
|
|
@@ -40173,7 +39932,7 @@ function registerInitCommand(program2) {
|
|
|
40173
39932
|
...telemetryChoice ? { telemetry: telemetryChoice } : {},
|
|
40174
39933
|
init: {
|
|
40175
39934
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40176
|
-
cli_version: true ? "0.34.0-experimental.
|
|
39935
|
+
cli_version: true ? "0.34.0-experimental.ba15b96" : "dev"
|
|
40177
39936
|
}
|
|
40178
39937
|
});
|
|
40179
39938
|
} catch (err2) {
|
|
@@ -40223,8 +39982,8 @@ function registerInitCommand(program2) {
|
|
|
40223
39982
|
}
|
|
40224
39983
|
|
|
40225
39984
|
// src/commands/uninstall.ts
|
|
40226
|
-
var
|
|
40227
|
-
var
|
|
39985
|
+
var import_node_fs66 = require("node:fs");
|
|
39986
|
+
var import_node_path50 = require("node:path");
|
|
40228
39987
|
function registerUninstallCommand(program2) {
|
|
40229
39988
|
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) => {
|
|
40230
39989
|
const dryRun = opts.dryRun ?? false;
|
|
@@ -40233,11 +39992,11 @@ function registerUninstallCommand(program2) {
|
|
|
40233
39992
|
const actions = [];
|
|
40234
39993
|
const skillsRoot = projectPath(".claude/skills");
|
|
40235
39994
|
for (const name2 of PROJECT_SKILL_NAMES) {
|
|
40236
|
-
const dir = (0,
|
|
40237
|
-
if ((0,
|
|
39995
|
+
const dir = (0, import_node_path50.join)(skillsRoot, name2);
|
|
39996
|
+
if ((0, import_node_fs66.existsSync)(dir)) {
|
|
40238
39997
|
actions.push({
|
|
40239
39998
|
label: `Remove .claude/skills/${name2}/`,
|
|
40240
|
-
apply: () => (0,
|
|
39999
|
+
apply: () => (0, import_node_fs66.rmSync)(dir, { recursive: true, force: true })
|
|
40241
40000
|
});
|
|
40242
40001
|
}
|
|
40243
40002
|
}
|
|
@@ -40251,24 +40010,24 @@ function registerUninstallCommand(program2) {
|
|
|
40251
40010
|
});
|
|
40252
40011
|
}
|
|
40253
40012
|
const verityDir = projectPath(VERITY_DIR);
|
|
40254
|
-
if ((0,
|
|
40013
|
+
if ((0, import_node_fs66.existsSync)(verityDir)) {
|
|
40255
40014
|
actions.push({
|
|
40256
40015
|
label: `Remove ${VERITY_DIR}/`,
|
|
40257
|
-
apply: () => (0,
|
|
40016
|
+
apply: () => (0, import_node_fs66.rmSync)(verityDir, { recursive: true, force: true })
|
|
40258
40017
|
});
|
|
40259
40018
|
}
|
|
40260
40019
|
if (!keepVerityMd) {
|
|
40261
40020
|
const verityMd = projectPath(VERITY_MD_FILE);
|
|
40262
|
-
if ((0,
|
|
40021
|
+
if ((0, import_node_fs66.existsSync)(verityMd)) {
|
|
40263
40022
|
actions.push({
|
|
40264
40023
|
label: `Remove ${VERITY_MD_FILE}`,
|
|
40265
|
-
apply: () => (0,
|
|
40024
|
+
apply: () => (0, import_node_fs66.rmSync)(verityMd, { force: true })
|
|
40266
40025
|
});
|
|
40267
40026
|
}
|
|
40268
40027
|
}
|
|
40269
40028
|
const cleanupEmptyDir = (path) => {
|
|
40270
|
-
if ((0,
|
|
40271
|
-
(0,
|
|
40029
|
+
if ((0, import_node_fs66.existsSync)(path) && (0, import_node_fs66.statSync)(path).isDirectory() && (0, import_node_fs66.readdirSync)(path).length === 0) {
|
|
40030
|
+
(0, import_node_fs66.rmdirSync)(path);
|
|
40272
40031
|
}
|
|
40273
40032
|
};
|
|
40274
40033
|
actions.push({
|
|
@@ -40279,11 +40038,11 @@ function registerUninstallCommand(program2) {
|
|
|
40279
40038
|
}
|
|
40280
40039
|
});
|
|
40281
40040
|
const home = process.env.HOME ?? "";
|
|
40282
|
-
const globalVerityDir = (0,
|
|
40283
|
-
if (purgeGlobal && (0,
|
|
40041
|
+
const globalVerityDir = (0, import_node_path50.join)(home, ".verity");
|
|
40042
|
+
if (purgeGlobal && (0, import_node_fs66.existsSync)(globalVerityDir)) {
|
|
40284
40043
|
actions.push({
|
|
40285
40044
|
label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
|
|
40286
|
-
apply: () => (0,
|
|
40045
|
+
apply: () => (0, import_node_fs66.rmSync)(globalVerityDir, { recursive: true, force: true })
|
|
40287
40046
|
});
|
|
40288
40047
|
}
|
|
40289
40048
|
if (actions.length === 0) {
|
|
@@ -40477,8 +40236,8 @@ function registerTaskCommands(program2) {
|
|
|
40477
40236
|
}
|
|
40478
40237
|
|
|
40479
40238
|
// src/commands/reset.ts
|
|
40480
|
-
var
|
|
40481
|
-
var
|
|
40239
|
+
var import_node_fs67 = require("node:fs");
|
|
40240
|
+
var import_node_path51 = require("node:path");
|
|
40482
40241
|
function registerResetCommand(program2) {
|
|
40483
40242
|
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) => {
|
|
40484
40243
|
const globals = program2.opts();
|
|
@@ -40515,11 +40274,11 @@ function registerResetCommand(program2) {
|
|
|
40515
40274
|
}
|
|
40516
40275
|
const cacheDir = projectPath(CACHE_DIR);
|
|
40517
40276
|
let purged = 0;
|
|
40518
|
-
if ((0,
|
|
40519
|
-
for (const entry of (0,
|
|
40277
|
+
if ((0, import_node_fs67.existsSync)(cacheDir)) {
|
|
40278
|
+
for (const entry of (0, import_node_fs67.readdirSync)(cacheDir)) {
|
|
40520
40279
|
if (entry.startsWith("pending-")) {
|
|
40521
40280
|
try {
|
|
40522
|
-
(0,
|
|
40281
|
+
(0, import_node_fs67.unlinkSync)((0, import_node_path51.join)(cacheDir, entry));
|
|
40523
40282
|
purged++;
|
|
40524
40283
|
} catch {
|
|
40525
40284
|
}
|
|
@@ -40534,19 +40293,19 @@ function registerResetCommand(program2) {
|
|
|
40534
40293
|
projectPath(`${VERITY_DIR}/.last-analysis`)
|
|
40535
40294
|
];
|
|
40536
40295
|
for (const file of filesToClear) {
|
|
40537
|
-
if ((0,
|
|
40296
|
+
if ((0, import_node_fs67.existsSync)(file)) {
|
|
40538
40297
|
try {
|
|
40539
|
-
(0,
|
|
40298
|
+
(0, import_node_fs67.writeFileSync)(file, "");
|
|
40540
40299
|
} catch {
|
|
40541
40300
|
}
|
|
40542
40301
|
}
|
|
40543
40302
|
}
|
|
40544
40303
|
if (opts.all) {
|
|
40545
40304
|
const logsDir = projectPath(`${VERITY_DIR}/.logs`);
|
|
40546
|
-
if ((0,
|
|
40547
|
-
for (const entry of (0,
|
|
40305
|
+
if ((0, import_node_fs67.existsSync)(logsDir)) {
|
|
40306
|
+
for (const entry of (0, import_node_fs67.readdirSync)(logsDir)) {
|
|
40548
40307
|
try {
|
|
40549
|
-
(0,
|
|
40308
|
+
(0, import_node_fs67.unlinkSync)((0, import_node_path51.join)(logsDir, entry));
|
|
40550
40309
|
} catch {
|
|
40551
40310
|
}
|
|
40552
40311
|
}
|
|
@@ -40558,7 +40317,7 @@ function registerResetCommand(program2) {
|
|
|
40558
40317
|
}
|
|
40559
40318
|
|
|
40560
40319
|
// src/commands/reflect.ts
|
|
40561
|
-
var
|
|
40320
|
+
var import_node_fs68 = require("node:fs");
|
|
40562
40321
|
|
|
40563
40322
|
// src/lib/reflection-globs.ts
|
|
40564
40323
|
var MAX_GLOBS = 6;
|
|
@@ -40566,7 +40325,7 @@ var PATH_TOKEN = /[A-Za-z0-9_./-]*[A-Za-z0-9_-]\.[A-Za-z0-9]{1,8}(?::\d+(?::\d+)
|
|
|
40566
40325
|
function clean(token) {
|
|
40567
40326
|
return token.replace(/:\d+(?::\d+)?$/, "").replace(/^[`'"(\[]+/, "").replace(/[`'"),\].;!?]+$/, "").replace(/^\.\//, "");
|
|
40568
40327
|
}
|
|
40569
|
-
function
|
|
40328
|
+
function resolve6(token, treePaths) {
|
|
40570
40329
|
if (treePaths.includes(token)) return token;
|
|
40571
40330
|
const suffix = token.startsWith("/") ? token : `/${token}`;
|
|
40572
40331
|
const matches = treePaths.filter((p) => p.endsWith(suffix));
|
|
@@ -40579,7 +40338,7 @@ function deriveFileGlobs(text, treePaths) {
|
|
|
40579
40338
|
for (const raw of text.match(PATH_TOKEN) ?? []) {
|
|
40580
40339
|
const token = clean(raw);
|
|
40581
40340
|
if (!token) continue;
|
|
40582
|
-
const path =
|
|
40341
|
+
const path = resolve6(token, treePaths);
|
|
40583
40342
|
if (!path || seen.has(path)) continue;
|
|
40584
40343
|
seen.add(path);
|
|
40585
40344
|
out2.push(path);
|
|
@@ -40596,19 +40355,14 @@ async function writeNodeToDisk(args2) {
|
|
|
40596
40355
|
{ treePaths: listTrackedFiles(), recordBaseline: false }
|
|
40597
40356
|
);
|
|
40598
40357
|
if (written === 0) return false;
|
|
40599
|
-
return (0,
|
|
40358
|
+
return (0, import_node_fs68.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
|
|
40600
40359
|
} catch {
|
|
40601
40360
|
return false;
|
|
40602
40361
|
}
|
|
40603
40362
|
}
|
|
40604
40363
|
function registerReflectCommand(program2) {
|
|
40605
|
-
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)
|
|
40364
|
+
program2.command("reflect").description("Capture learnings \u2014 auto-extract or record a reflection").option("--user-input <text>", "The reflection to record (the agent-drafted or user-dictated text)").option("--kind <kind>", "Node kind (decision, gotcha, pattern, security, quality, intent, domain, integration)", "gotcha").option("--task-id <id>", "Task to reflect on (defaults to current task)").option("--confirmed", "The USER authored or confirmed these exact words \u2014 records as human-authored (source: user, confidence 1.0)").option("--file-globs <glob...>", "Files this reflection is about. Without any, the paths cited in the text are used; a reflection matching no file never surfaces in a review").option("--autonomous", "(deprecated, ignored) reflections are always recorded without a confirm step").action(async (opts) => {
|
|
40606
40365
|
const globals = program2.opts();
|
|
40607
|
-
const input = readTextInput(opts.userInput, "--user-input");
|
|
40608
|
-
if (!input.ok) {
|
|
40609
|
-
printError(input.error);
|
|
40610
|
-
process.exit(1);
|
|
40611
|
-
}
|
|
40612
40366
|
await ensureMemoryDir();
|
|
40613
40367
|
const tokenResult = await resolveToken(globals.token);
|
|
40614
40368
|
if (!tokenResult.ok) {
|
|
@@ -40669,7 +40423,7 @@ function registerReflectCommand(program2) {
|
|
|
40669
40423
|
taskResolution = "none";
|
|
40670
40424
|
printWarn("No active task found \u2014 saving as an unattached reflection.");
|
|
40671
40425
|
}
|
|
40672
|
-
const userInput =
|
|
40426
|
+
const userInput = opts.userInput;
|
|
40673
40427
|
if (userInput) {
|
|
40674
40428
|
const validKinds = ["decision", "gotcha", "pattern", "security", "quality", "intent", "domain", "integration"];
|
|
40675
40429
|
const kind = validKinds.includes(opts.kind) ? opts.kind : "gotcha";
|
|
@@ -41033,9 +40787,9 @@ function registerRunCommand(program2) {
|
|
|
41033
40787
|
}
|
|
41034
40788
|
|
|
41035
40789
|
// src/commands/telemetry.ts
|
|
41036
|
-
var
|
|
40790
|
+
var import_node_fs69 = require("node:fs");
|
|
41037
40791
|
async function recordTelemetryChoice(choice) {
|
|
41038
|
-
if (!(0,
|
|
40792
|
+
if (!(0, import_node_fs69.existsSync)(projectPath(SETUP_STATE_FILE))) return;
|
|
41039
40793
|
try {
|
|
41040
40794
|
if ((await readSetupState())?.telemetry === choice) return;
|
|
41041
40795
|
await writeSetupState({ telemetry: choice });
|
|
@@ -41112,8 +40866,8 @@ function registerTelemetryCommands(program2) {
|
|
|
41112
40866
|
}
|
|
41113
40867
|
|
|
41114
40868
|
// src/commands/prove.ts
|
|
41115
|
-
var
|
|
41116
|
-
var
|
|
40869
|
+
var import_node_fs70 = require("node:fs");
|
|
40870
|
+
var import_node_path52 = require("node:path");
|
|
41117
40871
|
|
|
41118
40872
|
// src/lib/prove/hint-pool.ts
|
|
41119
40873
|
var STOP2 = /* @__PURE__ */ new Set([
|
|
@@ -41240,13 +40994,7 @@ async function proveAuth(program2) {
|
|
|
41240
40994
|
}
|
|
41241
40995
|
function registerProveCommand(program2) {
|
|
41242
40996
|
const prove = program2.command("prove").description("Formal verification (Lean 4) of small, risky pieces of code \u2014 on demand");
|
|
41243
|
-
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)
|
|
41244
|
-
const hint = readTextInput(opts.hint, "--hint");
|
|
41245
|
-
if (!hint.ok) {
|
|
41246
|
-
printError(hint.error);
|
|
41247
|
-
process.exit(2);
|
|
41248
|
-
}
|
|
41249
|
-
opts.hint = hint.text;
|
|
40997
|
+
prove.command("candidates [paths...]").description("Rank code worth a formal model, from git history and risk signals").option("--since <when>", `git --since window (default: "${DEFAULT_SINCE}")`).option("--limit <n>", "Candidates to show", "10").option("--rank <ranker>", "deterministic | luna | jev (luna and jev need an API key)", "deterministic").option("--hint <text>", "What the user wants checked, in their words (biases the rank; implies --rank luna)").option("--json", "Machine-readable output").action(async (paths, opts) => {
|
|
41250
40998
|
if (opts.hint && opts.rank === "deterministic") opts.rank = "luna";
|
|
41251
40999
|
const root = repoRoot();
|
|
41252
41000
|
const ranker = RANKERS[opts.rank];
|
|
@@ -41255,7 +41003,7 @@ function registerProveCommand(program2) {
|
|
|
41255
41003
|
process.exit(2);
|
|
41256
41004
|
}
|
|
41257
41005
|
const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
|
|
41258
|
-
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0,
|
|
41006
|
+
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path52.relative)(root, (0, import_node_path52.resolve)(p)) || ".") });
|
|
41259
41007
|
if (opts.hint && paths.length === 0) {
|
|
41260
41008
|
const hit = hintMatches(root, opts.hint);
|
|
41261
41009
|
if (hit.files.length > 0) {
|
|
@@ -41309,7 +41057,7 @@ function registerProveCommand(program2) {
|
|
|
41309
41057
|
});
|
|
41310
41058
|
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) => {
|
|
41311
41059
|
const root = repoRoot();
|
|
41312
|
-
if (!(0,
|
|
41060
|
+
if (!(0, import_node_fs70.existsSync)((0, import_node_path52.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41313
41061
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41314
41062
|
process.exit(2);
|
|
41315
41063
|
}
|
|
@@ -41333,7 +41081,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41333
41081
|
const reports = [];
|
|
41334
41082
|
for (const f of files) {
|
|
41335
41083
|
const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
|
|
41336
|
-
report.file = (0,
|
|
41084
|
+
report.file = (0, import_node_path52.relative)(root, f);
|
|
41337
41085
|
reports.push(report);
|
|
41338
41086
|
try {
|
|
41339
41087
|
writeResult(root, report);
|
|
@@ -41371,7 +41119,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41371
41119
|
printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
|
|
41372
41120
|
process.exit(2);
|
|
41373
41121
|
}
|
|
41374
|
-
if (!(0,
|
|
41122
|
+
if (!(0, import_node_fs70.existsSync)((0, import_node_path52.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41375
41123
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41376
41124
|
process.exit(2);
|
|
41377
41125
|
}
|
|
@@ -41402,7 +41150,7 @@ ${report.error ?? ""}`);
|
|
|
41402
41150
|
printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
|
|
41403
41151
|
return;
|
|
41404
41152
|
}
|
|
41405
|
-
const modelSource = readRegularFileInRoot(root, (0,
|
|
41153
|
+
const modelSource = readRegularFileInRoot(root, (0, import_node_path52.relative)(root, file), 512 * 1024);
|
|
41406
41154
|
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`);
|
|
41407
41155
|
const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
|
|
41408
41156
|
const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
|
|
@@ -41422,7 +41170,7 @@ ${report.error ?? ""}`);
|
|
|
41422
41170
|
});
|
|
41423
41171
|
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) => {
|
|
41424
41172
|
const root = repoRoot();
|
|
41425
|
-
let files = paths.map((p) => (0,
|
|
41173
|
+
let files = paths.map((p) => (0, import_node_path52.relative)(root, (0, import_node_path52.resolve)(p)));
|
|
41426
41174
|
if (files.length === 0) {
|
|
41427
41175
|
const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
|
|
41428
41176
|
const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
|
|
@@ -41451,19 +41199,7 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41451
41199
|
}
|
|
41452
41200
|
process.exit(outcome.findings.some((f) => f.verdict === "reproduced") ? 1 : 0);
|
|
41453
41201
|
});
|
|
41454
|
-
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)
|
|
41455
|
-
if (opts.hint === "-" && opts.note === "-") {
|
|
41456
|
-
printError("Only one of --hint and --note can read stdin (-).");
|
|
41457
|
-
process.exit(2);
|
|
41458
|
-
}
|
|
41459
|
-
for (const flag of ["hint", "note"]) {
|
|
41460
|
-
const input = readTextInput(opts[flag], `--${flag}`);
|
|
41461
|
-
if (!input.ok) {
|
|
41462
|
-
printError(input.error);
|
|
41463
|
-
process.exit(2);
|
|
41464
|
-
}
|
|
41465
|
-
opts[flag] = input.text;
|
|
41466
|
-
}
|
|
41202
|
+
prove.command("generate <target>").description("Have the Verity service write a Lean model of one symbol (file#symbol), lint it, and check it here \u2014 up to 3 rounds").option("--lines <a-b>", "Model a region of the file (1-based, inclusive) instead of a named symbol").option("--hint <text>", "The user's worry, in their words (may become an intent property)").option("--revise <model>", "Revise this existing model after a diverged replay (with --note)").option("--note <text>", "What the replay showed was different (with --revise)").option("--json", "Machine-readable output").action(async (targetArg, opts) => {
|
|
41467
41203
|
const root = repoRoot();
|
|
41468
41204
|
const auth2 = await proveAuth(program2);
|
|
41469
41205
|
if (!auth2 && !(process.env.VERITY_PROVE_DIRECT === "1" && process.env.OPENAI_API_KEY)) {
|
|
@@ -41494,9 +41230,9 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41494
41230
|
let revise;
|
|
41495
41231
|
if (opts.revise) {
|
|
41496
41232
|
const existing = resolveModelFile(root, opts.revise);
|
|
41497
|
-
const src = existing ? readRegularFileInRoot(root, (0,
|
|
41233
|
+
const src = existing ? readRegularFileInRoot(root, (0, import_node_path52.relative)(root, existing), 64 * 1024) : null;
|
|
41498
41234
|
if (!src || !src.ok || !opts.note) {
|
|
41499
|
-
printError(
|
|
41235
|
+
printError('--revise needs an existing model under Models/ and --note "<what the replay showed>"');
|
|
41500
41236
|
process.exit(2);
|
|
41501
41237
|
}
|
|
41502
41238
|
revise = { source: src.content, note: opts.note };
|
|
@@ -41533,8 +41269,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41533
41269
|
});
|
|
41534
41270
|
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) => {
|
|
41535
41271
|
const root = repoRoot();
|
|
41536
|
-
const rel0 = (0,
|
|
41537
|
-
const rel = rel0.startsWith("..") || (0,
|
|
41272
|
+
const rel0 = (0, import_node_path52.relative)(root, (0, import_node_path52.isAbsolute)(file) ? file : (0, import_node_path52.join)(root, file)).replace(/\\/g, "/");
|
|
41273
|
+
const rel = rel0.startsWith("..") || (0, import_node_path52.isAbsolute)(rel0) ? null : rel0;
|
|
41538
41274
|
if (!rel) {
|
|
41539
41275
|
printError(`${file} is not inside this repository`);
|
|
41540
41276
|
process.exit(2);
|
|
@@ -41550,8 +41286,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41550
41286
|
});
|
|
41551
41287
|
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) => {
|
|
41552
41288
|
const root = repoRoot();
|
|
41553
|
-
const rel = (0,
|
|
41554
|
-
const digest = rel.startsWith("..") || (0,
|
|
41289
|
+
const rel = (0, import_node_path52.relative)(root, (0, import_node_path52.isAbsolute)(file) ? file : (0, import_node_path52.join)(root, file));
|
|
41290
|
+
const digest = rel.startsWith("..") || (0, import_node_path52.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
|
|
41555
41291
|
if (!digest) {
|
|
41556
41292
|
printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
|
|
41557
41293
|
process.exit(2);
|
|
@@ -41585,10 +41321,10 @@ function refreshScaffold(root) {
|
|
|
41585
41321
|
}
|
|
41586
41322
|
|
|
41587
41323
|
// src/commands/lean.ts
|
|
41588
|
-
var
|
|
41324
|
+
var import_node_fs71 = require("node:fs");
|
|
41589
41325
|
var import_node_child_process20 = require("node:child_process");
|
|
41590
41326
|
var import_node_os11 = require("node:os");
|
|
41591
|
-
var
|
|
41327
|
+
var import_node_path53 = require("node:path");
|
|
41592
41328
|
function registerLeanCommand(program2) {
|
|
41593
41329
|
const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
|
|
41594
41330
|
lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
|
|
@@ -41605,7 +41341,7 @@ function registerLeanCommand(program2) {
|
|
|
41605
41341
|
const managed = pinnedVersionDir();
|
|
41606
41342
|
const matches = version ? version.includes(pin) : false;
|
|
41607
41343
|
if (opts.json) {
|
|
41608
|
-
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0,
|
|
41344
|
+
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs71.existsSync)((0, import_node_path53.join)(managed, "bin")), asset: leanAssetName() });
|
|
41609
41345
|
return;
|
|
41610
41346
|
}
|
|
41611
41347
|
printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
|
|
@@ -41623,7 +41359,7 @@ function registerLeanCommand(program2) {
|
|
|
41623
41359
|
process.exit(2);
|
|
41624
41360
|
}
|
|
41625
41361
|
const dir = pinnedVersionDir();
|
|
41626
|
-
if ((0,
|
|
41362
|
+
if ((0, import_node_fs71.existsSync)((0, import_node_path53.join)(dir, "bin", "lake")) && !opts.force) {
|
|
41627
41363
|
printInfo(`already installed at ${dir}`);
|
|
41628
41364
|
return;
|
|
41629
41365
|
}
|
|
@@ -41659,18 +41395,18 @@ function registerLeanCommand(program2) {
|
|
|
41659
41395
|
});
|
|
41660
41396
|
lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
|
|
41661
41397
|
const dir = pinnedVersionDir();
|
|
41662
|
-
if (!(0,
|
|
41398
|
+
if (!(0, import_node_fs71.existsSync)(dir)) {
|
|
41663
41399
|
printInfo("nothing to remove");
|
|
41664
41400
|
return;
|
|
41665
41401
|
}
|
|
41666
|
-
(0,
|
|
41402
|
+
(0, import_node_fs71.rmSync)(dir, { recursive: true, force: true });
|
|
41667
41403
|
printInfo(`removed ${dir}`);
|
|
41668
41404
|
});
|
|
41669
41405
|
}
|
|
41670
41406
|
|
|
41671
41407
|
// src/cli.ts
|
|
41672
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.
|
|
41673
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.
|
|
41408
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.ba15b96").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) => {
|
|
41409
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.ba15b96");
|
|
41674
41410
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
41675
41411
|
try {
|
|
41676
41412
|
await foldLegacyLocalCredential();
|