@codacy/verity-cli 0.34.0-experimental.7e3f52d → 0.34.0-experimental.b9e8508
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/verity.js +767 -866
- package/package.json +1 -1
package/bin/verity.js
CHANGED
|
@@ -17104,10 +17104,6 @@ async function applyMomentSelection(moments) {
|
|
|
17104
17104
|
}
|
|
17105
17105
|
|
|
17106
17106
|
// src/lib/project-config.ts
|
|
17107
|
-
var import_node_fs6 = require("node:fs");
|
|
17108
|
-
var import_node_path8 = require("node:path");
|
|
17109
|
-
|
|
17110
|
-
// src/lib/repo-controlled.ts
|
|
17111
17107
|
var import_node_fs5 = require("node:fs");
|
|
17112
17108
|
var import_node_path7 = require("node:path");
|
|
17113
17109
|
|
|
@@ -17184,26 +17180,6 @@ function runGit(cwd, args2, opts = {}) {
|
|
|
17184
17180
|
});
|
|
17185
17181
|
}
|
|
17186
17182
|
|
|
17187
|
-
// src/lib/repo-controlled.ts
|
|
17188
|
-
function repoControlled(worktree, rel) {
|
|
17189
|
-
const parts2 = rel.split("/").filter(Boolean);
|
|
17190
|
-
for (let i2 = 1; i2 <= parts2.length; i2++) {
|
|
17191
|
-
let st;
|
|
17192
|
-
try {
|
|
17193
|
-
st = (0, import_node_fs5.lstatSync)((0, import_node_path7.join)(worktree, ...parts2.slice(0, i2)));
|
|
17194
|
-
} catch (err2) {
|
|
17195
|
-
const code = err2?.code;
|
|
17196
|
-
if (code === "ENOENT" || code === "ENOTDIR") return null;
|
|
17197
|
-
return "unverified";
|
|
17198
|
-
}
|
|
17199
|
-
if (st.isSymbolicLink()) return "symlink";
|
|
17200
|
-
if (i2 === parts2.length && !st.isFile()) return "symlink";
|
|
17201
|
-
}
|
|
17202
|
-
const r = runGitSync(worktree, ["ls-files", "-z", "--", rel], { timeoutMs: 5e3 });
|
|
17203
|
-
if (!r.ok) return "unverified";
|
|
17204
|
-
return r.stdout.length > 0 ? "tracked" : null;
|
|
17205
|
-
}
|
|
17206
|
-
|
|
17207
17183
|
// src/lib/project-config.ts
|
|
17208
17184
|
var DEFAULTS = { git_moments: [] };
|
|
17209
17185
|
function isMoment(value) {
|
|
@@ -17214,14 +17190,14 @@ function parseMoments(raw) {
|
|
|
17214
17190
|
}
|
|
17215
17191
|
function readConfigFile(path) {
|
|
17216
17192
|
try {
|
|
17217
|
-
if (!(0,
|
|
17218
|
-
const raw = JSON.parse((0,
|
|
17193
|
+
if (!(0, import_node_fs5.existsSync)(path)) return null;
|
|
17194
|
+
const raw = JSON.parse((0, import_node_fs5.readFileSync)(path, "utf-8"));
|
|
17219
17195
|
const moments = Array.isArray(raw.git_moments) ? raw.git_moments.filter(isMoment) : [];
|
|
17220
17196
|
const source2 = raw.git_moments_source === "user" || raw.git_moments_source === "init" ? raw.git_moments_source : void 0;
|
|
17221
17197
|
return {
|
|
17222
17198
|
git_moments: [...new Set(moments)],
|
|
17223
17199
|
...source2 ? { git_moments_source: source2 } : {},
|
|
17224
|
-
...raw.formal === "push"
|
|
17200
|
+
...raw.formal === "push" ? { formal: "push" } : {}
|
|
17225
17201
|
};
|
|
17226
17202
|
} catch {
|
|
17227
17203
|
return DEFAULTS;
|
|
@@ -17232,13 +17208,22 @@ function candidates() {
|
|
|
17232
17208
|
const out2 = [{ path: local, source: "local" }];
|
|
17233
17209
|
const main = mainWorktreeRoot();
|
|
17234
17210
|
if (main) {
|
|
17235
|
-
const inherited = (0,
|
|
17211
|
+
const inherited = (0, import_node_path7.join)(main, PROJECT_CONFIG_FILE);
|
|
17236
17212
|
if (inherited !== local) out2.push({ path: inherited, source: "main-worktree" });
|
|
17237
17213
|
}
|
|
17238
17214
|
return out2;
|
|
17239
17215
|
}
|
|
17240
17216
|
function formalRefusal(path) {
|
|
17241
|
-
|
|
17217
|
+
const worktree = (0, import_node_path7.dirname)((0, import_node_path7.dirname)(path));
|
|
17218
|
+
try {
|
|
17219
|
+
if ((0, import_node_fs5.lstatSync)((0, import_node_path7.join)(worktree, VERITY_DIR)).isSymbolicLink()) return "symlink";
|
|
17220
|
+
if (!(0, import_node_fs5.lstatSync)(path).isFile()) return "symlink";
|
|
17221
|
+
} catch {
|
|
17222
|
+
return "unverified";
|
|
17223
|
+
}
|
|
17224
|
+
const r = runGitSync(worktree, ["ls-files", "-z", "--", PROJECT_CONFIG_FILE], { timeoutMs: 5e3 });
|
|
17225
|
+
if (!r.ok) return "unverified";
|
|
17226
|
+
return r.stdout.length > 0 ? "tracked" : null;
|
|
17242
17227
|
}
|
|
17243
17228
|
function readProjectConfigRaw() {
|
|
17244
17229
|
for (const { path, source: source2 } of candidates()) {
|
|
@@ -17250,10 +17235,10 @@ function readProjectConfigRaw() {
|
|
|
17250
17235
|
function readProjectConfig() {
|
|
17251
17236
|
const cfg = readProjectConfigRaw();
|
|
17252
17237
|
if (cfg.formal !== "push" || !cfg.path) return cfg;
|
|
17253
|
-
const
|
|
17254
|
-
if (!
|
|
17238
|
+
const refused = formalRefusal(cfg.path);
|
|
17239
|
+
if (!refused) return cfg;
|
|
17255
17240
|
const { formal: _dropped, ...rest } = cfg;
|
|
17256
|
-
return { ...rest, formal_refused:
|
|
17241
|
+
return { ...rest, formal_refused: refused };
|
|
17257
17242
|
}
|
|
17258
17243
|
function formalRefusalMessage(reason) {
|
|
17259
17244
|
switch (reason) {
|
|
@@ -17274,8 +17259,8 @@ function writeProjectConfig(patch) {
|
|
|
17274
17259
|
...patch
|
|
17275
17260
|
};
|
|
17276
17261
|
const target = projectPath(PROJECT_CONFIG_FILE);
|
|
17277
|
-
(0,
|
|
17278
|
-
(0,
|
|
17262
|
+
(0, import_node_fs5.mkdirSync)((0, import_node_path7.dirname)(target), { recursive: true });
|
|
17263
|
+
(0, import_node_fs5.writeFileSync)(target, JSON.stringify(next, null, 2) + "\n");
|
|
17279
17264
|
return next;
|
|
17280
17265
|
}
|
|
17281
17266
|
function resolveGuardMoments(explicit) {
|
|
@@ -17284,11 +17269,11 @@ function resolveGuardMoments(explicit) {
|
|
|
17284
17269
|
}
|
|
17285
17270
|
|
|
17286
17271
|
// src/lib/plugin-ownership.ts
|
|
17287
|
-
var
|
|
17272
|
+
var import_node_fs8 = require("node:fs");
|
|
17288
17273
|
|
|
17289
17274
|
// src/lib/which.ts
|
|
17290
|
-
var
|
|
17291
|
-
var
|
|
17275
|
+
var import_node_fs6 = require("node:fs");
|
|
17276
|
+
var import_node_path8 = require("node:path");
|
|
17292
17277
|
function executableExtensions(platform4, pathext) {
|
|
17293
17278
|
if (platform4 !== "win32") return [""];
|
|
17294
17279
|
const raw = (pathext ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean);
|
|
@@ -17306,14 +17291,14 @@ function whichSync(bin, opts = {}) {
|
|
|
17306
17291
|
if (!rawPath) return null;
|
|
17307
17292
|
const exts = executableExtensions(platform4, opts.pathext ?? process.env.PATHEXT);
|
|
17308
17293
|
const real = opts.real ?? true;
|
|
17309
|
-
for (const dir of rawPath.split(
|
|
17294
|
+
for (const dir of rawPath.split(import_node_path8.delimiter)) {
|
|
17310
17295
|
if (!dir) continue;
|
|
17311
17296
|
for (const ext of exts) {
|
|
17312
|
-
const candidate = (0,
|
|
17297
|
+
const candidate = (0, import_node_path8.join)(dir, bin + ext);
|
|
17313
17298
|
try {
|
|
17314
|
-
if (!(0,
|
|
17315
|
-
if (platform4 !== "win32") (0,
|
|
17316
|
-
return real ? (0,
|
|
17299
|
+
if (!(0, import_node_fs6.statSync)(candidate).isFile()) continue;
|
|
17300
|
+
if (platform4 !== "win32") (0, import_node_fs6.accessSync)(candidate, import_node_fs6.constants.X_OK);
|
|
17301
|
+
return real ? (0, import_node_fs6.realpathSync)(candidate) : candidate;
|
|
17317
17302
|
} catch {
|
|
17318
17303
|
continue;
|
|
17319
17304
|
}
|
|
@@ -17324,10 +17309,10 @@ function whichSync(bin, opts = {}) {
|
|
|
17324
17309
|
|
|
17325
17310
|
// src/lib/plugin-ownership.ts
|
|
17326
17311
|
var import_node_os2 = require("node:os");
|
|
17327
|
-
var
|
|
17312
|
+
var import_node_path9 = require("node:path");
|
|
17328
17313
|
|
|
17329
17314
|
// src/lib/stderr-log.ts
|
|
17330
|
-
var
|
|
17315
|
+
var import_node_fs7 = require("node:fs");
|
|
17331
17316
|
var TOKEN_RE2 = /verity_[0-9a-f]{16,}/g;
|
|
17332
17317
|
var ANSI_RE = /\u001b\[[0-?]*[ -/]*[@-~]/g;
|
|
17333
17318
|
function scrub(s) {
|
|
@@ -17340,9 +17325,9 @@ function append(text) {
|
|
|
17340
17325
|
try {
|
|
17341
17326
|
const dir = projectPath(DEBUG_LOG_DIR);
|
|
17342
17327
|
const file = projectPath(STDERR_LOG_FILE);
|
|
17343
|
-
(0,
|
|
17328
|
+
(0, import_node_fs7.mkdirSync)(dir, { recursive: true });
|
|
17344
17329
|
rotateIfNeeded(file);
|
|
17345
|
-
(0,
|
|
17330
|
+
(0, import_node_fs7.appendFileSync)(file, text);
|
|
17346
17331
|
} catch {
|
|
17347
17332
|
}
|
|
17348
17333
|
}
|
|
@@ -17390,8 +17375,8 @@ function markerPath() {
|
|
|
17390
17375
|
}
|
|
17391
17376
|
function readMarker() {
|
|
17392
17377
|
try {
|
|
17393
|
-
if (!(0,
|
|
17394
|
-
const raw = JSON.parse((0,
|
|
17378
|
+
if (!(0, import_node_fs8.existsSync)(markerPath())) return null;
|
|
17379
|
+
const raw = JSON.parse((0, import_node_fs8.readFileSync)(markerPath(), "utf-8"));
|
|
17395
17380
|
const pluginRoot = typeof raw.plugin_root === "string" ? raw.plugin_root : "";
|
|
17396
17381
|
if (!pluginRoot || CONTROL_CHARS2.test(pluginRoot)) return null;
|
|
17397
17382
|
const version = typeof raw.version === "string" && !CONTROL_CHARS2.test(raw.version) ? raw.version : null;
|
|
@@ -17409,23 +17394,23 @@ function recordPluginOwnership(sessionId) {
|
|
|
17409
17394
|
const pluginRoot = process.env.VERITY_PLUGIN_ROOT;
|
|
17410
17395
|
if (!pluginRoot) return;
|
|
17411
17396
|
try {
|
|
17412
|
-
(0,
|
|
17397
|
+
(0, import_node_fs8.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
|
|
17413
17398
|
const marker = {
|
|
17414
17399
|
session_id: sessionId,
|
|
17415
17400
|
plugin_root: pluginRoot,
|
|
17416
17401
|
version: process.env.VERITY_PLUGIN_VERSION || null,
|
|
17417
17402
|
ts: Math.floor(Date.now() / 1e3)
|
|
17418
17403
|
};
|
|
17419
|
-
(0,
|
|
17404
|
+
(0, import_node_fs8.writeFileSync)(markerPath(), JSON.stringify(marker));
|
|
17420
17405
|
} catch {
|
|
17421
17406
|
}
|
|
17422
17407
|
}
|
|
17423
17408
|
function claudeConfigDir() {
|
|
17424
|
-
return process.env.CLAUDE_CONFIG_DIR || (0,
|
|
17409
|
+
return process.env.CLAUDE_CONFIG_DIR || (0, import_node_path9.join)((0, import_node_os2.homedir)(), ".claude");
|
|
17425
17410
|
}
|
|
17426
17411
|
function readJsonFile(path) {
|
|
17427
17412
|
try {
|
|
17428
|
-
const parsed = JSON.parse((0,
|
|
17413
|
+
const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path, "utf-8"));
|
|
17429
17414
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
17430
17415
|
} catch {
|
|
17431
17416
|
return null;
|
|
@@ -17433,9 +17418,9 @@ function readJsonFile(path) {
|
|
|
17433
17418
|
}
|
|
17434
17419
|
function enabledPluginSetting(key) {
|
|
17435
17420
|
const files = [
|
|
17436
|
-
projectPath((0,
|
|
17437
|
-
projectPath((0,
|
|
17438
|
-
(0,
|
|
17421
|
+
projectPath((0, import_node_path9.join)(".claude", "settings.local.json")),
|
|
17422
|
+
projectPath((0, import_node_path9.join)(".claude", "settings.json")),
|
|
17423
|
+
(0, import_node_path9.join)(claudeConfigDir(), "settings.json")
|
|
17439
17424
|
];
|
|
17440
17425
|
for (const file of files) {
|
|
17441
17426
|
const map = readJsonFile(file)?.enabledPlugins;
|
|
@@ -17447,11 +17432,11 @@ function enabledPluginSetting(key) {
|
|
|
17447
17432
|
}
|
|
17448
17433
|
function marketplaceLocations() {
|
|
17449
17434
|
const out2 = /* @__PURE__ */ new Map();
|
|
17450
|
-
const known = readJsonFile((0,
|
|
17435
|
+
const known = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
|
|
17451
17436
|
if (!known) return out2;
|
|
17452
17437
|
for (const [name2, entry] of Object.entries(known)) {
|
|
17453
17438
|
const loc2 = entry?.installLocation;
|
|
17454
|
-
if (typeof loc2 === "string" && loc2) out2.set(name2, (0,
|
|
17439
|
+
if (typeof loc2 === "string" && loc2) out2.set(name2, (0, import_node_path9.resolve)(loc2));
|
|
17455
17440
|
}
|
|
17456
17441
|
return out2;
|
|
17457
17442
|
}
|
|
@@ -17465,7 +17450,7 @@ function globalVerityVersion() {
|
|
|
17465
17450
|
const entry = verityPathEntry();
|
|
17466
17451
|
if (!entry) return null;
|
|
17467
17452
|
try {
|
|
17468
|
-
const pkg = readJsonFile((0,
|
|
17453
|
+
const pkg = readJsonFile((0, import_node_path9.join)((0, import_node_path9.dirname)((0, import_node_fs8.realpathSync)(entry)), "..", "package.json"));
|
|
17469
17454
|
if (pkg?.name !== "@codacy/verity-cli" || typeof pkg.version !== "string") return null;
|
|
17470
17455
|
return pkg.version;
|
|
17471
17456
|
} catch {
|
|
@@ -17482,7 +17467,7 @@ var VERITY_MARKETPLACE_REPO = "codacy/verity";
|
|
|
17482
17467
|
function marketplaceConflict() {
|
|
17483
17468
|
const wanted = VERITY_MARKETPLACE;
|
|
17484
17469
|
for (const file of ["settings.json", "settings.local.json"]) {
|
|
17485
|
-
const path = (0,
|
|
17470
|
+
const path = (0, import_node_path9.join)(claudeConfigDir(), file);
|
|
17486
17471
|
const declared = readJsonFile(path)?.extraKnownMarketplaces ?? null;
|
|
17487
17472
|
const entry2 = declared && typeof declared === "object" ? declared[wanted] : void 0;
|
|
17488
17473
|
if (entry2 && typeof entry2 === "object") {
|
|
@@ -17492,7 +17477,7 @@ function marketplaceConflict() {
|
|
|
17492
17477
|
}
|
|
17493
17478
|
}
|
|
17494
17479
|
}
|
|
17495
|
-
const known = readJsonFile((0,
|
|
17480
|
+
const known = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
|
|
17496
17481
|
const entry = known?.[wanted];
|
|
17497
17482
|
if (entry && typeof entry === "object" && !pointsAtVerity(entry.source)) {
|
|
17498
17483
|
return { name: wanted, declaredAs: describeSource(entry.source) };
|
|
@@ -17513,7 +17498,7 @@ function describeSource(src) {
|
|
|
17513
17498
|
return target ? `${kind} \u2192 ${target}` : kind;
|
|
17514
17499
|
}
|
|
17515
17500
|
function legacyMarketplaceInstall() {
|
|
17516
|
-
const plugins = readJsonFile((0,
|
|
17501
|
+
const plugins = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17517
17502
|
if (!plugins || typeof plugins !== "object") return null;
|
|
17518
17503
|
for (const key of Object.keys(plugins)) {
|
|
17519
17504
|
const at = key.lastIndexOf("@");
|
|
@@ -17525,13 +17510,13 @@ function legacyMarketplaceInstall() {
|
|
|
17525
17510
|
}
|
|
17526
17511
|
function realpathOr(p) {
|
|
17527
17512
|
try {
|
|
17528
|
-
return
|
|
17513
|
+
return import_node_fs8.realpathSync.native(p);
|
|
17529
17514
|
} catch {
|
|
17530
|
-
return (0,
|
|
17515
|
+
return (0, import_node_path9.resolve)(p);
|
|
17531
17516
|
}
|
|
17532
17517
|
}
|
|
17533
17518
|
function isWithin(want, dir) {
|
|
17534
|
-
return want === dir || want.startsWith(dir +
|
|
17519
|
+
return want === dir || want.startsWith(dir + import_node_path9.sep);
|
|
17535
17520
|
}
|
|
17536
17521
|
function entryAppliesHere(entry, here) {
|
|
17537
17522
|
const e = entry;
|
|
@@ -17541,9 +17526,9 @@ function entryAppliesHere(entry, here) {
|
|
|
17541
17526
|
return forProject === here;
|
|
17542
17527
|
}
|
|
17543
17528
|
function registrySays(pluginRoot) {
|
|
17544
|
-
const plugins = readJsonFile((0,
|
|
17529
|
+
const plugins = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17545
17530
|
if (!plugins || typeof plugins !== "object") return "unverified";
|
|
17546
|
-
const want = (0,
|
|
17531
|
+
const want = (0, import_node_path9.resolve)(pluginRoot);
|
|
17547
17532
|
const here = realpathOr(repoRoot());
|
|
17548
17533
|
const markets = marketplaceLocations();
|
|
17549
17534
|
for (const [key, value] of Object.entries(plugins)) {
|
|
@@ -17552,15 +17537,15 @@ function registrySays(pluginRoot) {
|
|
|
17552
17537
|
const applicable = (Array.isArray(value) ? value : []).filter((entry) => entryAppliesHere(entry, here));
|
|
17553
17538
|
const claims = applicable.some((entry) => {
|
|
17554
17539
|
const installPath = entry?.installPath;
|
|
17555
|
-
return typeof installPath === "string" && (0,
|
|
17540
|
+
return typeof installPath === "string" && (0, import_node_path9.resolve)(installPath) === want;
|
|
17556
17541
|
}) || source2 !== void 0 && applicable.length > 0 && isWithin(want, source2);
|
|
17557
17542
|
if (claims) {
|
|
17558
17543
|
if (enabledPluginSetting(key) === false) return "gone";
|
|
17559
|
-
return (0,
|
|
17544
|
+
return (0, import_node_fs8.existsSync)(pluginRoot) ? "live" : "gone";
|
|
17560
17545
|
}
|
|
17561
17546
|
}
|
|
17562
|
-
const managed = (0,
|
|
17563
|
-
return want === managed || want.startsWith(managed +
|
|
17547
|
+
const managed = (0, import_node_path9.resolve)((0, import_node_path9.join)(claudeConfigDir(), "plugins", "cache"));
|
|
17548
|
+
return want === managed || want.startsWith(managed + import_node_path9.sep) ? "gone" : "unverified";
|
|
17564
17549
|
}
|
|
17565
17550
|
var _live = /* @__PURE__ */ new Map();
|
|
17566
17551
|
function pluginLiveness(pluginRoot) {
|
|
@@ -17574,7 +17559,7 @@ function clearStalePluginMarker() {
|
|
|
17574
17559
|
const marker = readMarker();
|
|
17575
17560
|
if (!marker || pluginLiveness(marker.plugin_root) !== "gone") return null;
|
|
17576
17561
|
try {
|
|
17577
|
-
(0,
|
|
17562
|
+
(0, import_node_fs8.rmSync)(markerPath(), { force: true });
|
|
17578
17563
|
} catch {
|
|
17579
17564
|
return null;
|
|
17580
17565
|
}
|
|
@@ -17602,7 +17587,7 @@ function pluginActiveHere() {
|
|
|
17602
17587
|
return activePluginInstall() !== null;
|
|
17603
17588
|
}
|
|
17604
17589
|
function registeredVerityPlugin() {
|
|
17605
|
-
const plugins = readJsonFile((0,
|
|
17590
|
+
const plugins = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17606
17591
|
if (!plugins || typeof plugins !== "object") return null;
|
|
17607
17592
|
const here = realpathOr(repoRoot());
|
|
17608
17593
|
for (const [key, value] of Object.entries(plugins)) {
|
|
@@ -17612,7 +17597,7 @@ function registeredVerityPlugin() {
|
|
|
17612
17597
|
for (const entry of Array.isArray(value) ? value : []) {
|
|
17613
17598
|
const e = entry;
|
|
17614
17599
|
const installPath = typeof e.installPath === "string" ? e.installPath : "";
|
|
17615
|
-
if (!installPath || !(0,
|
|
17600
|
+
if (!installPath || !(0, import_node_fs8.existsSync)(installPath)) continue;
|
|
17616
17601
|
if (!entryAppliesHere(entry, here)) continue;
|
|
17617
17602
|
return { pluginRoot: installPath, version: typeof e.version === "string" ? e.version : null };
|
|
17618
17603
|
}
|
|
@@ -17664,28 +17649,28 @@ async function resolveHookWiring() {
|
|
|
17664
17649
|
}
|
|
17665
17650
|
|
|
17666
17651
|
// src/lib/cli-provenance.ts
|
|
17667
|
-
var
|
|
17652
|
+
var import_node_fs9 = require("node:fs");
|
|
17668
17653
|
var import_node_os3 = require("node:os");
|
|
17669
|
-
var
|
|
17654
|
+
var import_node_path10 = require("node:path");
|
|
17670
17655
|
var CLI_PACKAGE = "@codacy/verity-cli";
|
|
17671
|
-
var CLI_ENTRY = (0,
|
|
17656
|
+
var CLI_ENTRY = (0, import_node_path10.join)("node_modules", CLI_PACKAGE, "bin", "verity.js");
|
|
17672
17657
|
function readJson(path) {
|
|
17673
17658
|
try {
|
|
17674
|
-
const parsed = JSON.parse((0,
|
|
17659
|
+
const parsed = JSON.parse((0, import_node_fs9.readFileSync)(path, "utf-8"));
|
|
17675
17660
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
17676
17661
|
} catch {
|
|
17677
17662
|
return null;
|
|
17678
17663
|
}
|
|
17679
17664
|
}
|
|
17680
17665
|
function versionUnder(base) {
|
|
17681
|
-
const entry = (0,
|
|
17682
|
-
if (!(0,
|
|
17683
|
-
const pkg = readJson((0,
|
|
17666
|
+
const entry = (0, import_node_path10.join)(base, CLI_ENTRY);
|
|
17667
|
+
if (!(0, import_node_fs9.existsSync)(entry)) return null;
|
|
17668
|
+
const pkg = readJson((0, import_node_path10.join)(base, "node_modules", CLI_PACKAGE, "package.json"));
|
|
17684
17669
|
return typeof pkg?.version === "string" ? pkg.version : null;
|
|
17685
17670
|
}
|
|
17686
17671
|
function versionForEntry(entry) {
|
|
17687
17672
|
try {
|
|
17688
|
-
const pkg = readJson((0,
|
|
17673
|
+
const pkg = readJson((0, import_node_path10.join)((0, import_node_path10.dirname)((0, import_node_fs9.realpathSync)(entry)), "..", "package.json"));
|
|
17689
17674
|
return typeof pkg?.version === "string" ? pkg.version : null;
|
|
17690
17675
|
} catch {
|
|
17691
17676
|
return null;
|
|
@@ -17693,16 +17678,16 @@ function versionForEntry(entry) {
|
|
|
17693
17678
|
}
|
|
17694
17679
|
function resolveHooksCli(pluginRoot) {
|
|
17695
17680
|
const override = process.env.VERITY_CLI_PATH;
|
|
17696
|
-
if (override && (0,
|
|
17681
|
+
if (override && (0, import_node_fs9.existsSync)(override)) {
|
|
17697
17682
|
return { version: versionForEntry(override), rung: "override" };
|
|
17698
17683
|
}
|
|
17699
17684
|
const fromPlugin = versionUnder(pluginRoot);
|
|
17700
17685
|
if (fromPlugin !== null) return { version: fromPlugin, rung: "plugin" };
|
|
17701
|
-
if ((0,
|
|
17702
|
-
const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0,
|
|
17686
|
+
if ((0, import_node_fs9.existsSync)((0, import_node_path10.join)(pluginRoot, CLI_ENTRY))) return { version: null, rung: "plugin" };
|
|
17687
|
+
const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0, import_node_path10.join)((0, import_node_os3.homedir)(), ".verity", "plugin-cli");
|
|
17703
17688
|
const fromData = versionUnder(dataDir);
|
|
17704
17689
|
if (fromData !== null) return { version: fromData, rung: "plugin-data" };
|
|
17705
|
-
if ((0,
|
|
17690
|
+
if ((0, import_node_fs9.existsSync)((0, import_node_path10.join)(dataDir, CLI_ENTRY))) return { version: null, rung: "plugin-data" };
|
|
17706
17691
|
const global = globalVerityVersion();
|
|
17707
17692
|
if (global !== null) return { version: global, rung: "global" };
|
|
17708
17693
|
return null;
|
|
@@ -17804,7 +17789,7 @@ function pluginCliInvocation() {
|
|
|
17804
17789
|
return resolverCommand(root);
|
|
17805
17790
|
}
|
|
17806
17791
|
function resolverCommand(root) {
|
|
17807
|
-
return `node ${JSON.stringify((0,
|
|
17792
|
+
return `node ${JSON.stringify((0, import_node_path10.join)(root, "scripts", "verity.mjs"))}`;
|
|
17808
17793
|
}
|
|
17809
17794
|
|
|
17810
17795
|
// src/commands/hooks.ts
|
|
@@ -17944,7 +17929,7 @@ var import_node_crypto9 = require("node:crypto");
|
|
|
17944
17929
|
|
|
17945
17930
|
// src/lib/conversation-buffer.ts
|
|
17946
17931
|
var import_promises5 = require("node:fs/promises");
|
|
17947
|
-
var
|
|
17932
|
+
var import_node_fs10 = require("node:fs");
|
|
17948
17933
|
var import_node_child_process6 = require("node:child_process");
|
|
17949
17934
|
var import_node_crypto = require("node:crypto");
|
|
17950
17935
|
function stripImageReferences(text) {
|
|
@@ -17980,7 +17965,7 @@ async function appendToConversationBuffer(prompt, sessionId) {
|
|
|
17980
17965
|
}
|
|
17981
17966
|
async function readAndClearConversationBuffer(currentSessionId) {
|
|
17982
17967
|
try {
|
|
17983
|
-
if ((0,
|
|
17968
|
+
if ((0, import_node_fs10.existsSync)(CONVERSATION_BUFFER_FILE)) {
|
|
17984
17969
|
const entries = await readBufferEntries();
|
|
17985
17970
|
let mine = entries;
|
|
17986
17971
|
let others = [];
|
|
@@ -18004,7 +17989,7 @@ async function readAndClearConversationBuffer(currentSessionId) {
|
|
|
18004
17989
|
};
|
|
18005
17990
|
}
|
|
18006
17991
|
}
|
|
18007
|
-
if ((0,
|
|
17992
|
+
if ((0, import_node_fs10.existsSync)(INTENT_FILE)) {
|
|
18008
17993
|
try {
|
|
18009
17994
|
const content = await (0, import_promises5.readFile)(INTENT_FILE, "utf-8");
|
|
18010
17995
|
await (0, import_promises5.unlink)(INTENT_FILE).catch(() => {
|
|
@@ -18297,9 +18282,9 @@ function isCommandOnlyTurn(input) {
|
|
|
18297
18282
|
|
|
18298
18283
|
// src/lib/context-identity.ts
|
|
18299
18284
|
var import_node_crypto2 = require("node:crypto");
|
|
18300
|
-
var
|
|
18285
|
+
var import_node_fs11 = require("node:fs");
|
|
18301
18286
|
var import_node_os4 = require("node:os");
|
|
18302
|
-
var
|
|
18287
|
+
var import_node_path11 = require("node:path");
|
|
18303
18288
|
var SHARED_SENTINELS = /* @__PURE__ */ new Set([
|
|
18304
18289
|
"",
|
|
18305
18290
|
"-",
|
|
@@ -18337,7 +18322,7 @@ function contextIdentity(input) {
|
|
|
18337
18322
|
if (rawTree && !isSharedSentinel(rawTree)) {
|
|
18338
18323
|
let resolved = rawTree;
|
|
18339
18324
|
try {
|
|
18340
|
-
resolved =
|
|
18325
|
+
resolved = import_node_fs11.realpathSync.native(rawTree);
|
|
18341
18326
|
} catch {
|
|
18342
18327
|
}
|
|
18343
18328
|
treeKey = (0, import_node_crypto2.createHash)("sha256").update(resolved).digest("hex").slice(0, 12);
|
|
@@ -18353,13 +18338,13 @@ function contextIdentity(input) {
|
|
|
18353
18338
|
}
|
|
18354
18339
|
function verityHome() {
|
|
18355
18340
|
const override = process.env.VERITY_HOME;
|
|
18356
|
-
return override && override.trim() ? (0,
|
|
18341
|
+
return override && override.trim() ? (0, import_node_path11.resolve)(override) : (0, import_node_path11.join)((0, import_node_os4.homedir)(), ".verity");
|
|
18357
18342
|
}
|
|
18358
18343
|
function dossierDir(identity) {
|
|
18359
|
-
return (0,
|
|
18344
|
+
return (0, import_node_path11.join)(verityHome(), "sessions", identity.userKey, identity.treeKey, identity.sessionKey);
|
|
18360
18345
|
}
|
|
18361
18346
|
function treeDir(identity) {
|
|
18362
|
-
return (0,
|
|
18347
|
+
return (0, import_node_path11.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
|
|
18363
18348
|
}
|
|
18364
18349
|
function scopeIdentity(token, sessionId) {
|
|
18365
18350
|
const t = (token ?? "").trim();
|
|
@@ -18374,8 +18359,8 @@ function sessionScopeKey(token, sessionId) {
|
|
|
18374
18359
|
|
|
18375
18360
|
// src/lib/task-context-buffer.ts
|
|
18376
18361
|
var import_promises6 = require("node:fs/promises");
|
|
18377
|
-
var
|
|
18378
|
-
var
|
|
18362
|
+
var import_node_fs12 = require("node:fs");
|
|
18363
|
+
var import_node_path12 = require("node:path");
|
|
18379
18364
|
var TASK_CONTEXT_DIR = `${VERITY_DIR}/.task-context`;
|
|
18380
18365
|
var MAX_BUFFER_BYTES = 500 * 1024;
|
|
18381
18366
|
var MAX_PROMPT_CHARS = 2e3;
|
|
@@ -18414,7 +18399,7 @@ async function appendResponseToTaskBuffer(taskId, assistantResponse, actionSumma
|
|
|
18414
18399
|
}
|
|
18415
18400
|
async function readTaskContextBuffer(taskId) {
|
|
18416
18401
|
const filePath = bufferPath(taskId);
|
|
18417
|
-
if (!(0,
|
|
18402
|
+
if (!(0, import_node_fs12.existsSync)(filePath)) return null;
|
|
18418
18403
|
try {
|
|
18419
18404
|
const content = await (0, import_promises6.readFile)(filePath, "utf-8");
|
|
18420
18405
|
if (!content.trim()) return null;
|
|
@@ -18448,12 +18433,12 @@ async function readTaskContextBuffer(taskId) {
|
|
|
18448
18433
|
}
|
|
18449
18434
|
async function cleanupTaskContextBuffers() {
|
|
18450
18435
|
try {
|
|
18451
|
-
if (!(0,
|
|
18436
|
+
if (!(0, import_node_fs12.existsSync)(TASK_CONTEXT_DIR)) return;
|
|
18452
18437
|
const files = await (0, import_promises6.readdir)(TASK_CONTEXT_DIR);
|
|
18453
18438
|
const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1e3;
|
|
18454
18439
|
for (const file of files) {
|
|
18455
18440
|
if (!file.endsWith(".jsonl")) continue;
|
|
18456
|
-
const filePath = (0,
|
|
18441
|
+
const filePath = (0, import_node_path12.join)(TASK_CONTEXT_DIR, file);
|
|
18457
18442
|
try {
|
|
18458
18443
|
const stats = await (0, import_promises6.stat)(filePath);
|
|
18459
18444
|
if (stats.mtimeMs < cutoffMs) {
|
|
@@ -18467,13 +18452,13 @@ async function cleanupTaskContextBuffers() {
|
|
|
18467
18452
|
}
|
|
18468
18453
|
function bufferPath(taskId) {
|
|
18469
18454
|
const safe = taskId.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
18470
|
-
return (0,
|
|
18455
|
+
return (0, import_node_path12.join)(TASK_CONTEXT_DIR, `${safe}.jsonl`);
|
|
18471
18456
|
}
|
|
18472
18457
|
async function appendEntry(taskId, entry) {
|
|
18473
18458
|
try {
|
|
18474
18459
|
await (0, import_promises6.mkdir)(TASK_CONTEXT_DIR, { recursive: true });
|
|
18475
18460
|
const filePath = bufferPath(taskId);
|
|
18476
|
-
if ((0,
|
|
18461
|
+
if ((0, import_node_fs12.existsSync)(filePath)) {
|
|
18477
18462
|
const stats = await (0, import_promises6.stat)(filePath);
|
|
18478
18463
|
if (stats.size >= MAX_BUFFER_BYTES) {
|
|
18479
18464
|
const content = await (0, import_promises6.readFile)(filePath, "utf-8");
|
|
@@ -18484,7 +18469,7 @@ async function appendEntry(taskId, entry) {
|
|
|
18484
18469
|
}
|
|
18485
18470
|
}
|
|
18486
18471
|
const line2 = JSON.stringify(entry) + "\n";
|
|
18487
|
-
const existing = (0,
|
|
18472
|
+
const existing = (0, import_node_fs12.existsSync)(filePath) ? await (0, import_promises6.readFile)(filePath, "utf-8") : "";
|
|
18488
18473
|
await (0, import_promises6.writeFile)(filePath, existing + line2);
|
|
18489
18474
|
} catch {
|
|
18490
18475
|
}
|
|
@@ -18492,20 +18477,20 @@ async function appendEntry(taskId, entry) {
|
|
|
18492
18477
|
|
|
18493
18478
|
// src/lib/memory-retrieval.ts
|
|
18494
18479
|
var import_promises8 = require("node:fs/promises");
|
|
18495
|
-
var
|
|
18496
|
-
var
|
|
18480
|
+
var import_node_fs15 = require("node:fs");
|
|
18481
|
+
var import_node_path15 = require("node:path");
|
|
18497
18482
|
|
|
18498
18483
|
// src/lib/org-mirror.ts
|
|
18499
|
-
var
|
|
18484
|
+
var import_node_fs13 = require("node:fs");
|
|
18500
18485
|
var import_promises7 = require("node:fs/promises");
|
|
18501
|
-
var
|
|
18486
|
+
var import_node_path13 = require("node:path");
|
|
18502
18487
|
var ORG_KINDS = ["decision", "security", "gotcha", "pattern", "domain", "integration"];
|
|
18503
18488
|
var STATE_FILE = ".org-pull-state.json";
|
|
18504
18489
|
var BODY_MAX = 8192;
|
|
18505
18490
|
function orgMirrorDir(remote = requestRemote()) {
|
|
18506
18491
|
const parsed = parseRemote(remote);
|
|
18507
18492
|
if (!parsed) return null;
|
|
18508
|
-
return (0,
|
|
18493
|
+
return (0, import_node_path13.join)(verityHome(), "orgs", parsed.host, parsed.owner.toLowerCase(), "memory");
|
|
18509
18494
|
}
|
|
18510
18495
|
function slugify(s) {
|
|
18511
18496
|
return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
@@ -18571,7 +18556,7 @@ function parseOrgNode(content) {
|
|
|
18571
18556
|
}
|
|
18572
18557
|
async function readState(dir) {
|
|
18573
18558
|
try {
|
|
18574
|
-
const parsed = JSON.parse(await (0, import_promises7.readFile)((0,
|
|
18559
|
+
const parsed = JSON.parse(await (0, import_promises7.readFile)((0, import_node_path13.join)(dir, STATE_FILE), "utf-8"));
|
|
18575
18560
|
return {
|
|
18576
18561
|
version: typeof parsed?.version === "string" ? parsed.version : null,
|
|
18577
18562
|
organization: parsed?.organization && typeof parsed.organization.id === "string" ? parsed.organization : null,
|
|
@@ -18583,7 +18568,7 @@ async function readState(dir) {
|
|
|
18583
18568
|
}
|
|
18584
18569
|
async function writeState(dir, state) {
|
|
18585
18570
|
await (0, import_promises7.mkdir)(dir, { recursive: true });
|
|
18586
|
-
await (0, import_promises7.writeFile)((0,
|
|
18571
|
+
await (0, import_promises7.writeFile)((0, import_node_path13.join)(dir, STATE_FILE), JSON.stringify({
|
|
18587
18572
|
...state.version ? { version: state.version } : {},
|
|
18588
18573
|
organization: state.organization,
|
|
18589
18574
|
pulled_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -18648,24 +18633,24 @@ async function pullOrgKnowledge(opts) {
|
|
|
18648
18633
|
for (const n of nodes) {
|
|
18649
18634
|
const rel = orgNodePath(n);
|
|
18650
18635
|
if (written.has(rel)) continue;
|
|
18651
|
-
await (0, import_promises7.mkdir)((0,
|
|
18652
|
-
await (0, import_promises7.writeFile)((0,
|
|
18636
|
+
await (0, import_promises7.mkdir)((0, import_node_path13.join)(dir, rel.split("/")[0]), { recursive: true });
|
|
18637
|
+
await (0, import_promises7.writeFile)((0, import_node_path13.join)(dir, rel), renderOrgNode(n, org?.name ?? ""));
|
|
18653
18638
|
written.add(rel);
|
|
18654
18639
|
}
|
|
18655
18640
|
for (const rel of state.files) {
|
|
18656
|
-
if (!written.has(rel)) await (0, import_promises7.rm)((0,
|
|
18641
|
+
if (!written.has(rel)) await (0, import_promises7.rm)((0, import_node_path13.join)(dir, rel), { force: true });
|
|
18657
18642
|
}
|
|
18658
|
-
await (0, import_promises7.writeFile)((0,
|
|
18643
|
+
await (0, import_promises7.writeFile)((0, import_node_path13.join)(dir, "index.md"), renderIndex(org?.name ?? "no organization", nodes));
|
|
18659
18644
|
await writeState(dir, { version: org ? page.version : null, organization: org, files: [...written].sort() });
|
|
18660
18645
|
return { ok: true, status: org ? "pulled" : "none", received: nodes.length, dir };
|
|
18661
18646
|
}
|
|
18662
18647
|
async function readOrgMirror(remote = requestRemote()) {
|
|
18663
18648
|
const dir = orgMirrorDir(remote);
|
|
18664
|
-
if (!dir || !(0,
|
|
18649
|
+
if (!dir || !(0, import_node_fs13.existsSync)(dir)) return [];
|
|
18665
18650
|
const out2 = [];
|
|
18666
18651
|
for (const kind of ORG_KINDS) {
|
|
18667
|
-
const kindDir = (0,
|
|
18668
|
-
if (!(0,
|
|
18652
|
+
const kindDir = (0, import_node_path13.join)(dir, kind);
|
|
18653
|
+
if (!(0, import_node_fs13.existsSync)(kindDir)) continue;
|
|
18669
18654
|
let files;
|
|
18670
18655
|
try {
|
|
18671
18656
|
files = await (0, import_promises7.readdir)(kindDir);
|
|
@@ -18675,7 +18660,7 @@ async function readOrgMirror(remote = requestRemote()) {
|
|
|
18675
18660
|
for (const file of files) {
|
|
18676
18661
|
if (!file.endsWith(".md")) continue;
|
|
18677
18662
|
try {
|
|
18678
|
-
const node = parseOrgNode(await (0, import_promises7.readFile)((0,
|
|
18663
|
+
const node = parseOrgNode(await (0, import_promises7.readFile)((0, import_node_path13.join)(kindDir, file), "utf-8"));
|
|
18679
18664
|
if (node) out2.push(node);
|
|
18680
18665
|
} catch {
|
|
18681
18666
|
}
|
|
@@ -18685,29 +18670,29 @@ async function readOrgMirror(remote = requestRemote()) {
|
|
|
18685
18670
|
}
|
|
18686
18671
|
|
|
18687
18672
|
// src/lib/safe-read.ts
|
|
18688
|
-
var
|
|
18689
|
-
var
|
|
18690
|
-
var FLAGS =
|
|
18673
|
+
var import_node_fs14 = require("node:fs");
|
|
18674
|
+
var import_node_path14 = require("node:path");
|
|
18675
|
+
var FLAGS = import_node_fs14.constants;
|
|
18691
18676
|
var NOFOLLOW = FLAGS.O_NOFOLLOW;
|
|
18692
18677
|
var NONBLOCK = FLAGS.O_NONBLOCK;
|
|
18693
18678
|
function closeOpened(fd) {
|
|
18694
18679
|
try {
|
|
18695
|
-
(0,
|
|
18680
|
+
(0, import_node_fs14.closeSync)(fd);
|
|
18696
18681
|
} catch {
|
|
18697
18682
|
}
|
|
18698
18683
|
}
|
|
18699
18684
|
function isInsideRoot(realRoot, realPath) {
|
|
18700
|
-
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(
|
|
18685
|
+
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path14.sep) ? realRoot : realRoot + import_node_path14.sep);
|
|
18701
18686
|
}
|
|
18702
18687
|
function sameOpenedFile(opened, current, nofollowAvailable) {
|
|
18703
18688
|
if (!nofollowAvailable && (opened.ino === 0n || current.ino === 0n)) return false;
|
|
18704
18689
|
return opened.ino === current.ino && opened.dev === current.dev;
|
|
18705
18690
|
}
|
|
18706
18691
|
function openRegularInRoot(root, path) {
|
|
18707
|
-
const full = (0,
|
|
18692
|
+
const full = (0, import_node_path14.isAbsolute)(path) ? path : (0, import_node_path14.join)(root, path);
|
|
18708
18693
|
let fd;
|
|
18709
18694
|
try {
|
|
18710
|
-
fd = (0,
|
|
18695
|
+
fd = (0, import_node_fs14.openSync)(full, import_node_fs14.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
|
|
18711
18696
|
} catch (err2) {
|
|
18712
18697
|
const code = err2.code;
|
|
18713
18698
|
if (code === "ELOOP" || code === "EMLINK" || code === "EFTYPE") return { ok: false, reason: "symlink" };
|
|
@@ -18715,18 +18700,18 @@ function openRegularInRoot(root, path) {
|
|
|
18715
18700
|
return { ok: false, reason: "unreadable" };
|
|
18716
18701
|
}
|
|
18717
18702
|
try {
|
|
18718
|
-
const opened = (0,
|
|
18703
|
+
const opened = (0, import_node_fs14.fstatSync)(fd, { bigint: true });
|
|
18719
18704
|
if (!opened.isFile()) {
|
|
18720
18705
|
closeOpened(fd);
|
|
18721
18706
|
return { ok: false, reason: "not-regular" };
|
|
18722
18707
|
}
|
|
18723
|
-
const realRoot =
|
|
18724
|
-
const realPath =
|
|
18708
|
+
const realRoot = import_node_fs14.realpathSync.native(root);
|
|
18709
|
+
const realPath = import_node_fs14.realpathSync.native(full);
|
|
18725
18710
|
if (!isInsideRoot(realRoot, realPath)) {
|
|
18726
18711
|
closeOpened(fd);
|
|
18727
18712
|
return { ok: false, reason: "outside-root" };
|
|
18728
18713
|
}
|
|
18729
|
-
const current = (0,
|
|
18714
|
+
const current = (0, import_node_fs14.statSync)(realPath, { bigint: true });
|
|
18730
18715
|
if (!sameOpenedFile(opened, current, NOFOLLOW !== void 0)) {
|
|
18731
18716
|
closeOpened(fd);
|
|
18732
18717
|
return { ok: false, reason: NOFOLLOW === void 0 ? "unreadable" : "outside-root" };
|
|
@@ -18748,7 +18733,7 @@ function readOpened(fd, size) {
|
|
|
18748
18733
|
const buffer = Buffer.alloc(size);
|
|
18749
18734
|
let offset = 0;
|
|
18750
18735
|
while (offset < size) {
|
|
18751
|
-
const n = (0,
|
|
18736
|
+
const n = (0, import_node_fs14.readSync)(fd, buffer, offset, size - offset, offset);
|
|
18752
18737
|
if (n === 0) break;
|
|
18753
18738
|
offset += n;
|
|
18754
18739
|
}
|
|
@@ -19063,14 +19048,14 @@ function parseFrontmatter(content) {
|
|
|
19063
19048
|
return { fm, body: match[2].trim() };
|
|
19064
19049
|
}
|
|
19065
19050
|
async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = DEFAULT_BUDGET_TOKENS) {
|
|
19066
|
-
const hasRepoGraph = (0,
|
|
19051
|
+
const hasRepoGraph = (0, import_node_fs15.existsSync)(memoryDir());
|
|
19067
19052
|
const budget = Math.min(budgetTokens, MAX_BUDGET_TOKENS);
|
|
19068
19053
|
const promptTokens = tokenize(promptText);
|
|
19069
19054
|
const orgPromptTerms = orgTerms(promptText);
|
|
19070
19055
|
const nodes = [];
|
|
19071
19056
|
for (const domain of hasRepoGraph ? DOMAINS : []) {
|
|
19072
|
-
const domainDir = (0,
|
|
19073
|
-
if (!(0,
|
|
19057
|
+
const domainDir = (0, import_node_path15.join)(memoryDir(), domain);
|
|
19058
|
+
if (!(0, import_node_fs15.existsSync)(domainDir)) continue;
|
|
19074
19059
|
try {
|
|
19075
19060
|
const files = await (0, import_promises8.readdir)(domainDir);
|
|
19076
19061
|
for (const file of files) {
|
|
@@ -19144,27 +19129,27 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
|
|
|
19144
19129
|
}
|
|
19145
19130
|
|
|
19146
19131
|
// src/lib/injection-record.ts
|
|
19147
|
-
var
|
|
19132
|
+
var import_node_fs17 = require("node:fs");
|
|
19148
19133
|
var import_node_crypto3 = require("node:crypto");
|
|
19149
19134
|
|
|
19150
19135
|
// src/lib/safe-write.ts
|
|
19151
|
-
var
|
|
19152
|
-
var
|
|
19153
|
-
var FLAGS2 =
|
|
19136
|
+
var import_node_fs16 = require("node:fs");
|
|
19137
|
+
var import_node_path16 = require("node:path");
|
|
19138
|
+
var FLAGS2 = import_node_fs16.constants;
|
|
19154
19139
|
var O_NOFOLLOW = FLAGS2.O_NOFOLLOW ?? 0;
|
|
19155
19140
|
var NOFOLLOW_AVAILABLE = O_NOFOLLOW !== 0;
|
|
19156
19141
|
function validateRoot(root) {
|
|
19157
19142
|
try {
|
|
19158
|
-
const parentReal = (0,
|
|
19159
|
-
const expected = (0,
|
|
19143
|
+
const parentReal = (0, import_node_fs16.realpathSync)((0, import_node_path16.dirname)(root));
|
|
19144
|
+
const expected = (0, import_node_path16.join)(parentReal, (0, import_node_path16.basename)(root));
|
|
19160
19145
|
try {
|
|
19161
|
-
(0,
|
|
19146
|
+
(0, import_node_fs16.mkdirSync)(expected);
|
|
19162
19147
|
} catch (e) {
|
|
19163
19148
|
if (e.code !== "EEXIST") return null;
|
|
19164
19149
|
}
|
|
19165
|
-
const st = (0,
|
|
19150
|
+
const st = (0, import_node_fs16.lstatSync)(expected, { bigint: true });
|
|
19166
19151
|
if (st.isSymbolicLink() || !st.isDirectory()) return null;
|
|
19167
|
-
if ((0,
|
|
19152
|
+
if ((0, import_node_fs16.realpathSync)(expected) !== expected) return null;
|
|
19168
19153
|
return { real: expected, dev: st.dev, ino: st.ino };
|
|
19169
19154
|
} catch {
|
|
19170
19155
|
return null;
|
|
@@ -19172,18 +19157,18 @@ function validateRoot(root) {
|
|
|
19172
19157
|
}
|
|
19173
19158
|
function rootUnchanged(root) {
|
|
19174
19159
|
try {
|
|
19175
|
-
const st = (0,
|
|
19160
|
+
const st = (0, import_node_fs16.lstatSync)(root.real, { bigint: true });
|
|
19176
19161
|
return !st.isSymbolicLink() && st.isDirectory() && st.dev === root.dev && st.ino === root.ino;
|
|
19177
19162
|
} catch {
|
|
19178
19163
|
return false;
|
|
19179
19164
|
}
|
|
19180
19165
|
}
|
|
19181
19166
|
function bareName(name2) {
|
|
19182
|
-
return !!name2 && name2 === (0,
|
|
19167
|
+
return !!name2 && name2 === (0, import_node_path16.basename)(name2) && name2 !== "." && name2 !== ".." && !name2.includes("\0");
|
|
19183
19168
|
}
|
|
19184
19169
|
function absentOrRegular(path) {
|
|
19185
19170
|
try {
|
|
19186
|
-
const st = (0,
|
|
19171
|
+
const st = (0, import_node_fs16.lstatSync)(path);
|
|
19187
19172
|
return st.isFile() && !st.isSymbolicLink();
|
|
19188
19173
|
} catch (e) {
|
|
19189
19174
|
return e.code === "ENOENT";
|
|
@@ -19191,11 +19176,11 @@ function absentOrRegular(path) {
|
|
|
19191
19176
|
}
|
|
19192
19177
|
function verifyOpened(fd, path, root) {
|
|
19193
19178
|
try {
|
|
19194
|
-
const opened = (0,
|
|
19179
|
+
const opened = (0, import_node_fs16.fstatSync)(fd, { bigint: true });
|
|
19195
19180
|
if (!opened.isFile() || opened.nlink !== 1n) return false;
|
|
19196
|
-
const real = (0,
|
|
19181
|
+
const real = (0, import_node_fs16.realpathSync)(path);
|
|
19197
19182
|
if (!isInsideRoot(root.real, real)) return false;
|
|
19198
|
-
const current = (0,
|
|
19183
|
+
const current = (0, import_node_fs16.statSync)(real, { bigint: true });
|
|
19199
19184
|
if (!sameOpenedFile(opened, current, NOFOLLOW_AVAILABLE)) return false;
|
|
19200
19185
|
return rootUnchanged(root);
|
|
19201
19186
|
} catch {
|
|
@@ -19204,21 +19189,21 @@ function verifyOpened(fd, path, root) {
|
|
|
19204
19189
|
}
|
|
19205
19190
|
function removeIfOurs(fd, path) {
|
|
19206
19191
|
try {
|
|
19207
|
-
const opened = (0,
|
|
19208
|
-
const at = (0,
|
|
19209
|
-
if (!at.isSymbolicLink() && at.dev === opened.dev && at.ino === opened.ino) (0,
|
|
19192
|
+
const opened = (0, import_node_fs16.fstatSync)(fd, { bigint: true });
|
|
19193
|
+
const at = (0, import_node_fs16.lstatSync)(path, { bigint: true });
|
|
19194
|
+
if (!at.isSymbolicLink() && at.dev === opened.dev && at.ino === opened.ino) (0, import_node_fs16.unlinkSync)(path);
|
|
19210
19195
|
} catch {
|
|
19211
19196
|
}
|
|
19212
19197
|
}
|
|
19213
19198
|
function openTarget(path, append2) {
|
|
19214
|
-
const base =
|
|
19199
|
+
const base = import_node_fs16.constants.O_WRONLY | (append2 ? import_node_fs16.constants.O_APPEND : 0) | O_NOFOLLOW;
|
|
19215
19200
|
try {
|
|
19216
|
-
return { fd: (0,
|
|
19201
|
+
return { fd: (0, import_node_fs16.openSync)(path, base), created: false };
|
|
19217
19202
|
} catch (e) {
|
|
19218
19203
|
if (e.code !== "ENOENT") return null;
|
|
19219
19204
|
}
|
|
19220
19205
|
try {
|
|
19221
|
-
return { fd: (0,
|
|
19206
|
+
return { fd: (0, import_node_fs16.openSync)(path, base | import_node_fs16.constants.O_CREAT | import_node_fs16.constants.O_EXCL, 384), created: true };
|
|
19222
19207
|
} catch {
|
|
19223
19208
|
return null;
|
|
19224
19209
|
}
|
|
@@ -19226,7 +19211,7 @@ function openTarget(path, append2) {
|
|
|
19226
19211
|
function writeVerified(root, name2, hooks, append2, write) {
|
|
19227
19212
|
const r = validateRoot(root);
|
|
19228
19213
|
if (!r || !bareName(name2)) return false;
|
|
19229
|
-
const path = (0,
|
|
19214
|
+
const path = (0, import_node_path16.join)(r.real, name2);
|
|
19230
19215
|
if (!absentOrRegular(path)) return false;
|
|
19231
19216
|
if (!runHook(hooks)) return false;
|
|
19232
19217
|
const opened = openTarget(path, append2);
|
|
@@ -19242,7 +19227,7 @@ function writeVerified(root, name2, hooks, append2, write) {
|
|
|
19242
19227
|
return false;
|
|
19243
19228
|
} finally {
|
|
19244
19229
|
try {
|
|
19245
|
-
(0,
|
|
19230
|
+
(0, import_node_fs16.closeSync)(opened.fd);
|
|
19246
19231
|
} catch {
|
|
19247
19232
|
}
|
|
19248
19233
|
}
|
|
@@ -19257,13 +19242,13 @@ function runHook(hooks) {
|
|
|
19257
19242
|
}
|
|
19258
19243
|
function appendInRoot(root, name2, text, hooks = {}) {
|
|
19259
19244
|
return writeVerified(root, name2, hooks, true, (fd) => {
|
|
19260
|
-
(0,
|
|
19245
|
+
(0, import_node_fs16.writeSync)(fd, text);
|
|
19261
19246
|
});
|
|
19262
19247
|
}
|
|
19263
19248
|
function replaceInRoot(root, name2, text, hooks = {}) {
|
|
19264
19249
|
return writeVerified(root, name2, hooks, false, (fd) => {
|
|
19265
|
-
(0,
|
|
19266
|
-
(0,
|
|
19250
|
+
(0, import_node_fs16.ftruncateSync)(fd, 0);
|
|
19251
|
+
(0, import_node_fs16.writeSync)(fd, text, 0);
|
|
19267
19252
|
});
|
|
19268
19253
|
}
|
|
19269
19254
|
|
|
@@ -19311,7 +19296,7 @@ function hashPrompt(prompt) {
|
|
|
19311
19296
|
function recordInjection(event) {
|
|
19312
19297
|
if (!appendInRoot(projectPath(VERITY_DIR), "injections.jsonl", JSON.stringify(event) + "\n")) return;
|
|
19313
19298
|
try {
|
|
19314
|
-
if ((0,
|
|
19299
|
+
if ((0, import_node_fs17.lstatSync)(recordPath()).size > COMPACT_AT_BYTES) writeEvents(readPendingInjections());
|
|
19315
19300
|
} catch {
|
|
19316
19301
|
}
|
|
19317
19302
|
}
|
|
@@ -19321,7 +19306,7 @@ function writeEvents(events) {
|
|
|
19321
19306
|
function readPendingInjections() {
|
|
19322
19307
|
try {
|
|
19323
19308
|
const p = recordPath();
|
|
19324
|
-
if (!(0,
|
|
19309
|
+
if (!(0, import_node_fs17.existsSync)(p)) return [];
|
|
19325
19310
|
const read2 = readRegularFileInRoot(projectPath(VERITY_DIR), "injections.jsonl", MAX_RECORD_BYTES);
|
|
19326
19311
|
if (!read2.ok) return [];
|
|
19327
19312
|
const out2 = [];
|
|
@@ -19341,13 +19326,13 @@ function readPendingInjections() {
|
|
|
19341
19326
|
|
|
19342
19327
|
// src/lib/memory-sync.ts
|
|
19343
19328
|
var import_promises9 = require("node:fs/promises");
|
|
19344
|
-
var
|
|
19345
|
-
var
|
|
19329
|
+
var import_node_fs20 = require("node:fs");
|
|
19330
|
+
var import_node_path18 = require("node:path");
|
|
19346
19331
|
var import_node_crypto4 = require("node:crypto");
|
|
19347
19332
|
|
|
19348
19333
|
// src/lib/gitignore.ts
|
|
19349
19334
|
var import_node_child_process7 = require("node:child_process");
|
|
19350
|
-
var
|
|
19335
|
+
var import_node_fs18 = require("node:fs");
|
|
19351
19336
|
var VERITY_GITIGNORE_MARKER = "# Verity \u2014 machine-local state.";
|
|
19352
19337
|
var SETTINGS_LOCAL_IGNORE_ENTRY = ".claude/settings.local.json";
|
|
19353
19338
|
var VERITY_GITIGNORE_BLOCK = [
|
|
@@ -19431,7 +19416,7 @@ function fenceMemoryLines(lines) {
|
|
|
19431
19416
|
function ensureVerityGitignore() {
|
|
19432
19417
|
let content = "";
|
|
19433
19418
|
try {
|
|
19434
|
-
content = (0,
|
|
19419
|
+
content = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
|
|
19435
19420
|
} catch {
|
|
19436
19421
|
}
|
|
19437
19422
|
const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
|
|
@@ -19458,7 +19443,7 @@ function ensureVerityGitignore() {
|
|
|
19458
19443
|
const sep5 = text === "" ? "" : text.endsWith("\n") ? "\n" : "\n\n";
|
|
19459
19444
|
text = text + sep5 + VERITY_GITIGNORE_BLOCK;
|
|
19460
19445
|
}
|
|
19461
|
-
if (text !== content) (0,
|
|
19446
|
+
if (text !== content) (0, import_node_fs18.writeFileSync)(".gitignore", text);
|
|
19462
19447
|
return verified(
|
|
19463
19448
|
memoryIsCommitted ? "memory-tracked" : hasSupersededMemory ? "memory-fenced" : needsRepair ? "repaired" : "added"
|
|
19464
19449
|
);
|
|
@@ -19478,7 +19463,7 @@ function untrackMemory() {
|
|
|
19478
19463
|
function writeFencedBlock() {
|
|
19479
19464
|
let content = "";
|
|
19480
19465
|
try {
|
|
19481
|
-
content = (0,
|
|
19466
|
+
content = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
|
|
19482
19467
|
} catch {
|
|
19483
19468
|
}
|
|
19484
19469
|
const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
|
|
@@ -19490,7 +19475,7 @@ function writeFencedBlock() {
|
|
|
19490
19475
|
text = text + sep5 + VERITY_GITIGNORE_BLOCK;
|
|
19491
19476
|
}
|
|
19492
19477
|
try {
|
|
19493
|
-
(0,
|
|
19478
|
+
(0, import_node_fs18.writeFileSync)(".gitignore", text);
|
|
19494
19479
|
return true;
|
|
19495
19480
|
} catch {
|
|
19496
19481
|
return false;
|
|
@@ -19499,14 +19484,14 @@ function writeFencedBlock() {
|
|
|
19499
19484
|
function fenceMemory() {
|
|
19500
19485
|
let original = null;
|
|
19501
19486
|
try {
|
|
19502
|
-
original = (0,
|
|
19487
|
+
original = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
|
|
19503
19488
|
} catch {
|
|
19504
19489
|
original = null;
|
|
19505
19490
|
}
|
|
19506
19491
|
const restore = () => {
|
|
19507
19492
|
try {
|
|
19508
|
-
if (original === null) (0,
|
|
19509
|
-
else (0,
|
|
19493
|
+
if (original === null) (0, import_node_fs18.rmSync)(".gitignore", { force: true });
|
|
19494
|
+
else (0, import_node_fs18.writeFileSync)(".gitignore", original);
|
|
19510
19495
|
} catch {
|
|
19511
19496
|
}
|
|
19512
19497
|
};
|
|
@@ -19524,7 +19509,7 @@ function fenceMemory() {
|
|
|
19524
19509
|
}
|
|
19525
19510
|
function memoryOptOut() {
|
|
19526
19511
|
try {
|
|
19527
|
-
return (0,
|
|
19512
|
+
return (0, import_node_fs18.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
|
|
19528
19513
|
} catch {
|
|
19529
19514
|
return false;
|
|
19530
19515
|
}
|
|
@@ -19532,13 +19517,13 @@ function memoryOptOut() {
|
|
|
19532
19517
|
function keepMemoryTracked() {
|
|
19533
19518
|
let content = "";
|
|
19534
19519
|
try {
|
|
19535
|
-
content = (0,
|
|
19520
|
+
content = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
|
|
19536
19521
|
} catch {
|
|
19537
19522
|
}
|
|
19538
19523
|
if (content.includes(MEMORY_OPT_OUT_MARKER)) return "already";
|
|
19539
19524
|
try {
|
|
19540
19525
|
const sep5 = content === "" ? "" : content.endsWith("\n") ? "\n" : "\n\n";
|
|
19541
|
-
(0,
|
|
19526
|
+
(0, import_node_fs18.writeFileSync)(".gitignore", content + sep5 + MEMORY_OPT_OUT_STANZA);
|
|
19542
19527
|
} catch {
|
|
19543
19528
|
return "failed";
|
|
19544
19529
|
}
|
|
@@ -19573,26 +19558,26 @@ function untrackVerityState() {
|
|
|
19573
19558
|
}
|
|
19574
19559
|
|
|
19575
19560
|
// src/lib/safe-path.ts
|
|
19576
|
-
var
|
|
19577
|
-
var
|
|
19561
|
+
var import_node_fs19 = require("node:fs");
|
|
19562
|
+
var import_node_path17 = require("node:path");
|
|
19578
19563
|
function resolveInside(baseDir, candidate) {
|
|
19579
19564
|
if (typeof candidate !== "string" || candidate.length === 0) return null;
|
|
19580
|
-
if ((0,
|
|
19581
|
-
const baseAbs = (0,
|
|
19582
|
-
const full = (0,
|
|
19583
|
-
const baseSep = baseAbs.endsWith(
|
|
19565
|
+
if ((0, import_node_path17.isAbsolute)(candidate)) return null;
|
|
19566
|
+
const baseAbs = (0, import_node_path17.resolve)(baseDir);
|
|
19567
|
+
const full = (0, import_node_path17.resolve)(baseAbs, candidate);
|
|
19568
|
+
const baseSep = baseAbs.endsWith(import_node_path17.sep) ? baseAbs : baseAbs + import_node_path17.sep;
|
|
19584
19569
|
if (full !== baseAbs && !full.startsWith(baseSep)) return null;
|
|
19585
19570
|
try {
|
|
19586
|
-
if ((0,
|
|
19587
|
-
const realBase = (0,
|
|
19588
|
-
const realBaseSep = realBase.endsWith(
|
|
19571
|
+
if ((0, import_node_fs19.existsSync)(baseAbs)) {
|
|
19572
|
+
const realBase = (0, import_node_fs19.realpathSync)(baseAbs);
|
|
19573
|
+
const realBaseSep = realBase.endsWith(import_node_path17.sep) ? realBase : realBase + import_node_path17.sep;
|
|
19589
19574
|
let probe = full;
|
|
19590
|
-
while (!(0,
|
|
19591
|
-
const parent = (0,
|
|
19575
|
+
while (!(0, import_node_fs19.existsSync)(probe)) {
|
|
19576
|
+
const parent = (0, import_node_path17.dirname)(probe);
|
|
19592
19577
|
if (parent === probe) break;
|
|
19593
19578
|
probe = parent;
|
|
19594
19579
|
}
|
|
19595
|
-
const realProbe = (0,
|
|
19580
|
+
const realProbe = (0, import_node_fs19.realpathSync)(probe);
|
|
19596
19581
|
if (realProbe !== realBase && !realProbe.startsWith(realBaseSep)) return null;
|
|
19597
19582
|
}
|
|
19598
19583
|
} catch {
|
|
@@ -19600,37 +19585,37 @@ function resolveInside(baseDir, candidate) {
|
|
|
19600
19585
|
}
|
|
19601
19586
|
return full;
|
|
19602
19587
|
}
|
|
19603
|
-
var O_NOFOLLOW2 = typeof
|
|
19588
|
+
var O_NOFOLLOW2 = typeof import_node_fs19.constants.O_NOFOLLOW === "number" ? import_node_fs19.constants.O_NOFOLLOW : 0;
|
|
19604
19589
|
function readFileInside(baseDir, candidate, maxBytes) {
|
|
19605
19590
|
const full = resolveInside(baseDir, candidate);
|
|
19606
19591
|
if (!full) return null;
|
|
19607
19592
|
let realParent;
|
|
19608
19593
|
let realBase;
|
|
19609
19594
|
try {
|
|
19610
|
-
realParent = (0,
|
|
19611
|
-
realBase = (0,
|
|
19595
|
+
realParent = (0, import_node_fs19.realpathSync)((0, import_node_path17.dirname)(full));
|
|
19596
|
+
realBase = (0, import_node_fs19.realpathSync)((0, import_node_path17.resolve)(baseDir));
|
|
19612
19597
|
} catch {
|
|
19613
19598
|
return null;
|
|
19614
19599
|
}
|
|
19615
|
-
const realBaseSep = realBase.endsWith(
|
|
19600
|
+
const realBaseSep = realBase.endsWith(import_node_path17.sep) ? realBase : realBase + import_node_path17.sep;
|
|
19616
19601
|
if (realParent !== realBase && !realParent.startsWith(realBaseSep)) return null;
|
|
19617
|
-
const target = (0,
|
|
19602
|
+
const target = (0, import_node_path17.join)(realParent, (0, import_node_path17.basename)(full));
|
|
19618
19603
|
let fd = null;
|
|
19619
19604
|
try {
|
|
19620
|
-
fd = (0,
|
|
19621
|
-
const st = (0,
|
|
19605
|
+
fd = (0, import_node_fs19.openSync)(target, import_node_fs19.constants.O_RDONLY | O_NOFOLLOW2);
|
|
19606
|
+
const st = (0, import_node_fs19.fstatSync)(fd);
|
|
19622
19607
|
if (!st.isFile()) return null;
|
|
19623
19608
|
const cap2 = Math.min(maxBytes, st.size);
|
|
19624
19609
|
if (cap2 <= 0) return "";
|
|
19625
19610
|
const buf = Buffer.alloc(cap2);
|
|
19626
|
-
const bytesRead = (0,
|
|
19611
|
+
const bytesRead = (0, import_node_fs19.readSync)(fd, buf, 0, cap2, 0);
|
|
19627
19612
|
return buf.subarray(0, bytesRead).toString("utf-8");
|
|
19628
19613
|
} catch {
|
|
19629
19614
|
return null;
|
|
19630
19615
|
} finally {
|
|
19631
19616
|
if (fd !== null) {
|
|
19632
19617
|
try {
|
|
19633
|
-
(0,
|
|
19618
|
+
(0, import_node_fs19.closeSync)(fd);
|
|
19634
19619
|
} catch {
|
|
19635
19620
|
}
|
|
19636
19621
|
}
|
|
@@ -19713,32 +19698,32 @@ var syncStateFile = () => projectPath(`${VERITY_DIR}/.memory-sync-state.json`);
|
|
|
19713
19698
|
async function ensureMemoryDir() {
|
|
19714
19699
|
await (0, import_promises9.mkdir)(memoryDir2(), { recursive: true });
|
|
19715
19700
|
for (const domain of DOMAINS2) {
|
|
19716
|
-
await (0, import_promises9.mkdir)((0,
|
|
19701
|
+
await (0, import_promises9.mkdir)((0, import_node_path18.join)(memoryDir2(), domain), { recursive: true });
|
|
19717
19702
|
}
|
|
19718
|
-
if (!(0,
|
|
19719
|
-
await (0, import_promises9.writeFile)((0,
|
|
19703
|
+
if (!(0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "SCHEMA.md"))) {
|
|
19704
|
+
await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
|
|
19720
19705
|
}
|
|
19721
|
-
if (!(0,
|
|
19722
|
-
await (0, import_promises9.writeFile)((0,
|
|
19706
|
+
if (!(0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "index.md"))) {
|
|
19707
|
+
await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
|
|
19723
19708
|
}
|
|
19724
|
-
if (!(0,
|
|
19725
|
-
await (0, import_promises9.writeFile)((0,
|
|
19709
|
+
if (!(0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "log.md"))) {
|
|
19710
|
+
await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
|
|
19726
19711
|
}
|
|
19727
19712
|
}
|
|
19728
19713
|
async function buildManifest() {
|
|
19729
|
-
if (!(0,
|
|
19714
|
+
if (!(0, import_node_fs20.existsSync)(memoryDir2())) {
|
|
19730
19715
|
return { schema_version: 1, nodes: [], index_hash: null, log_length: 0 };
|
|
19731
19716
|
}
|
|
19732
19717
|
const nodes = [];
|
|
19733
19718
|
for (const domain of DOMAINS2) {
|
|
19734
|
-
const domainDir = (0,
|
|
19735
|
-
if (!(0,
|
|
19719
|
+
const domainDir = (0, import_node_path18.join)(memoryDir2(), domain);
|
|
19720
|
+
if (!(0, import_node_fs20.existsSync)(domainDir)) continue;
|
|
19736
19721
|
try {
|
|
19737
19722
|
const files = await (0, import_promises9.readdir)(domainDir);
|
|
19738
19723
|
for (const file of files) {
|
|
19739
19724
|
if (!file.endsWith(".md")) continue;
|
|
19740
19725
|
const filePath = `${domain}/${file}`;
|
|
19741
|
-
const fullPath = (0,
|
|
19726
|
+
const fullPath = (0, import_node_path18.join)(memoryDir2(), filePath);
|
|
19742
19727
|
try {
|
|
19743
19728
|
const content = await (0, import_promises9.readFile)(fullPath, "utf-8");
|
|
19744
19729
|
const hash = (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex").slice(0, 16);
|
|
@@ -19751,13 +19736,13 @@ async function buildManifest() {
|
|
|
19751
19736
|
}
|
|
19752
19737
|
let indexHash = null;
|
|
19753
19738
|
try {
|
|
19754
|
-
const indexContent = await (0, import_promises9.readFile)((0,
|
|
19739
|
+
const indexContent = await (0, import_promises9.readFile)((0, import_node_path18.join)(memoryDir2(), "index.md"), "utf-8");
|
|
19755
19740
|
indexHash = `sha256:${(0, import_node_crypto4.createHash)("sha256").update(indexContent).digest("hex").slice(0, 16)}`;
|
|
19756
19741
|
} catch {
|
|
19757
19742
|
}
|
|
19758
19743
|
let logLength = 0;
|
|
19759
19744
|
try {
|
|
19760
|
-
const logContent = await (0, import_promises9.readFile)((0,
|
|
19745
|
+
const logContent = await (0, import_promises9.readFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), "utf-8");
|
|
19761
19746
|
logLength = logContent.split("\n").length;
|
|
19762
19747
|
} catch {
|
|
19763
19748
|
}
|
|
@@ -19768,15 +19753,15 @@ function hashContent(content) {
|
|
|
19768
19753
|
}
|
|
19769
19754
|
async function readOnDiskNodes() {
|
|
19770
19755
|
const out2 = /* @__PURE__ */ new Map();
|
|
19771
|
-
if (!(0,
|
|
19756
|
+
if (!(0, import_node_fs20.existsSync)(memoryDir2())) return out2;
|
|
19772
19757
|
for (const domain of DOMAINS2) {
|
|
19773
|
-
const domainDir = (0,
|
|
19774
|
-
if (!(0,
|
|
19758
|
+
const domainDir = (0, import_node_path18.join)(memoryDir2(), domain);
|
|
19759
|
+
if (!(0, import_node_fs20.existsSync)(domainDir)) continue;
|
|
19775
19760
|
try {
|
|
19776
19761
|
for (const file of await (0, import_promises9.readdir)(domainDir)) {
|
|
19777
19762
|
if (!file.endsWith(".md")) continue;
|
|
19778
19763
|
try {
|
|
19779
|
-
out2.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0,
|
|
19764
|
+
out2.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0, import_node_path18.join)(domainDir, file), "utf-8")));
|
|
19780
19765
|
} catch {
|
|
19781
19766
|
}
|
|
19782
19767
|
}
|
|
@@ -19813,7 +19798,7 @@ async function recordSyncedNodePaths() {
|
|
|
19813
19798
|
}
|
|
19814
19799
|
}
|
|
19815
19800
|
async function writeFileAtomic(path, content) {
|
|
19816
|
-
await (0, import_promises9.mkdir)((0,
|
|
19801
|
+
await (0, import_promises9.mkdir)((0, import_node_path18.dirname)(path), { recursive: true });
|
|
19817
19802
|
const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
19818
19803
|
await (0, import_promises9.writeFile)(tmp, content);
|
|
19819
19804
|
await (0, import_promises9.rename)(tmp, path);
|
|
@@ -19827,8 +19812,8 @@ async function computeEditedNodeUploads() {
|
|
|
19827
19812
|
const uploads = [];
|
|
19828
19813
|
for (const [path, prevHash] of prev) {
|
|
19829
19814
|
if (prevHash == null) continue;
|
|
19830
|
-
const full = (0,
|
|
19831
|
-
if (!(0,
|
|
19815
|
+
const full = (0, import_node_path18.join)(memoryDir2(), path);
|
|
19816
|
+
if (!(0, import_node_fs20.existsSync)(full)) continue;
|
|
19832
19817
|
let content;
|
|
19833
19818
|
try {
|
|
19834
19819
|
content = await (0, import_promises9.readFile)(full, "utf-8");
|
|
@@ -19872,8 +19857,8 @@ async function applyMemoryWrites(writes, opts = {}) {
|
|
|
19872
19857
|
const logLines = [`- ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 16)} \u2014 Applied ${count} write(s) from server`];
|
|
19873
19858
|
for (const n of notes) logLines.push(` - ${n}`);
|
|
19874
19859
|
try {
|
|
19875
|
-
const existing = (0,
|
|
19876
|
-
await (0, import_promises9.writeFile)((0,
|
|
19860
|
+
const existing = (0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "log.md")) ? await (0, import_promises9.readFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
|
|
19861
|
+
await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
|
|
19877
19862
|
} catch {
|
|
19878
19863
|
}
|
|
19879
19864
|
if (opts.baseline === "written") await mergeSyncBaseline(synced);
|
|
@@ -19883,7 +19868,7 @@ async function applyMemoryWrites(writes, opts = {}) {
|
|
|
19883
19868
|
async function mergeSyncBaseline(entries) {
|
|
19884
19869
|
if (entries.size === 0) return;
|
|
19885
19870
|
try {
|
|
19886
|
-
if ((0,
|
|
19871
|
+
if ((0, import_node_fs20.existsSync)(syncStateFile())) {
|
|
19887
19872
|
try {
|
|
19888
19873
|
JSON.parse(await (0, import_promises9.readFile)(syncStateFile(), "utf-8"));
|
|
19889
19874
|
} catch {
|
|
@@ -19911,7 +19896,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
|
|
|
19911
19896
|
notes.push(`${write.path}: dropped unmatched file_globs [${grounded.dropped.join(", ")}]`);
|
|
19912
19897
|
}
|
|
19913
19898
|
}
|
|
19914
|
-
if ((0,
|
|
19899
|
+
if ((0, import_node_fs20.existsSync)(fullPath)) {
|
|
19915
19900
|
let existing = "";
|
|
19916
19901
|
try {
|
|
19917
19902
|
existing = await (0, import_promises9.readFile)(fullPath, "utf-8");
|
|
@@ -19927,7 +19912,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
|
|
|
19927
19912
|
notes.push(`${write.path}: updated from server (untouched here since the server delivered it)`);
|
|
19928
19913
|
}
|
|
19929
19914
|
}
|
|
19930
|
-
await (0, import_promises9.mkdir)((0,
|
|
19915
|
+
await (0, import_promises9.mkdir)((0, import_node_path18.dirname)(fullPath), { recursive: true });
|
|
19931
19916
|
await (0, import_promises9.writeFile)(fullPath, content);
|
|
19932
19917
|
return { written: true, syncedHash: hashContent(content), notes };
|
|
19933
19918
|
}
|
|
@@ -19968,8 +19953,8 @@ async function regenerateIndex() {
|
|
|
19968
19953
|
];
|
|
19969
19954
|
let totalNodes = 0;
|
|
19970
19955
|
for (const domain of DOMAINS2.filter((d) => d !== "_archive")) {
|
|
19971
|
-
const domainDir = (0,
|
|
19972
|
-
if (!(0,
|
|
19956
|
+
const domainDir = (0, import_node_path18.join)(memoryDir2(), domain);
|
|
19957
|
+
if (!(0, import_node_fs20.existsSync)(domainDir)) continue;
|
|
19973
19958
|
try {
|
|
19974
19959
|
const files = await (0, import_promises9.readdir)(domainDir);
|
|
19975
19960
|
const mdFiles = files.filter((f) => f.endsWith(".md"));
|
|
@@ -19979,7 +19964,7 @@ async function regenerateIndex() {
|
|
|
19979
19964
|
for (const file of mdFiles.sort()) {
|
|
19980
19965
|
const slug = file.replace(/\.md$/, "");
|
|
19981
19966
|
try {
|
|
19982
|
-
const content = await (0, import_promises9.readFile)((0,
|
|
19967
|
+
const content = await (0, import_promises9.readFile)((0, import_node_path18.join)(domainDir, file), "utf-8");
|
|
19983
19968
|
const title = pickFrontmatter(content, "title") ?? slug;
|
|
19984
19969
|
const kind = pickFrontmatter(content, "kind") ?? "-";
|
|
19985
19970
|
const confidence = pickFrontmatter(content, "confidence");
|
|
@@ -20003,7 +19988,7 @@ async function regenerateIndex() {
|
|
|
20003
19988
|
lines.push("No nodes yet. Run an analysis to start building the knowledge graph.");
|
|
20004
19989
|
}
|
|
20005
19990
|
const next = lines.join("\n") + "\n";
|
|
20006
|
-
const indexPath = (0,
|
|
19991
|
+
const indexPath = (0, import_node_path18.join)(memoryDir2(), "index.md");
|
|
20007
19992
|
let existing = null;
|
|
20008
19993
|
try {
|
|
20009
19994
|
existing = await (0, import_promises9.readFile)(indexPath, "utf-8");
|
|
@@ -20400,9 +20385,9 @@ function hasLegacyMemoryBlock(text) {
|
|
|
20400
20385
|
return findMarker(text, LEGACY_MD_START) !== -1;
|
|
20401
20386
|
}
|
|
20402
20387
|
async function ensureClaudeMdPointer(cwd = repoRoot()) {
|
|
20403
|
-
const claudeMdPath = (0,
|
|
20388
|
+
const claudeMdPath = (0, import_node_path18.join)(cwd, "CLAUDE.md");
|
|
20404
20389
|
let existing = "";
|
|
20405
|
-
if ((0,
|
|
20390
|
+
if ((0, import_node_fs20.existsSync)(claudeMdPath)) {
|
|
20406
20391
|
existing = await (0, import_promises9.readFile)(claudeMdPath, "utf-8");
|
|
20407
20392
|
}
|
|
20408
20393
|
let startTag = CLAUDE_MD_START;
|
|
@@ -20543,9 +20528,9 @@ Body content (\u22648KB). Use [[node-id]] wikilinks for cross-references.
|
|
|
20543
20528
|
`;
|
|
20544
20529
|
|
|
20545
20530
|
// src/lib/dossier-session.ts
|
|
20546
|
-
var
|
|
20531
|
+
var import_node_fs25 = require("node:fs");
|
|
20547
20532
|
var import_node_crypto8 = require("node:crypto");
|
|
20548
|
-
var
|
|
20533
|
+
var import_node_path21 = require("node:path");
|
|
20549
20534
|
|
|
20550
20535
|
// src/lib/pending-repeat.ts
|
|
20551
20536
|
var STOP = /* @__PURE__ */ new Set([
|
|
@@ -20650,8 +20635,8 @@ function statementAnchorKey(file, patternId) {
|
|
|
20650
20635
|
|
|
20651
20636
|
// src/lib/dossier/log.ts
|
|
20652
20637
|
var import_node_crypto5 = require("node:crypto");
|
|
20653
|
-
var
|
|
20654
|
-
var
|
|
20638
|
+
var import_node_fs21 = require("node:fs");
|
|
20639
|
+
var import_node_path19 = require("node:path");
|
|
20655
20640
|
var CRC_TABLE = (() => {
|
|
20656
20641
|
const t = new Int32Array(256);
|
|
20657
20642
|
for (let i2 = 0; i2 < 256; i2++) {
|
|
@@ -20670,13 +20655,13 @@ function crc32(s) {
|
|
|
20670
20655
|
function openDossier(identity) {
|
|
20671
20656
|
try {
|
|
20672
20657
|
const dir = dossierDir(identity);
|
|
20673
|
-
(0,
|
|
20658
|
+
(0, import_node_fs21.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
20674
20659
|
return {
|
|
20675
20660
|
dir,
|
|
20676
20661
|
identity,
|
|
20677
|
-
eventsPath: (0,
|
|
20678
|
-
foldPath: (0,
|
|
20679
|
-
rotatedDir: (0,
|
|
20662
|
+
eventsPath: (0, import_node_path19.join)(dir, "events.jsonl"),
|
|
20663
|
+
foldPath: (0, import_node_path19.join)(dir, "fold.json"),
|
|
20664
|
+
rotatedDir: (0, import_node_path19.join)(dir, "rotated")
|
|
20680
20665
|
};
|
|
20681
20666
|
} catch {
|
|
20682
20667
|
return null;
|
|
@@ -20738,7 +20723,7 @@ function appendEvent(d, ev) {
|
|
|
20738
20723
|
at: ev.at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
20739
20724
|
...ev
|
|
20740
20725
|
});
|
|
20741
|
-
(0,
|
|
20726
|
+
(0, import_node_fs21.appendFileSync)(d.eventsPath, line2, { mode: 384 });
|
|
20742
20727
|
return true;
|
|
20743
20728
|
} catch {
|
|
20744
20729
|
return false;
|
|
@@ -20746,14 +20731,14 @@ function appendEvent(d, ev) {
|
|
|
20746
20731
|
}
|
|
20747
20732
|
function rotateIfNeeded2(d) {
|
|
20748
20733
|
try {
|
|
20749
|
-
if (!(0,
|
|
20750
|
-
if ((0,
|
|
20751
|
-
(0,
|
|
20752
|
-
(0,
|
|
20753
|
-
const kept = (0,
|
|
20734
|
+
if (!(0, import_node_fs21.existsSync)(d.eventsPath)) return;
|
|
20735
|
+
if ((0, import_node_fs21.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
|
|
20736
|
+
(0, import_node_fs21.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
|
|
20737
|
+
(0, import_node_fs21.renameSync)(d.eventsPath, (0, import_node_path19.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
|
|
20738
|
+
const kept = (0, import_node_fs21.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
|
|
20754
20739
|
for (const stale of kept.slice(0, Math.max(0, kept.length - ROTATE_KEEP))) {
|
|
20755
20740
|
try {
|
|
20756
|
-
(0,
|
|
20741
|
+
(0, import_node_fs21.renameSync)((0, import_node_path19.join)(d.rotatedDir, stale), (0, import_node_path19.join)(d.rotatedDir, `${stale}.pruned`));
|
|
20757
20742
|
} catch {
|
|
20758
20743
|
}
|
|
20759
20744
|
}
|
|
@@ -20763,8 +20748,8 @@ function rotateIfNeeded2(d) {
|
|
|
20763
20748
|
|
|
20764
20749
|
// src/lib/dossier/fold-dossier.ts
|
|
20765
20750
|
var import_node_crypto6 = require("node:crypto");
|
|
20766
|
-
var
|
|
20767
|
-
var
|
|
20751
|
+
var import_node_fs22 = require("node:fs");
|
|
20752
|
+
var import_node_path20 = require("node:path");
|
|
20768
20753
|
var EMPTY_CAPABILITIES = () => ({
|
|
20769
20754
|
human_reachable: { value: "unknown", tier: "unknown" },
|
|
20770
20755
|
authorship_observability: { value: "unknown", tier: "unknown" },
|
|
@@ -20815,12 +20800,12 @@ function foldDossier(d, opts = {}) {
|
|
|
20815
20800
|
}
|
|
20816
20801
|
};
|
|
20817
20802
|
try {
|
|
20818
|
-
if ((0,
|
|
20819
|
-
const files = (0,
|
|
20803
|
+
if ((0, import_node_fs22.existsSync)(d.rotatedDir)) {
|
|
20804
|
+
const files = (0, import_node_fs22.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
|
|
20820
20805
|
state.meta.rotations = files.length;
|
|
20821
20806
|
for (const f of files) {
|
|
20822
20807
|
try {
|
|
20823
|
-
ingest((0,
|
|
20808
|
+
ingest((0, import_node_fs22.readFileSync)((0, import_node_path20.join)(d.rotatedDir, f), "utf8"));
|
|
20824
20809
|
} catch {
|
|
20825
20810
|
state.meta.dropped_lines++;
|
|
20826
20811
|
}
|
|
@@ -20829,9 +20814,9 @@ function foldDossier(d, opts = {}) {
|
|
|
20829
20814
|
} catch {
|
|
20830
20815
|
}
|
|
20831
20816
|
try {
|
|
20832
|
-
if ((0,
|
|
20833
|
-
state.meta.upto_offset = (0,
|
|
20834
|
-
ingest((0,
|
|
20817
|
+
if ((0, import_node_fs22.existsSync)(d.eventsPath)) {
|
|
20818
|
+
state.meta.upto_offset = (0, import_node_fs22.statSync)(d.eventsPath).size;
|
|
20819
|
+
ingest((0, import_node_fs22.readFileSync)(d.eventsPath, "utf8"));
|
|
20835
20820
|
}
|
|
20836
20821
|
} catch {
|
|
20837
20822
|
}
|
|
@@ -21102,7 +21087,7 @@ function applyBounds(state, input) {
|
|
|
21102
21087
|
}
|
|
21103
21088
|
|
|
21104
21089
|
// src/lib/dossier/cache.ts
|
|
21105
|
-
var
|
|
21090
|
+
var import_node_fs23 = require("node:fs");
|
|
21106
21091
|
function compactState(s) {
|
|
21107
21092
|
const ms = (iso) => Date.parse(iso) || 0;
|
|
21108
21093
|
return {
|
|
@@ -21231,20 +21216,20 @@ function encodeState(s) {
|
|
|
21231
21216
|
function writeFoldCache(d, state) {
|
|
21232
21217
|
try {
|
|
21233
21218
|
const tmp = `${d.foldPath}.${process.pid}.tmp`;
|
|
21234
|
-
(0,
|
|
21235
|
-
(0,
|
|
21219
|
+
(0, import_node_fs23.writeFileSync)(tmp, encodeState(state), { mode: 384 });
|
|
21220
|
+
(0, import_node_fs23.renameSync)(tmp, d.foldPath);
|
|
21236
21221
|
} catch {
|
|
21237
21222
|
}
|
|
21238
21223
|
}
|
|
21239
21224
|
function readFoldCache(d) {
|
|
21240
21225
|
try {
|
|
21241
|
-
if (!(0,
|
|
21242
|
-
const raw = JSON.parse((0,
|
|
21226
|
+
if (!(0, import_node_fs23.existsSync)(d.foldPath)) return null;
|
|
21227
|
+
const raw = JSON.parse((0, import_node_fs23.readFileSync)(d.foldPath, "utf8"));
|
|
21243
21228
|
if (raw?.v !== 1) return null;
|
|
21244
21229
|
const cached2 = expandState(raw);
|
|
21245
21230
|
if (!cached2?.meta) return null;
|
|
21246
|
-
const size = (0,
|
|
21247
|
-
const rotations = (0,
|
|
21231
|
+
const size = (0, import_node_fs23.existsSync)(d.eventsPath) ? (0, import_node_fs23.statSync)(d.eventsPath).size : 0;
|
|
21232
|
+
const rotations = (0, import_node_fs23.existsSync)(d.rotatedDir) ? (0, import_node_fs23.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
|
|
21248
21233
|
if (cached2.meta.upto_offset !== size || cached2.meta.rotations !== rotations) return null;
|
|
21249
21234
|
return cached2;
|
|
21250
21235
|
} catch {
|
|
@@ -21295,13 +21280,13 @@ function assessContinuity(i2) {
|
|
|
21295
21280
|
|
|
21296
21281
|
// src/lib/dossier/reanchor.ts
|
|
21297
21282
|
var import_node_crypto7 = require("node:crypto");
|
|
21298
|
-
var
|
|
21283
|
+
var import_node_fs24 = require("node:fs");
|
|
21299
21284
|
function lineSha(text) {
|
|
21300
21285
|
return (0, import_node_crypto7.createHash)("sha256").update(text.trim()).digest("hex").slice(0, HASH_WIDTH);
|
|
21301
21286
|
}
|
|
21302
21287
|
function fileHash(path) {
|
|
21303
21288
|
try {
|
|
21304
|
-
return (0, import_node_crypto7.createHash)("sha256").update((0,
|
|
21289
|
+
return (0, import_node_crypto7.createHash)("sha256").update((0, import_node_fs24.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
|
|
21305
21290
|
} catch {
|
|
21306
21291
|
return null;
|
|
21307
21292
|
}
|
|
@@ -21673,20 +21658,20 @@ function foreignAuthoredPaths(identity, opts = {}) {
|
|
|
21673
21658
|
let sessions = 0;
|
|
21674
21659
|
try {
|
|
21675
21660
|
const dir = treeDir(identity);
|
|
21676
|
-
if (!(0,
|
|
21677
|
-
for (const entry of (0,
|
|
21661
|
+
if (!(0, import_node_fs25.existsSync)(dir)) return { paths: [], sessions: 0 };
|
|
21662
|
+
for (const entry of (0, import_node_fs25.readdirSync)(dir, { withFileTypes: true })) {
|
|
21678
21663
|
if (!entry.isDirectory()) continue;
|
|
21679
21664
|
if (entry.name === identity.sessionKey) continue;
|
|
21680
|
-
const log = (0,
|
|
21665
|
+
const log = (0, import_node_path21.join)(dir, entry.name, "events.jsonl");
|
|
21681
21666
|
try {
|
|
21682
|
-
if (!(0,
|
|
21683
|
-
if (now - (0,
|
|
21667
|
+
if (!(0, import_node_fs25.existsSync)(log)) continue;
|
|
21668
|
+
if (now - (0, import_node_fs25.statSync)(log).mtimeMs > windowMs) continue;
|
|
21684
21669
|
const sib = {
|
|
21685
|
-
dir: (0,
|
|
21670
|
+
dir: (0, import_node_path21.join)(dir, entry.name),
|
|
21686
21671
|
identity,
|
|
21687
21672
|
eventsPath: log,
|
|
21688
|
-
foldPath: (0,
|
|
21689
|
-
rotatedDir: (0,
|
|
21673
|
+
foldPath: (0, import_node_path21.join)(dir, entry.name, "fold.json"),
|
|
21674
|
+
rotatedDir: (0, import_node_path21.join)(dir, entry.name, "rotated")
|
|
21690
21675
|
};
|
|
21691
21676
|
const state = readFoldCache(sib) ?? foldDossier(sib);
|
|
21692
21677
|
sessions++;
|
|
@@ -21714,25 +21699,25 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
|
|
|
21714
21699
|
let removed = 0;
|
|
21715
21700
|
try {
|
|
21716
21701
|
const mine = dossierDir(identity);
|
|
21717
|
-
const userDir = (0,
|
|
21718
|
-
if (!(0,
|
|
21702
|
+
const userDir = (0, import_node_path21.dirname)((0, import_node_path21.dirname)(mine));
|
|
21703
|
+
if (!(0, import_node_fs25.existsSync)(userDir)) return 0;
|
|
21719
21704
|
const cutoff = Date.now() - maxAgeMs;
|
|
21720
|
-
for (const tree of (0,
|
|
21705
|
+
for (const tree of (0, import_node_fs25.readdirSync)(userDir, { withFileTypes: true })) {
|
|
21721
21706
|
if (!tree.isDirectory()) continue;
|
|
21722
|
-
const treePath = (0,
|
|
21707
|
+
const treePath = (0, import_node_path21.join)(userDir, tree.name);
|
|
21723
21708
|
let live = 0;
|
|
21724
|
-
for (const entry of (0,
|
|
21709
|
+
for (const entry of (0, import_node_fs25.readdirSync)(treePath, { withFileTypes: true })) {
|
|
21725
21710
|
if (!entry.isDirectory()) continue;
|
|
21726
|
-
const dir = (0,
|
|
21711
|
+
const dir = (0, import_node_path21.join)(treePath, entry.name);
|
|
21727
21712
|
if (dir === mine) {
|
|
21728
21713
|
live++;
|
|
21729
21714
|
continue;
|
|
21730
21715
|
}
|
|
21731
21716
|
try {
|
|
21732
|
-
const log = (0,
|
|
21733
|
-
const at = (0,
|
|
21717
|
+
const log = (0, import_node_path21.join)(dir, "events.jsonl");
|
|
21718
|
+
const at = (0, import_node_fs25.existsSync)(log) ? (0, import_node_fs25.statSync)(log).mtimeMs : (0, import_node_fs25.statSync)(dir).mtimeMs;
|
|
21734
21719
|
if (at < cutoff) {
|
|
21735
|
-
(0,
|
|
21720
|
+
(0, import_node_fs25.rmSync)(dir, { recursive: true, force: true });
|
|
21736
21721
|
removed++;
|
|
21737
21722
|
} else {
|
|
21738
21723
|
live++;
|
|
@@ -21742,7 +21727,7 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
|
|
|
21742
21727
|
}
|
|
21743
21728
|
if (live === 0) {
|
|
21744
21729
|
try {
|
|
21745
|
-
(0,
|
|
21730
|
+
(0, import_node_fs25.rmSync)(treePath, { recursive: false, force: false });
|
|
21746
21731
|
} catch {
|
|
21747
21732
|
}
|
|
21748
21733
|
}
|
|
@@ -21759,8 +21744,8 @@ function sessionDossier(token, sessionId) {
|
|
|
21759
21744
|
}
|
|
21760
21745
|
function hasActiveGoal(d) {
|
|
21761
21746
|
try {
|
|
21762
|
-
if (!(0,
|
|
21763
|
-
return (0,
|
|
21747
|
+
if (!(0, import_node_fs25.existsSync)(d.eventsPath)) return false;
|
|
21748
|
+
return (0, import_node_fs25.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
|
|
21764
21749
|
} catch {
|
|
21765
21750
|
return false;
|
|
21766
21751
|
}
|
|
@@ -21784,7 +21769,7 @@ function recordTurn(d, t) {
|
|
|
21784
21769
|
for (const a of t.authored) {
|
|
21785
21770
|
const origin = a.owner === "subagent" ? "subagent" : "edit_tool";
|
|
21786
21771
|
const prior = t.known?.authored?.get(a.p);
|
|
21787
|
-
const hash = fileHash((0,
|
|
21772
|
+
const hash = fileHash((0, import_node_path21.join)(root, a.p));
|
|
21788
21773
|
const hunks = Math.max(0, a.h - (prior?.hunks ?? 0));
|
|
21789
21774
|
const adds = Math.max(0, a.a - (prior?.adds ?? 0));
|
|
21790
21775
|
const dels = Math.max(0, a.d - (prior?.dels ?? 0));
|
|
@@ -21817,7 +21802,7 @@ function recordTurn(d, t) {
|
|
|
21817
21802
|
}
|
|
21818
21803
|
const seenDivergence = t.known?.divergence ?? /* @__PURE__ */ new Set();
|
|
21819
21804
|
for (const u of t.unobserved) {
|
|
21820
|
-
const hash = fileHash((0,
|
|
21805
|
+
const hash = fileHash((0, import_node_path21.join)(root, u.p));
|
|
21821
21806
|
if (seenDivergence.has(divergenceKey(u.p, hash))) continue;
|
|
21822
21807
|
appendEvent(d, { k: "divergence", kind: "external_mutation", path: u.p, hash });
|
|
21823
21808
|
}
|
|
@@ -21852,8 +21837,8 @@ function recordVerdict(d, v) {
|
|
|
21852
21837
|
if (!sent.has(f.file)) continue;
|
|
21853
21838
|
if (!lines.has(f.file)) {
|
|
21854
21839
|
try {
|
|
21855
|
-
const abs = (0,
|
|
21856
|
-
lines.set(f.file, (0,
|
|
21840
|
+
const abs = (0, import_node_path21.join)(root, f.file);
|
|
21841
|
+
lines.set(f.file, (0, import_node_fs25.existsSync)(abs) ? (0, import_node_fs25.readFileSync)(abs, "utf8").split("\n") : null);
|
|
21857
21842
|
} catch {
|
|
21858
21843
|
lines.set(f.file, null);
|
|
21859
21844
|
}
|
|
@@ -21953,8 +21938,8 @@ function recallMemory(d, identity, opts) {
|
|
|
21953
21938
|
budgetBytes: opts.budgetBytes,
|
|
21954
21939
|
readFileLines: (file) => {
|
|
21955
21940
|
try {
|
|
21956
|
-
const abs = (0,
|
|
21957
|
-
return (0,
|
|
21941
|
+
const abs = (0, import_node_path21.join)(root, file);
|
|
21942
|
+
return (0, import_node_fs25.existsSync)(abs) ? (0, import_node_fs25.readFileSync)(abs, "utf8").split("\n") : null;
|
|
21958
21943
|
} catch {
|
|
21959
21944
|
return null;
|
|
21960
21945
|
}
|
|
@@ -22122,21 +22107,21 @@ async function fireClassify(prompt, sessionId, globals) {
|
|
|
22122
22107
|
}
|
|
22123
22108
|
|
|
22124
22109
|
// src/commands/lifecycle.ts
|
|
22125
|
-
var import_node_fs29 = require("node:fs");
|
|
22126
|
-
var import_node_path26 = require("node:path");
|
|
22127
|
-
|
|
22128
|
-
// src/lib/baseline.ts
|
|
22129
22110
|
var import_node_fs28 = require("node:fs");
|
|
22130
22111
|
var import_node_path25 = require("node:path");
|
|
22131
|
-
var import_node_crypto10 = require("node:crypto");
|
|
22132
22112
|
|
|
22133
|
-
// src/lib/
|
|
22113
|
+
// src/lib/baseline.ts
|
|
22134
22114
|
var import_node_fs27 = require("node:fs");
|
|
22135
22115
|
var import_node_path24 = require("node:path");
|
|
22116
|
+
var import_node_crypto10 = require("node:crypto");
|
|
22117
|
+
|
|
22118
|
+
// src/lib/snapshot.ts
|
|
22119
|
+
var import_node_fs26 = require("node:fs");
|
|
22120
|
+
var import_node_path23 = require("node:path");
|
|
22136
22121
|
var import_node_child_process8 = require("node:child_process");
|
|
22137
22122
|
|
|
22138
22123
|
// src/lib/files.ts
|
|
22139
|
-
var
|
|
22124
|
+
var import_node_path22 = require("node:path");
|
|
22140
22125
|
var LANG_MAP = {
|
|
22141
22126
|
// Analyzable (static analysis + Gemini)
|
|
22142
22127
|
ts: "typescript",
|
|
@@ -22204,7 +22189,7 @@ var LANG_MAP = {
|
|
|
22204
22189
|
mk: "make"
|
|
22205
22190
|
};
|
|
22206
22191
|
function detectLanguage(filepath) {
|
|
22207
|
-
const ext = (0,
|
|
22192
|
+
const ext = (0, import_node_path22.extname)(filepath).slice(1);
|
|
22208
22193
|
return LANG_MAP[ext] ?? ext;
|
|
22209
22194
|
}
|
|
22210
22195
|
function sortByMtime(files) {
|
|
@@ -22295,16 +22280,16 @@ function collectCodeDelta(files, opts) {
|
|
|
22295
22280
|
|
|
22296
22281
|
// src/lib/snapshot.ts
|
|
22297
22282
|
function generateSnapshotDiffs(files) {
|
|
22298
|
-
if (!(0,
|
|
22283
|
+
if (!(0, import_node_fs26.existsSync)(SNAPSHOT_DIR)) {
|
|
22299
22284
|
return { diffs: [], has_snapshots: false };
|
|
22300
22285
|
}
|
|
22301
22286
|
const diffs = [];
|
|
22302
22287
|
for (const file of files) {
|
|
22303
22288
|
if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
|
|
22304
|
-
const snapshotPath = (0,
|
|
22289
|
+
const snapshotPath = (0, import_node_path23.join)(SNAPSHOT_DIR, file.path);
|
|
22305
22290
|
const language = file.language ?? detectLanguage(file.path);
|
|
22306
|
-
if ((0,
|
|
22307
|
-
const oldContent = (0,
|
|
22291
|
+
if ((0, import_node_fs26.existsSync)(snapshotPath)) {
|
|
22292
|
+
const oldContent = (0, import_node_fs26.readFileSync)(snapshotPath, "utf-8");
|
|
22308
22293
|
if (oldContent === file.content) continue;
|
|
22309
22294
|
const diff = computeDiff(oldContent, file.content, file.path);
|
|
22310
22295
|
if (diff) {
|
|
@@ -22329,20 +22314,20 @@ function saveSnapshots(files) {
|
|
|
22329
22314
|
const snapshotPaths = /* @__PURE__ */ new Set();
|
|
22330
22315
|
for (const file of files) {
|
|
22331
22316
|
if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
|
|
22332
|
-
const snapshotPath = (0,
|
|
22317
|
+
const snapshotPath = (0, import_node_path23.join)(SNAPSHOT_DIR, file.path);
|
|
22333
22318
|
snapshotPaths.add(snapshotPath);
|
|
22334
|
-
(0,
|
|
22335
|
-
(0,
|
|
22319
|
+
(0, import_node_fs26.mkdirSync)((0, import_node_path23.dirname)(snapshotPath), { recursive: true });
|
|
22320
|
+
(0, import_node_fs26.writeFileSync)(snapshotPath, file.content);
|
|
22336
22321
|
}
|
|
22337
22322
|
cleanStaleSnapshots(SNAPSHOT_DIR, snapshotPaths);
|
|
22338
22323
|
}
|
|
22339
22324
|
function computeDiff(oldContent, newContent, filePath) {
|
|
22340
|
-
const tmpOld = (0,
|
|
22341
|
-
const tmpNew = (0,
|
|
22325
|
+
const tmpOld = (0, import_node_path23.join)(SNAPSHOT_DIR, ".diff-old.tmp");
|
|
22326
|
+
const tmpNew = (0, import_node_path23.join)(SNAPSHOT_DIR, ".diff-new.tmp");
|
|
22342
22327
|
try {
|
|
22343
|
-
(0,
|
|
22344
|
-
(0,
|
|
22345
|
-
(0,
|
|
22328
|
+
(0, import_node_fs26.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
|
|
22329
|
+
(0, import_node_fs26.writeFileSync)(tmpOld, oldContent);
|
|
22330
|
+
(0, import_node_fs26.writeFileSync)(tmpNew, newContent);
|
|
22346
22331
|
const result = (0, import_node_child_process8.execSync)(
|
|
22347
22332
|
`git diff --no-index --unified=10 -- "${tmpOld}" "${tmpNew}"`,
|
|
22348
22333
|
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -22356,32 +22341,32 @@ function computeDiff(oldContent, newContent, filePath) {
|
|
|
22356
22341
|
return null;
|
|
22357
22342
|
} finally {
|
|
22358
22343
|
try {
|
|
22359
|
-
(0,
|
|
22344
|
+
(0, import_node_fs26.unlinkSync)(tmpOld);
|
|
22360
22345
|
} catch {
|
|
22361
22346
|
}
|
|
22362
22347
|
try {
|
|
22363
|
-
(0,
|
|
22348
|
+
(0, import_node_fs26.unlinkSync)(tmpNew);
|
|
22364
22349
|
} catch {
|
|
22365
22350
|
}
|
|
22366
22351
|
}
|
|
22367
22352
|
}
|
|
22368
22353
|
function cleanStaleSnapshots(dir, keepSet) {
|
|
22369
|
-
if (!(0,
|
|
22354
|
+
if (!(0, import_node_fs26.existsSync)(dir)) return;
|
|
22370
22355
|
try {
|
|
22371
|
-
const entries = (0,
|
|
22356
|
+
const entries = (0, import_node_fs26.readdirSync)(dir, { withFileTypes: true });
|
|
22372
22357
|
for (const entry of entries) {
|
|
22373
22358
|
if (dir === SNAPSHOT_DIR && (entry.name === ".diff-old.tmp" || entry.name === ".diff-new.tmp")) continue;
|
|
22374
|
-
const fullPath = (0,
|
|
22359
|
+
const fullPath = (0, import_node_path23.join)(dir, entry.name);
|
|
22375
22360
|
if (entry.isDirectory()) {
|
|
22376
22361
|
cleanStaleSnapshots(fullPath, keepSet);
|
|
22377
22362
|
try {
|
|
22378
|
-
const remaining = (0,
|
|
22379
|
-
if (remaining.length === 0) (0,
|
|
22363
|
+
const remaining = (0, import_node_fs26.readdirSync)(fullPath);
|
|
22364
|
+
if (remaining.length === 0) (0, import_node_fs26.rmdirSync)(fullPath);
|
|
22380
22365
|
} catch {
|
|
22381
22366
|
}
|
|
22382
22367
|
} else if (!keepSet.has(fullPath)) {
|
|
22383
22368
|
try {
|
|
22384
|
-
(0,
|
|
22369
|
+
(0, import_node_fs26.unlinkSync)(fullPath);
|
|
22385
22370
|
} catch {
|
|
22386
22371
|
}
|
|
22387
22372
|
}
|
|
@@ -22400,20 +22385,20 @@ function sessionKey(sessionId) {
|
|
|
22400
22385
|
return (0, import_node_crypto10.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
|
|
22401
22386
|
}
|
|
22402
22387
|
function sessionDir(key) {
|
|
22403
|
-
return (0,
|
|
22388
|
+
return (0, import_node_path24.join)(projectPath(BASELINE_DIR), key);
|
|
22404
22389
|
}
|
|
22405
22390
|
function manifestPath(dir) {
|
|
22406
|
-
return (0,
|
|
22391
|
+
return (0, import_node_path24.join)(dir, "manifest.json");
|
|
22407
22392
|
}
|
|
22408
22393
|
function mirrorPath(dir, repoRelPath) {
|
|
22409
|
-
return (0,
|
|
22394
|
+
return (0, import_node_path24.join)(dir, "files", repoRelPath);
|
|
22410
22395
|
}
|
|
22411
22396
|
var CARRY_FILE = `${BASELINE_DIR}/.carry`;
|
|
22412
22397
|
var CARRY_WINDOW_MS = 12e4;
|
|
22413
22398
|
function writeCarry(sessionId, headSha) {
|
|
22414
22399
|
try {
|
|
22415
|
-
(0,
|
|
22416
|
-
(0,
|
|
22400
|
+
(0, import_node_fs27.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
|
|
22401
|
+
(0, import_node_fs27.writeFileSync)(
|
|
22417
22402
|
projectPath(CARRY_FILE),
|
|
22418
22403
|
JSON.stringify({ from_key: sessionKey(sessionId), head_sha: headSha, ts: Date.now() })
|
|
22419
22404
|
);
|
|
@@ -22423,10 +22408,10 @@ function writeCarry(sessionId, headSha) {
|
|
|
22423
22408
|
function claimCarry(newKey) {
|
|
22424
22409
|
const carryPath = projectPath(CARRY_FILE);
|
|
22425
22410
|
try {
|
|
22426
|
-
if (!(0,
|
|
22427
|
-
const carry = JSON.parse((0,
|
|
22411
|
+
if (!(0, import_node_fs27.existsSync)(carryPath)) return null;
|
|
22412
|
+
const carry = JSON.parse((0, import_node_fs27.readFileSync)(carryPath, "utf-8"));
|
|
22428
22413
|
try {
|
|
22429
|
-
(0,
|
|
22414
|
+
(0, import_node_fs27.rmSync)(carryPath, { force: true });
|
|
22430
22415
|
} catch {
|
|
22431
22416
|
}
|
|
22432
22417
|
if (!carry?.from_key || typeof carry.ts !== "number") return null;
|
|
@@ -22437,11 +22422,11 @@ function claimCarry(newKey) {
|
|
|
22437
22422
|
if (!prior) return null;
|
|
22438
22423
|
const toDir = sessionDir(newKey);
|
|
22439
22424
|
try {
|
|
22440
|
-
(0,
|
|
22425
|
+
(0, import_node_fs27.rmSync)(toDir, { recursive: true, force: true });
|
|
22441
22426
|
} catch {
|
|
22442
22427
|
}
|
|
22443
|
-
(0,
|
|
22444
|
-
(0,
|
|
22428
|
+
(0, import_node_fs27.renameSync)(fromDir, toDir);
|
|
22429
|
+
(0, import_node_fs27.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
|
|
22445
22430
|
return readManifest(toDir);
|
|
22446
22431
|
} catch {
|
|
22447
22432
|
return null;
|
|
@@ -22465,21 +22450,21 @@ function captureBaseline(opts = {}) {
|
|
|
22465
22450
|
const head_sha = getCurrentCommit();
|
|
22466
22451
|
const dirty = getDirtyFiles();
|
|
22467
22452
|
try {
|
|
22468
|
-
(0,
|
|
22453
|
+
(0, import_node_fs27.rmSync)(dir, { recursive: true, force: true });
|
|
22469
22454
|
} catch {
|
|
22470
22455
|
}
|
|
22471
|
-
const filesDir = (0,
|
|
22456
|
+
const filesDir = (0, import_node_path24.join)(dir, "files");
|
|
22472
22457
|
const mirrored = [];
|
|
22473
22458
|
try {
|
|
22474
|
-
(0,
|
|
22459
|
+
(0, import_node_fs27.mkdirSync)(filesDir, { recursive: true });
|
|
22475
22460
|
for (const p of dirty) {
|
|
22476
22461
|
if (p.includes("..")) continue;
|
|
22477
22462
|
const content = safeReadForMirror(projectPath(p));
|
|
22478
22463
|
if (content === null) continue;
|
|
22479
22464
|
const dest = mirrorPath(dir, p);
|
|
22480
22465
|
try {
|
|
22481
|
-
(0,
|
|
22482
|
-
(0,
|
|
22466
|
+
(0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(dest), { recursive: true });
|
|
22467
|
+
(0, import_node_fs27.writeFileSync)(dest, content);
|
|
22483
22468
|
mirrored.push(p);
|
|
22484
22469
|
} catch {
|
|
22485
22470
|
}
|
|
@@ -22494,8 +22479,8 @@ function captureBaseline(opts = {}) {
|
|
|
22494
22479
|
version: BASELINE_VERSION
|
|
22495
22480
|
};
|
|
22496
22481
|
try {
|
|
22497
|
-
(0,
|
|
22498
|
-
(0,
|
|
22482
|
+
(0, import_node_fs27.mkdirSync)(dir, { recursive: true });
|
|
22483
|
+
(0, import_node_fs27.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
|
|
22499
22484
|
} catch {
|
|
22500
22485
|
}
|
|
22501
22486
|
pruneOldBaselines();
|
|
@@ -22506,9 +22491,9 @@ function readBaseline(sessionId) {
|
|
|
22506
22491
|
}
|
|
22507
22492
|
function readManifest(dir) {
|
|
22508
22493
|
const mp = manifestPath(dir);
|
|
22509
|
-
if (!(0,
|
|
22494
|
+
if (!(0, import_node_fs27.existsSync)(mp)) return null;
|
|
22510
22495
|
try {
|
|
22511
|
-
const parsed = JSON.parse((0,
|
|
22496
|
+
const parsed = JSON.parse((0, import_node_fs27.readFileSync)(mp, "utf-8"));
|
|
22512
22497
|
if (typeof parsed.head_sha !== "string" || typeof parsed.captured_at !== "number" || !Array.isArray(parsed.dirty_paths) || parsed.version !== BASELINE_VERSION) {
|
|
22513
22498
|
return null;
|
|
22514
22499
|
}
|
|
@@ -22539,9 +22524,9 @@ function preImage(repoRelPath, baseline) {
|
|
|
22539
22524
|
function resolvePreImage(repoRelPath, baseline) {
|
|
22540
22525
|
if (baseline.dirty_paths.includes(repoRelPath)) {
|
|
22541
22526
|
const mp = mirrorPath(sessionDir(sessionKey(baseline.session_id)), repoRelPath);
|
|
22542
|
-
if ((0,
|
|
22527
|
+
if ((0, import_node_fs27.existsSync)(mp)) {
|
|
22543
22528
|
try {
|
|
22544
|
-
return { content: (0,
|
|
22529
|
+
return { content: (0, import_node_fs27.readFileSync)(mp, "utf-8"), existed: true };
|
|
22545
22530
|
} catch {
|
|
22546
22531
|
}
|
|
22547
22532
|
}
|
|
@@ -22586,8 +22571,8 @@ function absorbIntoBaseline(paths, sessionId) {
|
|
|
22586
22571
|
const content = safeReadForMirror(projectPath(p));
|
|
22587
22572
|
if (content === null) continue;
|
|
22588
22573
|
const dest = mirrorPath(dir, p);
|
|
22589
|
-
(0,
|
|
22590
|
-
(0,
|
|
22574
|
+
(0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(dest), { recursive: true });
|
|
22575
|
+
(0, import_node_fs27.writeFileSync)(dest, content);
|
|
22591
22576
|
dirty.add(p);
|
|
22592
22577
|
adopted++;
|
|
22593
22578
|
} catch {
|
|
@@ -22596,7 +22581,7 @@ function absorbIntoBaseline(paths, sessionId) {
|
|
|
22596
22581
|
if (adopted === 0) return 0;
|
|
22597
22582
|
try {
|
|
22598
22583
|
const updated = { ...baseline, dirty_paths: [...dirty] };
|
|
22599
|
-
(0,
|
|
22584
|
+
(0, import_node_fs27.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
|
|
22600
22585
|
preImageCache.delete(baseline);
|
|
22601
22586
|
} catch {
|
|
22602
22587
|
return 0;
|
|
@@ -22607,7 +22592,7 @@ function changedSinceBaseline(repoRelPath, baseline) {
|
|
|
22607
22592
|
const pre = preImage(repoRelPath, baseline);
|
|
22608
22593
|
let current;
|
|
22609
22594
|
try {
|
|
22610
|
-
current = (0,
|
|
22595
|
+
current = (0, import_node_fs27.readFileSync)(projectPath(repoRelPath), "utf-8");
|
|
22611
22596
|
} catch {
|
|
22612
22597
|
return pre.existed;
|
|
22613
22598
|
}
|
|
@@ -22616,8 +22601,8 @@ function changedSinceBaseline(repoRelPath, baseline) {
|
|
|
22616
22601
|
}
|
|
22617
22602
|
function safeReadForMirror(absPath) {
|
|
22618
22603
|
try {
|
|
22619
|
-
if ((0,
|
|
22620
|
-
const buf = (0,
|
|
22604
|
+
if ((0, import_node_fs27.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
|
|
22605
|
+
const buf = (0, import_node_fs27.readFileSync)(absPath);
|
|
22621
22606
|
if (buf.includes(0)) return null;
|
|
22622
22607
|
return buf.toString("utf-8");
|
|
22623
22608
|
} catch {
|
|
@@ -22628,18 +22613,18 @@ function pruneOldBaselines() {
|
|
|
22628
22613
|
const root = projectPath(BASELINE_DIR);
|
|
22629
22614
|
let entries;
|
|
22630
22615
|
try {
|
|
22631
|
-
entries = (0,
|
|
22616
|
+
entries = (0, import_node_fs27.readdirSync)(root);
|
|
22632
22617
|
} catch {
|
|
22633
22618
|
return;
|
|
22634
22619
|
}
|
|
22635
22620
|
const now = Date.now();
|
|
22636
22621
|
for (const name2 of entries) {
|
|
22637
|
-
const dir = (0,
|
|
22622
|
+
const dir = (0, import_node_path24.join)(root, name2);
|
|
22638
22623
|
const manifest = readManifest(dir);
|
|
22639
22624
|
if (!manifest) {
|
|
22640
22625
|
try {
|
|
22641
|
-
if (now - (0,
|
|
22642
|
-
(0,
|
|
22626
|
+
if (now - (0, import_node_fs27.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
|
|
22627
|
+
(0, import_node_fs27.rmSync)(dir, { recursive: true, force: true });
|
|
22643
22628
|
}
|
|
22644
22629
|
} catch {
|
|
22645
22630
|
}
|
|
@@ -22647,7 +22632,7 @@ function pruneOldBaselines() {
|
|
|
22647
22632
|
}
|
|
22648
22633
|
if (now - manifest.captured_at <= BASELINE_TTL_MS) continue;
|
|
22649
22634
|
try {
|
|
22650
|
-
(0,
|
|
22635
|
+
(0, import_node_fs27.rmSync)(dir, { recursive: true, force: true });
|
|
22651
22636
|
} catch {
|
|
22652
22637
|
}
|
|
22653
22638
|
}
|
|
@@ -22822,8 +22807,8 @@ function buildCompactionContext(session) {
|
|
|
22822
22807
|
commitsSince: commitsSincePaths(watermark, (state.authored ?? []).map((a) => a.path)),
|
|
22823
22808
|
readFileLines: (file) => {
|
|
22824
22809
|
try {
|
|
22825
|
-
const abs = (0,
|
|
22826
|
-
return (0,
|
|
22810
|
+
const abs = (0, import_node_path25.join)(root, file);
|
|
22811
|
+
return (0, import_node_fs28.existsSync)(abs) ? (0, import_node_fs28.readFileSync)(abs, "utf8").split("\n") : null;
|
|
22827
22812
|
} catch {
|
|
22828
22813
|
return null;
|
|
22829
22814
|
}
|
|
@@ -22880,24 +22865,24 @@ async function readHookStdin() {
|
|
|
22880
22865
|
|
|
22881
22866
|
// src/commands/standard.ts
|
|
22882
22867
|
var import_promises13 = require("node:fs/promises");
|
|
22883
|
-
var
|
|
22868
|
+
var import_node_fs35 = require("node:fs");
|
|
22884
22869
|
var import_yaml3 = __toESM2(require_dist());
|
|
22885
22870
|
|
|
22886
22871
|
// src/lib/synthesize.ts
|
|
22887
22872
|
var import_node_child_process10 = require("node:child_process");
|
|
22888
|
-
var
|
|
22873
|
+
var import_node_fs31 = require("node:fs");
|
|
22889
22874
|
var import_promises10 = require("node:fs/promises");
|
|
22890
|
-
var
|
|
22875
|
+
var import_node_path28 = require("node:path");
|
|
22891
22876
|
var import_yaml = __toESM2(require_dist());
|
|
22892
22877
|
|
|
22893
22878
|
// src/lib/data-dir.ts
|
|
22894
|
-
var
|
|
22895
|
-
var
|
|
22879
|
+
var import_node_fs29 = require("node:fs");
|
|
22880
|
+
var import_node_path26 = require("node:path");
|
|
22896
22881
|
function resolveDataDir() {
|
|
22897
22882
|
const candidates2 = [
|
|
22898
|
-
(0,
|
|
22883
|
+
(0, import_node_path26.join)(__dirname, "..", "data"),
|
|
22899
22884
|
// installed: node_modules/@codacy/verity-cli/data
|
|
22900
|
-
(0,
|
|
22885
|
+
(0, import_node_path26.join)(__dirname, "..", "..", "data"),
|
|
22901
22886
|
// edge case: nested resolution
|
|
22902
22887
|
// THE COMMITTED SOURCE, for a source checkout that has not been built.
|
|
22903
22888
|
// cli/data/skills/ is a BUILD ARTIFACT (scripts/build.js copies client/skills
|
|
@@ -22906,14 +22891,14 @@ function resolveDataDir() {
|
|
|
22906
22891
|
// without this the synthesizer throws "Could not find Verity skill data"
|
|
22907
22892
|
// for every test and every `verity` run from source. Resolved from this
|
|
22908
22893
|
// module's own location, never the cwd: see the warning below.
|
|
22909
|
-
(0,
|
|
22894
|
+
(0, import_node_path26.join)(__dirname, "..", "..", "client"),
|
|
22910
22895
|
// bundled: cli/bin/ → ../../client
|
|
22911
|
-
(0,
|
|
22896
|
+
(0, import_node_path26.join)(__dirname, "..", "..", "..", "client"),
|
|
22912
22897
|
// tsx: cli/src/lib/ → ../../../client
|
|
22913
22898
|
...process.env.VERITY_DEV_DATA_DIR ? [process.env.VERITY_DEV_DATA_DIR] : []
|
|
22914
22899
|
];
|
|
22915
22900
|
for (const candidate of candidates2) {
|
|
22916
|
-
if ((0,
|
|
22901
|
+
if ((0, import_node_fs29.existsSync)((0, import_node_path26.join)(candidate, "skills"))) {
|
|
22917
22902
|
return candidate;
|
|
22918
22903
|
}
|
|
22919
22904
|
}
|
|
@@ -22922,13 +22907,13 @@ function resolveDataDir() {
|
|
|
22922
22907
|
);
|
|
22923
22908
|
}
|
|
22924
22909
|
function setupDataPath(file) {
|
|
22925
|
-
return (0,
|
|
22910
|
+
return (0, import_node_path26.join)(resolveDataDir(), "skills", "verity-setup", file);
|
|
22926
22911
|
}
|
|
22927
22912
|
|
|
22928
22913
|
// src/lib/detect.ts
|
|
22929
22914
|
var import_node_child_process9 = require("node:child_process");
|
|
22930
|
-
var
|
|
22931
|
-
var
|
|
22915
|
+
var import_node_fs30 = require("node:fs");
|
|
22916
|
+
var import_node_path27 = require("node:path");
|
|
22932
22917
|
var TOOLED_LANGUAGES = /* @__PURE__ */ new Set([
|
|
22933
22918
|
"typescript",
|
|
22934
22919
|
"javascript",
|
|
@@ -22985,25 +22970,25 @@ function walk(root) {
|
|
|
22985
22970
|
if (depth > WALK_MAX_DEPTH || found.length >= WALK_MAX_FILES) return;
|
|
22986
22971
|
let entries;
|
|
22987
22972
|
try {
|
|
22988
|
-
entries = (0,
|
|
22973
|
+
entries = (0, import_node_fs30.readdirSync)(dir, { withFileTypes: true });
|
|
22989
22974
|
} catch {
|
|
22990
22975
|
return;
|
|
22991
22976
|
}
|
|
22992
22977
|
for (const entry of entries) {
|
|
22993
22978
|
if (found.length >= WALK_MAX_FILES) return;
|
|
22994
22979
|
if (IGNORED_SEGMENTS.includes(entry.name)) continue;
|
|
22995
|
-
const full = (0,
|
|
22980
|
+
const full = (0, import_node_path27.join)(dir, entry.name);
|
|
22996
22981
|
if (entry.isDirectory()) visit(full, depth + 1);
|
|
22997
|
-
else if (entry.isFile()) found.push((0,
|
|
22982
|
+
else if (entry.isFile()) found.push((0, import_node_path27.relative)(root, full));
|
|
22998
22983
|
}
|
|
22999
22984
|
};
|
|
23000
22985
|
visit(root, 0);
|
|
23001
22986
|
return found;
|
|
23002
22987
|
}
|
|
23003
22988
|
function languageOf(path) {
|
|
23004
|
-
const name2 = (0,
|
|
22989
|
+
const name2 = (0, import_node_path27.basename)(path);
|
|
23005
22990
|
if (/^Dockerfile(\..+)?$/i.test(name2)) return "dockerfile";
|
|
23006
|
-
if (!(0,
|
|
22991
|
+
if (!(0, import_node_path27.extname)(name2)) return null;
|
|
23007
22992
|
const lang = detectLanguage(path);
|
|
23008
22993
|
return lang || null;
|
|
23009
22994
|
}
|
|
@@ -23060,7 +23045,7 @@ var TOOL_CONFIG_MARKERS = [
|
|
|
23060
23045
|
];
|
|
23061
23046
|
function readJson2(path) {
|
|
23062
23047
|
try {
|
|
23063
|
-
return JSON.parse((0,
|
|
23048
|
+
return JSON.parse((0, import_node_fs30.readFileSync)(path, "utf-8"));
|
|
23064
23049
|
} catch {
|
|
23065
23050
|
return null;
|
|
23066
23051
|
}
|
|
@@ -23085,17 +23070,17 @@ function declaredDependencies(root, files) {
|
|
|
23085
23070
|
if (deps && typeof deps === "object") names2.push(...Object.keys(deps));
|
|
23086
23071
|
}
|
|
23087
23072
|
};
|
|
23088
|
-
readPackageJson((0,
|
|
23089
|
-
const nested = files.filter((f) => f.includes("/") && (0,
|
|
23090
|
-
for (const rel of nested) readPackageJson((0,
|
|
23073
|
+
readPackageJson((0, import_node_path27.join)(root, "package.json"));
|
|
23074
|
+
const nested = files.filter((f) => f.includes("/") && (0, import_node_path27.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
|
|
23075
|
+
for (const rel of nested) readPackageJson((0, import_node_path27.join)(root, rel));
|
|
23091
23076
|
const pythonManifests = [
|
|
23092
|
-
...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0,
|
|
23093
|
-
...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0,
|
|
23077
|
+
...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path27.join)(root, f)),
|
|
23078
|
+
...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path27.join)(root, f))
|
|
23094
23079
|
];
|
|
23095
23080
|
for (const path of pythonManifests) {
|
|
23096
|
-
if (!(0,
|
|
23081
|
+
if (!(0, import_node_fs30.existsSync)(path)) continue;
|
|
23097
23082
|
try {
|
|
23098
|
-
const text = (0,
|
|
23083
|
+
const text = (0, import_node_fs30.readFileSync)(path, "utf-8");
|
|
23099
23084
|
for (const m of text.matchAll(/^\s*["']?([A-Za-z][A-Za-z0-9._-]+)/gm)) names2.push(m[1]);
|
|
23100
23085
|
for (const line2 of text.split("\n")) {
|
|
23101
23086
|
if (!/dependencies\s*=/.test(line2)) continue;
|
|
@@ -23105,13 +23090,13 @@ function declaredDependencies(root, files) {
|
|
|
23105
23090
|
}
|
|
23106
23091
|
}
|
|
23107
23092
|
const goMods = [
|
|
23108
|
-
(0,
|
|
23109
|
-
...files.filter((f) => f.includes("/") && (0,
|
|
23093
|
+
(0, import_node_path27.join)(root, "go.mod"),
|
|
23094
|
+
...files.filter((f) => f.includes("/") && (0, import_node_path27.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path27.join)(root, f))
|
|
23110
23095
|
];
|
|
23111
23096
|
for (const path of goMods) {
|
|
23112
|
-
if (!(0,
|
|
23097
|
+
if (!(0, import_node_fs30.existsSync)(path)) continue;
|
|
23113
23098
|
try {
|
|
23114
|
-
const text = (0,
|
|
23099
|
+
const text = (0, import_node_fs30.readFileSync)(path, "utf-8");
|
|
23115
23100
|
for (const m of text.matchAll(/^\s+([\w.-]+\/[\w./-]+)\s+v/gm)) {
|
|
23116
23101
|
names2.push(m[1].replace(/^github\.com\//, ""));
|
|
23117
23102
|
}
|
|
@@ -23119,10 +23104,10 @@ function declaredDependencies(root, files) {
|
|
|
23119
23104
|
}
|
|
23120
23105
|
}
|
|
23121
23106
|
for (const file of ["pom.xml", "build.gradle", "build.gradle.kts", "Gemfile", "Cargo.toml"]) {
|
|
23122
|
-
const path = (0,
|
|
23123
|
-
if (!(0,
|
|
23107
|
+
const path = (0, import_node_path27.join)(root, file);
|
|
23108
|
+
if (!(0, import_node_fs30.existsSync)(path)) continue;
|
|
23124
23109
|
try {
|
|
23125
|
-
const text = (0,
|
|
23110
|
+
const text = (0, import_node_fs30.readFileSync)(path, "utf-8");
|
|
23126
23111
|
for (const m of text.matchAll(/["'<]([A-Za-z][A-Za-z0-9._-]{2,})["'>]/g)) names2.push(m[1]);
|
|
23127
23112
|
} catch {
|
|
23128
23113
|
}
|
|
@@ -23130,7 +23115,7 @@ function declaredDependencies(root, files) {
|
|
|
23130
23115
|
return names2;
|
|
23131
23116
|
}
|
|
23132
23117
|
function detectBuildSystem(root, files) {
|
|
23133
|
-
const has = (f) => (0,
|
|
23118
|
+
const has = (f) => (0, import_node_fs30.existsSync)((0, import_node_path27.join)(root, f)) || files.some((p) => (0, import_node_path27.basename)(p) === f);
|
|
23134
23119
|
if (has("pnpm-lock.yaml")) return "pnpm";
|
|
23135
23120
|
if (has("yarn.lock")) return "yarn";
|
|
23136
23121
|
if (has("bun.lock") || has("bun.lockb")) return "bun";
|
|
@@ -23147,8 +23132,8 @@ function detectBuildSystem(root, files) {
|
|
|
23147
23132
|
}
|
|
23148
23133
|
function detectArchitecture(root, files) {
|
|
23149
23134
|
const workspaceMarkers = ["lerna.json", "pnpm-workspace.yaml", "nx.json", "turbo.json", "rush.json"];
|
|
23150
|
-
if (workspaceMarkers.some((m) => (0,
|
|
23151
|
-
const pkg = readJson2((0,
|
|
23135
|
+
if (workspaceMarkers.some((m) => (0, import_node_fs30.existsSync)((0, import_node_path27.join)(root, m)))) return "monorepo";
|
|
23136
|
+
const pkg = readJson2((0, import_node_path27.join)(root, "package.json"));
|
|
23152
23137
|
if (pkg && "workspaces" in pkg) return "monorepo";
|
|
23153
23138
|
const manifests = files.filter((f) => /(^|\/)(package\.json|go\.mod|pyproject\.toml|Cargo\.toml|pom\.xml)$/.test(f));
|
|
23154
23139
|
const nested = manifests.filter((f) => f.includes("/"));
|
|
@@ -23170,10 +23155,10 @@ function measureAvgFileLength(root, files, languages) {
|
|
|
23170
23155
|
let total = 0;
|
|
23171
23156
|
let counted = 0;
|
|
23172
23157
|
for (let i2 = 0; i2 < candidates2.length; i2 += stride) {
|
|
23173
|
-
const path = (0,
|
|
23158
|
+
const path = (0, import_node_path27.join)(root, candidates2[i2]);
|
|
23174
23159
|
try {
|
|
23175
|
-
if ((0,
|
|
23176
|
-
total += (0,
|
|
23160
|
+
if ((0, import_node_fs30.statSync)(path).size > 2 * 1024 * 1024) continue;
|
|
23161
|
+
total += (0, import_node_fs30.readFileSync)(path, "utf-8").split("\n").length;
|
|
23177
23162
|
counted++;
|
|
23178
23163
|
} catch {
|
|
23179
23164
|
}
|
|
@@ -23203,14 +23188,14 @@ function detectProject(root = repoRoot()) {
|
|
|
23203
23188
|
const existingToolConfigs = [];
|
|
23204
23189
|
for (const [tool, markers] of TOOL_CONFIG_MARKERS) {
|
|
23205
23190
|
for (const marker of markers) {
|
|
23206
|
-
if ((0,
|
|
23191
|
+
if ((0, import_node_fs30.existsSync)((0, import_node_path27.join)(root, marker))) {
|
|
23207
23192
|
existingToolConfigs.push({ tool, path: `./${marker}` });
|
|
23208
23193
|
break;
|
|
23209
23194
|
}
|
|
23210
23195
|
}
|
|
23211
23196
|
}
|
|
23212
23197
|
return {
|
|
23213
|
-
projectName: (0,
|
|
23198
|
+
projectName: (0, import_node_path27.basename)(root),
|
|
23214
23199
|
languages,
|
|
23215
23200
|
languageCounts,
|
|
23216
23201
|
frameworks: matchAll(dependencies, FRAMEWORK_BY_DEPENDENCY),
|
|
@@ -23308,8 +23293,8 @@ ${closingNote(input.origin)}
|
|
|
23308
23293
|
|
|
23309
23294
|
// src/lib/synthesize.ts
|
|
23310
23295
|
function loadCatalog() {
|
|
23311
|
-
const catalog = (0, import_yaml.parse)((0,
|
|
23312
|
-
const template = (0, import_yaml.parse)((0,
|
|
23296
|
+
const catalog = (0, import_yaml.parse)((0, import_node_fs31.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
|
|
23297
|
+
const template = (0, import_yaml.parse)((0, import_node_fs31.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
|
|
23313
23298
|
return { catalog, template };
|
|
23314
23299
|
}
|
|
23315
23300
|
function selectTools(languages, intensity, catalog) {
|
|
@@ -23587,7 +23572,7 @@ function validatePatternIds() {
|
|
|
23587
23572
|
}
|
|
23588
23573
|
async function runSynthesis(opts) {
|
|
23589
23574
|
const standardPath = projectPath(STANDARD_FILE);
|
|
23590
|
-
if ((0,
|
|
23575
|
+
if ((0, import_node_fs31.existsSync)(standardPath) && !opts.force) {
|
|
23591
23576
|
return { refused: `${STANDARD_FILE} already exists \u2014 pass --force to replace it.` };
|
|
23592
23577
|
}
|
|
23593
23578
|
const detected = opts.detected ?? detectProject();
|
|
@@ -23656,7 +23641,7 @@ async function correctVerityMdVersion(opts) {
|
|
|
23656
23641
|
}
|
|
23657
23642
|
async function writeFileTo(relative6, body2) {
|
|
23658
23643
|
const target = projectPath(relative6);
|
|
23659
|
-
await (0, import_promises10.mkdir)((0,
|
|
23644
|
+
await (0, import_promises10.mkdir)((0, import_node_path28.dirname)(target), { recursive: true });
|
|
23660
23645
|
await (0, import_promises10.writeFile)(target, body2);
|
|
23661
23646
|
}
|
|
23662
23647
|
async function deriveConfigForStandard(standard) {
|
|
@@ -23715,11 +23700,11 @@ ${validation.detail}`);
|
|
|
23715
23700
|
|
|
23716
23701
|
// src/lib/setup-state.ts
|
|
23717
23702
|
var import_promises11 = require("node:fs/promises");
|
|
23718
|
-
var
|
|
23703
|
+
var import_node_fs32 = require("node:fs");
|
|
23719
23704
|
var SETUP_STATE_FILE = `${VERITY_DIR}/setup.json`;
|
|
23720
23705
|
async function readSetupState() {
|
|
23721
23706
|
const path = projectPath(SETUP_STATE_FILE);
|
|
23722
|
-
if (!(0,
|
|
23707
|
+
if (!(0, import_node_fs32.existsSync)(path)) return null;
|
|
23723
23708
|
try {
|
|
23724
23709
|
const parsed = JSON.parse(await (0, import_promises11.readFile)(path, "utf-8"));
|
|
23725
23710
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
@@ -23735,12 +23720,12 @@ async function writeSetupState(patch) {
|
|
|
23735
23720
|
}
|
|
23736
23721
|
|
|
23737
23722
|
// src/lib/push-setup.ts
|
|
23738
|
-
var
|
|
23723
|
+
var import_node_fs34 = require("node:fs");
|
|
23739
23724
|
var import_promises12 = require("node:fs/promises");
|
|
23740
23725
|
var import_yaml2 = __toESM2(require_dist());
|
|
23741
23726
|
|
|
23742
23727
|
// src/lib/verityignore.ts
|
|
23743
|
-
var
|
|
23728
|
+
var import_node_fs33 = require("node:fs");
|
|
23744
23729
|
var EMPTY = { rules: [], securityOverlap: [], problems: [] };
|
|
23745
23730
|
var SECURITY_PROBES = [
|
|
23746
23731
|
".env",
|
|
@@ -23833,9 +23818,9 @@ function isIgnored3(ig, path) {
|
|
|
23833
23818
|
}
|
|
23834
23819
|
function loadVerityIgnore() {
|
|
23835
23820
|
const file = projectPath(VERITYIGNORE_FILE);
|
|
23836
|
-
if (!(0,
|
|
23821
|
+
if (!(0, import_node_fs33.existsSync)(file)) return EMPTY;
|
|
23837
23822
|
try {
|
|
23838
|
-
return parseVerityIgnore((0,
|
|
23823
|
+
return parseVerityIgnore((0, import_node_fs33.readFileSync)(file, "utf-8"));
|
|
23839
23824
|
} catch {
|
|
23840
23825
|
return EMPTY;
|
|
23841
23826
|
}
|
|
@@ -23873,9 +23858,9 @@ function buildStandardUpload(standard, ignoreRaw) {
|
|
|
23873
23858
|
}
|
|
23874
23859
|
function readVerityIgnoreRaw() {
|
|
23875
23860
|
const file = projectPath(VERITYIGNORE_FILE);
|
|
23876
|
-
if (!(0,
|
|
23861
|
+
if (!(0, import_node_fs33.existsSync)(file)) return null;
|
|
23877
23862
|
try {
|
|
23878
|
-
return (0,
|
|
23863
|
+
return (0, import_node_fs33.readFileSync)(file, "utf-8");
|
|
23879
23864
|
} catch {
|
|
23880
23865
|
return null;
|
|
23881
23866
|
}
|
|
@@ -23903,7 +23888,7 @@ async function pushStandardAndConfig(globals, what = {}) {
|
|
|
23903
23888
|
}
|
|
23904
23889
|
let standardVersion = null;
|
|
23905
23890
|
const standardPath = projectPath(STANDARD_FILE);
|
|
23906
|
-
if (pushStandard && (0,
|
|
23891
|
+
if (pushStandard && (0, import_node_fs34.existsSync)(standardPath)) {
|
|
23907
23892
|
try {
|
|
23908
23893
|
const content = (0, import_yaml2.parse)(await (0, import_promises12.readFile)(standardPath, "utf-8"));
|
|
23909
23894
|
const upload = buildStandardUpload(content, readVerityIgnoreRaw());
|
|
@@ -23928,7 +23913,7 @@ async function pushStandardAndConfig(globals, what = {}) {
|
|
|
23928
23913
|
}
|
|
23929
23914
|
let configPushed = false;
|
|
23930
23915
|
const configPath = projectPath(CODACY_CONFIG_FILE);
|
|
23931
|
-
if (pushConfig && (0,
|
|
23916
|
+
if (pushConfig && (0, import_node_fs34.existsSync)(configPath)) {
|
|
23932
23917
|
try {
|
|
23933
23918
|
const content = JSON.parse(await (0, import_promises12.readFile)(configPath, "utf-8"));
|
|
23934
23919
|
const result = await apiRequest({
|
|
@@ -23960,7 +23945,7 @@ function registerStandardCommands(program2) {
|
|
|
23960
23945
|
const state = await readSetupState();
|
|
23961
23946
|
if (opts.configOnly) {
|
|
23962
23947
|
const standardPath = projectPath(STANDARD_FILE);
|
|
23963
|
-
if (!(0,
|
|
23948
|
+
if (!(0, import_node_fs35.existsSync)(standardPath)) {
|
|
23964
23949
|
printError(`No ${STANDARD_FILE} here \u2014 run "verity standard synthesize" to create one.`);
|
|
23965
23950
|
process.exit(1);
|
|
23966
23951
|
}
|
|
@@ -24152,7 +24137,7 @@ function registerConfigCommands(program2) {
|
|
|
24152
24137
|
config.command("formal [state]").description('Get or set formal verification at push: "push" or "off" (needs Lean \u2014 verity lean status)').action((state) => {
|
|
24153
24138
|
if (state === void 0) {
|
|
24154
24139
|
const cfg = readProjectConfig();
|
|
24155
|
-
process.stdout.write((cfg.formal
|
|
24140
|
+
process.stdout.write((cfg.formal ?? "off") + "\n");
|
|
24156
24141
|
if (cfg.formal_refused) printWarn(formalRefusalMessage(cfg.formal_refused));
|
|
24157
24142
|
return;
|
|
24158
24143
|
}
|
|
@@ -24160,10 +24145,10 @@ function registerConfigCommands(program2) {
|
|
|
24160
24145
|
printError(`Unrecognised state: ${state}. Use "push" or "off".`);
|
|
24161
24146
|
process.exit(1);
|
|
24162
24147
|
}
|
|
24163
|
-
writeProjectConfig({ formal: state === "push" ? "push" :
|
|
24164
|
-
const
|
|
24165
|
-
if (
|
|
24166
|
-
printWarn(`Formal verification at push: still off \u2014 ${formalRefusalMessage(
|
|
24148
|
+
writeProjectConfig({ formal: state === "push" ? "push" : void 0 });
|
|
24149
|
+
const refused = state === "push" ? readProjectConfig().formal_refused : void 0;
|
|
24150
|
+
if (refused) {
|
|
24151
|
+
printWarn(`Formal verification at push: still off \u2014 ${formalRefusalMessage(refused)}`);
|
|
24167
24152
|
return;
|
|
24168
24153
|
}
|
|
24169
24154
|
printInfo(state === "push" ? "Formal verification at push: on for this checkout (Lean must be installed \u2014 verity lean status)" : "Formal verification at push: off");
|
|
@@ -24313,10 +24298,10 @@ function formatRunDetail(run4) {
|
|
|
24313
24298
|
}
|
|
24314
24299
|
|
|
24315
24300
|
// src/lib/ignore-declaration.ts
|
|
24316
|
-
var
|
|
24301
|
+
var import_node_fs37 = require("node:fs");
|
|
24317
24302
|
|
|
24318
24303
|
// src/lib/debounce.ts
|
|
24319
|
-
var
|
|
24304
|
+
var import_node_fs36 = require("node:fs");
|
|
24320
24305
|
var import_node_crypto11 = require("node:crypto");
|
|
24321
24306
|
function scopedFile(base, sessionId) {
|
|
24322
24307
|
if (!sessionId) return base;
|
|
@@ -24324,9 +24309,9 @@ function scopedFile(base, sessionId) {
|
|
|
24324
24309
|
}
|
|
24325
24310
|
function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
|
|
24326
24311
|
const file = scopedFile(DEBOUNCE_FILE, sessionId);
|
|
24327
|
-
if (!(0,
|
|
24312
|
+
if (!(0, import_node_fs36.existsSync)(file)) return null;
|
|
24328
24313
|
try {
|
|
24329
|
-
const lastTs = parseInt((0,
|
|
24314
|
+
const lastTs = parseInt((0, import_node_fs36.readFileSync)(file, "utf-8").trim(), 10);
|
|
24330
24315
|
const nowTs = Math.floor(Date.now() / 1e3);
|
|
24331
24316
|
const elapsed = nowTs - lastTs;
|
|
24332
24317
|
if (elapsed < debounceSeconds) {
|
|
@@ -24339,10 +24324,10 @@ function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
|
|
|
24339
24324
|
function checkMtime(files, bypassForRecentCommits, sessionId) {
|
|
24340
24325
|
if (bypassForRecentCommits) return null;
|
|
24341
24326
|
const file = scopedFile(DEBOUNCE_FILE, sessionId);
|
|
24342
|
-
if (!(0,
|
|
24327
|
+
if (!(0, import_node_fs36.existsSync)(file)) return null;
|
|
24343
24328
|
let debounceTime;
|
|
24344
24329
|
try {
|
|
24345
|
-
debounceTime = (0,
|
|
24330
|
+
debounceTime = (0, import_node_fs36.statSync)(file).mtimeMs;
|
|
24346
24331
|
} catch {
|
|
24347
24332
|
return null;
|
|
24348
24333
|
}
|
|
@@ -24350,7 +24335,7 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
|
|
|
24350
24335
|
const resolved = resolveFile(f);
|
|
24351
24336
|
if (!resolved) continue;
|
|
24352
24337
|
try {
|
|
24353
|
-
const stat3 = (0,
|
|
24338
|
+
const stat3 = (0, import_node_fs36.statSync)(resolved);
|
|
24354
24339
|
if (stat3.mtimeMs > debounceTime) {
|
|
24355
24340
|
return null;
|
|
24356
24341
|
}
|
|
@@ -24366,8 +24351,8 @@ function computeContentHash(files) {
|
|
|
24366
24351
|
for (const f of sorted) {
|
|
24367
24352
|
const resolved = resolveFile(f) ?? f;
|
|
24368
24353
|
try {
|
|
24369
|
-
if ((0,
|
|
24370
|
-
hash.update((0,
|
|
24354
|
+
if ((0, import_node_fs36.existsSync)(resolved)) {
|
|
24355
|
+
hash.update((0, import_node_fs36.readFileSync)(resolved));
|
|
24371
24356
|
}
|
|
24372
24357
|
} catch {
|
|
24373
24358
|
}
|
|
@@ -24377,9 +24362,9 @@ function computeContentHash(files) {
|
|
|
24377
24362
|
function checkContentHash(files, sessionId) {
|
|
24378
24363
|
const hash = computeContentHash(files);
|
|
24379
24364
|
const file = scopedFile(HASH_FILE, sessionId);
|
|
24380
|
-
if ((0,
|
|
24365
|
+
if ((0, import_node_fs36.existsSync)(file)) {
|
|
24381
24366
|
try {
|
|
24382
|
-
const storedHash = (0,
|
|
24367
|
+
const storedHash = (0, import_node_fs36.readFileSync)(file, "utf-8").trim();
|
|
24383
24368
|
if (hash === storedHash) {
|
|
24384
24369
|
return { skip: "No source changes since last analysis", hash };
|
|
24385
24370
|
}
|
|
@@ -24389,24 +24374,24 @@ function checkContentHash(files, sessionId) {
|
|
|
24389
24374
|
return { skip: null, hash };
|
|
24390
24375
|
}
|
|
24391
24376
|
function recordAnalysisStart(sessionId) {
|
|
24392
|
-
(0,
|
|
24393
|
-
(0,
|
|
24377
|
+
(0, import_node_fs36.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
24378
|
+
(0, import_node_fs36.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
|
|
24394
24379
|
}
|
|
24395
24380
|
function recordPassHash(hash, sessionId) {
|
|
24396
|
-
(0,
|
|
24381
|
+
(0, import_node_fs36.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
|
|
24397
24382
|
}
|
|
24398
24383
|
function narrowToRecent(files, sessionId) {
|
|
24399
24384
|
const file = scopedFile(DEBOUNCE_FILE, sessionId);
|
|
24400
|
-
if (!(0,
|
|
24385
|
+
if (!(0, import_node_fs36.existsSync)(file)) return files;
|
|
24401
24386
|
let debounceTime;
|
|
24402
24387
|
try {
|
|
24403
|
-
debounceTime = (0,
|
|
24388
|
+
debounceTime = (0, import_node_fs36.statSync)(file).mtimeMs;
|
|
24404
24389
|
} catch {
|
|
24405
24390
|
return files;
|
|
24406
24391
|
}
|
|
24407
24392
|
const recent = files.filter((f) => {
|
|
24408
24393
|
try {
|
|
24409
|
-
return (0,
|
|
24394
|
+
return (0, import_node_fs36.existsSync)(f) && (0, import_node_fs36.statSync)(f).mtimeMs > debounceTime;
|
|
24410
24395
|
} catch {
|
|
24411
24396
|
return false;
|
|
24412
24397
|
}
|
|
@@ -24419,9 +24404,9 @@ function readIteration(currentCommit, _contentHash) {
|
|
|
24419
24404
|
var NO_BLOCKS = { attempts: 0, blocks: 0, fingerprint: null };
|
|
24420
24405
|
function readBlockState(currentCommit, opts) {
|
|
24421
24406
|
if (opts?.newUserPrompt) return NO_BLOCKS;
|
|
24422
|
-
if (!(0,
|
|
24407
|
+
if (!(0, import_node_fs36.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
|
|
24423
24408
|
try {
|
|
24424
|
-
const stored = (0,
|
|
24409
|
+
const stored = (0, import_node_fs36.readFileSync)(ITERATION_FILE, "utf-8").trim();
|
|
24425
24410
|
const parsed = stored.startsWith("{") ? parseJsonState(stored) : parseLegacyState(stored);
|
|
24426
24411
|
if (!parsed) return NO_BLOCKS;
|
|
24427
24412
|
if (parsed.commit !== currentCommit) return NO_BLOCKS;
|
|
@@ -24467,8 +24452,8 @@ function isSameProblem(previous, current) {
|
|
|
24467
24452
|
return current.split(",").some((k) => prev.has(k));
|
|
24468
24453
|
}
|
|
24469
24454
|
function writeBlockState(commit, state) {
|
|
24470
|
-
(0,
|
|
24471
|
-
(0,
|
|
24455
|
+
(0, import_node_fs36.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
24456
|
+
(0, import_node_fs36.writeFileSync)(
|
|
24472
24457
|
ITERATION_FILE,
|
|
24473
24458
|
JSON.stringify({
|
|
24474
24459
|
v: 2,
|
|
@@ -24573,9 +24558,9 @@ function resolveIgnoreState(keys) {
|
|
|
24573
24558
|
}
|
|
24574
24559
|
function readIgnoreState(sessionId) {
|
|
24575
24560
|
const file = stateFile(sessionId);
|
|
24576
|
-
if (!(0,
|
|
24561
|
+
if (!(0, import_node_fs37.existsSync)(file)) return null;
|
|
24577
24562
|
try {
|
|
24578
|
-
const o = JSON.parse((0,
|
|
24563
|
+
const o = JSON.parse((0, import_node_fs37.readFileSync)(file, "utf-8")) ?? {};
|
|
24579
24564
|
const spent = typeof o.spent === "number" ? o.spent : 0;
|
|
24580
24565
|
const raw = o.active;
|
|
24581
24566
|
let active = null;
|
|
@@ -24599,8 +24584,8 @@ function readIgnoreState(sessionId) {
|
|
|
24599
24584
|
}
|
|
24600
24585
|
function writeIgnoreState(state, sessionId) {
|
|
24601
24586
|
try {
|
|
24602
|
-
(0,
|
|
24603
|
-
(0,
|
|
24587
|
+
(0, import_node_fs37.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
|
|
24588
|
+
(0, import_node_fs37.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
|
|
24604
24589
|
} catch {
|
|
24605
24590
|
}
|
|
24606
24591
|
}
|
|
@@ -24983,7 +24968,7 @@ function createRun(opts, globals) {
|
|
|
24983
24968
|
}
|
|
24984
24969
|
|
|
24985
24970
|
// src/commands/analyze/index.ts
|
|
24986
|
-
var
|
|
24971
|
+
var import_node_fs51 = require("node:fs");
|
|
24987
24972
|
|
|
24988
24973
|
// src/lib/repo-context.ts
|
|
24989
24974
|
var import_node_child_process11 = require("node:child_process");
|
|
@@ -25947,10 +25932,10 @@ function installRunEvidence(run4) {
|
|
|
25947
25932
|
}
|
|
25948
25933
|
|
|
25949
25934
|
// src/lib/git-frame.ts
|
|
25950
|
-
var
|
|
25935
|
+
var import_node_fs38 = require("node:fs");
|
|
25951
25936
|
var import_node_os6 = require("node:os");
|
|
25937
|
+
var import_node_path29 = require("node:path");
|
|
25952
25938
|
var import_node_path30 = require("node:path");
|
|
25953
|
-
var import_node_path31 = require("node:path");
|
|
25954
25939
|
var VALUE_TOKEN = `(?:'[^']*'|"[^"]*"|\\S+)`;
|
|
25955
25940
|
var GIT_GLOBAL_OPTS = `(?:\\s+(?:-[Cc]\\s+${VALUE_TOKEN}|--?[\\w-]+(?:=\\S+)?))*`;
|
|
25956
25941
|
var COMMIT_HEAD = `git${GIT_GLOBAL_OPTS}\\s+commit(?![\\w-])`;
|
|
@@ -26037,8 +26022,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
|
|
|
26037
26022
|
if (SHELL_DYNAMIC.test(raw) || raw === "-") {
|
|
26038
26023
|
return { dir: null, named: true, unresolvable: `cd target not statically resolvable: ${raw}` };
|
|
26039
26024
|
}
|
|
26040
|
-
const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0,
|
|
26041
|
-
dir = (0,
|
|
26025
|
+
const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path30.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
|
|
26026
|
+
dir = (0, import_node_path29.isAbsolute)(expanded) ? expanded : (0, import_node_path29.resolve)(dir, expanded);
|
|
26042
26027
|
}
|
|
26043
26028
|
const seg = segments[segmentIndex];
|
|
26044
26029
|
const overrideMatch = /--(?:git-dir|work-tree)(?:=|\s)|\bGIT_(?:DIR|WORK_TREE|INDEX_FILE)=/.exec(seg);
|
|
@@ -26056,8 +26041,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
|
|
|
26056
26041
|
if (SHELL_DYNAMIC.test(raw)) {
|
|
26057
26042
|
return { dir: null, named: true, unresolvable: `-C target not statically resolvable: ${raw}` };
|
|
26058
26043
|
}
|
|
26059
|
-
const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0,
|
|
26060
|
-
dir = (0,
|
|
26044
|
+
const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path30.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
|
|
26045
|
+
dir = (0, import_node_path29.isAbsolute)(expanded) ? expanded : (0, import_node_path29.resolve)(dir, expanded);
|
|
26061
26046
|
}
|
|
26062
26047
|
}
|
|
26063
26048
|
return { dir, named, unresolvable: null };
|
|
@@ -26117,14 +26102,14 @@ function gitAt(dir, args2) {
|
|
|
26117
26102
|
}
|
|
26118
26103
|
function realpathOr2(p) {
|
|
26119
26104
|
try {
|
|
26120
|
-
return
|
|
26105
|
+
return import_node_fs38.realpathSync.native(p);
|
|
26121
26106
|
} catch {
|
|
26122
|
-
return (0,
|
|
26107
|
+
return (0, import_node_path29.resolve)(p);
|
|
26123
26108
|
}
|
|
26124
26109
|
}
|
|
26125
26110
|
function resolveFrame(input) {
|
|
26126
26111
|
const found = findMomentSegment(input.command, input.on);
|
|
26127
|
-
const hookDirUsable = !!input.hookCwd && (0,
|
|
26112
|
+
const hookDirUsable = !!input.hookCwd && (0, import_node_fs38.existsSync)(input.hookCwd);
|
|
26128
26113
|
const baseDir = hookDirUsable ? input.hookCwd : process.cwd();
|
|
26129
26114
|
let anchor = hookDirUsable ? "hook-cwd" : "process-cwd";
|
|
26130
26115
|
const refuse = (refusal) => ({
|
|
@@ -26147,7 +26132,7 @@ function resolveFrame(input) {
|
|
|
26147
26132
|
if (dirs.size > 1) return refuse(`target:multiple ${found.moment} targets in one command`);
|
|
26148
26133
|
const targetDir = dirs.size === 1 ? [...dirs][0] : baseDir;
|
|
26149
26134
|
if (targetDir !== baseDir) {
|
|
26150
|
-
if (!(0,
|
|
26135
|
+
if (!(0, import_node_fs38.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
|
|
26151
26136
|
dir = targetDir;
|
|
26152
26137
|
}
|
|
26153
26138
|
}
|
|
@@ -26158,7 +26143,7 @@ function resolveFrame(input) {
|
|
|
26158
26143
|
const gitDirRaw = gitAt(dir, ["rev-parse", "--absolute-git-dir"]);
|
|
26159
26144
|
const commonRaw = gitAt(dir, ["rev-parse", "--git-common-dir"]);
|
|
26160
26145
|
const gitDir = gitDirRaw ? realpathOr2(gitDirRaw) : null;
|
|
26161
|
-
const commonDir = commonRaw ? realpathOr2((0,
|
|
26146
|
+
const commonDir = commonRaw ? realpathOr2((0, import_node_path29.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path29.resolve)(dir, commonRaw)) : null;
|
|
26162
26147
|
const branchRaw = gitAt(dir, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
26163
26148
|
return {
|
|
26164
26149
|
moment: found?.moment ?? null,
|
|
@@ -26333,8 +26318,8 @@ function stagedRange(frame, command) {
|
|
|
26333
26318
|
if (plan.kind === "unpredictable") {
|
|
26334
26319
|
return { kind: "staged", base: "HEAD", head: "INDEX", via: "staged-in-command", refusal: plan.reason };
|
|
26335
26320
|
}
|
|
26336
|
-
const mergeHead = frame.gitDir ? (0,
|
|
26337
|
-
if (mergeHead && (0,
|
|
26321
|
+
const mergeHead = frame.gitDir ? (0, import_node_path30.join)(frame.gitDir, "MERGE_HEAD") : null;
|
|
26322
|
+
if (mergeHead && (0, import_node_fs38.existsSync)(mergeHead)) {
|
|
26338
26323
|
const vsHead = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "HEAD"]).split("\n").filter(Boolean));
|
|
26339
26324
|
const vsMerge = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "MERGE_HEAD"]).split("\n").filter(Boolean));
|
|
26340
26325
|
const resolutions = new Set([...vsHead].filter((f) => vsMerge.has(f) && !isVerityOwnedPath(f)));
|
|
@@ -26468,7 +26453,7 @@ function truthy(v) {
|
|
|
26468
26453
|
}
|
|
26469
26454
|
|
|
26470
26455
|
// src/lib/transcript.ts
|
|
26471
|
-
var
|
|
26456
|
+
var import_node_fs39 = require("node:fs");
|
|
26472
26457
|
var MAX_READ_BYTES = 256 * 1024;
|
|
26473
26458
|
var SMALL_FILE_BYTES = 64 * 1024;
|
|
26474
26459
|
var MAX_FILES_LIST = 20;
|
|
@@ -26495,7 +26480,7 @@ async function extractActionSummary(transcriptPath) {
|
|
|
26495
26480
|
function readTurnLines(transcriptPath) {
|
|
26496
26481
|
let size;
|
|
26497
26482
|
try {
|
|
26498
|
-
size = (0,
|
|
26483
|
+
size = (0, import_node_fs39.statSync)(transcriptPath).size;
|
|
26499
26484
|
} catch {
|
|
26500
26485
|
return null;
|
|
26501
26486
|
}
|
|
@@ -26503,7 +26488,7 @@ function readTurnLines(transcriptPath) {
|
|
|
26503
26488
|
let raw;
|
|
26504
26489
|
let windowed = false;
|
|
26505
26490
|
if (size <= SMALL_FILE_BYTES) {
|
|
26506
|
-
raw = (0,
|
|
26491
|
+
raw = (0, import_node_fs39.readFileSync)(transcriptPath, "utf-8");
|
|
26507
26492
|
} else {
|
|
26508
26493
|
windowed = true;
|
|
26509
26494
|
const buf = Buffer.alloc(Math.min(MAX_READ_BYTES, size));
|
|
@@ -27073,7 +27058,7 @@ function channelSilence(input) {
|
|
|
27073
27058
|
// src/lib/cli-version.ts
|
|
27074
27059
|
function cliVersion() {
|
|
27075
27060
|
try {
|
|
27076
|
-
return true ? "0.34.0-experimental.
|
|
27061
|
+
return true ? "0.34.0-experimental.b9e8508" : "dev";
|
|
27077
27062
|
} catch {
|
|
27078
27063
|
return "dev";
|
|
27079
27064
|
}
|
|
@@ -27114,7 +27099,7 @@ async function sendSkipBeacon(ctx, reason) {
|
|
|
27114
27099
|
|
|
27115
27100
|
// src/lib/static-analysis.ts
|
|
27116
27101
|
var import_node_child_process12 = require("node:child_process");
|
|
27117
|
-
var
|
|
27102
|
+
var import_node_fs40 = require("node:fs");
|
|
27118
27103
|
var SEVERITY_ORDER = {
|
|
27119
27104
|
Error: 0,
|
|
27120
27105
|
Critical: 0,
|
|
@@ -27170,7 +27155,7 @@ function runCodacyAnalysis(files) {
|
|
|
27170
27155
|
if (files.length === 0) return empty;
|
|
27171
27156
|
const existingFiles = files.filter((f) => {
|
|
27172
27157
|
try {
|
|
27173
|
-
return (0,
|
|
27158
|
+
return (0, import_node_fs40.existsSync)(f);
|
|
27174
27159
|
} catch {
|
|
27175
27160
|
return false;
|
|
27176
27161
|
}
|
|
@@ -27439,8 +27424,8 @@ async function scope(run4) {
|
|
|
27439
27424
|
}
|
|
27440
27425
|
|
|
27441
27426
|
// src/lib/specs.ts
|
|
27442
|
-
var
|
|
27443
|
-
var
|
|
27427
|
+
var import_node_fs41 = require("node:fs");
|
|
27428
|
+
var import_node_path31 = require("node:path");
|
|
27444
27429
|
var SPEC_CANDIDATES = [
|
|
27445
27430
|
"CLAUDE.md",
|
|
27446
27431
|
"AGENTS.md",
|
|
@@ -27462,7 +27447,7 @@ var UNCONSULTED_TOTAL_BYTES = 30720;
|
|
|
27462
27447
|
function readSpecFiles(specsOpt, root) {
|
|
27463
27448
|
const out2 = [];
|
|
27464
27449
|
for (const raw of specsOpt.split(",").map((f) => f.trim()).filter(Boolean)) {
|
|
27465
|
-
const candidate = (0,
|
|
27450
|
+
const candidate = (0, import_node_path31.isAbsolute)(raw) ? (0, import_node_path31.relative)(root, raw) : raw;
|
|
27466
27451
|
const content = readFileInside(root, candidate, MAX_EXPLICIT_SPEC_FILE_BYTES);
|
|
27467
27452
|
if (content === null) continue;
|
|
27468
27453
|
out2.push({ path: raw, content });
|
|
@@ -27481,7 +27466,7 @@ function discoverSpecs(consulted = []) {
|
|
|
27481
27466
|
const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
|
|
27482
27467
|
if (totalBytes >= totalCap) return false;
|
|
27483
27468
|
if (seen.has(specPath)) return true;
|
|
27484
|
-
if (!(0,
|
|
27469
|
+
if (!(0, import_node_fs41.existsSync)(specPath)) return true;
|
|
27485
27470
|
seen.add(specPath);
|
|
27486
27471
|
const remaining = totalCap - totalBytes;
|
|
27487
27472
|
const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
|
|
@@ -27504,7 +27489,7 @@ function discoverSpecs(consulted = []) {
|
|
|
27504
27489
|
if (!addSpec(candidate)) break;
|
|
27505
27490
|
}
|
|
27506
27491
|
for (const dir of ["spec", "docs"]) {
|
|
27507
|
-
if (!(0,
|
|
27492
|
+
if (!(0, import_node_fs41.existsSync)(dir)) continue;
|
|
27508
27493
|
try {
|
|
27509
27494
|
const mdFiles = findMdFiles(dir, 2).sort();
|
|
27510
27495
|
for (const mdFile of mdFiles) {
|
|
@@ -27519,9 +27504,9 @@ function findMdFiles(dir, maxDepth, depth = 0) {
|
|
|
27519
27504
|
if (depth >= maxDepth) return [];
|
|
27520
27505
|
const result = [];
|
|
27521
27506
|
try {
|
|
27522
|
-
const entries = (0,
|
|
27507
|
+
const entries = (0, import_node_fs41.readdirSync)(dir, { withFileTypes: true });
|
|
27523
27508
|
for (const entry of entries) {
|
|
27524
|
-
const fullPath = (0,
|
|
27509
|
+
const fullPath = (0, import_node_path31.join)(dir, entry.name);
|
|
27525
27510
|
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
27526
27511
|
result.push(fullPath);
|
|
27527
27512
|
} else if (entry.isDirectory() && depth < maxDepth - 1) {
|
|
@@ -27534,25 +27519,25 @@ function findMdFiles(dir, maxDepth, depth = 0) {
|
|
|
27534
27519
|
}
|
|
27535
27520
|
function discoverPlans() {
|
|
27536
27521
|
const home = process.env.HOME ?? "";
|
|
27537
|
-
const homePlansDir = (0,
|
|
27522
|
+
const homePlansDir = (0, import_node_path31.join)(home, ".claude", "plans");
|
|
27538
27523
|
const sources = [];
|
|
27539
27524
|
if (isRealDirectoryChain(process.cwd(), [".claude", "plans"])) {
|
|
27540
|
-
sources.push({ root: process.cwd(), prefix: (0,
|
|
27525
|
+
sources.push({ root: process.cwd(), prefix: (0, import_node_path31.join)(".claude", "plans") });
|
|
27541
27526
|
}
|
|
27542
|
-
if (home && (0,
|
|
27527
|
+
if (home && (0, import_node_fs41.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
|
|
27543
27528
|
const candidates2 = [];
|
|
27544
27529
|
const seen = /* @__PURE__ */ new Set();
|
|
27545
27530
|
for (const source2 of sources) {
|
|
27546
27531
|
let names2;
|
|
27547
27532
|
try {
|
|
27548
|
-
names2 = (0,
|
|
27533
|
+
names2 = (0, import_node_fs41.readdirSync)(source2.prefix ? (0, import_node_path31.join)(source2.root, source2.prefix) : source2.root);
|
|
27549
27534
|
} catch {
|
|
27550
27535
|
continue;
|
|
27551
27536
|
}
|
|
27552
27537
|
for (const f of names2) {
|
|
27553
27538
|
if (!f.endsWith(".md") || seen.has(f)) continue;
|
|
27554
27539
|
seen.add(f);
|
|
27555
|
-
const relPath = source2.prefix ? (0,
|
|
27540
|
+
const relPath = source2.prefix ? (0, import_node_path31.join)(source2.prefix, f) : f;
|
|
27556
27541
|
const stat3 = statRegularInRoot(source2.root, relPath);
|
|
27557
27542
|
if (!stat3.ok) continue;
|
|
27558
27543
|
candidates2.push({ name: f, root: source2.root, relPath, mtime: stat3.mtimeMs, size: stat3.size });
|
|
@@ -27570,9 +27555,9 @@ function discoverPlans() {
|
|
|
27570
27555
|
function isRealDirectoryChain(root, parts2) {
|
|
27571
27556
|
let current = root;
|
|
27572
27557
|
for (const part of parts2) {
|
|
27573
|
-
current = (0,
|
|
27558
|
+
current = (0, import_node_path31.join)(current, part);
|
|
27574
27559
|
try {
|
|
27575
|
-
if (!(0,
|
|
27560
|
+
if (!(0, import_node_fs41.lstatSync)(current).isDirectory()) return false;
|
|
27576
27561
|
} catch {
|
|
27577
27562
|
return false;
|
|
27578
27563
|
}
|
|
@@ -27587,7 +27572,7 @@ function discoverGuardDocs(rangeFiles2) {
|
|
|
27587
27572
|
if (result.length >= MAX_SPEC_FILES) break;
|
|
27588
27573
|
if (!GUARD_DOC_EXT.test(path)) continue;
|
|
27589
27574
|
if (path.startsWith("/") || path.includes("..")) continue;
|
|
27590
|
-
if (!(0,
|
|
27575
|
+
if (!(0, import_node_fs41.existsSync)(path)) continue;
|
|
27591
27576
|
const opened = openRegularInRoot(process.cwd(), path);
|
|
27592
27577
|
if (!opened.ok) continue;
|
|
27593
27578
|
if (opened.size > MAX_PLAN_FILE_BYTES || totalBytes + opened.size > MAX_TOTAL_SPEC_BYTES) {
|
|
@@ -27773,8 +27758,8 @@ async function mode(run4) {
|
|
|
27773
27758
|
}
|
|
27774
27759
|
|
|
27775
27760
|
// src/lib/fold.ts
|
|
27776
|
-
var
|
|
27777
|
-
var
|
|
27761
|
+
var import_node_fs42 = require("node:fs");
|
|
27762
|
+
var import_node_path32 = require("node:path");
|
|
27778
27763
|
var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
|
|
27779
27764
|
"user",
|
|
27780
27765
|
"assistant",
|
|
@@ -27911,7 +27896,7 @@ function candidateRoots(repoRoot2) {
|
|
|
27911
27896
|
const norm2 = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
27912
27897
|
const out2 = [norm2];
|
|
27913
27898
|
try {
|
|
27914
|
-
const real =
|
|
27899
|
+
const real = import_node_fs42.realpathSync.native(norm2).replace(/\\/g, "/").replace(/\/+$/, "");
|
|
27915
27900
|
if (real !== norm2) out2.push(real);
|
|
27916
27901
|
} catch {
|
|
27917
27902
|
}
|
|
@@ -27999,31 +27984,31 @@ function fold(transcriptPath, opts = {}) {
|
|
|
27999
27984
|
}
|
|
28000
27985
|
};
|
|
28001
27986
|
try {
|
|
28002
|
-
if (!(0,
|
|
28003
|
-
ingest((0,
|
|
27987
|
+
if (!(0, import_node_fs42.existsSync)(transcriptPath)) return result;
|
|
27988
|
+
ingest((0, import_node_fs42.readFileSync)(transcriptPath, "utf8"), "agent");
|
|
28004
27989
|
result.coverage.complete = true;
|
|
28005
27990
|
} catch {
|
|
28006
27991
|
return result;
|
|
28007
27992
|
}
|
|
28008
27993
|
try {
|
|
28009
|
-
const sidecarDir = (0,
|
|
28010
|
-
(0,
|
|
28011
|
-
(0,
|
|
27994
|
+
const sidecarDir = (0, import_node_path32.join)(
|
|
27995
|
+
(0, import_node_path32.dirname)(transcriptPath),
|
|
27996
|
+
(0, import_node_path32.basename)(transcriptPath).replace(/\.jsonl$/, ""),
|
|
28012
27997
|
"subagents"
|
|
28013
27998
|
);
|
|
28014
|
-
if ((0,
|
|
27999
|
+
if ((0, import_node_fs42.existsSync)(sidecarDir)) {
|
|
28015
28000
|
const maxFiles = opts.maxSidecars ?? 200;
|
|
28016
28001
|
const maxBytes = opts.maxSidecarBytes ?? 16 * 1024 * 1024;
|
|
28017
28002
|
const found = [];
|
|
28018
28003
|
const walk2 = (d, depth) => {
|
|
28019
28004
|
if (depth > 4) return;
|
|
28020
|
-
for (const e of (0,
|
|
28021
|
-
const p = (0,
|
|
28005
|
+
for (const e of (0, import_node_fs42.readdirSync)(d, { withFileTypes: true })) {
|
|
28006
|
+
const p = (0, import_node_path32.join)(d, e.name);
|
|
28022
28007
|
if (e.isDirectory()) {
|
|
28023
28008
|
walk2(p, depth + 1);
|
|
28024
28009
|
} else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
|
|
28025
28010
|
try {
|
|
28026
|
-
const st = (0,
|
|
28011
|
+
const st = (0, import_node_fs42.statSync)(p);
|
|
28027
28012
|
found.push({ path: p, size: st.size, mtimeMs: st.mtimeMs });
|
|
28028
28013
|
} catch {
|
|
28029
28014
|
result.coverage.malformed++;
|
|
@@ -28040,7 +28025,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28040
28025
|
continue;
|
|
28041
28026
|
}
|
|
28042
28027
|
try {
|
|
28043
|
-
ingest((0,
|
|
28028
|
+
ingest((0, import_node_fs42.readFileSync)(f.path, "utf8"), "subagent");
|
|
28044
28029
|
bytes += f.size;
|
|
28045
28030
|
result.coverage.subagentFiles++;
|
|
28046
28031
|
} catch {
|
|
@@ -28075,7 +28060,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28075
28060
|
}
|
|
28076
28061
|
function classifyUnobserved(path) {
|
|
28077
28062
|
try {
|
|
28078
|
-
const st = (0,
|
|
28063
|
+
const st = (0, import_node_fs42.statSync)(path);
|
|
28079
28064
|
if (!st.isFile()) return "unreadable";
|
|
28080
28065
|
} catch {
|
|
28081
28066
|
return "unreadable";
|
|
@@ -28390,20 +28375,20 @@ async function evidence(run4) {
|
|
|
28390
28375
|
}
|
|
28391
28376
|
|
|
28392
28377
|
// src/lib/cache-cleanup.ts
|
|
28393
|
-
var
|
|
28394
|
-
var
|
|
28378
|
+
var import_node_fs43 = require("node:fs");
|
|
28379
|
+
var import_node_path33 = require("node:path");
|
|
28395
28380
|
var CACHE_TTL_DAYS = 7;
|
|
28396
28381
|
function pruneStaleCache() {
|
|
28397
28382
|
try {
|
|
28398
28383
|
const dir = projectPath(CACHE_DIR);
|
|
28399
28384
|
const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
|
|
28400
|
-
for (const entry of (0,
|
|
28385
|
+
for (const entry of (0, import_node_fs43.readdirSync)(dir)) {
|
|
28401
28386
|
if (!entry.startsWith("pending-")) continue;
|
|
28402
|
-
const path = (0,
|
|
28387
|
+
const path = (0, import_node_path33.join)(dir, entry);
|
|
28403
28388
|
try {
|
|
28404
|
-
const stat3 = (0,
|
|
28389
|
+
const stat3 = (0, import_node_fs43.statSync)(path);
|
|
28405
28390
|
if (stat3.mtimeMs < cutoff) {
|
|
28406
|
-
(0,
|
|
28391
|
+
(0, import_node_fs43.unlinkSync)(path);
|
|
28407
28392
|
logEvent("cache_entry_pruned", {
|
|
28408
28393
|
path: entry,
|
|
28409
28394
|
age_days: Math.round((Date.now() - stat3.mtimeMs) / 864e5)
|
|
@@ -28417,7 +28402,7 @@ function pruneStaleCache() {
|
|
|
28417
28402
|
}
|
|
28418
28403
|
|
|
28419
28404
|
// src/lib/context-files.ts
|
|
28420
|
-
var
|
|
28405
|
+
var import_node_fs44 = require("node:fs");
|
|
28421
28406
|
var import_node_os7 = require("node:os");
|
|
28422
28407
|
var MAX_CONTEXT_FILES = 10;
|
|
28423
28408
|
var MAX_CONTEXT_FILE_BYTES = 10240;
|
|
@@ -28475,7 +28460,7 @@ function gatherContextFiles(contextPaths, deltaFiles, opts) {
|
|
|
28475
28460
|
continue;
|
|
28476
28461
|
}
|
|
28477
28462
|
try {
|
|
28478
|
-
const content = (0,
|
|
28463
|
+
const content = (0, import_node_fs44.readFileSync)(safePath, "utf8");
|
|
28479
28464
|
const bytes = Buffer.byteLength(content);
|
|
28480
28465
|
if (bytes > MAX_CONTEXT_FILE_BYTES) {
|
|
28481
28466
|
logEvent("context_file_skipped", { path: filePath, reason: "too_large", bytes });
|
|
@@ -28633,8 +28618,8 @@ function languageOf2(path) {
|
|
|
28633
28618
|
}
|
|
28634
28619
|
|
|
28635
28620
|
// src/lib/code/runtime.ts
|
|
28636
|
-
var
|
|
28637
|
-
var
|
|
28621
|
+
var import_node_fs45 = require("node:fs");
|
|
28622
|
+
var import_node_path34 = require("node:path");
|
|
28638
28623
|
var import_web_tree_sitter2 = __toESM2(require_web_tree_sitter2());
|
|
28639
28624
|
|
|
28640
28625
|
// src/lib/code/grammars.json
|
|
@@ -28694,18 +28679,18 @@ var grammars_default = {
|
|
|
28694
28679
|
var MAX_PARSE_BYTES = 512 * 1024;
|
|
28695
28680
|
function grammarCandidates(file, pkg, env = process.env) {
|
|
28696
28681
|
return [
|
|
28697
|
-
...env.VERITY_GRAMMAR_DIR ? [(0,
|
|
28698
|
-
(0,
|
|
28682
|
+
...env.VERITY_GRAMMAR_DIR ? [(0, import_node_path34.join)(env.VERITY_GRAMMAR_DIR, file)] : [],
|
|
28683
|
+
(0, import_node_path34.join)(__dirname, "..", "data", "grammars", file),
|
|
28699
28684
|
// bundled: cli/bin/ → cli/data/grammars/
|
|
28700
|
-
(0,
|
|
28685
|
+
(0, import_node_path34.join)(__dirname, "..", "..", "..", "data", "grammars", file),
|
|
28701
28686
|
// tsx: cli/src/lib/code/ → cli/data/grammars/
|
|
28702
|
-
(0,
|
|
28687
|
+
(0, import_node_path34.join)(__dirname, "..", "..", "..", "node_modules", pkg, file)
|
|
28703
28688
|
// tsx, before a build: the pinned devDependency
|
|
28704
28689
|
];
|
|
28705
28690
|
}
|
|
28706
28691
|
function locateGrammar(id, env = process.env) {
|
|
28707
28692
|
const g = grammars_default[id];
|
|
28708
|
-
return grammarCandidates(g.file, g.package, env).find((p) => (0,
|
|
28693
|
+
return grammarCandidates(g.file, g.package, env).find((p) => (0, import_node_fs45.existsSync)(p)) ?? null;
|
|
28709
28694
|
}
|
|
28710
28695
|
var loading = null;
|
|
28711
28696
|
function loadRuntime(env = process.env) {
|
|
@@ -31034,8 +31019,8 @@ async function repoContext(run4) {
|
|
|
31034
31019
|
|
|
31035
31020
|
// src/lib/seed-runner.ts
|
|
31036
31021
|
var import_promises15 = require("node:fs/promises");
|
|
31037
|
-
var
|
|
31038
|
-
var
|
|
31022
|
+
var import_node_fs46 = require("node:fs");
|
|
31023
|
+
var import_node_path35 = require("node:path");
|
|
31039
31024
|
var import_yaml4 = __toESM2(require_dist());
|
|
31040
31025
|
|
|
31041
31026
|
// src/lib/seed.ts
|
|
@@ -31258,8 +31243,8 @@ function normalizeTitle(title) {
|
|
|
31258
31243
|
async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
|
|
31259
31244
|
const titles = /* @__PURE__ */ new Set();
|
|
31260
31245
|
for (const dir of NODE_DIRS) {
|
|
31261
|
-
const full = (0,
|
|
31262
|
-
if (!(0,
|
|
31246
|
+
const full = (0, import_node_path35.join)(memoryDir3, dir);
|
|
31247
|
+
if (!(0, import_node_fs46.existsSync)(full)) continue;
|
|
31263
31248
|
let files;
|
|
31264
31249
|
try {
|
|
31265
31250
|
files = await (0, import_promises15.readdir)(full);
|
|
@@ -31270,7 +31255,7 @@ async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
|
|
|
31270
31255
|
if (!file.endsWith(".md")) continue;
|
|
31271
31256
|
let content;
|
|
31272
31257
|
try {
|
|
31273
|
-
content = await (0, import_promises15.readFile)((0,
|
|
31258
|
+
content = await (0, import_promises15.readFile)((0, import_node_path35.join)(full, file), "utf-8");
|
|
31274
31259
|
} catch {
|
|
31275
31260
|
continue;
|
|
31276
31261
|
}
|
|
@@ -31341,7 +31326,7 @@ function renderNodeMarkdown(candidate, nodeId, createdAt) {
|
|
|
31341
31326
|
return fm;
|
|
31342
31327
|
}
|
|
31343
31328
|
async function runSeed(opts) {
|
|
31344
|
-
if (!(0,
|
|
31329
|
+
if (!(0, import_node_fs46.existsSync)(STANDARD_FILE)) {
|
|
31345
31330
|
return { created: 0, existing: 0, failed: 0, skipped: "no_standard", candidates: [] };
|
|
31346
31331
|
}
|
|
31347
31332
|
let standardDoc;
|
|
@@ -31353,7 +31338,7 @@ async function runSeed(opts) {
|
|
|
31353
31338
|
}
|
|
31354
31339
|
const knowledgeSpec = standardDoc.knowledge_spec ?? {};
|
|
31355
31340
|
let readmeContent;
|
|
31356
|
-
if ((0,
|
|
31341
|
+
if ((0, import_node_fs46.existsSync)("README.md")) {
|
|
31357
31342
|
try {
|
|
31358
31343
|
readmeContent = await (0, import_promises15.readFile)("README.md", "utf-8");
|
|
31359
31344
|
} catch {
|
|
@@ -31361,7 +31346,7 @@ async function runSeed(opts) {
|
|
|
31361
31346
|
}
|
|
31362
31347
|
let claudeMdContent;
|
|
31363
31348
|
for (const p of ["CLAUDE.md", ".claude/CLAUDE.md"]) {
|
|
31364
|
-
if ((0,
|
|
31349
|
+
if ((0, import_node_fs46.existsSync)(p)) {
|
|
31365
31350
|
try {
|
|
31366
31351
|
claudeMdContent = await (0, import_promises15.readFile)(p, "utf-8");
|
|
31367
31352
|
break;
|
|
@@ -31441,13 +31426,13 @@ async function runSeed(opts) {
|
|
|
31441
31426
|
continue;
|
|
31442
31427
|
}
|
|
31443
31428
|
const deduplicated = res.data.deduplicated === true;
|
|
31444
|
-
if (deduplicated && (0,
|
|
31429
|
+
if (deduplicated && (0, import_node_fs46.existsSync)(targetPath)) {
|
|
31445
31430
|
existing++;
|
|
31446
31431
|
continue;
|
|
31447
31432
|
}
|
|
31448
31433
|
const content = typeof res.data.content === "string" && res.data.content.length > 0 ? res.data.content : renderNodeMarkdown(c, nodeId, createdAt);
|
|
31449
31434
|
try {
|
|
31450
|
-
await (0, import_promises15.mkdir)((0,
|
|
31435
|
+
await (0, import_promises15.mkdir)((0, import_node_path35.dirname)(targetPath), { recursive: true });
|
|
31451
31436
|
await (0, import_promises15.writeFile)(targetPath, content);
|
|
31452
31437
|
if (deduplicated) existing++;
|
|
31453
31438
|
else {
|
|
@@ -31463,8 +31448,8 @@ async function runSeed(opts) {
|
|
|
31463
31448
|
}
|
|
31464
31449
|
|
|
31465
31450
|
// src/commands/analyze/phases/08-memory-manifest.ts
|
|
31466
|
-
var
|
|
31467
|
-
var
|
|
31451
|
+
var import_node_fs47 = require("node:fs");
|
|
31452
|
+
var import_node_path36 = require("node:path");
|
|
31468
31453
|
async function memoryManifest(run4) {
|
|
31469
31454
|
const { globals } = run4;
|
|
31470
31455
|
const { serviceUrl, token } = run4;
|
|
@@ -31474,9 +31459,9 @@ async function memoryManifest(run4) {
|
|
|
31474
31459
|
let autoSeedNotice = null;
|
|
31475
31460
|
try {
|
|
31476
31461
|
await ensureMemoryDir();
|
|
31477
|
-
const seedMarker = (0,
|
|
31478
|
-
const hasStandard = (0,
|
|
31479
|
-
const alreadyTried = (0,
|
|
31462
|
+
const seedMarker = (0, import_node_path36.join)(VERITY_DIR, ".seeded");
|
|
31463
|
+
const hasStandard = (0, import_node_fs47.existsSync)(STANDARD_FILE);
|
|
31464
|
+
const alreadyTried = (0, import_node_fs47.existsSync)(seedMarker);
|
|
31480
31465
|
if (hasStandard && !alreadyTried) {
|
|
31481
31466
|
const preManifest = await buildManifest();
|
|
31482
31467
|
if (preManifest.nodes.length === 0) {
|
|
@@ -31489,7 +31474,7 @@ async function memoryManifest(run4) {
|
|
|
31489
31474
|
dryRun: false
|
|
31490
31475
|
});
|
|
31491
31476
|
if (seedResult.created > 0 || seedResult.existing > 0) {
|
|
31492
|
-
(0,
|
|
31477
|
+
(0, import_node_fs47.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created} existing=${seedResult.existing}
|
|
31493
31478
|
`);
|
|
31494
31479
|
if (seedResult.created > 0) {
|
|
31495
31480
|
autoSeedNotice = `Seeded ${seedResult.created} knowledge node(s) from your existing Standard (one-time).`;
|
|
@@ -31500,7 +31485,7 @@ async function memoryManifest(run4) {
|
|
|
31500
31485
|
failed: seedResult.failed
|
|
31501
31486
|
});
|
|
31502
31487
|
} else if (seedResult.skipped === "already_seeded") {
|
|
31503
|
-
(0,
|
|
31488
|
+
(0, import_node_fs47.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
|
|
31504
31489
|
`);
|
|
31505
31490
|
} else {
|
|
31506
31491
|
logEvent("auto_seed_noop", {
|
|
@@ -31595,7 +31580,7 @@ function computeIncrement(reviewedPaths, hashOf, priorAuthored) {
|
|
|
31595
31580
|
}
|
|
31596
31581
|
|
|
31597
31582
|
// src/commands/analyze/phases/10-working-memory.ts
|
|
31598
|
-
var
|
|
31583
|
+
var import_node_path37 = require("node:path");
|
|
31599
31584
|
async function workingMemory(run4) {
|
|
31600
31585
|
const { opts } = run4;
|
|
31601
31586
|
const { allForReview, baseline, conversation, foldResult, sessionId, token, transcriptPath } = run4;
|
|
@@ -31607,7 +31592,7 @@ async function workingMemory(run4) {
|
|
|
31607
31592
|
const priorState = foldForMarks(memorySession.d);
|
|
31608
31593
|
incrementReport = computeIncrement(
|
|
31609
31594
|
allForReview,
|
|
31610
|
-
(p) => fileHash((0,
|
|
31595
|
+
(p) => fileHash((0, import_node_path37.join)(repoRoot(), p)),
|
|
31611
31596
|
priorState.authored_all.map((a) => ({
|
|
31612
31597
|
path: a.path,
|
|
31613
31598
|
hash_at_last_verdict: a.hash_at_last_verdict
|
|
@@ -31689,7 +31674,7 @@ async function workingMemory(run4) {
|
|
|
31689
31674
|
}
|
|
31690
31675
|
|
|
31691
31676
|
// src/lib/note-budget.ts
|
|
31692
|
-
var
|
|
31677
|
+
var import_node_fs48 = require("node:fs");
|
|
31693
31678
|
var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
|
|
31694
31679
|
var EPISODE_STALE_SECONDS = 30 * 60;
|
|
31695
31680
|
var FRESH = { delivered: 0, tasksCompleted: 0, ts: 0 };
|
|
@@ -31711,9 +31696,9 @@ function advisoryBudgetSpent(episode, rawDecision) {
|
|
|
31711
31696
|
}
|
|
31712
31697
|
function readAdvisoryEpisode(sessionId) {
|
|
31713
31698
|
const file = scopedFile(ADVISORY_EPISODE_FILE, sessionId);
|
|
31714
|
-
if (!(0,
|
|
31699
|
+
if (!(0, import_node_fs48.existsSync)(file)) return null;
|
|
31715
31700
|
try {
|
|
31716
|
-
const o = JSON.parse((0,
|
|
31701
|
+
const o = JSON.parse((0, import_node_fs48.readFileSync)(file, "utf-8")) ?? {};
|
|
31717
31702
|
const delivered = typeof o.delivered === "number" ? o.delivered : NaN;
|
|
31718
31703
|
if (isNaN(delivered)) return null;
|
|
31719
31704
|
return {
|
|
@@ -31727,8 +31712,8 @@ function readAdvisoryEpisode(sessionId) {
|
|
|
31727
31712
|
}
|
|
31728
31713
|
function writeAdvisoryEpisode(episode, sessionId) {
|
|
31729
31714
|
try {
|
|
31730
|
-
(0,
|
|
31731
|
-
(0,
|
|
31715
|
+
(0, import_node_fs48.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
31716
|
+
(0, import_node_fs48.writeFileSync)(
|
|
31732
31717
|
scopedFile(ADVISORY_EPISODE_FILE, sessionId),
|
|
31733
31718
|
JSON.stringify({ v: 1, ...episode })
|
|
31734
31719
|
);
|
|
@@ -32060,14 +32045,14 @@ async function buildRequest(run4) {
|
|
|
32060
32045
|
}
|
|
32061
32046
|
|
|
32062
32047
|
// src/lib/offline.ts
|
|
32063
|
-
var
|
|
32048
|
+
var import_node_fs49 = require("node:fs");
|
|
32064
32049
|
var import_node_crypto13 = require("node:crypto");
|
|
32065
32050
|
function cacheRequest(body2) {
|
|
32066
32051
|
try {
|
|
32067
|
-
(0,
|
|
32052
|
+
(0, import_node_fs49.mkdirSync)(CACHE_DIR, { recursive: true });
|
|
32068
32053
|
const suffix = (0, import_node_crypto13.randomBytes)(4).toString("hex");
|
|
32069
32054
|
const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
|
|
32070
|
-
(0,
|
|
32055
|
+
(0, import_node_fs49.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body2)));
|
|
32071
32056
|
} catch {
|
|
32072
32057
|
}
|
|
32073
32058
|
}
|
|
@@ -32186,8 +32171,8 @@ async function transmit(run4) {
|
|
|
32186
32171
|
}
|
|
32187
32172
|
|
|
32188
32173
|
// src/commands/analyze/phases/13-reconcile.ts
|
|
32189
|
-
var
|
|
32190
|
-
var
|
|
32174
|
+
var import_node_fs50 = require("node:fs");
|
|
32175
|
+
var import_node_path38 = require("node:path");
|
|
32191
32176
|
async function reconcile(run4) {
|
|
32192
32177
|
const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory: memory2, memorySession, response, reviewable, securityFiles, turnId } = run4;
|
|
32193
32178
|
const sentPaths = codeDelta.files.map((f) => f.path);
|
|
@@ -32216,7 +32201,7 @@ async function reconcile(run4) {
|
|
|
32216
32201
|
const st = foldDossier(memorySession.d);
|
|
32217
32202
|
openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line2) => {
|
|
32218
32203
|
try {
|
|
32219
|
-
const src = (0,
|
|
32204
|
+
const src = (0, import_node_fs50.readFileSync)((0, import_node_path38.join)(repoRoot(), file), "utf8").split("\n");
|
|
32220
32205
|
const at = src[line2 - 1];
|
|
32221
32206
|
return at === void 0 ? null : lineSha(at);
|
|
32222
32207
|
} catch {
|
|
@@ -33038,7 +33023,7 @@ function registerAnalyzeCommand(program2) {
|
|
|
33038
33023
|
var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
|
|
33039
33024
|
async function runAnalyze(opts, globals) {
|
|
33040
33025
|
if (!verityConfigured()) {
|
|
33041
|
-
(0,
|
|
33026
|
+
(0, import_node_fs51.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
|
|
33042
33027
|
process.exit(0);
|
|
33043
33028
|
}
|
|
33044
33029
|
const run4 = createRun(opts, globals);
|
|
@@ -33059,11 +33044,11 @@ async function runAnalyze(opts, globals) {
|
|
|
33059
33044
|
}
|
|
33060
33045
|
|
|
33061
33046
|
// src/commands/baseline.ts
|
|
33062
|
-
var
|
|
33047
|
+
var import_node_fs53 = require("node:fs");
|
|
33063
33048
|
|
|
33064
33049
|
// src/lib/project-skills.ts
|
|
33065
|
-
var
|
|
33066
|
-
var
|
|
33050
|
+
var import_node_fs52 = require("node:fs");
|
|
33051
|
+
var import_node_path39 = require("node:path");
|
|
33067
33052
|
var PROJECT_SKILL_NAMES = [
|
|
33068
33053
|
"verity-setup",
|
|
33069
33054
|
"verity-analyze",
|
|
@@ -33089,14 +33074,14 @@ var LEGACY_SKILL_NAMES = [
|
|
|
33089
33074
|
var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
|
|
33090
33075
|
function staleProjectSkills() {
|
|
33091
33076
|
const root = projectPath(".claude/skills");
|
|
33092
|
-
if (!(0,
|
|
33093
|
-
return ALL.filter((name2) => (0,
|
|
33077
|
+
if (!(0, import_node_fs52.existsSync)(root)) return [];
|
|
33078
|
+
return ALL.filter((name2) => (0, import_node_fs52.existsSync)((0, import_node_path39.join)(root, name2)));
|
|
33094
33079
|
}
|
|
33095
33080
|
function removeProjectSkills() {
|
|
33096
33081
|
const root = projectPath(".claude/skills");
|
|
33097
33082
|
const removed = [];
|
|
33098
33083
|
for (const name2 of staleProjectSkills()) {
|
|
33099
|
-
(0,
|
|
33084
|
+
(0, import_node_fs52.rmSync)((0, import_node_path39.join)(root, name2), { recursive: true, force: true });
|
|
33100
33085
|
removed.push(name2);
|
|
33101
33086
|
}
|
|
33102
33087
|
return removed;
|
|
@@ -33161,13 +33146,13 @@ function registerBaselineCommands(program2) {
|
|
|
33161
33146
|
let memoryMsg = null;
|
|
33162
33147
|
let memoryAgentLine = null;
|
|
33163
33148
|
const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
|
|
33164
|
-
if (realStart && !(0,
|
|
33149
|
+
if (realStart && !(0, import_node_fs53.existsSync)(memoryNotice)) {
|
|
33165
33150
|
const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
|
|
33166
33151
|
if (trackedGraph > 0) {
|
|
33167
33152
|
memoryMsg = `Verity: this project commits its knowledge base (${trackedGraph} files under .verity/memory/), so Verity's generated notes show up in every diff and pull request. Run \`verity memory untrack\` to keep them on disk but out of git, or \`verity memory track\` to keep committing them on purpose.`;
|
|
33168
33153
|
memoryAgentLine = `This project has ${trackedGraph} knowledge-graph files tracked in git under .verity/memory/. As of Verity 0.32.6 the graph is machine-local by default \u2014 it is rebuilt from the service, and committing it puts generated notes in every pull request. If the user wants that stopped, run \`verity memory untrack\` for them: it keeps every file on disk and stages their removal from the index, so they only need to commit \u2014 and their teammates' working copies will vanish on the next pull and re-sync from the service, which is expected. If they would rather keep committing it, \`verity memory track\` records that and nothing will offer again.`;
|
|
33169
33154
|
try {
|
|
33170
|
-
(0,
|
|
33155
|
+
(0, import_node_fs53.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
|
|
33171
33156
|
} catch {
|
|
33172
33157
|
}
|
|
33173
33158
|
}
|
|
@@ -33268,7 +33253,7 @@ function hookSource(value) {
|
|
|
33268
33253
|
}
|
|
33269
33254
|
|
|
33270
33255
|
// src/commands/review.ts
|
|
33271
|
-
var
|
|
33256
|
+
var import_node_fs54 = require("node:fs");
|
|
33272
33257
|
function registerReviewCommand(program2) {
|
|
33273
33258
|
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) => {
|
|
33274
33259
|
const globals = program2.opts();
|
|
@@ -33285,7 +33270,7 @@ async function runReview(opts, globals) {
|
|
|
33285
33270
|
const changedFiles = opts.changed ? opts.changed.split(",").map((f) => f.trim()).filter(Boolean) : allFiles;
|
|
33286
33271
|
const analyzable = filterAnalyzable(allFiles);
|
|
33287
33272
|
const securityFiles = filterSecurity(allFiles);
|
|
33288
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0,
|
|
33273
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs54.existsSync)(f) || resolveFile(f) !== null);
|
|
33289
33274
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
33290
33275
|
const codeDelta = collectCodeDelta(allFiles);
|
|
33291
33276
|
const tokenResult = await resolveToken(globals.token);
|
|
@@ -33351,8 +33336,8 @@ async function runReview(opts, globals) {
|
|
|
33351
33336
|
}
|
|
33352
33337
|
|
|
33353
33338
|
// src/commands/guard.ts
|
|
33354
|
-
var
|
|
33355
|
-
var
|
|
33339
|
+
var import_node_fs58 = require("node:fs");
|
|
33340
|
+
var import_node_path44 = require("node:path");
|
|
33356
33341
|
|
|
33357
33342
|
// src/lib/terminal-text.ts
|
|
33358
33343
|
var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/g;
|
|
@@ -33460,7 +33445,7 @@ async function runAgentReview(options) {
|
|
|
33460
33445
|
}
|
|
33461
33446
|
|
|
33462
33447
|
// src/lib/prove/auto.ts
|
|
33463
|
-
var
|
|
33448
|
+
var import_node_path43 = require("node:path");
|
|
33464
33449
|
var import_node_crypto18 = require("node:crypto");
|
|
33465
33450
|
|
|
33466
33451
|
// src/lib/prove/signals.ts
|
|
@@ -34873,10 +34858,10 @@ function parseReplayOutput(output) {
|
|
|
34873
34858
|
}
|
|
34874
34859
|
return { claim, shellCalls, executedCalls, shellTexts, outputTexts };
|
|
34875
34860
|
}
|
|
34876
|
-
var RESULT_LINE = /REPLAY_RESULT=(reproduced|diverged)\b
|
|
34861
|
+
var RESULT_LINE = /REPLAY_RESULT=(reproduced|diverged)\b/;
|
|
34877
34862
|
function printedResult(outputTexts) {
|
|
34878
34863
|
let last = null;
|
|
34879
|
-
for (const t of outputTexts) for (const m of t.matchAll(RESULT_LINE)) last = m[1];
|
|
34864
|
+
for (const t of outputTexts) for (const m of t.matchAll(new RegExp(RESULT_LINE.source, "g"))) last = m[1];
|
|
34880
34865
|
return last;
|
|
34881
34866
|
}
|
|
34882
34867
|
var RESULT_MISSING = "the harness never printed REPLAY_RESULT=reproduced on its own stdout \u2014 the verdict was the model's word, not the run's";
|
|
@@ -35182,18 +35167,18 @@ function renderReplay(model, property, r) {
|
|
|
35182
35167
|
// src/lib/prove/runner.ts
|
|
35183
35168
|
var import_node_child_process15 = require("node:child_process");
|
|
35184
35169
|
var import_node_os8 = require("node:os");
|
|
35185
|
-
var
|
|
35170
|
+
var import_node_fs57 = require("node:fs");
|
|
35186
35171
|
var import_node_os9 = require("node:os");
|
|
35187
|
-
var
|
|
35172
|
+
var import_node_path42 = require("node:path");
|
|
35188
35173
|
|
|
35189
35174
|
// src/lib/prove/scaffold.ts
|
|
35190
|
-
var
|
|
35191
|
-
var
|
|
35175
|
+
var import_node_fs56 = require("node:fs");
|
|
35176
|
+
var import_node_path41 = require("node:path");
|
|
35192
35177
|
|
|
35193
35178
|
// src/lib/prove/safe-write.ts
|
|
35194
|
-
var
|
|
35179
|
+
var import_node_fs55 = require("node:fs");
|
|
35195
35180
|
var import_node_crypto14 = require("node:crypto");
|
|
35196
|
-
var
|
|
35181
|
+
var import_node_path40 = require("node:path");
|
|
35197
35182
|
var SafeWriteError = class extends Error {
|
|
35198
35183
|
constructor(reason, path) {
|
|
35199
35184
|
super(`refusing to write ${path}: ${reason}`);
|
|
@@ -35202,10 +35187,10 @@ var SafeWriteError = class extends Error {
|
|
|
35202
35187
|
this.name = "SafeWriteError";
|
|
35203
35188
|
}
|
|
35204
35189
|
};
|
|
35205
|
-
var FLAGS3 =
|
|
35190
|
+
var FLAGS3 = import_node_fs55.constants;
|
|
35206
35191
|
var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
|
|
35207
35192
|
function assertPlainRelative(rel) {
|
|
35208
|
-
if (!rel || (0,
|
|
35193
|
+
if (!rel || (0, import_node_path40.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
|
|
35209
35194
|
for (const part of rel.split(/[\\/]/)) {
|
|
35210
35195
|
if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
|
|
35211
35196
|
}
|
|
@@ -35214,34 +35199,34 @@ function ensureDirsNoFollow(root, rel) {
|
|
|
35214
35199
|
const parts2 = rel.split(/[\\/]/);
|
|
35215
35200
|
let cur = root;
|
|
35216
35201
|
for (const part of parts2.slice(0, -1)) {
|
|
35217
|
-
cur = (0,
|
|
35202
|
+
cur = (0, import_node_path40.join)(cur, part);
|
|
35218
35203
|
let st;
|
|
35219
35204
|
try {
|
|
35220
|
-
st = (0,
|
|
35205
|
+
st = (0, import_node_fs55.lstatSync)(cur);
|
|
35221
35206
|
} catch {
|
|
35222
|
-
(0,
|
|
35207
|
+
(0, import_node_fs55.mkdirSync)(cur);
|
|
35223
35208
|
continue;
|
|
35224
35209
|
}
|
|
35225
35210
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
|
|
35226
35211
|
if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
|
|
35227
35212
|
}
|
|
35228
|
-
return (0,
|
|
35213
|
+
return (0, import_node_path40.join)(root, rel);
|
|
35229
35214
|
}
|
|
35230
35215
|
function insideRoot(realRoot, realPath) {
|
|
35231
|
-
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(
|
|
35216
|
+
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path40.sep) ? realRoot : realRoot + import_node_path40.sep);
|
|
35232
35217
|
}
|
|
35233
35218
|
function removeQuietly(path) {
|
|
35234
35219
|
try {
|
|
35235
|
-
(0,
|
|
35220
|
+
(0, import_node_fs55.unlinkSync)(path);
|
|
35236
35221
|
} catch {
|
|
35237
35222
|
}
|
|
35238
35223
|
}
|
|
35239
35224
|
function writeFileInRootNoFollow(root, rel, content) {
|
|
35240
35225
|
assertPlainRelative(rel);
|
|
35241
35226
|
const dest = ensureDirsNoFollow(root, rel);
|
|
35242
|
-
const dir = (0,
|
|
35227
|
+
const dir = (0, import_node_path40.dirname)(dest);
|
|
35243
35228
|
try {
|
|
35244
|
-
const st = (0,
|
|
35229
|
+
const st = (0, import_node_fs55.lstatSync)(dest);
|
|
35245
35230
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
|
|
35246
35231
|
if (!st.isFile()) throw new SafeWriteError("not-regular", dest);
|
|
35247
35232
|
} catch (err2) {
|
|
@@ -35249,41 +35234,41 @@ function writeFileInRootNoFollow(root, rel, content) {
|
|
|
35249
35234
|
}
|
|
35250
35235
|
let realRoot;
|
|
35251
35236
|
try {
|
|
35252
|
-
realRoot = (0,
|
|
35237
|
+
realRoot = (0, import_node_fs55.realpathSync)(root);
|
|
35253
35238
|
} catch {
|
|
35254
35239
|
throw new SafeWriteError("unwritable", root);
|
|
35255
35240
|
}
|
|
35256
|
-
const tmp = (0,
|
|
35241
|
+
const tmp = (0, import_node_path40.join)(dir, `.${(0, import_node_path40.basename)(dest)}.${(0, import_node_crypto14.randomBytes)(6).toString("hex")}.tmp`);
|
|
35257
35242
|
let fd;
|
|
35258
35243
|
try {
|
|
35259
|
-
fd = (0,
|
|
35244
|
+
fd = (0, import_node_fs55.openSync)(tmp, import_node_fs55.constants.O_WRONLY | import_node_fs55.constants.O_CREAT | import_node_fs55.constants.O_EXCL | NOFOLLOW2, 420);
|
|
35260
35245
|
} catch {
|
|
35261
35246
|
throw new SafeWriteError("unwritable", tmp);
|
|
35262
35247
|
}
|
|
35263
35248
|
try {
|
|
35264
|
-
const opened = (0,
|
|
35249
|
+
const opened = (0, import_node_fs55.fstatSync)(fd, { bigint: true });
|
|
35265
35250
|
let realTmp;
|
|
35266
35251
|
try {
|
|
35267
|
-
realTmp = (0,
|
|
35252
|
+
realTmp = (0, import_node_fs55.realpathSync)(tmp);
|
|
35268
35253
|
} catch {
|
|
35269
35254
|
throw new SafeWriteError("escaped", tmp);
|
|
35270
35255
|
}
|
|
35271
|
-
const there = (0,
|
|
35256
|
+
const there = (0, import_node_fs55.lstatSync)(realTmp, { bigint: true });
|
|
35272
35257
|
if (!opened.isFile() || there.ino !== opened.ino || there.dev !== opened.dev || !insideRoot(realRoot, realTmp)) {
|
|
35273
35258
|
throw new SafeWriteError("escaped", tmp);
|
|
35274
35259
|
}
|
|
35275
35260
|
const buf = Buffer.from(content, "utf-8");
|
|
35276
35261
|
let off = 0;
|
|
35277
|
-
while (off < buf.length) off += (0,
|
|
35262
|
+
while (off < buf.length) off += (0, import_node_fs55.writeSync)(fd, buf, off, buf.length - off);
|
|
35278
35263
|
} catch (err2) {
|
|
35279
|
-
(0,
|
|
35264
|
+
(0, import_node_fs55.closeSync)(fd);
|
|
35280
35265
|
removeQuietly(tmp);
|
|
35281
35266
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", tmp);
|
|
35282
35267
|
}
|
|
35283
|
-
(0,
|
|
35268
|
+
(0, import_node_fs55.closeSync)(fd);
|
|
35284
35269
|
try {
|
|
35285
|
-
if (!insideRoot(realRoot, (0,
|
|
35286
|
-
(0,
|
|
35270
|
+
if (!insideRoot(realRoot, (0, import_node_fs55.realpathSync)(dir)) || (0, import_node_fs55.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
|
|
35271
|
+
(0, import_node_fs55.renameSync)(tmp, dest);
|
|
35287
35272
|
} catch (err2) {
|
|
35288
35273
|
removeQuietly(tmp);
|
|
35289
35274
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", dest);
|
|
@@ -35297,9 +35282,9 @@ function pathHasNoLink(root, rel) {
|
|
|
35297
35282
|
}
|
|
35298
35283
|
let cur = root;
|
|
35299
35284
|
for (const part of rel.split(/[\\/]/)) {
|
|
35300
|
-
cur = cur +
|
|
35285
|
+
cur = cur + import_node_path40.sep + part;
|
|
35301
35286
|
try {
|
|
35302
|
-
if ((0,
|
|
35287
|
+
if ((0, import_node_fs55.lstatSync)(cur).isSymbolicLink()) return false;
|
|
35303
35288
|
} catch {
|
|
35304
35289
|
return true;
|
|
35305
35290
|
}
|
|
@@ -35609,20 +35594,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
|
|
|
35609
35594
|
never committed; what reaches the team is the bug report and the fix.
|
|
35610
35595
|
`;
|
|
35611
35596
|
function scaffoldProofs(root) {
|
|
35612
|
-
const proofsDir = (0,
|
|
35597
|
+
const proofsDir = (0, import_node_path41.join)(root, PROOFS_DIR);
|
|
35613
35598
|
const written = [];
|
|
35614
35599
|
const kept = [];
|
|
35615
35600
|
for (const stray of ["lakefile.lean"]) {
|
|
35616
35601
|
const rel = `${PROOFS_DIR}/${stray}`;
|
|
35617
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35602
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path41.join)(root, rel));
|
|
35618
35603
|
try {
|
|
35619
|
-
(0,
|
|
35604
|
+
(0, import_node_fs56.rmSync)((0, import_node_path41.join)(root, rel), { force: true });
|
|
35620
35605
|
} catch {
|
|
35621
35606
|
}
|
|
35622
35607
|
}
|
|
35623
35608
|
for (const f of PROOFS_TEMPLATE_FILES) {
|
|
35624
35609
|
const rel = `${PROOFS_DIR}/${f.path}`;
|
|
35625
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35610
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path41.join)(root, rel));
|
|
35626
35611
|
const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
|
|
35627
35612
|
if (current.ok && current.content === f.content) {
|
|
35628
35613
|
kept.push(rel);
|
|
@@ -35635,8 +35620,8 @@ function scaffoldProofs(root) {
|
|
|
35635
35620
|
[`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
|
|
35636
35621
|
[`${MODELS_DIR}/README.md`, MODELS_README]
|
|
35637
35622
|
]) {
|
|
35638
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35639
|
-
if (existsNoFollow((0,
|
|
35623
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path41.join)(root, rel));
|
|
35624
|
+
if (existsNoFollow((0, import_node_path41.join)(root, rel))) {
|
|
35640
35625
|
kept.push(rel);
|
|
35641
35626
|
continue;
|
|
35642
35627
|
}
|
|
@@ -35647,7 +35632,7 @@ function scaffoldProofs(root) {
|
|
|
35647
35632
|
}
|
|
35648
35633
|
function existsNoFollow(abs) {
|
|
35649
35634
|
try {
|
|
35650
|
-
(0,
|
|
35635
|
+
(0, import_node_fs56.lstatSync)(abs);
|
|
35651
35636
|
return true;
|
|
35652
35637
|
} catch {
|
|
35653
35638
|
return false;
|
|
@@ -35905,17 +35890,16 @@ function renderReport(r) {
|
|
|
35905
35890
|
|
|
35906
35891
|
// src/lib/prove/runner.ts
|
|
35907
35892
|
function verityLeanHome(env = process.env) {
|
|
35908
|
-
return env.VERITY_LEAN_HOME ?? (0,
|
|
35893
|
+
return env.VERITY_LEAN_HOME ?? (0, import_node_path42.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
|
|
35909
35894
|
}
|
|
35910
35895
|
function findToolchain(env = process.env) {
|
|
35911
|
-
const managedBin = (0,
|
|
35912
|
-
const elanBin = (0,
|
|
35913
|
-
const
|
|
35914
|
-
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)));
|
|
35915
|
-
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path43.delimiter);
|
|
35896
|
+
const managedBin = (0, import_node_path42.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
|
|
35897
|
+
const elanBin = (0, import_node_path42.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
|
|
35898
|
+
const path = [managedBin, elanBin, env.PATH ?? ""].filter(Boolean).join(import_node_path42.delimiter);
|
|
35916
35899
|
const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
|
|
35900
|
+
const elanHas = (0, import_node_fs57.existsSync)((0, import_node_path42.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
|
|
35917
35901
|
const exe = process.platform === "win32" ? "lake.exe" : "lake";
|
|
35918
|
-
const candidates2 = [(0,
|
|
35902
|
+
const candidates2 = [(0, import_node_path42.join)(managedBin, exe), ...elanHas ? [(0, import_node_path42.join)(elanBin, exe)] : [], exe];
|
|
35919
35903
|
for (const candidate of candidates2) {
|
|
35920
35904
|
try {
|
|
35921
35905
|
(0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
|
|
@@ -35990,80 +35974,53 @@ function runAsync(tc, cwd, args2, timeoutMs) {
|
|
|
35990
35974
|
}
|
|
35991
35975
|
var DEFAULT_BUILD_TIMEOUT_MS = 10 * 6e4;
|
|
35992
35976
|
var DEFAULT_CHECK_TIMEOUT_MS = 12e4;
|
|
35993
|
-
function proofsWorkspaceProblem(root) {
|
|
35994
|
-
for (const rel of [".verity", PROOFS_DIR, `${PROOFS_DIR}/.lake`]) {
|
|
35995
|
-
let st;
|
|
35996
|
-
try {
|
|
35997
|
-
st = (0, import_node_fs58.lstatSync)((0, import_node_path43.join)(root, rel));
|
|
35998
|
-
} catch {
|
|
35999
|
-
break;
|
|
36000
|
-
}
|
|
36001
|
-
if (st.isSymbolicLink()) return `${rel} is a symlink; Lean is not run through it`;
|
|
36002
|
-
}
|
|
36003
|
-
const r = runGitSync(root, ["ls-files", "-z", "--", PROOFS_DIR], { timeoutMs: 5e3 });
|
|
36004
|
-
if (!r.ok) return `could not confirm with git that ${PROOFS_DIR} holds no committed files; Lean is not run`;
|
|
36005
|
-
const tracked = r.stdout.split("\0").filter(Boolean);
|
|
36006
|
-
if (tracked.length > 0) {
|
|
36007
|
-
return `${tracked.length} file(s) under ${PROOFS_DIR} are tracked in git (e.g. ${tracked[0]}); Lean is not run on a workspace the repository supplies \u2014 untrack them with: git rm -r --cached ${PROOFS_DIR}`;
|
|
36008
|
-
}
|
|
36009
|
-
return null;
|
|
36010
|
-
}
|
|
36011
|
-
function refused(problem) {
|
|
36012
|
-
return { ok: false, stdout: "", stderr: problem, durationMs: 0, timedOut: false };
|
|
36013
|
-
}
|
|
36014
35977
|
function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
36015
|
-
|
|
36016
|
-
if (problem) return refused(problem);
|
|
36017
|
-
return run2(tc, (0, import_node_path43.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
35978
|
+
return run2(tc, (0, import_node_path42.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36018
35979
|
}
|
|
36019
|
-
|
|
36020
|
-
|
|
36021
|
-
if (problem) return refused(problem);
|
|
36022
|
-
return runAsync(tc, (0, import_node_path43.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
35980
|
+
function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
35981
|
+
return runAsync(tc, (0, import_node_path42.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36023
35982
|
}
|
|
36024
35983
|
function isModelInRoot(modelsAbs, rel) {
|
|
36025
|
-
if (!rel.endsWith(".lean") || (0,
|
|
35984
|
+
if (!rel.endsWith(".lean") || (0, import_node_path42.isAbsolute)(rel) || rel.startsWith("..")) return false;
|
|
36026
35985
|
return statRegularInRoot(modelsAbs, rel).ok;
|
|
36027
35986
|
}
|
|
36028
35987
|
function resolveModelFile(root, arg) {
|
|
36029
|
-
const modelsAbs = (0,
|
|
36030
|
-
const asPath = (0,
|
|
35988
|
+
const modelsAbs = (0, import_node_path42.join)(root, MODELS_DIR);
|
|
35989
|
+
const asPath = (0, import_node_path42.relative)(modelsAbs, (0, import_node_path42.isAbsolute)(arg) ? arg : (0, import_node_path42.resolve)(root, arg));
|
|
36031
35990
|
const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
|
|
36032
35991
|
for (const rel of candidates2) {
|
|
36033
|
-
if (isModelInRoot(modelsAbs, rel)) return (0,
|
|
35992
|
+
if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path42.join)(modelsAbs, rel);
|
|
36034
35993
|
}
|
|
36035
35994
|
return null;
|
|
36036
35995
|
}
|
|
36037
35996
|
function listModelFiles(root) {
|
|
36038
|
-
const modelsAbs = (0,
|
|
36039
|
-
if (!(0,
|
|
36040
|
-
return (0,
|
|
35997
|
+
const modelsAbs = (0, import_node_path42.join)(root, MODELS_DIR);
|
|
35998
|
+
if (!(0, import_node_fs57.existsSync)(modelsAbs)) return [];
|
|
35999
|
+
return (0, import_node_fs57.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path42.join)(modelsAbs, f));
|
|
36041
36000
|
}
|
|
36042
36001
|
function trimDiagnostics(text) {
|
|
36043
36002
|
return text.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
|
|
36044
36003
|
}
|
|
36045
36004
|
function checkModel(tc, root, modelFile, opts = {}) {
|
|
36046
|
-
const proofsAbs = (0,
|
|
36047
|
-
const rel = (0,
|
|
36048
|
-
const
|
|
36049
|
-
const res = problem ? refused(problem) : run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36005
|
+
const proofsAbs = (0, import_node_path42.join)(root, PROOFS_DIR);
|
|
36006
|
+
const rel = (0, import_node_path42.relative)(proofsAbs, modelFile);
|
|
36007
|
+
const res = run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36050
36008
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36051
36009
|
}
|
|
36052
36010
|
async function checkModelAsync(tc, root, modelFile, opts = {}) {
|
|
36053
|
-
const proofsAbs = (0,
|
|
36054
|
-
const rel = (0,
|
|
36055
|
-
const
|
|
36056
|
-
const res = problem ? refused(problem) : await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36011
|
+
const proofsAbs = (0, import_node_path42.join)(root, PROOFS_DIR);
|
|
36012
|
+
const rel = (0, import_node_path42.relative)(proofsAbs, modelFile);
|
|
36013
|
+
const res = await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36057
36014
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36058
36015
|
}
|
|
36059
36016
|
function toReport(res, root, modelFile, timeoutMs) {
|
|
36060
36017
|
const parsed = parseVerityLines(res.stdout);
|
|
36061
36018
|
const combined = `${res.stdout}
|
|
36062
36019
|
${res.stderr}`;
|
|
36063
|
-
const name2 = parsed.header?.model ?? (0,
|
|
36020
|
+
const name2 = parsed.header?.model ?? (0, import_node_path42.basename)(modelFile, ".lean");
|
|
36064
36021
|
const report = {
|
|
36065
36022
|
model: name2,
|
|
36066
|
-
file: (0,
|
|
36023
|
+
file: (0, import_node_path42.relative)(root, modelFile),
|
|
36067
36024
|
ok: res.ok,
|
|
36068
36025
|
header: parsed.header,
|
|
36069
36026
|
properties: parsed.properties,
|
|
@@ -36317,28 +36274,20 @@ function isEligible(s, largePush) {
|
|
|
36317
36274
|
function intersects(a, ranges) {
|
|
36318
36275
|
return ranges.some((b) => a.from <= b.to && b.from <= a.to);
|
|
36319
36276
|
}
|
|
36320
|
-
function isLocalState(root, rel) {
|
|
36321
|
-
return repoControlled(root, rel) === null;
|
|
36322
|
-
}
|
|
36323
|
-
function nonNegative(v) {
|
|
36324
|
-
return typeof v === "number" && Number.isFinite(v) && v > 0 ? v : 0;
|
|
36325
|
-
}
|
|
36326
36277
|
function readLedger(root) {
|
|
36327
36278
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
36328
36279
|
const empty = { day: today, models: 0, costUsd: 0 };
|
|
36329
|
-
if (!isLocalState(root, AUTO_LEDGER)) return empty;
|
|
36330
36280
|
const read2 = readRegularFileInRoot(root, AUTO_LEDGER, 4096);
|
|
36331
36281
|
if (!read2.ok) return empty;
|
|
36332
36282
|
try {
|
|
36333
36283
|
const o = JSON.parse(read2.content);
|
|
36334
36284
|
if (o.day !== today || typeof o.models !== "number") return empty;
|
|
36335
|
-
return { day: today, models:
|
|
36285
|
+
return { day: today, models: o.models, costUsd: typeof o.costUsd === "number" && Number.isFinite(o.costUsd) ? o.costUsd : 0 };
|
|
36336
36286
|
} catch {
|
|
36337
36287
|
return empty;
|
|
36338
36288
|
}
|
|
36339
36289
|
}
|
|
36340
36290
|
function writeLedger(root, l) {
|
|
36341
|
-
if (!isLocalState(root, AUTO_LEDGER)) return;
|
|
36342
36291
|
try {
|
|
36343
36292
|
writeFileInRootNoFollow(root, AUTO_LEDGER, JSON.stringify(l) + "\n");
|
|
36344
36293
|
} catch {
|
|
@@ -36351,7 +36300,6 @@ function addLedgerCost(root, usd) {
|
|
|
36351
36300
|
}
|
|
36352
36301
|
var FINDINGS_FILE = `${PROOFS_DIR}/.results/.findings.json`;
|
|
36353
36302
|
function readPersistedFindings(root) {
|
|
36354
|
-
if (!isLocalState(root, FINDINGS_FILE)) return [];
|
|
36355
36303
|
const read2 = readRegularFileInRoot(root, FINDINGS_FILE, 256 * 1024);
|
|
36356
36304
|
if (!read2.ok) return [];
|
|
36357
36305
|
try {
|
|
@@ -36375,7 +36323,6 @@ function waiveFormalFindings(root, file, reason) {
|
|
|
36375
36323
|
return n;
|
|
36376
36324
|
}
|
|
36377
36325
|
function writePersistedFindings(root, findings) {
|
|
36378
|
-
if (!isLocalState(root, FINDINGS_FILE)) return;
|
|
36379
36326
|
try {
|
|
36380
36327
|
writeFileInRootNoFollow(root, FINDINGS_FILE, JSON.stringify({ findings: findings.slice(0, 50) }, null, 2) + "\n");
|
|
36381
36328
|
} catch {
|
|
@@ -36650,7 +36597,7 @@ async function runFormalPhase(input) {
|
|
|
36650
36597
|
modelName = gen.name;
|
|
36651
36598
|
const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
|
|
36652
36599
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
36653
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
36600
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path43.join)(root, rel);
|
|
36654
36601
|
progress.model = { name: gen.name, file: rel, rounds: round };
|
|
36655
36602
|
progress.step = "check";
|
|
36656
36603
|
report = await deps.check(root, abs);
|
|
@@ -36772,7 +36719,7 @@ async function runFormalPhase(input) {
|
|
|
36772
36719
|
return done({
|
|
36773
36720
|
status: "checked",
|
|
36774
36721
|
target,
|
|
36775
|
-
model: { name: modelName, file: (0,
|
|
36722
|
+
model: { name: modelName, file: (0, import_node_path43.relative)(root, (0, import_node_path43.join)(root, modelFile)), rounds },
|
|
36776
36723
|
properties: report.properties,
|
|
36777
36724
|
findings
|
|
36778
36725
|
});
|
|
@@ -36835,7 +36782,7 @@ async function generateAndCheck(root, req, opts) {
|
|
|
36835
36782
|
}
|
|
36836
36783
|
const rel = `${dir}/${gen.name}.lean`;
|
|
36837
36784
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
36838
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
36785
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path43.join)(root, rel);
|
|
36839
36786
|
const report = await opts.deps.check(root, abs);
|
|
36840
36787
|
const abstracts = report.header?.abstracts ?? [];
|
|
36841
36788
|
const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
|
|
@@ -36873,8 +36820,6 @@ async function prepareFormalPhase(root, env = process.env, auth2, readSource, co
|
|
|
36873
36820
|
const apiKey = direct ? env.OPENAI_API_KEY : void 0;
|
|
36874
36821
|
const toolchain = findToolchain(env);
|
|
36875
36822
|
if (!toolchain) return { ok: false, skip: "no-toolchain" };
|
|
36876
|
-
const untrusted = proofsWorkspaceProblem(root);
|
|
36877
|
-
if (untrusted) return { ok: false, skip: "workspace-untrusted", detail: untrusted.slice(0, 200) };
|
|
36878
36823
|
try {
|
|
36879
36824
|
scaffoldProofs(root);
|
|
36880
36825
|
} catch (err2) {
|
|
@@ -36964,7 +36909,7 @@ var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
|
|
|
36964
36909
|
var WRITERS_BUDGET_MS = 1500;
|
|
36965
36910
|
var EXCERPT_MAX_LINES2 = 30;
|
|
36966
36911
|
var GUARD_BLOCK_CAP = 2;
|
|
36967
|
-
var GUARD_ITER_FILE = (0,
|
|
36912
|
+
var GUARD_ITER_FILE = (0, import_node_path44.join)(VERITY_DIR, ".guard-iteration");
|
|
36968
36913
|
function readPreToolUseStdin() {
|
|
36969
36914
|
const empty = { command: "", cwd: null, sessionId: null };
|
|
36970
36915
|
return new Promise((resolve8) => {
|
|
@@ -37009,7 +36954,7 @@ function readPreToolUseStdin() {
|
|
|
37009
36954
|
}
|
|
37010
36955
|
function readIterMap() {
|
|
37011
36956
|
try {
|
|
37012
|
-
const raw = JSON.parse((0,
|
|
36957
|
+
const raw = JSON.parse((0, import_node_fs58.readFileSync)(GUARD_ITER_FILE, "utf-8"));
|
|
37013
36958
|
if (raw && typeof raw === "object") {
|
|
37014
36959
|
if (typeof raw.moment === "string" && typeof raw.count === "number") {
|
|
37015
36960
|
return { [raw.moment]: raw.count };
|
|
@@ -37029,10 +36974,10 @@ function readIter(moment) {
|
|
|
37029
36974
|
}
|
|
37030
36975
|
function writeIter(moment, count) {
|
|
37031
36976
|
try {
|
|
37032
|
-
(0,
|
|
36977
|
+
(0, import_node_fs58.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
37033
36978
|
const map = readIterMap();
|
|
37034
36979
|
map[moment] = count;
|
|
37035
|
-
(0,
|
|
36980
|
+
(0, import_node_fs58.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
37036
36981
|
} catch {
|
|
37037
36982
|
}
|
|
37038
36983
|
}
|
|
@@ -37042,10 +36987,10 @@ function resetIter(moment) {
|
|
|
37042
36987
|
if (!(moment in map)) return;
|
|
37043
36988
|
delete map[moment];
|
|
37044
36989
|
if (Object.keys(map).length === 0) {
|
|
37045
|
-
if ((0,
|
|
36990
|
+
if ((0, import_node_fs58.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs58.unlinkSync)(GUARD_ITER_FILE);
|
|
37046
36991
|
} else {
|
|
37047
|
-
(0,
|
|
37048
|
-
(0,
|
|
36992
|
+
(0, import_node_fs58.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
36993
|
+
(0, import_node_fs58.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
37049
36994
|
}
|
|
37050
36995
|
} catch {
|
|
37051
36996
|
}
|
|
@@ -37115,7 +37060,7 @@ function hasBlockingFinding(response, sentFiles) {
|
|
|
37115
37060
|
function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
|
|
37116
37061
|
const analyzable = filterAnalyzable(files);
|
|
37117
37062
|
const securityFiles = filterSecurity(files);
|
|
37118
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0,
|
|
37063
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs58.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
|
|
37119
37064
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
37120
37065
|
const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
|
|
37121
37066
|
const requestBody = {
|
|
@@ -37735,7 +37680,7 @@ function registerIgnoreCommand(program2) {
|
|
|
37735
37680
|
|
|
37736
37681
|
// src/commands/waive.ts
|
|
37737
37682
|
var import_node_crypto19 = require("node:crypto");
|
|
37738
|
-
var
|
|
37683
|
+
var import_node_fs59 = require("node:fs");
|
|
37739
37684
|
function registerWaiveCommand(program2) {
|
|
37740
37685
|
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) => {
|
|
37741
37686
|
const globals = program2.opts();
|
|
@@ -37764,7 +37709,7 @@ function registerWaiveCommand(program2) {
|
|
|
37764
37709
|
if (opts.file) {
|
|
37765
37710
|
body2.file = opts.file;
|
|
37766
37711
|
try {
|
|
37767
|
-
body2.file_sha256 = (0, import_node_crypto19.createHash)("sha256").update((0,
|
|
37712
|
+
body2.file_sha256 = (0, import_node_crypto19.createHash)("sha256").update((0, import_node_fs59.readFileSync)(opts.file)).digest("hex");
|
|
37768
37713
|
} catch {
|
|
37769
37714
|
printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
|
|
37770
37715
|
process.exit(1);
|
|
@@ -37789,10 +37734,10 @@ function registerWaiveCommand(program2) {
|
|
|
37789
37734
|
}
|
|
37790
37735
|
|
|
37791
37736
|
// src/commands/init.ts
|
|
37792
|
-
var
|
|
37737
|
+
var import_node_fs64 = require("node:fs");
|
|
37793
37738
|
var import_promises20 = require("node:fs/promises");
|
|
37794
37739
|
var import_yaml6 = __toESM2(require_dist());
|
|
37795
|
-
var
|
|
37740
|
+
var import_node_path48 = require("node:path");
|
|
37796
37741
|
var import_node_child_process19 = require("node:child_process");
|
|
37797
37742
|
|
|
37798
37743
|
// src/lib/banner.ts
|
|
@@ -37871,7 +37816,7 @@ function printPhase(n, of, title, subtitle) {
|
|
|
37871
37816
|
}
|
|
37872
37817
|
|
|
37873
37818
|
// src/commands/doctor.ts
|
|
37874
|
-
var
|
|
37819
|
+
var import_node_fs60 = require("node:fs");
|
|
37875
37820
|
|
|
37876
37821
|
// src/lib/prereqs.ts
|
|
37877
37822
|
var import_node_child_process16 = require("node:child_process");
|
|
@@ -38079,11 +38024,11 @@ async function buildReport() {
|
|
|
38079
38024
|
const hooks = wiring.status;
|
|
38080
38025
|
const provenance = cliProvenance();
|
|
38081
38026
|
const telemetry = await checkTelemetry();
|
|
38082
|
-
const hasConfig = (0,
|
|
38027
|
+
const hasConfig = (0, import_node_fs60.existsSync)(projectPath(CODACY_CONFIG_FILE));
|
|
38083
38028
|
const artifacts = {
|
|
38084
|
-
standard: (0,
|
|
38029
|
+
standard: (0, import_node_fs60.existsSync)(projectPath(STANDARD_FILE)),
|
|
38085
38030
|
analysisConfig: hasConfig,
|
|
38086
|
-
verityMd: (0,
|
|
38031
|
+
verityMd: (0, import_node_fs60.existsSync)(projectPath(VERITY_MD_FILE)),
|
|
38087
38032
|
analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
|
|
38088
38033
|
};
|
|
38089
38034
|
const next = [];
|
|
@@ -38242,8 +38187,8 @@ function registerDoctorCommand(program2) {
|
|
|
38242
38187
|
}
|
|
38243
38188
|
|
|
38244
38189
|
// src/commands/migrate.ts
|
|
38245
|
-
var
|
|
38246
|
-
var
|
|
38190
|
+
var import_node_fs61 = require("node:fs");
|
|
38191
|
+
var import_node_path45 = require("node:path");
|
|
38247
38192
|
var import_node_child_process17 = require("node:child_process");
|
|
38248
38193
|
var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
|
|
38249
38194
|
function defaultNpmRemover(pkg) {
|
|
@@ -38280,12 +38225,12 @@ async function runMigration(opts = {}) {
|
|
|
38280
38225
|
return { actions, migrated: actions.length > 0 };
|
|
38281
38226
|
}
|
|
38282
38227
|
function migrateProjectDir(root, actions) {
|
|
38283
|
-
const gateDir = (0,
|
|
38284
|
-
const verityDir = (0,
|
|
38285
|
-
if ((0,
|
|
38228
|
+
const gateDir = (0, import_node_path45.join)(root, ".gate");
|
|
38229
|
+
const verityDir = (0, import_node_path45.join)(root, ".verity");
|
|
38230
|
+
if ((0, import_node_fs61.existsSync)(gateDir) && !(0, import_node_fs61.existsSync)(verityDir)) {
|
|
38286
38231
|
return migrateProjectDirRename(root, gateDir, verityDir, actions);
|
|
38287
38232
|
}
|
|
38288
|
-
if ((0,
|
|
38233
|
+
if ((0, import_node_fs61.existsSync)(gateDir) && (0, import_node_fs61.existsSync)(verityDir)) {
|
|
38289
38234
|
return migrateProjectDirCarry(gateDir, verityDir, actions);
|
|
38290
38235
|
}
|
|
38291
38236
|
return false;
|
|
@@ -38306,13 +38251,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
|
|
|
38306
38251
|
}
|
|
38307
38252
|
}
|
|
38308
38253
|
if (moved) {
|
|
38309
|
-
if ((0,
|
|
38254
|
+
if ((0, import_node_fs61.existsSync)(gateDir)) {
|
|
38310
38255
|
const carried = carryLegacyContents(gateDir, verityDir);
|
|
38311
38256
|
if (carried > 0) {
|
|
38312
38257
|
actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
|
|
38313
38258
|
}
|
|
38314
38259
|
try {
|
|
38315
|
-
(0,
|
|
38260
|
+
(0, import_node_fs61.rmSync)(gateDir, { recursive: true, force: true });
|
|
38316
38261
|
} catch {
|
|
38317
38262
|
}
|
|
38318
38263
|
}
|
|
@@ -38328,18 +38273,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
|
|
|
38328
38273
|
actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
|
|
38329
38274
|
}
|
|
38330
38275
|
try {
|
|
38331
|
-
(0,
|
|
38276
|
+
(0, import_node_fs61.rmSync)(gateDir, { recursive: true, force: true });
|
|
38332
38277
|
} catch {
|
|
38333
38278
|
}
|
|
38334
38279
|
return carried > 0;
|
|
38335
38280
|
}
|
|
38336
38281
|
function migrateGlobalCredentials(home, actions) {
|
|
38337
38282
|
if (!home) return;
|
|
38338
|
-
const gateCreds = (0,
|
|
38339
|
-
const verityCreds = (0,
|
|
38340
|
-
if (!(0,
|
|
38341
|
-
if (!(0,
|
|
38342
|
-
(0,
|
|
38283
|
+
const gateCreds = (0, import_node_path45.join)(home, ".gate", "credentials");
|
|
38284
|
+
const verityCreds = (0, import_node_path45.join)(home, ".verity", "credentials");
|
|
38285
|
+
if (!(0, import_node_fs61.existsSync)(gateCreds)) return;
|
|
38286
|
+
if (!(0, import_node_fs61.existsSync)(verityCreds)) {
|
|
38287
|
+
(0, import_node_fs61.mkdirSync)((0, import_node_path45.join)(home, ".verity"), { recursive: true });
|
|
38343
38288
|
moveFile(gateCreds, verityCreds);
|
|
38344
38289
|
actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
|
|
38345
38290
|
return;
|
|
@@ -38361,8 +38306,8 @@ async function migrateLegacyHooks(root, actions) {
|
|
|
38361
38306
|
}
|
|
38362
38307
|
}
|
|
38363
38308
|
async function migrateClaudeMd(root, actions) {
|
|
38364
|
-
const claudeMd = (0,
|
|
38365
|
-
const hadLegacyBlock = (0,
|
|
38309
|
+
const claudeMd = (0, import_node_path45.join)(root, "CLAUDE.md");
|
|
38310
|
+
const hadLegacyBlock = (0, import_node_fs61.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
|
|
38366
38311
|
if (!hadLegacyBlock) return;
|
|
38367
38312
|
try {
|
|
38368
38313
|
await ensureClaudeMdPointer(root);
|
|
@@ -38372,9 +38317,9 @@ async function migrateClaudeMd(root, actions) {
|
|
|
38372
38317
|
}
|
|
38373
38318
|
}
|
|
38374
38319
|
function migrateStandardFile(root, actions) {
|
|
38375
|
-
const gateMd = (0,
|
|
38376
|
-
const verityMd = (0,
|
|
38377
|
-
if (!(0,
|
|
38320
|
+
const gateMd = (0, import_node_path45.join)(root, "GATE.md");
|
|
38321
|
+
const verityMd = (0, import_node_path45.join)(root, "VERITY.md");
|
|
38322
|
+
if (!(0, import_node_fs61.existsSync)(gateMd) || (0, import_node_fs61.existsSync)(verityMd)) return;
|
|
38378
38323
|
let moved = false;
|
|
38379
38324
|
if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
|
|
38380
38325
|
try {
|
|
@@ -38386,12 +38331,12 @@ function migrateStandardFile(root, actions) {
|
|
|
38386
38331
|
if (!moved) moveFile(gateMd, verityMd);
|
|
38387
38332
|
const content = readFileSyncSafe(verityMd);
|
|
38388
38333
|
const refreshed = content.split("GATE.md").join("VERITY.md");
|
|
38389
|
-
if (refreshed !== content) (0,
|
|
38334
|
+
if (refreshed !== content) (0, import_node_fs61.writeFileSync)(verityMd, refreshed);
|
|
38390
38335
|
actions.push("Renamed GATE.md \u2192 VERITY.md");
|
|
38391
38336
|
}
|
|
38392
38337
|
async function migrateTelemetryHeaders(root, actions) {
|
|
38393
|
-
const file = (0,
|
|
38394
|
-
if (!(0,
|
|
38338
|
+
const file = (0, import_node_path45.join)(root, ".claude", "settings.local.json");
|
|
38339
|
+
if (!(0, import_node_fs61.existsSync)(file)) return;
|
|
38395
38340
|
let settings;
|
|
38396
38341
|
try {
|
|
38397
38342
|
settings = JSON.parse(readFileSyncSafe(file) || "{}");
|
|
@@ -38439,14 +38384,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
|
|
|
38439
38384
|
}
|
|
38440
38385
|
if (toAppend.length > 0) {
|
|
38441
38386
|
const sep5 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
|
|
38442
|
-
(0,
|
|
38387
|
+
(0, import_node_fs61.writeFileSync)(verityCreds, verityContent + sep5 + toAppend.join("\n") + "\n");
|
|
38443
38388
|
}
|
|
38444
|
-
(0,
|
|
38389
|
+
(0, import_node_fs61.rmSync)(gateCreds, { force: true });
|
|
38445
38390
|
return toAppend.length;
|
|
38446
38391
|
}
|
|
38447
38392
|
function readFileSyncSafe(path) {
|
|
38448
38393
|
try {
|
|
38449
|
-
return (0,
|
|
38394
|
+
return (0, import_node_fs61.readFileSync)(path, "utf-8");
|
|
38450
38395
|
} catch {
|
|
38451
38396
|
return "";
|
|
38452
38397
|
}
|
|
@@ -38461,35 +38406,35 @@ function hasStagedChanges(root) {
|
|
|
38461
38406
|
}
|
|
38462
38407
|
function moveDir(from, to) {
|
|
38463
38408
|
try {
|
|
38464
|
-
(0,
|
|
38409
|
+
(0, import_node_fs61.renameSync)(from, to);
|
|
38465
38410
|
} catch (err2) {
|
|
38466
38411
|
if (err2.code !== "EXDEV") throw err2;
|
|
38467
|
-
(0,
|
|
38468
|
-
(0,
|
|
38412
|
+
(0, import_node_fs61.cpSync)(from, to, { recursive: true });
|
|
38413
|
+
(0, import_node_fs61.rmSync)(from, { recursive: true, force: true });
|
|
38469
38414
|
}
|
|
38470
38415
|
}
|
|
38471
38416
|
function moveFile(from, to) {
|
|
38472
38417
|
try {
|
|
38473
|
-
(0,
|
|
38418
|
+
(0, import_node_fs61.renameSync)(from, to);
|
|
38474
38419
|
} catch (err2) {
|
|
38475
38420
|
if (err2.code !== "EXDEV") throw err2;
|
|
38476
|
-
(0,
|
|
38477
|
-
(0,
|
|
38421
|
+
(0, import_node_fs61.cpSync)(from, to);
|
|
38422
|
+
(0, import_node_fs61.rmSync)(from, { force: true });
|
|
38478
38423
|
}
|
|
38479
38424
|
}
|
|
38480
38425
|
function carryLegacyContents(gateDir, verityDir) {
|
|
38481
38426
|
let copied = 0;
|
|
38482
38427
|
const walk2 = (relDir) => {
|
|
38483
|
-
const srcDir = (0,
|
|
38484
|
-
for (const entry of (0,
|
|
38485
|
-
const rel = relDir ? (0,
|
|
38486
|
-
const src = (0,
|
|
38487
|
-
const dest = (0,
|
|
38488
|
-
if ((0,
|
|
38428
|
+
const srcDir = (0, import_node_path45.join)(gateDir, relDir);
|
|
38429
|
+
for (const entry of (0, import_node_fs61.readdirSync)(srcDir)) {
|
|
38430
|
+
const rel = relDir ? (0, import_node_path45.join)(relDir, entry) : entry;
|
|
38431
|
+
const src = (0, import_node_path45.join)(gateDir, rel);
|
|
38432
|
+
const dest = (0, import_node_path45.join)(verityDir, rel);
|
|
38433
|
+
if ((0, import_node_fs61.statSync)(src).isDirectory()) {
|
|
38489
38434
|
walk2(rel);
|
|
38490
|
-
} else if (!(0,
|
|
38491
|
-
(0,
|
|
38492
|
-
(0,
|
|
38435
|
+
} else if (!(0, import_node_fs61.existsSync)(dest)) {
|
|
38436
|
+
(0, import_node_fs61.mkdirSync)((0, import_node_path45.dirname)(dest), { recursive: true });
|
|
38437
|
+
(0, import_node_fs61.cpSync)(src, dest);
|
|
38493
38438
|
copied++;
|
|
38494
38439
|
}
|
|
38495
38440
|
}
|
|
@@ -38498,22 +38443,22 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
38498
38443
|
return copied;
|
|
38499
38444
|
}
|
|
38500
38445
|
async function needsMigration(root = repoRoot()) {
|
|
38501
|
-
const gateDir = (0,
|
|
38502
|
-
const verityDir = (0,
|
|
38503
|
-
if ((0,
|
|
38504
|
-
if ((0,
|
|
38505
|
-
if ((0,
|
|
38446
|
+
const gateDir = (0, import_node_path45.join)(root, ".gate");
|
|
38447
|
+
const verityDir = (0, import_node_path45.join)(root, ".verity");
|
|
38448
|
+
if ((0, import_node_fs61.existsSync)(gateDir) && !(0, import_node_fs61.existsSync)(verityDir)) return true;
|
|
38449
|
+
if ((0, import_node_fs61.existsSync)(gateDir) && (0, import_node_fs61.existsSync)(verityDir)) {
|
|
38450
|
+
if ((0, import_node_fs61.existsSync)((0, import_node_path45.join)(gateDir, "credentials")) && !(0, import_node_fs61.existsSync)((0, import_node_path45.join)(verityDir, "credentials"))) {
|
|
38506
38451
|
return true;
|
|
38507
38452
|
}
|
|
38508
|
-
if ((0,
|
|
38453
|
+
if ((0, import_node_fs61.existsSync)((0, import_node_path45.join)(gateDir, "memory")) && !(0, import_node_fs61.existsSync)((0, import_node_path45.join)(verityDir, "memory"))) {
|
|
38509
38454
|
return true;
|
|
38510
38455
|
}
|
|
38511
38456
|
}
|
|
38512
|
-
const claudeMd = (0,
|
|
38513
|
-
if ((0,
|
|
38457
|
+
const claudeMd = (0, import_node_path45.join)(root, "CLAUDE.md");
|
|
38458
|
+
if ((0, import_node_fs61.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
|
|
38514
38459
|
return true;
|
|
38515
38460
|
}
|
|
38516
|
-
if ((0,
|
|
38461
|
+
if ((0, import_node_fs61.existsSync)((0, import_node_path45.join)(root, "GATE.md")) && !(0, import_node_fs61.existsSync)((0, import_node_path45.join)(root, "VERITY.md"))) {
|
|
38517
38462
|
return true;
|
|
38518
38463
|
}
|
|
38519
38464
|
if (await hasLegacyHooksAt(root)) return true;
|
|
@@ -38794,31 +38739,15 @@ async function promptMultiSelect(question, choices, fallback) {
|
|
|
38794
38739
|
}
|
|
38795
38740
|
|
|
38796
38741
|
// src/lib/prove/lean-install.ts
|
|
38797
|
-
var
|
|
38742
|
+
var import_node_fs62 = require("node:fs");
|
|
38798
38743
|
var import_node_crypto20 = require("node:crypto");
|
|
38799
38744
|
var import_node_child_process18 = require("node:child_process");
|
|
38800
38745
|
var import_node_os10 = require("node:os");
|
|
38801
|
-
var
|
|
38746
|
+
var import_node_path46 = require("node:path");
|
|
38802
38747
|
var import_promises18 = require("node:stream/promises");
|
|
38803
38748
|
var import_node_stream = require("node:stream");
|
|
38804
38749
|
var RELEASES = "https://releases.lean-lang.org/lean4";
|
|
38805
38750
|
var LEAN_DOWNLOAD_SIZE = "\u2248800 MB download, 2.7 GB on disk";
|
|
38806
|
-
var DOWNLOAD_STALL_MS = 6e4;
|
|
38807
|
-
var LEAN_DISK_NEEDED_BYTES = 3.75 * 1024 ** 3;
|
|
38808
|
-
function freeBytes(dir) {
|
|
38809
|
-
let d = dir;
|
|
38810
|
-
for (let i2 = 0; i2 < 64; i2++) {
|
|
38811
|
-
try {
|
|
38812
|
-
const st = (0, import_node_fs63.statfsSync)(d);
|
|
38813
|
-
return Number(st.bavail) * Number(st.bsize);
|
|
38814
|
-
} catch {
|
|
38815
|
-
const up = (0, import_node_path47.join)(d, "..");
|
|
38816
|
-
if (up === d) return null;
|
|
38817
|
-
d = up;
|
|
38818
|
-
}
|
|
38819
|
-
}
|
|
38820
|
-
return null;
|
|
38821
|
-
}
|
|
38822
38751
|
var LEAN_ASSET_SHA256 = {
|
|
38823
38752
|
"v4.34.0": {
|
|
38824
38753
|
"lean-4.34.0-darwin.zip": "75a2a4b8e3d35680e8f51fae5a42c79702f463dd73ee1520fb61e5a9143e336c",
|
|
@@ -38834,7 +38763,7 @@ function expectedSha256(asset, version = pinnedVersion()) {
|
|
|
38834
38763
|
function sha256File(path) {
|
|
38835
38764
|
return new Promise((resolve8, reject) => {
|
|
38836
38765
|
const hash = (0, import_node_crypto20.createHash)("sha256");
|
|
38837
|
-
(0,
|
|
38766
|
+
(0, import_node_fs62.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve8(hash.digest("hex"))).on("error", reject);
|
|
38838
38767
|
});
|
|
38839
38768
|
}
|
|
38840
38769
|
async function verifyDownload(zip, asset, version = pinnedVersion()) {
|
|
@@ -38854,7 +38783,7 @@ function leanAssetName(version = pinnedVersion()) {
|
|
|
38854
38783
|
return suffix ? `lean-${v}-${suffix}.zip` : null;
|
|
38855
38784
|
}
|
|
38856
38785
|
function pinnedVersionDir(env = process.env) {
|
|
38857
|
-
return (0,
|
|
38786
|
+
return (0, import_node_path46.join)(verityLeanHome(env), pinnedVersion());
|
|
38858
38787
|
}
|
|
38859
38788
|
function lakeBinary() {
|
|
38860
38789
|
return (0, import_node_os10.platform)() === "win32" ? "lake.exe" : "lake";
|
|
@@ -38865,44 +38794,29 @@ function unzip(zip, dest) {
|
|
|
38865
38794
|
for (const [cmd, args2] of attempts) {
|
|
38866
38795
|
try {
|
|
38867
38796
|
(0, import_node_child_process18.execFileSync)(cmd, args2, { stdio: ["ignore", "ignore", "pipe"], timeout: 15 * 6e4 });
|
|
38868
|
-
if ((0,
|
|
38797
|
+
if ((0, import_node_fs62.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
|
|
38869
38798
|
errors.push(`${cmd}: produced nothing`);
|
|
38870
38799
|
} catch (err2) {
|
|
38871
38800
|
errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
|
|
38872
38801
|
try {
|
|
38873
|
-
for (const e of (0,
|
|
38802
|
+
for (const e of (0, import_node_fs62.readdirSync)(dest)) (0, import_node_fs62.rmSync)((0, import_node_path46.join)(dest, e), { recursive: true, force: true });
|
|
38874
38803
|
} catch {
|
|
38875
38804
|
}
|
|
38876
38805
|
}
|
|
38877
38806
|
}
|
|
38878
38807
|
return { ok: false, error: errors.join("; ") };
|
|
38879
38808
|
}
|
|
38880
|
-
async function download(url, dest, onProgress
|
|
38881
|
-
const
|
|
38882
|
-
|
|
38883
|
-
const
|
|
38884
|
-
|
|
38885
|
-
|
|
38886
|
-
|
|
38887
|
-
|
|
38888
|
-
|
|
38889
|
-
|
|
38890
|
-
|
|
38891
|
-
const total = Number(res.headers.get("content-length")) || null;
|
|
38892
|
-
let seen = 0;
|
|
38893
|
-
const stream = import_node_stream.Readable.fromWeb(res.body);
|
|
38894
|
-
stream.on("data", (chunk) => {
|
|
38895
|
-
arm();
|
|
38896
|
-
seen += chunk.length;
|
|
38897
|
-
onProgress(seen, total);
|
|
38898
|
-
});
|
|
38899
|
-
await (0, import_promises18.pipeline)(stream, (0, import_node_fs63.createWriteStream)(dest), { signal: ctrl.signal });
|
|
38900
|
-
} catch (err2) {
|
|
38901
|
-
if (ctrl.signal.aborted) throw new Error(`download stalled: nothing received for ${Math.round(stallMs / 1e3)} s`);
|
|
38902
|
-
throw err2;
|
|
38903
|
-
} finally {
|
|
38904
|
-
clearTimeout(timer);
|
|
38905
|
-
}
|
|
38809
|
+
async function download(url, dest, onProgress) {
|
|
38810
|
+
const res = await fetch(url, { redirect: "follow" });
|
|
38811
|
+
if (!res.ok || !res.body) throw new Error(`download failed: HTTP ${res.status}`);
|
|
38812
|
+
const total = Number(res.headers.get("content-length")) || null;
|
|
38813
|
+
let seen = 0;
|
|
38814
|
+
const stream = import_node_stream.Readable.fromWeb(res.body);
|
|
38815
|
+
stream.on("data", (chunk) => {
|
|
38816
|
+
seen += chunk.length;
|
|
38817
|
+
onProgress(seen, total);
|
|
38818
|
+
});
|
|
38819
|
+
await (0, import_promises18.pipeline)(stream, (0, import_node_fs62.createWriteStream)(dest));
|
|
38906
38820
|
}
|
|
38907
38821
|
function inPlaceProgress(label2, write = (s) => process.stderr.write(s)) {
|
|
38908
38822
|
let active = false;
|
|
@@ -38940,16 +38854,10 @@ async function installLean(opts = {}) {
|
|
|
38940
38854
|
const dir = pinnedVersionDir(env);
|
|
38941
38855
|
const url = `${RELEASES}/${pinnedVersion()}/${asset}`;
|
|
38942
38856
|
const home = verityLeanHome(env);
|
|
38943
|
-
const
|
|
38944
|
-
|
|
38945
|
-
|
|
38946
|
-
|
|
38947
|
-
return { ok: false, error: `not enough disk space for Lean: ${gb(free)} GB free where ${home} lives, needs about ${gb(needed)} GB` };
|
|
38948
|
-
}
|
|
38949
|
-
const tmp = (0, import_node_path47.join)(home, ".tmp");
|
|
38950
|
-
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
38951
|
-
(0, import_node_fs63.mkdirSync)(tmp, { recursive: true });
|
|
38952
|
-
const zip = (0, import_node_path47.join)(tmp, asset);
|
|
38857
|
+
const tmp = (0, import_node_path46.join)(home, ".tmp");
|
|
38858
|
+
(0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
|
|
38859
|
+
(0, import_node_fs62.mkdirSync)(tmp, { recursive: true });
|
|
38860
|
+
const zip = (0, import_node_path46.join)(tmp, asset);
|
|
38953
38861
|
say(`downloading ${url}`);
|
|
38954
38862
|
let lastPct = -1;
|
|
38955
38863
|
try {
|
|
@@ -38962,40 +38870,40 @@ async function installLean(opts = {}) {
|
|
|
38962
38870
|
}
|
|
38963
38871
|
});
|
|
38964
38872
|
} catch (err2) {
|
|
38965
|
-
(0,
|
|
38873
|
+
(0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
|
|
38966
38874
|
return { ok: false, error: err2.message };
|
|
38967
38875
|
}
|
|
38968
38876
|
say("verifying checksum");
|
|
38969
38877
|
const verified = await verifyDownload(zip, asset);
|
|
38970
38878
|
if (!verified.ok) {
|
|
38971
|
-
(0,
|
|
38879
|
+
(0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
|
|
38972
38880
|
return { ok: false, error: verified.error };
|
|
38973
38881
|
}
|
|
38974
38882
|
say("unpacking (this takes a minute)");
|
|
38975
|
-
const unpack = (0,
|
|
38976
|
-
(0,
|
|
38883
|
+
const unpack = (0, import_node_path46.join)(tmp, "unpack");
|
|
38884
|
+
(0, import_node_fs62.mkdirSync)(unpack);
|
|
38977
38885
|
const unpacked = unzip(zip, unpack);
|
|
38978
38886
|
if (!unpacked.ok) {
|
|
38979
|
-
(0,
|
|
38887
|
+
(0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
|
|
38980
38888
|
return { ok: false, error: `unpack failed: ${unpacked.error}` };
|
|
38981
38889
|
}
|
|
38982
|
-
const entries = (0,
|
|
38983
|
-
const top = entries.length === 1 && (0,
|
|
38984
|
-
if (!(0,
|
|
38985
|
-
(0,
|
|
38890
|
+
const entries = (0, import_node_fs62.readdirSync)(unpack);
|
|
38891
|
+
const top = entries.length === 1 && (0, import_node_fs62.statSync)((0, import_node_path46.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path46.join)(unpack, entries[0]) : unpack;
|
|
38892
|
+
if (!(0, import_node_fs62.existsSync)((0, import_node_path46.join)(top, "bin", lakeBinary()))) {
|
|
38893
|
+
(0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
|
|
38986
38894
|
return { ok: false, error: "the archive did not contain bin/lake" };
|
|
38987
38895
|
}
|
|
38988
|
-
(0,
|
|
38989
|
-
(0,
|
|
38990
|
-
(0,
|
|
38991
|
-
(0,
|
|
38896
|
+
(0, import_node_fs62.rmSync)(dir, { recursive: true, force: true });
|
|
38897
|
+
(0, import_node_fs62.mkdirSync)(home, { recursive: true });
|
|
38898
|
+
(0, import_node_fs62.renameSync)(top, dir);
|
|
38899
|
+
(0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
|
|
38992
38900
|
return { ok: true, dir };
|
|
38993
38901
|
}
|
|
38994
38902
|
|
|
38995
38903
|
// src/lib/remote-config.ts
|
|
38996
|
-
var
|
|
38904
|
+
var import_node_fs63 = require("node:fs");
|
|
38997
38905
|
var import_promises19 = require("node:fs/promises");
|
|
38998
|
-
var
|
|
38906
|
+
var import_node_path47 = require("node:path");
|
|
38999
38907
|
var import_yaml5 = __toESM2(require_dist());
|
|
39000
38908
|
var IGNORE_RIDER = "verityignore";
|
|
39001
38909
|
async function fetchRemoteSetup(opts) {
|
|
@@ -39040,7 +38948,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
39040
38948
|
written.push(STANDARD_FILE);
|
|
39041
38949
|
if (rider !== null) {
|
|
39042
38950
|
const localIgnore = projectPath(VERITYIGNORE_FILE);
|
|
39043
|
-
if (!(0,
|
|
38951
|
+
if (!(0, import_node_fs63.existsSync)(localIgnore)) {
|
|
39044
38952
|
await writeOut(VERITYIGNORE_FILE, rider);
|
|
39045
38953
|
written.push(VERITYIGNORE_FILE);
|
|
39046
38954
|
} else {
|
|
@@ -39073,7 +38981,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
39073
38981
|
}
|
|
39074
38982
|
async function writeOut(relative6, body2) {
|
|
39075
38983
|
const target = projectPath(relative6);
|
|
39076
|
-
await (0, import_promises19.mkdir)((0,
|
|
38984
|
+
await (0, import_promises19.mkdir)((0, import_node_path47.dirname)(target), { recursive: true });
|
|
39077
38985
|
await (0, import_promises19.writeFile)(target, body2);
|
|
39078
38986
|
}
|
|
39079
38987
|
function describeRemote(found) {
|
|
@@ -39190,15 +39098,15 @@ async function runOptionalAuth(resolution, opts = {}) {
|
|
|
39190
39098
|
}
|
|
39191
39099
|
function resolveDataDir2() {
|
|
39192
39100
|
const candidates2 = [
|
|
39193
|
-
(0,
|
|
39101
|
+
(0, import_node_path48.join)(__dirname, "..", "data"),
|
|
39194
39102
|
// installed: node_modules/@codacy/verity-cli/data
|
|
39195
|
-
(0,
|
|
39103
|
+
(0, import_node_path48.join)(__dirname, "..", "..", "data"),
|
|
39196
39104
|
// edge case: nested resolution
|
|
39197
|
-
(0,
|
|
39105
|
+
(0, import_node_path48.join)(process.cwd(), "cli", "data")
|
|
39198
39106
|
// local dev: running from repo root
|
|
39199
39107
|
];
|
|
39200
39108
|
for (const candidate of candidates2) {
|
|
39201
|
-
if ((0,
|
|
39109
|
+
if ((0, import_node_fs64.existsSync)((0, import_node_path48.join)(candidate, "skills"))) {
|
|
39202
39110
|
return candidate;
|
|
39203
39111
|
}
|
|
39204
39112
|
}
|
|
@@ -39214,9 +39122,9 @@ async function skillIsCurrent(src, dest) {
|
|
|
39214
39122
|
const list2 = (dir) => {
|
|
39215
39123
|
const out2 = [];
|
|
39216
39124
|
const walk2 = (d, prefix) => {
|
|
39217
|
-
for (const e of (0,
|
|
39125
|
+
for (const e of (0, import_node_fs64.readdirSync)(d, { withFileTypes: true })) {
|
|
39218
39126
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
39219
|
-
if (e.isDirectory()) walk2((0,
|
|
39127
|
+
if (e.isDirectory()) walk2((0, import_node_path48.join)(d, e.name), rel);
|
|
39220
39128
|
else if (e.isFile()) out2.push(rel);
|
|
39221
39129
|
}
|
|
39222
39130
|
};
|
|
@@ -39227,8 +39135,8 @@ async function skillIsCurrent(src, dest) {
|
|
|
39227
39135
|
const shipped = list2(src);
|
|
39228
39136
|
if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
|
|
39229
39137
|
for (const rel of shipped) {
|
|
39230
|
-
const a = await (0, import_promises20.readFile)((0,
|
|
39231
|
-
const b = await (0, import_promises20.readFile)((0,
|
|
39138
|
+
const a = await (0, import_promises20.readFile)((0, import_node_path48.join)(src, rel), "utf-8");
|
|
39139
|
+
const b = await (0, import_promises20.readFile)((0, import_node_path48.join)(dest, rel), "utf-8");
|
|
39232
39140
|
if (a !== b) return false;
|
|
39233
39141
|
}
|
|
39234
39142
|
return true;
|
|
@@ -39254,10 +39162,8 @@ var INTENSITY_CHOICES = [
|
|
|
39254
39162
|
{ id: "thorough", label: "thorough", hint: "all tools, all rules (~15s)" }
|
|
39255
39163
|
];
|
|
39256
39164
|
var FORMAL_CHOICES = [
|
|
39257
|
-
{ id: "yes", label: "yes", hint: "a Lean model of the riskiest changed function; blocks only on a REPRODUCED counterexample" },
|
|
39258
|
-
|
|
39259
|
-
// 2.7 GB, and a bare Enter must never do that.
|
|
39260
|
-
{ id: "no", label: "no", hint: "enable later with: verity config formal push", recommended: true }
|
|
39165
|
+
{ id: "yes", label: "yes", hint: "a Lean model of the riskiest changed function; blocks only on a REPRODUCED counterexample", recommended: true },
|
|
39166
|
+
{ id: "no", label: "no", hint: "enable later with: verity config formal push" }
|
|
39261
39167
|
];
|
|
39262
39168
|
var MOMENT_CHOICES = [
|
|
39263
39169
|
{ id: "stop", label: "On stop", hint: "after every agent turn \u2014 fast feedback while you work", recommended: true },
|
|
@@ -39431,7 +39337,7 @@ async function synthesizeLocally(opts) {
|
|
|
39431
39337
|
async function healStaleAnalysisConfig(globals) {
|
|
39432
39338
|
const configPath = projectPath(CODACY_CONFIG_FILE);
|
|
39433
39339
|
const standardPath = projectPath(STANDARD_FILE);
|
|
39434
|
-
if (!(0,
|
|
39340
|
+
if (!(0, import_node_fs64.existsSync)(configPath) || !(0, import_node_fs64.existsSync)(standardPath)) return;
|
|
39435
39341
|
const validation = validatePatternIds();
|
|
39436
39342
|
if (validation.status !== "invalid") return;
|
|
39437
39343
|
printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
|
|
@@ -39528,17 +39434,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
|
|
|
39528
39434
|
async function installSkills(force, step) {
|
|
39529
39435
|
step("Installing skills");
|
|
39530
39436
|
const dataDir = resolveDataDir2();
|
|
39531
|
-
const skillsSource = (0,
|
|
39437
|
+
const skillsSource = (0, import_node_path48.join)(dataDir, "skills");
|
|
39532
39438
|
const skillsDest = ".claude/skills";
|
|
39533
39439
|
let skillsInstalled = 0;
|
|
39534
39440
|
for (const skill of SKILLS) {
|
|
39535
|
-
const src = (0,
|
|
39536
|
-
const dest = (0,
|
|
39537
|
-
if (!(0,
|
|
39441
|
+
const src = (0, import_node_path48.join)(skillsSource, skill);
|
|
39442
|
+
const dest = (0, import_node_path48.join)(skillsDest, skill);
|
|
39443
|
+
if (!(0, import_node_fs64.existsSync)(src)) {
|
|
39538
39444
|
printWarn(` Skill data not found: ${skill}`);
|
|
39539
39445
|
continue;
|
|
39540
39446
|
}
|
|
39541
|
-
if ((0,
|
|
39447
|
+
if ((0, import_node_fs64.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
|
|
39542
39448
|
skillsInstalled++;
|
|
39543
39449
|
continue;
|
|
39544
39450
|
}
|
|
@@ -39663,20 +39569,16 @@ async function offerFormalVerification(defaultsOnly, pluginMode) {
|
|
|
39663
39569
|
printWarn(` Formal verification: off \u2014 ${formalRefusalMessage(cfg.formal_refused)}`);
|
|
39664
39570
|
return;
|
|
39665
39571
|
}
|
|
39572
|
+
const toolchain = findToolchain();
|
|
39666
39573
|
if (cfg.formal === "push") {
|
|
39667
|
-
if (
|
|
39574
|
+
if (toolchain) printInfo(" Formal verification at push \u2713");
|
|
39668
39575
|
else printWarn(" Formal verification is on but Lean is missing \u2014 run: verity lean install");
|
|
39669
39576
|
return;
|
|
39670
39577
|
}
|
|
39671
|
-
if (cfg.formal === "off") {
|
|
39672
|
-
printInfo(" Formal verification: off (enable with: verity config formal push)");
|
|
39673
|
-
return;
|
|
39674
|
-
}
|
|
39675
39578
|
if (defaultsOnly || !interactive()) {
|
|
39676
39579
|
printInfo(" Formal verification (a model-based bug finder at push): off \u2014 enable with: verity config formal push");
|
|
39677
39580
|
return;
|
|
39678
39581
|
}
|
|
39679
|
-
const toolchain = findToolchain();
|
|
39680
39582
|
console.log("");
|
|
39681
39583
|
console.log(" Formal verification review \u2014 a model-based bug finder for your riskiest code.");
|
|
39682
39584
|
console.log(" At push, Verity picks the riskiest changed function, checks a small model of");
|
|
@@ -39684,10 +39586,9 @@ async function offerFormalVerification(defaultsOnly, pluginMode) {
|
|
|
39684
39586
|
console.log(" Verity for that). Only a reproduced bug can block; most pushes get no model.");
|
|
39685
39587
|
console.log(` Adds /verity-prove <worry> to check any code on demand.${toolchain ? "" : ` Needs to install Lean 4 (${LEAN_DOWNLOAD_SIZE}) on "yes".`}`);
|
|
39686
39588
|
console.log("");
|
|
39687
|
-
const wants = await promptChoice("Formal verification at push?", FORMAL_CHOICES, "
|
|
39589
|
+
const wants = await promptChoice("Formal verification at push?", FORMAL_CHOICES, "yes");
|
|
39688
39590
|
if (wants === "yes" && pluginMode) printInfo(" Plugin: the push check works now; /verity:verity-prove arrives with the plugin's next release.");
|
|
39689
39591
|
if (wants !== "yes") {
|
|
39690
|
-
writeProjectConfig({ formal: "off" });
|
|
39691
39592
|
printInfo(" Formal verification: off (enable later with: verity config formal push)");
|
|
39692
39593
|
return;
|
|
39693
39594
|
}
|
|
@@ -39738,7 +39639,7 @@ function registerInitCommand(program2) {
|
|
|
39738
39639
|
const staleMarker = clearStalePluginMarker();
|
|
39739
39640
|
const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
|
|
39740
39641
|
const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
|
|
39741
|
-
const isProject = projectMarkers.some((m) => (0,
|
|
39642
|
+
const isProject = projectMarkers.some((m) => (0, import_node_fs64.existsSync)(m));
|
|
39742
39643
|
if (!isProject) {
|
|
39743
39644
|
printError("No project detected in the current directory.");
|
|
39744
39645
|
printInfo('Run "verity init" from your project root.');
|
|
@@ -39841,7 +39742,7 @@ function registerInitCommand(program2) {
|
|
|
39841
39742
|
untrackMemory: opts.untrackMemory === true,
|
|
39842
39743
|
untrackState: opts.untrackState === true
|
|
39843
39744
|
});
|
|
39844
|
-
const globalVerityDir = (0,
|
|
39745
|
+
const globalVerityDir = (0, import_node_path48.join)(process.env.HOME ?? "", ".verity");
|
|
39845
39746
|
await (0, import_promises20.mkdir)(globalVerityDir, { recursive: true });
|
|
39846
39747
|
console.log("");
|
|
39847
39748
|
step("Wiring Claude Code hooks");
|
|
@@ -39916,7 +39817,7 @@ function registerInitCommand(program2) {
|
|
|
39916
39817
|
}
|
|
39917
39818
|
step("Your project's Standard");
|
|
39918
39819
|
let haveStandard = false;
|
|
39919
|
-
if ((0,
|
|
39820
|
+
if ((0, import_node_fs64.existsSync)(projectPath(STANDARD_FILE))) {
|
|
39920
39821
|
printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
|
|
39921
39822
|
haveStandard = true;
|
|
39922
39823
|
} else {
|
|
@@ -39946,7 +39847,7 @@ function registerInitCommand(program2) {
|
|
|
39946
39847
|
...telemetryChoice ? { telemetry: telemetryChoice } : {},
|
|
39947
39848
|
init: {
|
|
39948
39849
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
39949
|
-
cli_version: true ? "0.34.0-experimental.
|
|
39850
|
+
cli_version: true ? "0.34.0-experimental.b9e8508" : "dev"
|
|
39950
39851
|
}
|
|
39951
39852
|
});
|
|
39952
39853
|
} catch (err2) {
|
|
@@ -39996,8 +39897,8 @@ function registerInitCommand(program2) {
|
|
|
39996
39897
|
}
|
|
39997
39898
|
|
|
39998
39899
|
// src/commands/uninstall.ts
|
|
39999
|
-
var
|
|
40000
|
-
var
|
|
39900
|
+
var import_node_fs65 = require("node:fs");
|
|
39901
|
+
var import_node_path49 = require("node:path");
|
|
40001
39902
|
function registerUninstallCommand(program2) {
|
|
40002
39903
|
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) => {
|
|
40003
39904
|
const dryRun = opts.dryRun ?? false;
|
|
@@ -40006,11 +39907,11 @@ function registerUninstallCommand(program2) {
|
|
|
40006
39907
|
const actions = [];
|
|
40007
39908
|
const skillsRoot = projectPath(".claude/skills");
|
|
40008
39909
|
for (const name2 of PROJECT_SKILL_NAMES) {
|
|
40009
|
-
const dir = (0,
|
|
40010
|
-
if ((0,
|
|
39910
|
+
const dir = (0, import_node_path49.join)(skillsRoot, name2);
|
|
39911
|
+
if ((0, import_node_fs65.existsSync)(dir)) {
|
|
40011
39912
|
actions.push({
|
|
40012
39913
|
label: `Remove .claude/skills/${name2}/`,
|
|
40013
|
-
apply: () => (0,
|
|
39914
|
+
apply: () => (0, import_node_fs65.rmSync)(dir, { recursive: true, force: true })
|
|
40014
39915
|
});
|
|
40015
39916
|
}
|
|
40016
39917
|
}
|
|
@@ -40024,24 +39925,24 @@ function registerUninstallCommand(program2) {
|
|
|
40024
39925
|
});
|
|
40025
39926
|
}
|
|
40026
39927
|
const verityDir = projectPath(VERITY_DIR);
|
|
40027
|
-
if ((0,
|
|
39928
|
+
if ((0, import_node_fs65.existsSync)(verityDir)) {
|
|
40028
39929
|
actions.push({
|
|
40029
39930
|
label: `Remove ${VERITY_DIR}/`,
|
|
40030
|
-
apply: () => (0,
|
|
39931
|
+
apply: () => (0, import_node_fs65.rmSync)(verityDir, { recursive: true, force: true })
|
|
40031
39932
|
});
|
|
40032
39933
|
}
|
|
40033
39934
|
if (!keepVerityMd) {
|
|
40034
39935
|
const verityMd = projectPath(VERITY_MD_FILE);
|
|
40035
|
-
if ((0,
|
|
39936
|
+
if ((0, import_node_fs65.existsSync)(verityMd)) {
|
|
40036
39937
|
actions.push({
|
|
40037
39938
|
label: `Remove ${VERITY_MD_FILE}`,
|
|
40038
|
-
apply: () => (0,
|
|
39939
|
+
apply: () => (0, import_node_fs65.rmSync)(verityMd, { force: true })
|
|
40039
39940
|
});
|
|
40040
39941
|
}
|
|
40041
39942
|
}
|
|
40042
39943
|
const cleanupEmptyDir = (path) => {
|
|
40043
|
-
if ((0,
|
|
40044
|
-
(0,
|
|
39944
|
+
if ((0, import_node_fs65.existsSync)(path) && (0, import_node_fs65.statSync)(path).isDirectory() && (0, import_node_fs65.readdirSync)(path).length === 0) {
|
|
39945
|
+
(0, import_node_fs65.rmdirSync)(path);
|
|
40045
39946
|
}
|
|
40046
39947
|
};
|
|
40047
39948
|
actions.push({
|
|
@@ -40052,11 +39953,11 @@ function registerUninstallCommand(program2) {
|
|
|
40052
39953
|
}
|
|
40053
39954
|
});
|
|
40054
39955
|
const home = process.env.HOME ?? "";
|
|
40055
|
-
const globalVerityDir = (0,
|
|
40056
|
-
if (purgeGlobal && (0,
|
|
39956
|
+
const globalVerityDir = (0, import_node_path49.join)(home, ".verity");
|
|
39957
|
+
if (purgeGlobal && (0, import_node_fs65.existsSync)(globalVerityDir)) {
|
|
40057
39958
|
actions.push({
|
|
40058
39959
|
label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
|
|
40059
|
-
apply: () => (0,
|
|
39960
|
+
apply: () => (0, import_node_fs65.rmSync)(globalVerityDir, { recursive: true, force: true })
|
|
40060
39961
|
});
|
|
40061
39962
|
}
|
|
40062
39963
|
if (actions.length === 0) {
|
|
@@ -40250,8 +40151,8 @@ function registerTaskCommands(program2) {
|
|
|
40250
40151
|
}
|
|
40251
40152
|
|
|
40252
40153
|
// src/commands/reset.ts
|
|
40253
|
-
var
|
|
40254
|
-
var
|
|
40154
|
+
var import_node_fs66 = require("node:fs");
|
|
40155
|
+
var import_node_path50 = require("node:path");
|
|
40255
40156
|
function registerResetCommand(program2) {
|
|
40256
40157
|
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) => {
|
|
40257
40158
|
const globals = program2.opts();
|
|
@@ -40288,11 +40189,11 @@ function registerResetCommand(program2) {
|
|
|
40288
40189
|
}
|
|
40289
40190
|
const cacheDir = projectPath(CACHE_DIR);
|
|
40290
40191
|
let purged = 0;
|
|
40291
|
-
if ((0,
|
|
40292
|
-
for (const entry of (0,
|
|
40192
|
+
if ((0, import_node_fs66.existsSync)(cacheDir)) {
|
|
40193
|
+
for (const entry of (0, import_node_fs66.readdirSync)(cacheDir)) {
|
|
40293
40194
|
if (entry.startsWith("pending-")) {
|
|
40294
40195
|
try {
|
|
40295
|
-
(0,
|
|
40196
|
+
(0, import_node_fs66.unlinkSync)((0, import_node_path50.join)(cacheDir, entry));
|
|
40296
40197
|
purged++;
|
|
40297
40198
|
} catch {
|
|
40298
40199
|
}
|
|
@@ -40307,19 +40208,19 @@ function registerResetCommand(program2) {
|
|
|
40307
40208
|
projectPath(`${VERITY_DIR}/.last-analysis`)
|
|
40308
40209
|
];
|
|
40309
40210
|
for (const file of filesToClear) {
|
|
40310
|
-
if ((0,
|
|
40211
|
+
if ((0, import_node_fs66.existsSync)(file)) {
|
|
40311
40212
|
try {
|
|
40312
|
-
(0,
|
|
40213
|
+
(0, import_node_fs66.writeFileSync)(file, "");
|
|
40313
40214
|
} catch {
|
|
40314
40215
|
}
|
|
40315
40216
|
}
|
|
40316
40217
|
}
|
|
40317
40218
|
if (opts.all) {
|
|
40318
40219
|
const logsDir = projectPath(`${VERITY_DIR}/.logs`);
|
|
40319
|
-
if ((0,
|
|
40320
|
-
for (const entry of (0,
|
|
40220
|
+
if ((0, import_node_fs66.existsSync)(logsDir)) {
|
|
40221
|
+
for (const entry of (0, import_node_fs66.readdirSync)(logsDir)) {
|
|
40321
40222
|
try {
|
|
40322
|
-
(0,
|
|
40223
|
+
(0, import_node_fs66.unlinkSync)((0, import_node_path50.join)(logsDir, entry));
|
|
40323
40224
|
} catch {
|
|
40324
40225
|
}
|
|
40325
40226
|
}
|
|
@@ -40331,7 +40232,7 @@ function registerResetCommand(program2) {
|
|
|
40331
40232
|
}
|
|
40332
40233
|
|
|
40333
40234
|
// src/commands/reflect.ts
|
|
40334
|
-
var
|
|
40235
|
+
var import_node_fs67 = require("node:fs");
|
|
40335
40236
|
|
|
40336
40237
|
// src/lib/reflection-globs.ts
|
|
40337
40238
|
var MAX_GLOBS = 6;
|
|
@@ -40369,7 +40270,7 @@ async function writeNodeToDisk(args2) {
|
|
|
40369
40270
|
{ treePaths: listTrackedFiles(), recordBaseline: false }
|
|
40370
40271
|
);
|
|
40371
40272
|
if (written === 0) return false;
|
|
40372
|
-
return (0,
|
|
40273
|
+
return (0, import_node_fs67.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
|
|
40373
40274
|
} catch {
|
|
40374
40275
|
return false;
|
|
40375
40276
|
}
|
|
@@ -40801,9 +40702,9 @@ function registerRunCommand(program2) {
|
|
|
40801
40702
|
}
|
|
40802
40703
|
|
|
40803
40704
|
// src/commands/telemetry.ts
|
|
40804
|
-
var
|
|
40705
|
+
var import_node_fs68 = require("node:fs");
|
|
40805
40706
|
async function recordTelemetryChoice(choice) {
|
|
40806
|
-
if (!(0,
|
|
40707
|
+
if (!(0, import_node_fs68.existsSync)(projectPath(SETUP_STATE_FILE))) return;
|
|
40807
40708
|
try {
|
|
40808
40709
|
if ((await readSetupState())?.telemetry === choice) return;
|
|
40809
40710
|
await writeSetupState({ telemetry: choice });
|
|
@@ -40880,8 +40781,8 @@ function registerTelemetryCommands(program2) {
|
|
|
40880
40781
|
}
|
|
40881
40782
|
|
|
40882
40783
|
// src/commands/prove.ts
|
|
40883
|
-
var
|
|
40884
|
-
var
|
|
40784
|
+
var import_node_fs69 = require("node:fs");
|
|
40785
|
+
var import_node_path51 = require("node:path");
|
|
40885
40786
|
|
|
40886
40787
|
// src/lib/prove/hint-pool.ts
|
|
40887
40788
|
var STOP2 = /* @__PURE__ */ new Set([
|
|
@@ -41017,7 +40918,7 @@ function registerProveCommand(program2) {
|
|
|
41017
40918
|
process.exit(2);
|
|
41018
40919
|
}
|
|
41019
40920
|
const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
|
|
41020
|
-
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0,
|
|
40921
|
+
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path51.relative)(root, (0, import_node_path51.resolve)(p)) || ".") });
|
|
41021
40922
|
if (opts.hint && paths.length === 0) {
|
|
41022
40923
|
const hit = hintMatches(root, opts.hint);
|
|
41023
40924
|
if (hit.files.length > 0) {
|
|
@@ -41071,7 +40972,7 @@ function registerProveCommand(program2) {
|
|
|
41071
40972
|
});
|
|
41072
40973
|
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) => {
|
|
41073
40974
|
const root = repoRoot();
|
|
41074
|
-
if (!(0,
|
|
40975
|
+
if (!(0, import_node_fs69.existsSync)((0, import_node_path51.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41075
40976
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41076
40977
|
process.exit(2);
|
|
41077
40978
|
}
|
|
@@ -41095,7 +40996,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41095
40996
|
const reports = [];
|
|
41096
40997
|
for (const f of files) {
|
|
41097
40998
|
const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
|
|
41098
|
-
report.file = (0,
|
|
40999
|
+
report.file = (0, import_node_path51.relative)(root, f);
|
|
41099
41000
|
reports.push(report);
|
|
41100
41001
|
try {
|
|
41101
41002
|
writeResult(root, report);
|
|
@@ -41133,7 +41034,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41133
41034
|
printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
|
|
41134
41035
|
process.exit(2);
|
|
41135
41036
|
}
|
|
41136
|
-
if (!(0,
|
|
41037
|
+
if (!(0, import_node_fs69.existsSync)((0, import_node_path51.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41137
41038
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41138
41039
|
process.exit(2);
|
|
41139
41040
|
}
|
|
@@ -41164,7 +41065,7 @@ ${report.error ?? ""}`);
|
|
|
41164
41065
|
printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
|
|
41165
41066
|
return;
|
|
41166
41067
|
}
|
|
41167
|
-
const modelSource = readRegularFileInRoot(root, (0,
|
|
41068
|
+
const modelSource = readRegularFileInRoot(root, (0, import_node_path51.relative)(root, file), 512 * 1024);
|
|
41168
41069
|
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`);
|
|
41169
41070
|
const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
|
|
41170
41071
|
const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
|
|
@@ -41184,7 +41085,7 @@ ${report.error ?? ""}`);
|
|
|
41184
41085
|
});
|
|
41185
41086
|
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) => {
|
|
41186
41087
|
const root = repoRoot();
|
|
41187
|
-
let files = paths.map((p) => (0,
|
|
41088
|
+
let files = paths.map((p) => (0, import_node_path51.relative)(root, (0, import_node_path51.resolve)(p)));
|
|
41188
41089
|
if (files.length === 0) {
|
|
41189
41090
|
const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
|
|
41190
41091
|
const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
|
|
@@ -41244,7 +41145,7 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41244
41145
|
let revise;
|
|
41245
41146
|
if (opts.revise) {
|
|
41246
41147
|
const existing = resolveModelFile(root, opts.revise);
|
|
41247
|
-
const src = existing ? readRegularFileInRoot(root, (0,
|
|
41148
|
+
const src = existing ? readRegularFileInRoot(root, (0, import_node_path51.relative)(root, existing), 64 * 1024) : null;
|
|
41248
41149
|
if (!src || !src.ok || !opts.note) {
|
|
41249
41150
|
printError('--revise needs an existing model under Models/ and --note "<what the replay showed>"');
|
|
41250
41151
|
process.exit(2);
|
|
@@ -41283,8 +41184,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41283
41184
|
});
|
|
41284
41185
|
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) => {
|
|
41285
41186
|
const root = repoRoot();
|
|
41286
|
-
const rel0 = (0,
|
|
41287
|
-
const rel = rel0.startsWith("..") || (0,
|
|
41187
|
+
const rel0 = (0, import_node_path51.relative)(root, (0, import_node_path51.isAbsolute)(file) ? file : (0, import_node_path51.join)(root, file)).replace(/\\/g, "/");
|
|
41188
|
+
const rel = rel0.startsWith("..") || (0, import_node_path51.isAbsolute)(rel0) ? null : rel0;
|
|
41288
41189
|
if (!rel) {
|
|
41289
41190
|
printError(`${file} is not inside this repository`);
|
|
41290
41191
|
process.exit(2);
|
|
@@ -41300,8 +41201,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41300
41201
|
});
|
|
41301
41202
|
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) => {
|
|
41302
41203
|
const root = repoRoot();
|
|
41303
|
-
const rel = (0,
|
|
41304
|
-
const digest = rel.startsWith("..") || (0,
|
|
41204
|
+
const rel = (0, import_node_path51.relative)(root, (0, import_node_path51.isAbsolute)(file) ? file : (0, import_node_path51.join)(root, file));
|
|
41205
|
+
const digest = rel.startsWith("..") || (0, import_node_path51.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
|
|
41305
41206
|
if (!digest) {
|
|
41306
41207
|
printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
|
|
41307
41208
|
process.exit(2);
|
|
@@ -41335,10 +41236,10 @@ function refreshScaffold(root) {
|
|
|
41335
41236
|
}
|
|
41336
41237
|
|
|
41337
41238
|
// src/commands/lean.ts
|
|
41338
|
-
var
|
|
41239
|
+
var import_node_fs70 = require("node:fs");
|
|
41339
41240
|
var import_node_child_process20 = require("node:child_process");
|
|
41340
41241
|
var import_node_os11 = require("node:os");
|
|
41341
|
-
var
|
|
41242
|
+
var import_node_path52 = require("node:path");
|
|
41342
41243
|
function registerLeanCommand(program2) {
|
|
41343
41244
|
const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
|
|
41344
41245
|
lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
|
|
@@ -41355,7 +41256,7 @@ function registerLeanCommand(program2) {
|
|
|
41355
41256
|
const managed = pinnedVersionDir();
|
|
41356
41257
|
const matches = version ? version.includes(pin) : false;
|
|
41357
41258
|
if (opts.json) {
|
|
41358
|
-
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0,
|
|
41259
|
+
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs70.existsSync)((0, import_node_path52.join)(managed, "bin")), asset: leanAssetName() });
|
|
41359
41260
|
return;
|
|
41360
41261
|
}
|
|
41361
41262
|
printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
|
|
@@ -41373,7 +41274,7 @@ function registerLeanCommand(program2) {
|
|
|
41373
41274
|
process.exit(2);
|
|
41374
41275
|
}
|
|
41375
41276
|
const dir = pinnedVersionDir();
|
|
41376
|
-
if ((0,
|
|
41277
|
+
if ((0, import_node_fs70.existsSync)((0, import_node_path52.join)(dir, "bin", "lake")) && !opts.force) {
|
|
41377
41278
|
printInfo(`already installed at ${dir}`);
|
|
41378
41279
|
return;
|
|
41379
41280
|
}
|
|
@@ -41409,18 +41310,18 @@ function registerLeanCommand(program2) {
|
|
|
41409
41310
|
});
|
|
41410
41311
|
lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
|
|
41411
41312
|
const dir = pinnedVersionDir();
|
|
41412
|
-
if (!(0,
|
|
41313
|
+
if (!(0, import_node_fs70.existsSync)(dir)) {
|
|
41413
41314
|
printInfo("nothing to remove");
|
|
41414
41315
|
return;
|
|
41415
41316
|
}
|
|
41416
|
-
(0,
|
|
41317
|
+
(0, import_node_fs70.rmSync)(dir, { recursive: true, force: true });
|
|
41417
41318
|
printInfo(`removed ${dir}`);
|
|
41418
41319
|
});
|
|
41419
41320
|
}
|
|
41420
41321
|
|
|
41421
41322
|
// src/cli.ts
|
|
41422
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.
|
|
41423
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.
|
|
41323
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.b9e8508").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) => {
|
|
41324
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.b9e8508");
|
|
41424
41325
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
41425
41326
|
try {
|
|
41426
41327
|
await foldLegacyLocalCredential();
|