@codacy/verity-cli 0.34.0-experimental.145d0fb → 0.34.0-experimental.421a631
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 +892 -824
- package/package.json +1 -1
package/bin/verity.js
CHANGED
|
@@ -17104,8 +17104,107 @@ 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
|
|
17107
17111
|
var import_node_fs5 = require("node:fs");
|
|
17108
17112
|
var import_node_path7 = require("node:path");
|
|
17113
|
+
|
|
17114
|
+
// src/lib/hardened-git.ts
|
|
17115
|
+
var import_node_child_process5 = require("node:child_process");
|
|
17116
|
+
var HARDENED_CONFIG_ARGS = [
|
|
17117
|
+
"-c",
|
|
17118
|
+
"core.fsmonitor=false",
|
|
17119
|
+
"-c",
|
|
17120
|
+
"core.pager=cat",
|
|
17121
|
+
"-c",
|
|
17122
|
+
"log.showSignature=false"
|
|
17123
|
+
];
|
|
17124
|
+
var DIFF_READ_FLAGS = ["--no-ext-diff", "--no-textconv"];
|
|
17125
|
+
var DEFAULT_GIT_TIMEOUT_MS = 6e4;
|
|
17126
|
+
var DEFAULT_GIT_MAX_BUFFER = 64 * 1024 * 1024;
|
|
17127
|
+
function hardenedGitEnv(base = process.env) {
|
|
17128
|
+
const env = {};
|
|
17129
|
+
for (const [key, value] of Object.entries(base)) {
|
|
17130
|
+
if (key.startsWith("GIT_")) continue;
|
|
17131
|
+
env[key] = value;
|
|
17132
|
+
}
|
|
17133
|
+
env.GIT_OPTIONAL_LOCKS = "0";
|
|
17134
|
+
env.GIT_TERMINAL_PROMPT = "0";
|
|
17135
|
+
return env;
|
|
17136
|
+
}
|
|
17137
|
+
function hardenedGitArgv(args2) {
|
|
17138
|
+
return [...HARDENED_CONFIG_ARGS, ...args2];
|
|
17139
|
+
}
|
|
17140
|
+
function classifyError(err2) {
|
|
17141
|
+
const e = err2;
|
|
17142
|
+
const stderr = typeof e?.stderr === "string" ? e.stderr : e?.stderr ? e.stderr.toString("utf-8") : "";
|
|
17143
|
+
if (e?.code === "ETIMEDOUT" || e?.killed && e?.signal === "SIGTERM") return { ok: false, error: "timeout", stderr };
|
|
17144
|
+
if (e?.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") return { ok: false, error: "too_large", stderr };
|
|
17145
|
+
return { ok: false, error: "failed", stderr };
|
|
17146
|
+
}
|
|
17147
|
+
function runGitSync(cwd, args2, opts = {}) {
|
|
17148
|
+
try {
|
|
17149
|
+
const stdout = (0, import_node_child_process5.execFileSync)("git", hardenedGitArgv(args2), {
|
|
17150
|
+
cwd,
|
|
17151
|
+
env: hardenedGitEnv(),
|
|
17152
|
+
encoding: "utf-8",
|
|
17153
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
17154
|
+
timeout: opts.timeoutMs ?? DEFAULT_GIT_TIMEOUT_MS,
|
|
17155
|
+
maxBuffer: opts.maxBuffer ?? DEFAULT_GIT_MAX_BUFFER
|
|
17156
|
+
});
|
|
17157
|
+
return { ok: true, stdout };
|
|
17158
|
+
} catch (err2) {
|
|
17159
|
+
return classifyError(err2);
|
|
17160
|
+
}
|
|
17161
|
+
}
|
|
17162
|
+
function runGit(cwd, args2, opts = {}) {
|
|
17163
|
+
return new Promise((resolvePromise) => {
|
|
17164
|
+
(0, import_node_child_process5.execFile)(
|
|
17165
|
+
"git",
|
|
17166
|
+
hardenedGitArgv(args2),
|
|
17167
|
+
{
|
|
17168
|
+
cwd,
|
|
17169
|
+
env: hardenedGitEnv(),
|
|
17170
|
+
encoding: "utf-8",
|
|
17171
|
+
timeout: opts.timeoutMs ?? DEFAULT_GIT_TIMEOUT_MS,
|
|
17172
|
+
maxBuffer: opts.maxBuffer ?? DEFAULT_GIT_MAX_BUFFER
|
|
17173
|
+
},
|
|
17174
|
+
(err2, stdout, stderr) => {
|
|
17175
|
+
if (err2) {
|
|
17176
|
+
const e = err2;
|
|
17177
|
+
e.stderr = stderr;
|
|
17178
|
+
resolvePromise(classifyError(e));
|
|
17179
|
+
return;
|
|
17180
|
+
}
|
|
17181
|
+
resolvePromise({ ok: true, stdout });
|
|
17182
|
+
}
|
|
17183
|
+
);
|
|
17184
|
+
});
|
|
17185
|
+
}
|
|
17186
|
+
|
|
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
|
+
// src/lib/project-config.ts
|
|
17109
17208
|
var DEFAULTS = { git_moments: [] };
|
|
17110
17209
|
function isMoment(value) {
|
|
17111
17210
|
return value === "commit" || value === "push";
|
|
@@ -17115,8 +17214,8 @@ function parseMoments(raw) {
|
|
|
17115
17214
|
}
|
|
17116
17215
|
function readConfigFile(path) {
|
|
17117
17216
|
try {
|
|
17118
|
-
if (!(0,
|
|
17119
|
-
const raw = JSON.parse((0,
|
|
17217
|
+
if (!(0, import_node_fs6.existsSync)(path)) return null;
|
|
17218
|
+
const raw = JSON.parse((0, import_node_fs6.readFileSync)(path, "utf-8"));
|
|
17120
17219
|
const moments = Array.isArray(raw.git_moments) ? raw.git_moments.filter(isMoment) : [];
|
|
17121
17220
|
const source2 = raw.git_moments_source === "user" || raw.git_moments_source === "init" ? raw.git_moments_source : void 0;
|
|
17122
17221
|
return {
|
|
@@ -17133,20 +17232,41 @@ function candidates() {
|
|
|
17133
17232
|
const out2 = [{ path: local, source: "local" }];
|
|
17134
17233
|
const main = mainWorktreeRoot();
|
|
17135
17234
|
if (main) {
|
|
17136
|
-
const inherited = (0,
|
|
17235
|
+
const inherited = (0, import_node_path8.join)(main, PROJECT_CONFIG_FILE);
|
|
17137
17236
|
if (inherited !== local) out2.push({ path: inherited, source: "main-worktree" });
|
|
17138
17237
|
}
|
|
17139
17238
|
return out2;
|
|
17140
17239
|
}
|
|
17141
|
-
function
|
|
17240
|
+
function formalRefusal(path) {
|
|
17241
|
+
return repoControlled((0, import_node_path8.dirname)((0, import_node_path8.dirname)(path)), PROJECT_CONFIG_FILE);
|
|
17242
|
+
}
|
|
17243
|
+
function readProjectConfigRaw() {
|
|
17142
17244
|
for (const { path, source: source2 } of candidates()) {
|
|
17143
17245
|
const cfg = readConfigFile(path);
|
|
17144
17246
|
if (cfg) return { ...cfg, source: source2, path };
|
|
17145
17247
|
}
|
|
17146
17248
|
return { ...DEFAULTS, source: "default" };
|
|
17147
17249
|
}
|
|
17250
|
+
function readProjectConfig() {
|
|
17251
|
+
const cfg = readProjectConfigRaw();
|
|
17252
|
+
if (cfg.formal !== "push" || !cfg.path) return cfg;
|
|
17253
|
+
const refused = formalRefusal(cfg.path);
|
|
17254
|
+
if (!refused) return cfg;
|
|
17255
|
+
const { formal: _dropped, ...rest } = cfg;
|
|
17256
|
+
return { ...rest, formal_refused: refused };
|
|
17257
|
+
}
|
|
17258
|
+
function formalRefusalMessage(reason) {
|
|
17259
|
+
switch (reason) {
|
|
17260
|
+
case "tracked":
|
|
17261
|
+
return ".verity/config.json is tracked in git, so its formal setting is ignored (a repository cannot switch formal verification on) \u2014 untrack it with: git rm --cached .verity/config.json";
|
|
17262
|
+
case "symlink":
|
|
17263
|
+
return ".verity/config.json is reached through a symlink, so its formal setting is ignored";
|
|
17264
|
+
case "unverified":
|
|
17265
|
+
return "could not confirm with git that .verity/config.json is untracked, so its formal setting is ignored";
|
|
17266
|
+
}
|
|
17267
|
+
}
|
|
17148
17268
|
function writeProjectConfig(patch) {
|
|
17149
|
-
const { git_moments, git_moments_source, formal } =
|
|
17269
|
+
const { git_moments, git_moments_source, formal } = readProjectConfigRaw();
|
|
17150
17270
|
const next = {
|
|
17151
17271
|
git_moments,
|
|
17152
17272
|
...git_moments_source ? { git_moments_source } : {},
|
|
@@ -17154,8 +17274,8 @@ function writeProjectConfig(patch) {
|
|
|
17154
17274
|
...patch
|
|
17155
17275
|
};
|
|
17156
17276
|
const target = projectPath(PROJECT_CONFIG_FILE);
|
|
17157
|
-
(0,
|
|
17158
|
-
(0,
|
|
17277
|
+
(0, import_node_fs6.mkdirSync)((0, import_node_path8.dirname)(target), { recursive: true });
|
|
17278
|
+
(0, import_node_fs6.writeFileSync)(target, JSON.stringify(next, null, 2) + "\n");
|
|
17159
17279
|
return next;
|
|
17160
17280
|
}
|
|
17161
17281
|
function resolveGuardMoments(explicit) {
|
|
@@ -17164,11 +17284,11 @@ function resolveGuardMoments(explicit) {
|
|
|
17164
17284
|
}
|
|
17165
17285
|
|
|
17166
17286
|
// src/lib/plugin-ownership.ts
|
|
17167
|
-
var
|
|
17287
|
+
var import_node_fs9 = require("node:fs");
|
|
17168
17288
|
|
|
17169
17289
|
// src/lib/which.ts
|
|
17170
|
-
var
|
|
17171
|
-
var
|
|
17290
|
+
var import_node_fs7 = require("node:fs");
|
|
17291
|
+
var import_node_path9 = require("node:path");
|
|
17172
17292
|
function executableExtensions(platform4, pathext) {
|
|
17173
17293
|
if (platform4 !== "win32") return [""];
|
|
17174
17294
|
const raw = (pathext ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean);
|
|
@@ -17186,14 +17306,14 @@ function whichSync(bin, opts = {}) {
|
|
|
17186
17306
|
if (!rawPath) return null;
|
|
17187
17307
|
const exts = executableExtensions(platform4, opts.pathext ?? process.env.PATHEXT);
|
|
17188
17308
|
const real = opts.real ?? true;
|
|
17189
|
-
for (const dir of rawPath.split(
|
|
17309
|
+
for (const dir of rawPath.split(import_node_path9.delimiter)) {
|
|
17190
17310
|
if (!dir) continue;
|
|
17191
17311
|
for (const ext of exts) {
|
|
17192
|
-
const candidate = (0,
|
|
17312
|
+
const candidate = (0, import_node_path9.join)(dir, bin + ext);
|
|
17193
17313
|
try {
|
|
17194
|
-
if (!(0,
|
|
17195
|
-
if (platform4 !== "win32") (0,
|
|
17196
|
-
return real ? (0,
|
|
17314
|
+
if (!(0, import_node_fs7.statSync)(candidate).isFile()) continue;
|
|
17315
|
+
if (platform4 !== "win32") (0, import_node_fs7.accessSync)(candidate, import_node_fs7.constants.X_OK);
|
|
17316
|
+
return real ? (0, import_node_fs7.realpathSync)(candidate) : candidate;
|
|
17197
17317
|
} catch {
|
|
17198
17318
|
continue;
|
|
17199
17319
|
}
|
|
@@ -17204,10 +17324,10 @@ function whichSync(bin, opts = {}) {
|
|
|
17204
17324
|
|
|
17205
17325
|
// src/lib/plugin-ownership.ts
|
|
17206
17326
|
var import_node_os2 = require("node:os");
|
|
17207
|
-
var
|
|
17327
|
+
var import_node_path10 = require("node:path");
|
|
17208
17328
|
|
|
17209
17329
|
// src/lib/stderr-log.ts
|
|
17210
|
-
var
|
|
17330
|
+
var import_node_fs8 = require("node:fs");
|
|
17211
17331
|
var TOKEN_RE2 = /verity_[0-9a-f]{16,}/g;
|
|
17212
17332
|
var ANSI_RE = /\u001b\[[0-?]*[ -/]*[@-~]/g;
|
|
17213
17333
|
function scrub(s) {
|
|
@@ -17220,9 +17340,9 @@ function append(text) {
|
|
|
17220
17340
|
try {
|
|
17221
17341
|
const dir = projectPath(DEBUG_LOG_DIR);
|
|
17222
17342
|
const file = projectPath(STDERR_LOG_FILE);
|
|
17223
|
-
(0,
|
|
17343
|
+
(0, import_node_fs8.mkdirSync)(dir, { recursive: true });
|
|
17224
17344
|
rotateIfNeeded(file);
|
|
17225
|
-
(0,
|
|
17345
|
+
(0, import_node_fs8.appendFileSync)(file, text);
|
|
17226
17346
|
} catch {
|
|
17227
17347
|
}
|
|
17228
17348
|
}
|
|
@@ -17270,8 +17390,8 @@ function markerPath() {
|
|
|
17270
17390
|
}
|
|
17271
17391
|
function readMarker() {
|
|
17272
17392
|
try {
|
|
17273
|
-
if (!(0,
|
|
17274
|
-
const raw = JSON.parse((0,
|
|
17393
|
+
if (!(0, import_node_fs9.existsSync)(markerPath())) return null;
|
|
17394
|
+
const raw = JSON.parse((0, import_node_fs9.readFileSync)(markerPath(), "utf-8"));
|
|
17275
17395
|
const pluginRoot = typeof raw.plugin_root === "string" ? raw.plugin_root : "";
|
|
17276
17396
|
if (!pluginRoot || CONTROL_CHARS2.test(pluginRoot)) return null;
|
|
17277
17397
|
const version = typeof raw.version === "string" && !CONTROL_CHARS2.test(raw.version) ? raw.version : null;
|
|
@@ -17289,23 +17409,23 @@ function recordPluginOwnership(sessionId) {
|
|
|
17289
17409
|
const pluginRoot = process.env.VERITY_PLUGIN_ROOT;
|
|
17290
17410
|
if (!pluginRoot) return;
|
|
17291
17411
|
try {
|
|
17292
|
-
(0,
|
|
17412
|
+
(0, import_node_fs9.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
|
|
17293
17413
|
const marker = {
|
|
17294
17414
|
session_id: sessionId,
|
|
17295
17415
|
plugin_root: pluginRoot,
|
|
17296
17416
|
version: process.env.VERITY_PLUGIN_VERSION || null,
|
|
17297
17417
|
ts: Math.floor(Date.now() / 1e3)
|
|
17298
17418
|
};
|
|
17299
|
-
(0,
|
|
17419
|
+
(0, import_node_fs9.writeFileSync)(markerPath(), JSON.stringify(marker));
|
|
17300
17420
|
} catch {
|
|
17301
17421
|
}
|
|
17302
17422
|
}
|
|
17303
17423
|
function claudeConfigDir() {
|
|
17304
|
-
return process.env.CLAUDE_CONFIG_DIR || (0,
|
|
17424
|
+
return process.env.CLAUDE_CONFIG_DIR || (0, import_node_path10.join)((0, import_node_os2.homedir)(), ".claude");
|
|
17305
17425
|
}
|
|
17306
17426
|
function readJsonFile(path) {
|
|
17307
17427
|
try {
|
|
17308
|
-
const parsed = JSON.parse((0,
|
|
17428
|
+
const parsed = JSON.parse((0, import_node_fs9.readFileSync)(path, "utf-8"));
|
|
17309
17429
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
17310
17430
|
} catch {
|
|
17311
17431
|
return null;
|
|
@@ -17313,9 +17433,9 @@ function readJsonFile(path) {
|
|
|
17313
17433
|
}
|
|
17314
17434
|
function enabledPluginSetting(key) {
|
|
17315
17435
|
const files = [
|
|
17316
|
-
projectPath((0,
|
|
17317
|
-
projectPath((0,
|
|
17318
|
-
(0,
|
|
17436
|
+
projectPath((0, import_node_path10.join)(".claude", "settings.local.json")),
|
|
17437
|
+
projectPath((0, import_node_path10.join)(".claude", "settings.json")),
|
|
17438
|
+
(0, import_node_path10.join)(claudeConfigDir(), "settings.json")
|
|
17319
17439
|
];
|
|
17320
17440
|
for (const file of files) {
|
|
17321
17441
|
const map = readJsonFile(file)?.enabledPlugins;
|
|
@@ -17327,11 +17447,11 @@ function enabledPluginSetting(key) {
|
|
|
17327
17447
|
}
|
|
17328
17448
|
function marketplaceLocations() {
|
|
17329
17449
|
const out2 = /* @__PURE__ */ new Map();
|
|
17330
|
-
const known = readJsonFile((0,
|
|
17450
|
+
const known = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
|
|
17331
17451
|
if (!known) return out2;
|
|
17332
17452
|
for (const [name2, entry] of Object.entries(known)) {
|
|
17333
17453
|
const loc2 = entry?.installLocation;
|
|
17334
|
-
if (typeof loc2 === "string" && loc2) out2.set(name2, (0,
|
|
17454
|
+
if (typeof loc2 === "string" && loc2) out2.set(name2, (0, import_node_path10.resolve)(loc2));
|
|
17335
17455
|
}
|
|
17336
17456
|
return out2;
|
|
17337
17457
|
}
|
|
@@ -17345,7 +17465,7 @@ function globalVerityVersion() {
|
|
|
17345
17465
|
const entry = verityPathEntry();
|
|
17346
17466
|
if (!entry) return null;
|
|
17347
17467
|
try {
|
|
17348
|
-
const pkg = readJsonFile((0,
|
|
17468
|
+
const pkg = readJsonFile((0, import_node_path10.join)((0, import_node_path10.dirname)((0, import_node_fs9.realpathSync)(entry)), "..", "package.json"));
|
|
17349
17469
|
if (pkg?.name !== "@codacy/verity-cli" || typeof pkg.version !== "string") return null;
|
|
17350
17470
|
return pkg.version;
|
|
17351
17471
|
} catch {
|
|
@@ -17362,7 +17482,7 @@ var VERITY_MARKETPLACE_REPO = "codacy/verity";
|
|
|
17362
17482
|
function marketplaceConflict() {
|
|
17363
17483
|
const wanted = VERITY_MARKETPLACE;
|
|
17364
17484
|
for (const file of ["settings.json", "settings.local.json"]) {
|
|
17365
|
-
const path = (0,
|
|
17485
|
+
const path = (0, import_node_path10.join)(claudeConfigDir(), file);
|
|
17366
17486
|
const declared = readJsonFile(path)?.extraKnownMarketplaces ?? null;
|
|
17367
17487
|
const entry2 = declared && typeof declared === "object" ? declared[wanted] : void 0;
|
|
17368
17488
|
if (entry2 && typeof entry2 === "object") {
|
|
@@ -17372,7 +17492,7 @@ function marketplaceConflict() {
|
|
|
17372
17492
|
}
|
|
17373
17493
|
}
|
|
17374
17494
|
}
|
|
17375
|
-
const known = readJsonFile((0,
|
|
17495
|
+
const known = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
|
|
17376
17496
|
const entry = known?.[wanted];
|
|
17377
17497
|
if (entry && typeof entry === "object" && !pointsAtVerity(entry.source)) {
|
|
17378
17498
|
return { name: wanted, declaredAs: describeSource(entry.source) };
|
|
@@ -17393,7 +17513,7 @@ function describeSource(src) {
|
|
|
17393
17513
|
return target ? `${kind} \u2192 ${target}` : kind;
|
|
17394
17514
|
}
|
|
17395
17515
|
function legacyMarketplaceInstall() {
|
|
17396
|
-
const plugins = readJsonFile((0,
|
|
17516
|
+
const plugins = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17397
17517
|
if (!plugins || typeof plugins !== "object") return null;
|
|
17398
17518
|
for (const key of Object.keys(plugins)) {
|
|
17399
17519
|
const at = key.lastIndexOf("@");
|
|
@@ -17405,13 +17525,13 @@ function legacyMarketplaceInstall() {
|
|
|
17405
17525
|
}
|
|
17406
17526
|
function realpathOr(p) {
|
|
17407
17527
|
try {
|
|
17408
|
-
return
|
|
17528
|
+
return import_node_fs9.realpathSync.native(p);
|
|
17409
17529
|
} catch {
|
|
17410
|
-
return (0,
|
|
17530
|
+
return (0, import_node_path10.resolve)(p);
|
|
17411
17531
|
}
|
|
17412
17532
|
}
|
|
17413
17533
|
function isWithin(want, dir) {
|
|
17414
|
-
return want === dir || want.startsWith(dir +
|
|
17534
|
+
return want === dir || want.startsWith(dir + import_node_path10.sep);
|
|
17415
17535
|
}
|
|
17416
17536
|
function entryAppliesHere(entry, here) {
|
|
17417
17537
|
const e = entry;
|
|
@@ -17421,9 +17541,9 @@ function entryAppliesHere(entry, here) {
|
|
|
17421
17541
|
return forProject === here;
|
|
17422
17542
|
}
|
|
17423
17543
|
function registrySays(pluginRoot) {
|
|
17424
|
-
const plugins = readJsonFile((0,
|
|
17544
|
+
const plugins = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17425
17545
|
if (!plugins || typeof plugins !== "object") return "unverified";
|
|
17426
|
-
const want = (0,
|
|
17546
|
+
const want = (0, import_node_path10.resolve)(pluginRoot);
|
|
17427
17547
|
const here = realpathOr(repoRoot());
|
|
17428
17548
|
const markets = marketplaceLocations();
|
|
17429
17549
|
for (const [key, value] of Object.entries(plugins)) {
|
|
@@ -17432,15 +17552,15 @@ function registrySays(pluginRoot) {
|
|
|
17432
17552
|
const applicable = (Array.isArray(value) ? value : []).filter((entry) => entryAppliesHere(entry, here));
|
|
17433
17553
|
const claims = applicable.some((entry) => {
|
|
17434
17554
|
const installPath = entry?.installPath;
|
|
17435
|
-
return typeof installPath === "string" && (0,
|
|
17555
|
+
return typeof installPath === "string" && (0, import_node_path10.resolve)(installPath) === want;
|
|
17436
17556
|
}) || source2 !== void 0 && applicable.length > 0 && isWithin(want, source2);
|
|
17437
17557
|
if (claims) {
|
|
17438
17558
|
if (enabledPluginSetting(key) === false) return "gone";
|
|
17439
|
-
return (0,
|
|
17559
|
+
return (0, import_node_fs9.existsSync)(pluginRoot) ? "live" : "gone";
|
|
17440
17560
|
}
|
|
17441
17561
|
}
|
|
17442
|
-
const managed = (0,
|
|
17443
|
-
return want === managed || want.startsWith(managed +
|
|
17562
|
+
const managed = (0, import_node_path10.resolve)((0, import_node_path10.join)(claudeConfigDir(), "plugins", "cache"));
|
|
17563
|
+
return want === managed || want.startsWith(managed + import_node_path10.sep) ? "gone" : "unverified";
|
|
17444
17564
|
}
|
|
17445
17565
|
var _live = /* @__PURE__ */ new Map();
|
|
17446
17566
|
function pluginLiveness(pluginRoot) {
|
|
@@ -17454,7 +17574,7 @@ function clearStalePluginMarker() {
|
|
|
17454
17574
|
const marker = readMarker();
|
|
17455
17575
|
if (!marker || pluginLiveness(marker.plugin_root) !== "gone") return null;
|
|
17456
17576
|
try {
|
|
17457
|
-
(0,
|
|
17577
|
+
(0, import_node_fs9.rmSync)(markerPath(), { force: true });
|
|
17458
17578
|
} catch {
|
|
17459
17579
|
return null;
|
|
17460
17580
|
}
|
|
@@ -17482,7 +17602,7 @@ function pluginActiveHere() {
|
|
|
17482
17602
|
return activePluginInstall() !== null;
|
|
17483
17603
|
}
|
|
17484
17604
|
function registeredVerityPlugin() {
|
|
17485
|
-
const plugins = readJsonFile((0,
|
|
17605
|
+
const plugins = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
17486
17606
|
if (!plugins || typeof plugins !== "object") return null;
|
|
17487
17607
|
const here = realpathOr(repoRoot());
|
|
17488
17608
|
for (const [key, value] of Object.entries(plugins)) {
|
|
@@ -17492,7 +17612,7 @@ function registeredVerityPlugin() {
|
|
|
17492
17612
|
for (const entry of Array.isArray(value) ? value : []) {
|
|
17493
17613
|
const e = entry;
|
|
17494
17614
|
const installPath = typeof e.installPath === "string" ? e.installPath : "";
|
|
17495
|
-
if (!installPath || !(0,
|
|
17615
|
+
if (!installPath || !(0, import_node_fs9.existsSync)(installPath)) continue;
|
|
17496
17616
|
if (!entryAppliesHere(entry, here)) continue;
|
|
17497
17617
|
return { pluginRoot: installPath, version: typeof e.version === "string" ? e.version : null };
|
|
17498
17618
|
}
|
|
@@ -17544,28 +17664,28 @@ async function resolveHookWiring() {
|
|
|
17544
17664
|
}
|
|
17545
17665
|
|
|
17546
17666
|
// src/lib/cli-provenance.ts
|
|
17547
|
-
var
|
|
17667
|
+
var import_node_fs10 = require("node:fs");
|
|
17548
17668
|
var import_node_os3 = require("node:os");
|
|
17549
|
-
var
|
|
17669
|
+
var import_node_path11 = require("node:path");
|
|
17550
17670
|
var CLI_PACKAGE = "@codacy/verity-cli";
|
|
17551
|
-
var CLI_ENTRY = (0,
|
|
17671
|
+
var CLI_ENTRY = (0, import_node_path11.join)("node_modules", CLI_PACKAGE, "bin", "verity.js");
|
|
17552
17672
|
function readJson(path) {
|
|
17553
17673
|
try {
|
|
17554
|
-
const parsed = JSON.parse((0,
|
|
17674
|
+
const parsed = JSON.parse((0, import_node_fs10.readFileSync)(path, "utf-8"));
|
|
17555
17675
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
17556
17676
|
} catch {
|
|
17557
17677
|
return null;
|
|
17558
17678
|
}
|
|
17559
17679
|
}
|
|
17560
17680
|
function versionUnder(base) {
|
|
17561
|
-
const entry = (0,
|
|
17562
|
-
if (!(0,
|
|
17563
|
-
const pkg = readJson((0,
|
|
17681
|
+
const entry = (0, import_node_path11.join)(base, CLI_ENTRY);
|
|
17682
|
+
if (!(0, import_node_fs10.existsSync)(entry)) return null;
|
|
17683
|
+
const pkg = readJson((0, import_node_path11.join)(base, "node_modules", CLI_PACKAGE, "package.json"));
|
|
17564
17684
|
return typeof pkg?.version === "string" ? pkg.version : null;
|
|
17565
17685
|
}
|
|
17566
17686
|
function versionForEntry(entry) {
|
|
17567
17687
|
try {
|
|
17568
|
-
const pkg = readJson((0,
|
|
17688
|
+
const pkg = readJson((0, import_node_path11.join)((0, import_node_path11.dirname)((0, import_node_fs10.realpathSync)(entry)), "..", "package.json"));
|
|
17569
17689
|
return typeof pkg?.version === "string" ? pkg.version : null;
|
|
17570
17690
|
} catch {
|
|
17571
17691
|
return null;
|
|
@@ -17573,16 +17693,16 @@ function versionForEntry(entry) {
|
|
|
17573
17693
|
}
|
|
17574
17694
|
function resolveHooksCli(pluginRoot) {
|
|
17575
17695
|
const override = process.env.VERITY_CLI_PATH;
|
|
17576
|
-
if (override && (0,
|
|
17696
|
+
if (override && (0, import_node_fs10.existsSync)(override)) {
|
|
17577
17697
|
return { version: versionForEntry(override), rung: "override" };
|
|
17578
17698
|
}
|
|
17579
17699
|
const fromPlugin = versionUnder(pluginRoot);
|
|
17580
17700
|
if (fromPlugin !== null) return { version: fromPlugin, rung: "plugin" };
|
|
17581
|
-
if ((0,
|
|
17582
|
-
const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0,
|
|
17701
|
+
if ((0, import_node_fs10.existsSync)((0, import_node_path11.join)(pluginRoot, CLI_ENTRY))) return { version: null, rung: "plugin" };
|
|
17702
|
+
const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0, import_node_path11.join)((0, import_node_os3.homedir)(), ".verity", "plugin-cli");
|
|
17583
17703
|
const fromData = versionUnder(dataDir);
|
|
17584
17704
|
if (fromData !== null) return { version: fromData, rung: "plugin-data" };
|
|
17585
|
-
if ((0,
|
|
17705
|
+
if ((0, import_node_fs10.existsSync)((0, import_node_path11.join)(dataDir, CLI_ENTRY))) return { version: null, rung: "plugin-data" };
|
|
17586
17706
|
const global = globalVerityVersion();
|
|
17587
17707
|
if (global !== null) return { version: global, rung: "global" };
|
|
17588
17708
|
return null;
|
|
@@ -17684,7 +17804,7 @@ function pluginCliInvocation() {
|
|
|
17684
17804
|
return resolverCommand(root);
|
|
17685
17805
|
}
|
|
17686
17806
|
function resolverCommand(root) {
|
|
17687
|
-
return `node ${JSON.stringify((0,
|
|
17807
|
+
return `node ${JSON.stringify((0, import_node_path11.join)(root, "scripts", "verity.mjs"))}`;
|
|
17688
17808
|
}
|
|
17689
17809
|
|
|
17690
17810
|
// src/commands/hooks.ts
|
|
@@ -17824,8 +17944,8 @@ var import_node_crypto9 = require("node:crypto");
|
|
|
17824
17944
|
|
|
17825
17945
|
// src/lib/conversation-buffer.ts
|
|
17826
17946
|
var import_promises5 = require("node:fs/promises");
|
|
17827
|
-
var
|
|
17828
|
-
var
|
|
17947
|
+
var import_node_fs11 = require("node:fs");
|
|
17948
|
+
var import_node_child_process6 = require("node:child_process");
|
|
17829
17949
|
var import_node_crypto = require("node:crypto");
|
|
17830
17950
|
function stripImageReferences(text) {
|
|
17831
17951
|
return text.replace(/\[Image #\d+\]/g, "[screenshot \u2014 not available for review]");
|
|
@@ -17860,7 +17980,7 @@ async function appendToConversationBuffer(prompt, sessionId) {
|
|
|
17860
17980
|
}
|
|
17861
17981
|
async function readAndClearConversationBuffer(currentSessionId) {
|
|
17862
17982
|
try {
|
|
17863
|
-
if ((0,
|
|
17983
|
+
if ((0, import_node_fs11.existsSync)(CONVERSATION_BUFFER_FILE)) {
|
|
17864
17984
|
const entries = await readBufferEntries();
|
|
17865
17985
|
let mine = entries;
|
|
17866
17986
|
let others = [];
|
|
@@ -17884,7 +18004,7 @@ async function readAndClearConversationBuffer(currentSessionId) {
|
|
|
17884
18004
|
};
|
|
17885
18005
|
}
|
|
17886
18006
|
}
|
|
17887
|
-
if ((0,
|
|
18007
|
+
if ((0, import_node_fs11.existsSync)(INTENT_FILE)) {
|
|
17888
18008
|
try {
|
|
17889
18009
|
const content = await (0, import_promises5.readFile)(INTENT_FILE, "utf-8");
|
|
17890
18010
|
await (0, import_promises5.unlink)(INTENT_FILE).catch(() => {
|
|
@@ -17928,7 +18048,7 @@ async function readBufferEntries() {
|
|
|
17928
18048
|
}
|
|
17929
18049
|
function getRecentCommitMessages() {
|
|
17930
18050
|
try {
|
|
17931
|
-
const output = (0,
|
|
18051
|
+
const output = (0, import_node_child_process6.execSync)(
|
|
17932
18052
|
'git log --since="30 minutes ago" --format="%s" -5',
|
|
17933
18053
|
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
17934
18054
|
).trim();
|
|
@@ -18177,9 +18297,9 @@ function isCommandOnlyTurn(input) {
|
|
|
18177
18297
|
|
|
18178
18298
|
// src/lib/context-identity.ts
|
|
18179
18299
|
var import_node_crypto2 = require("node:crypto");
|
|
18180
|
-
var
|
|
18300
|
+
var import_node_fs12 = require("node:fs");
|
|
18181
18301
|
var import_node_os4 = require("node:os");
|
|
18182
|
-
var
|
|
18302
|
+
var import_node_path12 = require("node:path");
|
|
18183
18303
|
var SHARED_SENTINELS = /* @__PURE__ */ new Set([
|
|
18184
18304
|
"",
|
|
18185
18305
|
"-",
|
|
@@ -18217,7 +18337,7 @@ function contextIdentity(input) {
|
|
|
18217
18337
|
if (rawTree && !isSharedSentinel(rawTree)) {
|
|
18218
18338
|
let resolved = rawTree;
|
|
18219
18339
|
try {
|
|
18220
|
-
resolved =
|
|
18340
|
+
resolved = import_node_fs12.realpathSync.native(rawTree);
|
|
18221
18341
|
} catch {
|
|
18222
18342
|
}
|
|
18223
18343
|
treeKey = (0, import_node_crypto2.createHash)("sha256").update(resolved).digest("hex").slice(0, 12);
|
|
@@ -18233,13 +18353,13 @@ function contextIdentity(input) {
|
|
|
18233
18353
|
}
|
|
18234
18354
|
function verityHome() {
|
|
18235
18355
|
const override = process.env.VERITY_HOME;
|
|
18236
|
-
return override && override.trim() ? (0,
|
|
18356
|
+
return override && override.trim() ? (0, import_node_path12.resolve)(override) : (0, import_node_path12.join)((0, import_node_os4.homedir)(), ".verity");
|
|
18237
18357
|
}
|
|
18238
18358
|
function dossierDir(identity) {
|
|
18239
|
-
return (0,
|
|
18359
|
+
return (0, import_node_path12.join)(verityHome(), "sessions", identity.userKey, identity.treeKey, identity.sessionKey);
|
|
18240
18360
|
}
|
|
18241
18361
|
function treeDir(identity) {
|
|
18242
|
-
return (0,
|
|
18362
|
+
return (0, import_node_path12.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
|
|
18243
18363
|
}
|
|
18244
18364
|
function scopeIdentity(token, sessionId) {
|
|
18245
18365
|
const t = (token ?? "").trim();
|
|
@@ -18254,8 +18374,8 @@ function sessionScopeKey(token, sessionId) {
|
|
|
18254
18374
|
|
|
18255
18375
|
// src/lib/task-context-buffer.ts
|
|
18256
18376
|
var import_promises6 = require("node:fs/promises");
|
|
18257
|
-
var
|
|
18258
|
-
var
|
|
18377
|
+
var import_node_fs13 = require("node:fs");
|
|
18378
|
+
var import_node_path13 = require("node:path");
|
|
18259
18379
|
var TASK_CONTEXT_DIR = `${VERITY_DIR}/.task-context`;
|
|
18260
18380
|
var MAX_BUFFER_BYTES = 500 * 1024;
|
|
18261
18381
|
var MAX_PROMPT_CHARS = 2e3;
|
|
@@ -18294,7 +18414,7 @@ async function appendResponseToTaskBuffer(taskId, assistantResponse, actionSumma
|
|
|
18294
18414
|
}
|
|
18295
18415
|
async function readTaskContextBuffer(taskId) {
|
|
18296
18416
|
const filePath = bufferPath(taskId);
|
|
18297
|
-
if (!(0,
|
|
18417
|
+
if (!(0, import_node_fs13.existsSync)(filePath)) return null;
|
|
18298
18418
|
try {
|
|
18299
18419
|
const content = await (0, import_promises6.readFile)(filePath, "utf-8");
|
|
18300
18420
|
if (!content.trim()) return null;
|
|
@@ -18328,12 +18448,12 @@ async function readTaskContextBuffer(taskId) {
|
|
|
18328
18448
|
}
|
|
18329
18449
|
async function cleanupTaskContextBuffers() {
|
|
18330
18450
|
try {
|
|
18331
|
-
if (!(0,
|
|
18451
|
+
if (!(0, import_node_fs13.existsSync)(TASK_CONTEXT_DIR)) return;
|
|
18332
18452
|
const files = await (0, import_promises6.readdir)(TASK_CONTEXT_DIR);
|
|
18333
18453
|
const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1e3;
|
|
18334
18454
|
for (const file of files) {
|
|
18335
18455
|
if (!file.endsWith(".jsonl")) continue;
|
|
18336
|
-
const filePath = (0,
|
|
18456
|
+
const filePath = (0, import_node_path13.join)(TASK_CONTEXT_DIR, file);
|
|
18337
18457
|
try {
|
|
18338
18458
|
const stats = await (0, import_promises6.stat)(filePath);
|
|
18339
18459
|
if (stats.mtimeMs < cutoffMs) {
|
|
@@ -18347,13 +18467,13 @@ async function cleanupTaskContextBuffers() {
|
|
|
18347
18467
|
}
|
|
18348
18468
|
function bufferPath(taskId) {
|
|
18349
18469
|
const safe = taskId.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
18350
|
-
return (0,
|
|
18470
|
+
return (0, import_node_path13.join)(TASK_CONTEXT_DIR, `${safe}.jsonl`);
|
|
18351
18471
|
}
|
|
18352
18472
|
async function appendEntry(taskId, entry) {
|
|
18353
18473
|
try {
|
|
18354
18474
|
await (0, import_promises6.mkdir)(TASK_CONTEXT_DIR, { recursive: true });
|
|
18355
18475
|
const filePath = bufferPath(taskId);
|
|
18356
|
-
if ((0,
|
|
18476
|
+
if ((0, import_node_fs13.existsSync)(filePath)) {
|
|
18357
18477
|
const stats = await (0, import_promises6.stat)(filePath);
|
|
18358
18478
|
if (stats.size >= MAX_BUFFER_BYTES) {
|
|
18359
18479
|
const content = await (0, import_promises6.readFile)(filePath, "utf-8");
|
|
@@ -18364,7 +18484,7 @@ async function appendEntry(taskId, entry) {
|
|
|
18364
18484
|
}
|
|
18365
18485
|
}
|
|
18366
18486
|
const line2 = JSON.stringify(entry) + "\n";
|
|
18367
|
-
const existing = (0,
|
|
18487
|
+
const existing = (0, import_node_fs13.existsSync)(filePath) ? await (0, import_promises6.readFile)(filePath, "utf-8") : "";
|
|
18368
18488
|
await (0, import_promises6.writeFile)(filePath, existing + line2);
|
|
18369
18489
|
} catch {
|
|
18370
18490
|
}
|
|
@@ -18372,20 +18492,20 @@ async function appendEntry(taskId, entry) {
|
|
|
18372
18492
|
|
|
18373
18493
|
// src/lib/memory-retrieval.ts
|
|
18374
18494
|
var import_promises8 = require("node:fs/promises");
|
|
18375
|
-
var
|
|
18376
|
-
var
|
|
18495
|
+
var import_node_fs16 = require("node:fs");
|
|
18496
|
+
var import_node_path16 = require("node:path");
|
|
18377
18497
|
|
|
18378
18498
|
// src/lib/org-mirror.ts
|
|
18379
|
-
var
|
|
18499
|
+
var import_node_fs14 = require("node:fs");
|
|
18380
18500
|
var import_promises7 = require("node:fs/promises");
|
|
18381
|
-
var
|
|
18501
|
+
var import_node_path14 = require("node:path");
|
|
18382
18502
|
var ORG_KINDS = ["decision", "security", "gotcha", "pattern", "domain", "integration"];
|
|
18383
18503
|
var STATE_FILE = ".org-pull-state.json";
|
|
18384
18504
|
var BODY_MAX = 8192;
|
|
18385
18505
|
function orgMirrorDir(remote = requestRemote()) {
|
|
18386
18506
|
const parsed = parseRemote(remote);
|
|
18387
18507
|
if (!parsed) return null;
|
|
18388
|
-
return (0,
|
|
18508
|
+
return (0, import_node_path14.join)(verityHome(), "orgs", parsed.host, parsed.owner.toLowerCase(), "memory");
|
|
18389
18509
|
}
|
|
18390
18510
|
function slugify(s) {
|
|
18391
18511
|
return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
@@ -18451,7 +18571,7 @@ function parseOrgNode(content) {
|
|
|
18451
18571
|
}
|
|
18452
18572
|
async function readState(dir) {
|
|
18453
18573
|
try {
|
|
18454
|
-
const parsed = JSON.parse(await (0, import_promises7.readFile)((0,
|
|
18574
|
+
const parsed = JSON.parse(await (0, import_promises7.readFile)((0, import_node_path14.join)(dir, STATE_FILE), "utf-8"));
|
|
18455
18575
|
return {
|
|
18456
18576
|
version: typeof parsed?.version === "string" ? parsed.version : null,
|
|
18457
18577
|
organization: parsed?.organization && typeof parsed.organization.id === "string" ? parsed.organization : null,
|
|
@@ -18463,7 +18583,7 @@ async function readState(dir) {
|
|
|
18463
18583
|
}
|
|
18464
18584
|
async function writeState(dir, state) {
|
|
18465
18585
|
await (0, import_promises7.mkdir)(dir, { recursive: true });
|
|
18466
|
-
await (0, import_promises7.writeFile)((0,
|
|
18586
|
+
await (0, import_promises7.writeFile)((0, import_node_path14.join)(dir, STATE_FILE), JSON.stringify({
|
|
18467
18587
|
...state.version ? { version: state.version } : {},
|
|
18468
18588
|
organization: state.organization,
|
|
18469
18589
|
pulled_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -18528,24 +18648,24 @@ async function pullOrgKnowledge(opts) {
|
|
|
18528
18648
|
for (const n of nodes) {
|
|
18529
18649
|
const rel = orgNodePath(n);
|
|
18530
18650
|
if (written.has(rel)) continue;
|
|
18531
|
-
await (0, import_promises7.mkdir)((0,
|
|
18532
|
-
await (0, import_promises7.writeFile)((0,
|
|
18651
|
+
await (0, import_promises7.mkdir)((0, import_node_path14.join)(dir, rel.split("/")[0]), { recursive: true });
|
|
18652
|
+
await (0, import_promises7.writeFile)((0, import_node_path14.join)(dir, rel), renderOrgNode(n, org?.name ?? ""));
|
|
18533
18653
|
written.add(rel);
|
|
18534
18654
|
}
|
|
18535
18655
|
for (const rel of state.files) {
|
|
18536
|
-
if (!written.has(rel)) await (0, import_promises7.rm)((0,
|
|
18656
|
+
if (!written.has(rel)) await (0, import_promises7.rm)((0, import_node_path14.join)(dir, rel), { force: true });
|
|
18537
18657
|
}
|
|
18538
|
-
await (0, import_promises7.writeFile)((0,
|
|
18658
|
+
await (0, import_promises7.writeFile)((0, import_node_path14.join)(dir, "index.md"), renderIndex(org?.name ?? "no organization", nodes));
|
|
18539
18659
|
await writeState(dir, { version: org ? page.version : null, organization: org, files: [...written].sort() });
|
|
18540
18660
|
return { ok: true, status: org ? "pulled" : "none", received: nodes.length, dir };
|
|
18541
18661
|
}
|
|
18542
18662
|
async function readOrgMirror(remote = requestRemote()) {
|
|
18543
18663
|
const dir = orgMirrorDir(remote);
|
|
18544
|
-
if (!dir || !(0,
|
|
18664
|
+
if (!dir || !(0, import_node_fs14.existsSync)(dir)) return [];
|
|
18545
18665
|
const out2 = [];
|
|
18546
18666
|
for (const kind of ORG_KINDS) {
|
|
18547
|
-
const kindDir = (0,
|
|
18548
|
-
if (!(0,
|
|
18667
|
+
const kindDir = (0, import_node_path14.join)(dir, kind);
|
|
18668
|
+
if (!(0, import_node_fs14.existsSync)(kindDir)) continue;
|
|
18549
18669
|
let files;
|
|
18550
18670
|
try {
|
|
18551
18671
|
files = await (0, import_promises7.readdir)(kindDir);
|
|
@@ -18555,7 +18675,7 @@ async function readOrgMirror(remote = requestRemote()) {
|
|
|
18555
18675
|
for (const file of files) {
|
|
18556
18676
|
if (!file.endsWith(".md")) continue;
|
|
18557
18677
|
try {
|
|
18558
|
-
const node = parseOrgNode(await (0, import_promises7.readFile)((0,
|
|
18678
|
+
const node = parseOrgNode(await (0, import_promises7.readFile)((0, import_node_path14.join)(kindDir, file), "utf-8"));
|
|
18559
18679
|
if (node) out2.push(node);
|
|
18560
18680
|
} catch {
|
|
18561
18681
|
}
|
|
@@ -18565,29 +18685,29 @@ async function readOrgMirror(remote = requestRemote()) {
|
|
|
18565
18685
|
}
|
|
18566
18686
|
|
|
18567
18687
|
// src/lib/safe-read.ts
|
|
18568
|
-
var
|
|
18569
|
-
var
|
|
18570
|
-
var FLAGS =
|
|
18688
|
+
var import_node_fs15 = require("node:fs");
|
|
18689
|
+
var import_node_path15 = require("node:path");
|
|
18690
|
+
var FLAGS = import_node_fs15.constants;
|
|
18571
18691
|
var NOFOLLOW = FLAGS.O_NOFOLLOW;
|
|
18572
18692
|
var NONBLOCK = FLAGS.O_NONBLOCK;
|
|
18573
18693
|
function closeOpened(fd) {
|
|
18574
18694
|
try {
|
|
18575
|
-
(0,
|
|
18695
|
+
(0, import_node_fs15.closeSync)(fd);
|
|
18576
18696
|
} catch {
|
|
18577
18697
|
}
|
|
18578
18698
|
}
|
|
18579
18699
|
function isInsideRoot(realRoot, realPath) {
|
|
18580
|
-
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(
|
|
18700
|
+
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path15.sep) ? realRoot : realRoot + import_node_path15.sep);
|
|
18581
18701
|
}
|
|
18582
18702
|
function sameOpenedFile(opened, current, nofollowAvailable) {
|
|
18583
18703
|
if (!nofollowAvailable && (opened.ino === 0n || current.ino === 0n)) return false;
|
|
18584
18704
|
return opened.ino === current.ino && opened.dev === current.dev;
|
|
18585
18705
|
}
|
|
18586
18706
|
function openRegularInRoot(root, path) {
|
|
18587
|
-
const full = (0,
|
|
18707
|
+
const full = (0, import_node_path15.isAbsolute)(path) ? path : (0, import_node_path15.join)(root, path);
|
|
18588
18708
|
let fd;
|
|
18589
18709
|
try {
|
|
18590
|
-
fd = (0,
|
|
18710
|
+
fd = (0, import_node_fs15.openSync)(full, import_node_fs15.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
|
|
18591
18711
|
} catch (err2) {
|
|
18592
18712
|
const code = err2.code;
|
|
18593
18713
|
if (code === "ELOOP" || code === "EMLINK" || code === "EFTYPE") return { ok: false, reason: "symlink" };
|
|
@@ -18595,18 +18715,18 @@ function openRegularInRoot(root, path) {
|
|
|
18595
18715
|
return { ok: false, reason: "unreadable" };
|
|
18596
18716
|
}
|
|
18597
18717
|
try {
|
|
18598
|
-
const opened = (0,
|
|
18718
|
+
const opened = (0, import_node_fs15.fstatSync)(fd, { bigint: true });
|
|
18599
18719
|
if (!opened.isFile()) {
|
|
18600
18720
|
closeOpened(fd);
|
|
18601
18721
|
return { ok: false, reason: "not-regular" };
|
|
18602
18722
|
}
|
|
18603
|
-
const realRoot =
|
|
18604
|
-
const realPath =
|
|
18723
|
+
const realRoot = import_node_fs15.realpathSync.native(root);
|
|
18724
|
+
const realPath = import_node_fs15.realpathSync.native(full);
|
|
18605
18725
|
if (!isInsideRoot(realRoot, realPath)) {
|
|
18606
18726
|
closeOpened(fd);
|
|
18607
18727
|
return { ok: false, reason: "outside-root" };
|
|
18608
18728
|
}
|
|
18609
|
-
const current = (0,
|
|
18729
|
+
const current = (0, import_node_fs15.statSync)(realPath, { bigint: true });
|
|
18610
18730
|
if (!sameOpenedFile(opened, current, NOFOLLOW !== void 0)) {
|
|
18611
18731
|
closeOpened(fd);
|
|
18612
18732
|
return { ok: false, reason: NOFOLLOW === void 0 ? "unreadable" : "outside-root" };
|
|
@@ -18628,7 +18748,7 @@ function readOpened(fd, size) {
|
|
|
18628
18748
|
const buffer = Buffer.alloc(size);
|
|
18629
18749
|
let offset = 0;
|
|
18630
18750
|
while (offset < size) {
|
|
18631
|
-
const n = (0,
|
|
18751
|
+
const n = (0, import_node_fs15.readSync)(fd, buffer, offset, size - offset, offset);
|
|
18632
18752
|
if (n === 0) break;
|
|
18633
18753
|
offset += n;
|
|
18634
18754
|
}
|
|
@@ -18943,14 +19063,14 @@ function parseFrontmatter(content) {
|
|
|
18943
19063
|
return { fm, body: match[2].trim() };
|
|
18944
19064
|
}
|
|
18945
19065
|
async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = DEFAULT_BUDGET_TOKENS) {
|
|
18946
|
-
const hasRepoGraph = (0,
|
|
19066
|
+
const hasRepoGraph = (0, import_node_fs16.existsSync)(memoryDir());
|
|
18947
19067
|
const budget = Math.min(budgetTokens, MAX_BUDGET_TOKENS);
|
|
18948
19068
|
const promptTokens = tokenize(promptText);
|
|
18949
19069
|
const orgPromptTerms = orgTerms(promptText);
|
|
18950
19070
|
const nodes = [];
|
|
18951
19071
|
for (const domain of hasRepoGraph ? DOMAINS : []) {
|
|
18952
|
-
const domainDir = (0,
|
|
18953
|
-
if (!(0,
|
|
19072
|
+
const domainDir = (0, import_node_path16.join)(memoryDir(), domain);
|
|
19073
|
+
if (!(0, import_node_fs16.existsSync)(domainDir)) continue;
|
|
18954
19074
|
try {
|
|
18955
19075
|
const files = await (0, import_promises8.readdir)(domainDir);
|
|
18956
19076
|
for (const file of files) {
|
|
@@ -19024,27 +19144,27 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
|
|
|
19024
19144
|
}
|
|
19025
19145
|
|
|
19026
19146
|
// src/lib/injection-record.ts
|
|
19027
|
-
var
|
|
19147
|
+
var import_node_fs18 = require("node:fs");
|
|
19028
19148
|
var import_node_crypto3 = require("node:crypto");
|
|
19029
19149
|
|
|
19030
19150
|
// src/lib/safe-write.ts
|
|
19031
|
-
var
|
|
19032
|
-
var
|
|
19033
|
-
var FLAGS2 =
|
|
19151
|
+
var import_node_fs17 = require("node:fs");
|
|
19152
|
+
var import_node_path17 = require("node:path");
|
|
19153
|
+
var FLAGS2 = import_node_fs17.constants;
|
|
19034
19154
|
var O_NOFOLLOW = FLAGS2.O_NOFOLLOW ?? 0;
|
|
19035
19155
|
var NOFOLLOW_AVAILABLE = O_NOFOLLOW !== 0;
|
|
19036
19156
|
function validateRoot(root) {
|
|
19037
19157
|
try {
|
|
19038
|
-
const parentReal = (0,
|
|
19039
|
-
const expected = (0,
|
|
19158
|
+
const parentReal = (0, import_node_fs17.realpathSync)((0, import_node_path17.dirname)(root));
|
|
19159
|
+
const expected = (0, import_node_path17.join)(parentReal, (0, import_node_path17.basename)(root));
|
|
19040
19160
|
try {
|
|
19041
|
-
(0,
|
|
19161
|
+
(0, import_node_fs17.mkdirSync)(expected);
|
|
19042
19162
|
} catch (e) {
|
|
19043
19163
|
if (e.code !== "EEXIST") return null;
|
|
19044
19164
|
}
|
|
19045
|
-
const st = (0,
|
|
19165
|
+
const st = (0, import_node_fs17.lstatSync)(expected, { bigint: true });
|
|
19046
19166
|
if (st.isSymbolicLink() || !st.isDirectory()) return null;
|
|
19047
|
-
if ((0,
|
|
19167
|
+
if ((0, import_node_fs17.realpathSync)(expected) !== expected) return null;
|
|
19048
19168
|
return { real: expected, dev: st.dev, ino: st.ino };
|
|
19049
19169
|
} catch {
|
|
19050
19170
|
return null;
|
|
@@ -19052,18 +19172,18 @@ function validateRoot(root) {
|
|
|
19052
19172
|
}
|
|
19053
19173
|
function rootUnchanged(root) {
|
|
19054
19174
|
try {
|
|
19055
|
-
const st = (0,
|
|
19175
|
+
const st = (0, import_node_fs17.lstatSync)(root.real, { bigint: true });
|
|
19056
19176
|
return !st.isSymbolicLink() && st.isDirectory() && st.dev === root.dev && st.ino === root.ino;
|
|
19057
19177
|
} catch {
|
|
19058
19178
|
return false;
|
|
19059
19179
|
}
|
|
19060
19180
|
}
|
|
19061
19181
|
function bareName(name2) {
|
|
19062
|
-
return !!name2 && name2 === (0,
|
|
19182
|
+
return !!name2 && name2 === (0, import_node_path17.basename)(name2) && name2 !== "." && name2 !== ".." && !name2.includes("\0");
|
|
19063
19183
|
}
|
|
19064
19184
|
function absentOrRegular(path) {
|
|
19065
19185
|
try {
|
|
19066
|
-
const st = (0,
|
|
19186
|
+
const st = (0, import_node_fs17.lstatSync)(path);
|
|
19067
19187
|
return st.isFile() && !st.isSymbolicLink();
|
|
19068
19188
|
} catch (e) {
|
|
19069
19189
|
return e.code === "ENOENT";
|
|
@@ -19071,11 +19191,11 @@ function absentOrRegular(path) {
|
|
|
19071
19191
|
}
|
|
19072
19192
|
function verifyOpened(fd, path, root) {
|
|
19073
19193
|
try {
|
|
19074
|
-
const opened = (0,
|
|
19194
|
+
const opened = (0, import_node_fs17.fstatSync)(fd, { bigint: true });
|
|
19075
19195
|
if (!opened.isFile() || opened.nlink !== 1n) return false;
|
|
19076
|
-
const real = (0,
|
|
19196
|
+
const real = (0, import_node_fs17.realpathSync)(path);
|
|
19077
19197
|
if (!isInsideRoot(root.real, real)) return false;
|
|
19078
|
-
const current = (0,
|
|
19198
|
+
const current = (0, import_node_fs17.statSync)(real, { bigint: true });
|
|
19079
19199
|
if (!sameOpenedFile(opened, current, NOFOLLOW_AVAILABLE)) return false;
|
|
19080
19200
|
return rootUnchanged(root);
|
|
19081
19201
|
} catch {
|
|
@@ -19084,21 +19204,21 @@ function verifyOpened(fd, path, root) {
|
|
|
19084
19204
|
}
|
|
19085
19205
|
function removeIfOurs(fd, path) {
|
|
19086
19206
|
try {
|
|
19087
|
-
const opened = (0,
|
|
19088
|
-
const at = (0,
|
|
19089
|
-
if (!at.isSymbolicLink() && at.dev === opened.dev && at.ino === opened.ino) (0,
|
|
19207
|
+
const opened = (0, import_node_fs17.fstatSync)(fd, { bigint: true });
|
|
19208
|
+
const at = (0, import_node_fs17.lstatSync)(path, { bigint: true });
|
|
19209
|
+
if (!at.isSymbolicLink() && at.dev === opened.dev && at.ino === opened.ino) (0, import_node_fs17.unlinkSync)(path);
|
|
19090
19210
|
} catch {
|
|
19091
19211
|
}
|
|
19092
19212
|
}
|
|
19093
19213
|
function openTarget(path, append2) {
|
|
19094
|
-
const base =
|
|
19214
|
+
const base = import_node_fs17.constants.O_WRONLY | (append2 ? import_node_fs17.constants.O_APPEND : 0) | O_NOFOLLOW;
|
|
19095
19215
|
try {
|
|
19096
|
-
return { fd: (0,
|
|
19216
|
+
return { fd: (0, import_node_fs17.openSync)(path, base), created: false };
|
|
19097
19217
|
} catch (e) {
|
|
19098
19218
|
if (e.code !== "ENOENT") return null;
|
|
19099
19219
|
}
|
|
19100
19220
|
try {
|
|
19101
|
-
return { fd: (0,
|
|
19221
|
+
return { fd: (0, import_node_fs17.openSync)(path, base | import_node_fs17.constants.O_CREAT | import_node_fs17.constants.O_EXCL, 384), created: true };
|
|
19102
19222
|
} catch {
|
|
19103
19223
|
return null;
|
|
19104
19224
|
}
|
|
@@ -19106,7 +19226,7 @@ function openTarget(path, append2) {
|
|
|
19106
19226
|
function writeVerified(root, name2, hooks, append2, write) {
|
|
19107
19227
|
const r = validateRoot(root);
|
|
19108
19228
|
if (!r || !bareName(name2)) return false;
|
|
19109
|
-
const path = (0,
|
|
19229
|
+
const path = (0, import_node_path17.join)(r.real, name2);
|
|
19110
19230
|
if (!absentOrRegular(path)) return false;
|
|
19111
19231
|
if (!runHook(hooks)) return false;
|
|
19112
19232
|
const opened = openTarget(path, append2);
|
|
@@ -19122,7 +19242,7 @@ function writeVerified(root, name2, hooks, append2, write) {
|
|
|
19122
19242
|
return false;
|
|
19123
19243
|
} finally {
|
|
19124
19244
|
try {
|
|
19125
|
-
(0,
|
|
19245
|
+
(0, import_node_fs17.closeSync)(opened.fd);
|
|
19126
19246
|
} catch {
|
|
19127
19247
|
}
|
|
19128
19248
|
}
|
|
@@ -19137,13 +19257,13 @@ function runHook(hooks) {
|
|
|
19137
19257
|
}
|
|
19138
19258
|
function appendInRoot(root, name2, text, hooks = {}) {
|
|
19139
19259
|
return writeVerified(root, name2, hooks, true, (fd) => {
|
|
19140
|
-
(0,
|
|
19260
|
+
(0, import_node_fs17.writeSync)(fd, text);
|
|
19141
19261
|
});
|
|
19142
19262
|
}
|
|
19143
19263
|
function replaceInRoot(root, name2, text, hooks = {}) {
|
|
19144
19264
|
return writeVerified(root, name2, hooks, false, (fd) => {
|
|
19145
|
-
(0,
|
|
19146
|
-
(0,
|
|
19265
|
+
(0, import_node_fs17.ftruncateSync)(fd, 0);
|
|
19266
|
+
(0, import_node_fs17.writeSync)(fd, text, 0);
|
|
19147
19267
|
});
|
|
19148
19268
|
}
|
|
19149
19269
|
|
|
@@ -19191,7 +19311,7 @@ function hashPrompt(prompt) {
|
|
|
19191
19311
|
function recordInjection(event) {
|
|
19192
19312
|
if (!appendInRoot(projectPath(VERITY_DIR), "injections.jsonl", JSON.stringify(event) + "\n")) return;
|
|
19193
19313
|
try {
|
|
19194
|
-
if ((0,
|
|
19314
|
+
if ((0, import_node_fs18.lstatSync)(recordPath()).size > COMPACT_AT_BYTES) writeEvents(readPendingInjections());
|
|
19195
19315
|
} catch {
|
|
19196
19316
|
}
|
|
19197
19317
|
}
|
|
@@ -19201,7 +19321,7 @@ function writeEvents(events) {
|
|
|
19201
19321
|
function readPendingInjections() {
|
|
19202
19322
|
try {
|
|
19203
19323
|
const p = recordPath();
|
|
19204
|
-
if (!(0,
|
|
19324
|
+
if (!(0, import_node_fs18.existsSync)(p)) return [];
|
|
19205
19325
|
const read2 = readRegularFileInRoot(projectPath(VERITY_DIR), "injections.jsonl", MAX_RECORD_BYTES);
|
|
19206
19326
|
if (!read2.ok) return [];
|
|
19207
19327
|
const out2 = [];
|
|
@@ -19221,13 +19341,13 @@ function readPendingInjections() {
|
|
|
19221
19341
|
|
|
19222
19342
|
// src/lib/memory-sync.ts
|
|
19223
19343
|
var import_promises9 = require("node:fs/promises");
|
|
19224
|
-
var
|
|
19225
|
-
var
|
|
19344
|
+
var import_node_fs21 = require("node:fs");
|
|
19345
|
+
var import_node_path19 = require("node:path");
|
|
19226
19346
|
var import_node_crypto4 = require("node:crypto");
|
|
19227
19347
|
|
|
19228
19348
|
// src/lib/gitignore.ts
|
|
19229
|
-
var
|
|
19230
|
-
var
|
|
19349
|
+
var import_node_child_process7 = require("node:child_process");
|
|
19350
|
+
var import_node_fs19 = require("node:fs");
|
|
19231
19351
|
var VERITY_GITIGNORE_MARKER = "# Verity \u2014 machine-local state.";
|
|
19232
19352
|
var SETTINGS_LOCAL_IGNORE_ENTRY = ".claude/settings.local.json";
|
|
19233
19353
|
var VERITY_GITIGNORE_BLOCK = [
|
|
@@ -19263,7 +19383,7 @@ var SUPERSEDED_MEMORY_LINES = /* @__PURE__ */ new Set([
|
|
|
19263
19383
|
]);
|
|
19264
19384
|
function isIgnored(path) {
|
|
19265
19385
|
try {
|
|
19266
|
-
(0,
|
|
19386
|
+
(0, import_node_child_process7.execSync)(`git check-ignore -q -- "${path}"`, { stdio: "pipe" });
|
|
19267
19387
|
return true;
|
|
19268
19388
|
} catch (err2) {
|
|
19269
19389
|
return err2.status === 1 ? false : null;
|
|
@@ -19283,7 +19403,7 @@ function memoryPosture() {
|
|
|
19283
19403
|
}
|
|
19284
19404
|
function committedMemoryFiles() {
|
|
19285
19405
|
try {
|
|
19286
|
-
return (0,
|
|
19406
|
+
return (0, import_node_child_process7.execSync)("git ls-files -z -- .verity/memory", {
|
|
19287
19407
|
encoding: "utf-8",
|
|
19288
19408
|
stdio: ["pipe", "pipe", "pipe"]
|
|
19289
19409
|
}).split("\0").filter(Boolean);
|
|
@@ -19311,7 +19431,7 @@ function fenceMemoryLines(lines) {
|
|
|
19311
19431
|
function ensureVerityGitignore() {
|
|
19312
19432
|
let content = "";
|
|
19313
19433
|
try {
|
|
19314
|
-
content = (0,
|
|
19434
|
+
content = (0, import_node_fs19.readFileSync)(".gitignore", "utf-8");
|
|
19315
19435
|
} catch {
|
|
19316
19436
|
}
|
|
19317
19437
|
const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
|
|
@@ -19338,7 +19458,7 @@ function ensureVerityGitignore() {
|
|
|
19338
19458
|
const sep5 = text === "" ? "" : text.endsWith("\n") ? "\n" : "\n\n";
|
|
19339
19459
|
text = text + sep5 + VERITY_GITIGNORE_BLOCK;
|
|
19340
19460
|
}
|
|
19341
|
-
if (text !== content) (0,
|
|
19461
|
+
if (text !== content) (0, import_node_fs19.writeFileSync)(".gitignore", text);
|
|
19342
19462
|
return verified(
|
|
19343
19463
|
memoryIsCommitted ? "memory-tracked" : hasSupersededMemory ? "memory-fenced" : needsRepair ? "repaired" : "added"
|
|
19344
19464
|
);
|
|
@@ -19349,7 +19469,7 @@ function ensureVerityGitignore() {
|
|
|
19349
19469
|
function untrackMemory() {
|
|
19350
19470
|
if (committedMemoryFiles().length === 0) return "none";
|
|
19351
19471
|
try {
|
|
19352
|
-
(0,
|
|
19472
|
+
(0, import_node_child_process7.execSync)("git rm -r --cached --quiet -- .verity/memory", { stdio: "pipe" });
|
|
19353
19473
|
return "untracked";
|
|
19354
19474
|
} catch {
|
|
19355
19475
|
return "failed";
|
|
@@ -19358,7 +19478,7 @@ function untrackMemory() {
|
|
|
19358
19478
|
function writeFencedBlock() {
|
|
19359
19479
|
let content = "";
|
|
19360
19480
|
try {
|
|
19361
|
-
content = (0,
|
|
19481
|
+
content = (0, import_node_fs19.readFileSync)(".gitignore", "utf-8");
|
|
19362
19482
|
} catch {
|
|
19363
19483
|
}
|
|
19364
19484
|
const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
|
|
@@ -19370,7 +19490,7 @@ function writeFencedBlock() {
|
|
|
19370
19490
|
text = text + sep5 + VERITY_GITIGNORE_BLOCK;
|
|
19371
19491
|
}
|
|
19372
19492
|
try {
|
|
19373
|
-
(0,
|
|
19493
|
+
(0, import_node_fs19.writeFileSync)(".gitignore", text);
|
|
19374
19494
|
return true;
|
|
19375
19495
|
} catch {
|
|
19376
19496
|
return false;
|
|
@@ -19379,14 +19499,14 @@ function writeFencedBlock() {
|
|
|
19379
19499
|
function fenceMemory() {
|
|
19380
19500
|
let original = null;
|
|
19381
19501
|
try {
|
|
19382
|
-
original = (0,
|
|
19502
|
+
original = (0, import_node_fs19.readFileSync)(".gitignore", "utf-8");
|
|
19383
19503
|
} catch {
|
|
19384
19504
|
original = null;
|
|
19385
19505
|
}
|
|
19386
19506
|
const restore = () => {
|
|
19387
19507
|
try {
|
|
19388
|
-
if (original === null) (0,
|
|
19389
|
-
else (0,
|
|
19508
|
+
if (original === null) (0, import_node_fs19.rmSync)(".gitignore", { force: true });
|
|
19509
|
+
else (0, import_node_fs19.writeFileSync)(".gitignore", original);
|
|
19390
19510
|
} catch {
|
|
19391
19511
|
}
|
|
19392
19512
|
};
|
|
@@ -19404,7 +19524,7 @@ function fenceMemory() {
|
|
|
19404
19524
|
}
|
|
19405
19525
|
function memoryOptOut() {
|
|
19406
19526
|
try {
|
|
19407
|
-
return (0,
|
|
19527
|
+
return (0, import_node_fs19.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
|
|
19408
19528
|
} catch {
|
|
19409
19529
|
return false;
|
|
19410
19530
|
}
|
|
@@ -19412,13 +19532,13 @@ function memoryOptOut() {
|
|
|
19412
19532
|
function keepMemoryTracked() {
|
|
19413
19533
|
let content = "";
|
|
19414
19534
|
try {
|
|
19415
|
-
content = (0,
|
|
19535
|
+
content = (0, import_node_fs19.readFileSync)(".gitignore", "utf-8");
|
|
19416
19536
|
} catch {
|
|
19417
19537
|
}
|
|
19418
19538
|
if (content.includes(MEMORY_OPT_OUT_MARKER)) return "already";
|
|
19419
19539
|
try {
|
|
19420
19540
|
const sep5 = content === "" ? "" : content.endsWith("\n") ? "\n" : "\n\n";
|
|
19421
|
-
(0,
|
|
19541
|
+
(0, import_node_fs19.writeFileSync)(".gitignore", content + sep5 + MEMORY_OPT_OUT_STANZA);
|
|
19422
19542
|
} catch {
|
|
19423
19543
|
return "failed";
|
|
19424
19544
|
}
|
|
@@ -19427,7 +19547,7 @@ function keepMemoryTracked() {
|
|
|
19427
19547
|
function committedVerityState() {
|
|
19428
19548
|
let out2 = "";
|
|
19429
19549
|
try {
|
|
19430
|
-
out2 = (0,
|
|
19550
|
+
out2 = (0, import_node_child_process7.execSync)("git ls-files -z -- .verity", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
19431
19551
|
} catch {
|
|
19432
19552
|
return [];
|
|
19433
19553
|
}
|
|
@@ -19437,12 +19557,12 @@ function untrackVerityState() {
|
|
|
19437
19557
|
const tracked = committedVerityState();
|
|
19438
19558
|
if (tracked.length === 0) return "none";
|
|
19439
19559
|
try {
|
|
19440
|
-
(0,
|
|
19560
|
+
(0, import_node_child_process7.execSync)("git rm -r --cached --quiet -- .verity", { stdio: "pipe" });
|
|
19441
19561
|
const keeps = [".verity/standard.yaml"];
|
|
19442
19562
|
if (memoryPosture() === "committable") keeps.push(".verity/memory");
|
|
19443
19563
|
for (const keep of keeps) {
|
|
19444
19564
|
try {
|
|
19445
|
-
(0,
|
|
19565
|
+
(0, import_node_child_process7.execSync)(`git add -- "${keep}"`, { stdio: "pipe" });
|
|
19446
19566
|
} catch {
|
|
19447
19567
|
}
|
|
19448
19568
|
}
|
|
@@ -19453,26 +19573,26 @@ function untrackVerityState() {
|
|
|
19453
19573
|
}
|
|
19454
19574
|
|
|
19455
19575
|
// src/lib/safe-path.ts
|
|
19456
|
-
var
|
|
19457
|
-
var
|
|
19576
|
+
var import_node_fs20 = require("node:fs");
|
|
19577
|
+
var import_node_path18 = require("node:path");
|
|
19458
19578
|
function resolveInside(baseDir, candidate) {
|
|
19459
19579
|
if (typeof candidate !== "string" || candidate.length === 0) return null;
|
|
19460
|
-
if ((0,
|
|
19461
|
-
const baseAbs = (0,
|
|
19462
|
-
const full = (0,
|
|
19463
|
-
const baseSep = baseAbs.endsWith(
|
|
19580
|
+
if ((0, import_node_path18.isAbsolute)(candidate)) return null;
|
|
19581
|
+
const baseAbs = (0, import_node_path18.resolve)(baseDir);
|
|
19582
|
+
const full = (0, import_node_path18.resolve)(baseAbs, candidate);
|
|
19583
|
+
const baseSep = baseAbs.endsWith(import_node_path18.sep) ? baseAbs : baseAbs + import_node_path18.sep;
|
|
19464
19584
|
if (full !== baseAbs && !full.startsWith(baseSep)) return null;
|
|
19465
19585
|
try {
|
|
19466
|
-
if ((0,
|
|
19467
|
-
const realBase = (0,
|
|
19468
|
-
const realBaseSep = realBase.endsWith(
|
|
19586
|
+
if ((0, import_node_fs20.existsSync)(baseAbs)) {
|
|
19587
|
+
const realBase = (0, import_node_fs20.realpathSync)(baseAbs);
|
|
19588
|
+
const realBaseSep = realBase.endsWith(import_node_path18.sep) ? realBase : realBase + import_node_path18.sep;
|
|
19469
19589
|
let probe = full;
|
|
19470
|
-
while (!(0,
|
|
19471
|
-
const parent = (0,
|
|
19590
|
+
while (!(0, import_node_fs20.existsSync)(probe)) {
|
|
19591
|
+
const parent = (0, import_node_path18.dirname)(probe);
|
|
19472
19592
|
if (parent === probe) break;
|
|
19473
19593
|
probe = parent;
|
|
19474
19594
|
}
|
|
19475
|
-
const realProbe = (0,
|
|
19595
|
+
const realProbe = (0, import_node_fs20.realpathSync)(probe);
|
|
19476
19596
|
if (realProbe !== realBase && !realProbe.startsWith(realBaseSep)) return null;
|
|
19477
19597
|
}
|
|
19478
19598
|
} catch {
|
|
@@ -19480,37 +19600,37 @@ function resolveInside(baseDir, candidate) {
|
|
|
19480
19600
|
}
|
|
19481
19601
|
return full;
|
|
19482
19602
|
}
|
|
19483
|
-
var O_NOFOLLOW2 = typeof
|
|
19603
|
+
var O_NOFOLLOW2 = typeof import_node_fs20.constants.O_NOFOLLOW === "number" ? import_node_fs20.constants.O_NOFOLLOW : 0;
|
|
19484
19604
|
function readFileInside(baseDir, candidate, maxBytes) {
|
|
19485
19605
|
const full = resolveInside(baseDir, candidate);
|
|
19486
19606
|
if (!full) return null;
|
|
19487
19607
|
let realParent;
|
|
19488
19608
|
let realBase;
|
|
19489
19609
|
try {
|
|
19490
|
-
realParent = (0,
|
|
19491
|
-
realBase = (0,
|
|
19610
|
+
realParent = (0, import_node_fs20.realpathSync)((0, import_node_path18.dirname)(full));
|
|
19611
|
+
realBase = (0, import_node_fs20.realpathSync)((0, import_node_path18.resolve)(baseDir));
|
|
19492
19612
|
} catch {
|
|
19493
19613
|
return null;
|
|
19494
19614
|
}
|
|
19495
|
-
const realBaseSep = realBase.endsWith(
|
|
19615
|
+
const realBaseSep = realBase.endsWith(import_node_path18.sep) ? realBase : realBase + import_node_path18.sep;
|
|
19496
19616
|
if (realParent !== realBase && !realParent.startsWith(realBaseSep)) return null;
|
|
19497
|
-
const target = (0,
|
|
19617
|
+
const target = (0, import_node_path18.join)(realParent, (0, import_node_path18.basename)(full));
|
|
19498
19618
|
let fd = null;
|
|
19499
19619
|
try {
|
|
19500
|
-
fd = (0,
|
|
19501
|
-
const st = (0,
|
|
19620
|
+
fd = (0, import_node_fs20.openSync)(target, import_node_fs20.constants.O_RDONLY | O_NOFOLLOW2);
|
|
19621
|
+
const st = (0, import_node_fs20.fstatSync)(fd);
|
|
19502
19622
|
if (!st.isFile()) return null;
|
|
19503
19623
|
const cap2 = Math.min(maxBytes, st.size);
|
|
19504
19624
|
if (cap2 <= 0) return "";
|
|
19505
19625
|
const buf = Buffer.alloc(cap2);
|
|
19506
|
-
const bytesRead = (0,
|
|
19626
|
+
const bytesRead = (0, import_node_fs20.readSync)(fd, buf, 0, cap2, 0);
|
|
19507
19627
|
return buf.subarray(0, bytesRead).toString("utf-8");
|
|
19508
19628
|
} catch {
|
|
19509
19629
|
return null;
|
|
19510
19630
|
} finally {
|
|
19511
19631
|
if (fd !== null) {
|
|
19512
19632
|
try {
|
|
19513
|
-
(0,
|
|
19633
|
+
(0, import_node_fs20.closeSync)(fd);
|
|
19514
19634
|
} catch {
|
|
19515
19635
|
}
|
|
19516
19636
|
}
|
|
@@ -19593,32 +19713,32 @@ var syncStateFile = () => projectPath(`${VERITY_DIR}/.memory-sync-state.json`);
|
|
|
19593
19713
|
async function ensureMemoryDir() {
|
|
19594
19714
|
await (0, import_promises9.mkdir)(memoryDir2(), { recursive: true });
|
|
19595
19715
|
for (const domain of DOMAINS2) {
|
|
19596
|
-
await (0, import_promises9.mkdir)((0,
|
|
19716
|
+
await (0, import_promises9.mkdir)((0, import_node_path19.join)(memoryDir2(), domain), { recursive: true });
|
|
19597
19717
|
}
|
|
19598
|
-
if (!(0,
|
|
19599
|
-
await (0, import_promises9.writeFile)((0,
|
|
19718
|
+
if (!(0, import_node_fs21.existsSync)((0, import_node_path19.join)(memoryDir2(), "SCHEMA.md"))) {
|
|
19719
|
+
await (0, import_promises9.writeFile)((0, import_node_path19.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
|
|
19600
19720
|
}
|
|
19601
|
-
if (!(0,
|
|
19602
|
-
await (0, import_promises9.writeFile)((0,
|
|
19721
|
+
if (!(0, import_node_fs21.existsSync)((0, import_node_path19.join)(memoryDir2(), "index.md"))) {
|
|
19722
|
+
await (0, import_promises9.writeFile)((0, import_node_path19.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
|
|
19603
19723
|
}
|
|
19604
|
-
if (!(0,
|
|
19605
|
-
await (0, import_promises9.writeFile)((0,
|
|
19724
|
+
if (!(0, import_node_fs21.existsSync)((0, import_node_path19.join)(memoryDir2(), "log.md"))) {
|
|
19725
|
+
await (0, import_promises9.writeFile)((0, import_node_path19.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
|
|
19606
19726
|
}
|
|
19607
19727
|
}
|
|
19608
19728
|
async function buildManifest() {
|
|
19609
|
-
if (!(0,
|
|
19729
|
+
if (!(0, import_node_fs21.existsSync)(memoryDir2())) {
|
|
19610
19730
|
return { schema_version: 1, nodes: [], index_hash: null, log_length: 0 };
|
|
19611
19731
|
}
|
|
19612
19732
|
const nodes = [];
|
|
19613
19733
|
for (const domain of DOMAINS2) {
|
|
19614
|
-
const domainDir = (0,
|
|
19615
|
-
if (!(0,
|
|
19734
|
+
const domainDir = (0, import_node_path19.join)(memoryDir2(), domain);
|
|
19735
|
+
if (!(0, import_node_fs21.existsSync)(domainDir)) continue;
|
|
19616
19736
|
try {
|
|
19617
19737
|
const files = await (0, import_promises9.readdir)(domainDir);
|
|
19618
19738
|
for (const file of files) {
|
|
19619
19739
|
if (!file.endsWith(".md")) continue;
|
|
19620
19740
|
const filePath = `${domain}/${file}`;
|
|
19621
|
-
const fullPath = (0,
|
|
19741
|
+
const fullPath = (0, import_node_path19.join)(memoryDir2(), filePath);
|
|
19622
19742
|
try {
|
|
19623
19743
|
const content = await (0, import_promises9.readFile)(fullPath, "utf-8");
|
|
19624
19744
|
const hash = (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex").slice(0, 16);
|
|
@@ -19631,13 +19751,13 @@ async function buildManifest() {
|
|
|
19631
19751
|
}
|
|
19632
19752
|
let indexHash = null;
|
|
19633
19753
|
try {
|
|
19634
|
-
const indexContent = await (0, import_promises9.readFile)((0,
|
|
19754
|
+
const indexContent = await (0, import_promises9.readFile)((0, import_node_path19.join)(memoryDir2(), "index.md"), "utf-8");
|
|
19635
19755
|
indexHash = `sha256:${(0, import_node_crypto4.createHash)("sha256").update(indexContent).digest("hex").slice(0, 16)}`;
|
|
19636
19756
|
} catch {
|
|
19637
19757
|
}
|
|
19638
19758
|
let logLength = 0;
|
|
19639
19759
|
try {
|
|
19640
|
-
const logContent = await (0, import_promises9.readFile)((0,
|
|
19760
|
+
const logContent = await (0, import_promises9.readFile)((0, import_node_path19.join)(memoryDir2(), "log.md"), "utf-8");
|
|
19641
19761
|
logLength = logContent.split("\n").length;
|
|
19642
19762
|
} catch {
|
|
19643
19763
|
}
|
|
@@ -19648,15 +19768,15 @@ function hashContent(content) {
|
|
|
19648
19768
|
}
|
|
19649
19769
|
async function readOnDiskNodes() {
|
|
19650
19770
|
const out2 = /* @__PURE__ */ new Map();
|
|
19651
|
-
if (!(0,
|
|
19771
|
+
if (!(0, import_node_fs21.existsSync)(memoryDir2())) return out2;
|
|
19652
19772
|
for (const domain of DOMAINS2) {
|
|
19653
|
-
const domainDir = (0,
|
|
19654
|
-
if (!(0,
|
|
19773
|
+
const domainDir = (0, import_node_path19.join)(memoryDir2(), domain);
|
|
19774
|
+
if (!(0, import_node_fs21.existsSync)(domainDir)) continue;
|
|
19655
19775
|
try {
|
|
19656
19776
|
for (const file of await (0, import_promises9.readdir)(domainDir)) {
|
|
19657
19777
|
if (!file.endsWith(".md")) continue;
|
|
19658
19778
|
try {
|
|
19659
|
-
out2.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0,
|
|
19779
|
+
out2.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0, import_node_path19.join)(domainDir, file), "utf-8")));
|
|
19660
19780
|
} catch {
|
|
19661
19781
|
}
|
|
19662
19782
|
}
|
|
@@ -19693,7 +19813,7 @@ async function recordSyncedNodePaths() {
|
|
|
19693
19813
|
}
|
|
19694
19814
|
}
|
|
19695
19815
|
async function writeFileAtomic(path, content) {
|
|
19696
|
-
await (0, import_promises9.mkdir)((0,
|
|
19816
|
+
await (0, import_promises9.mkdir)((0, import_node_path19.dirname)(path), { recursive: true });
|
|
19697
19817
|
const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
19698
19818
|
await (0, import_promises9.writeFile)(tmp, content);
|
|
19699
19819
|
await (0, import_promises9.rename)(tmp, path);
|
|
@@ -19707,8 +19827,8 @@ async function computeEditedNodeUploads() {
|
|
|
19707
19827
|
const uploads = [];
|
|
19708
19828
|
for (const [path, prevHash] of prev) {
|
|
19709
19829
|
if (prevHash == null) continue;
|
|
19710
|
-
const full = (0,
|
|
19711
|
-
if (!(0,
|
|
19830
|
+
const full = (0, import_node_path19.join)(memoryDir2(), path);
|
|
19831
|
+
if (!(0, import_node_fs21.existsSync)(full)) continue;
|
|
19712
19832
|
let content;
|
|
19713
19833
|
try {
|
|
19714
19834
|
content = await (0, import_promises9.readFile)(full, "utf-8");
|
|
@@ -19752,8 +19872,8 @@ async function applyMemoryWrites(writes, opts = {}) {
|
|
|
19752
19872
|
const logLines = [`- ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 16)} \u2014 Applied ${count} write(s) from server`];
|
|
19753
19873
|
for (const n of notes) logLines.push(` - ${n}`);
|
|
19754
19874
|
try {
|
|
19755
|
-
const existing = (0,
|
|
19756
|
-
await (0, import_promises9.writeFile)((0,
|
|
19875
|
+
const existing = (0, import_node_fs21.existsSync)((0, import_node_path19.join)(memoryDir2(), "log.md")) ? await (0, import_promises9.readFile)((0, import_node_path19.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
|
|
19876
|
+
await (0, import_promises9.writeFile)((0, import_node_path19.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
|
|
19757
19877
|
} catch {
|
|
19758
19878
|
}
|
|
19759
19879
|
if (opts.baseline === "written") await mergeSyncBaseline(synced);
|
|
@@ -19763,7 +19883,7 @@ async function applyMemoryWrites(writes, opts = {}) {
|
|
|
19763
19883
|
async function mergeSyncBaseline(entries) {
|
|
19764
19884
|
if (entries.size === 0) return;
|
|
19765
19885
|
try {
|
|
19766
|
-
if ((0,
|
|
19886
|
+
if ((0, import_node_fs21.existsSync)(syncStateFile())) {
|
|
19767
19887
|
try {
|
|
19768
19888
|
JSON.parse(await (0, import_promises9.readFile)(syncStateFile(), "utf-8"));
|
|
19769
19889
|
} catch {
|
|
@@ -19791,7 +19911,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
|
|
|
19791
19911
|
notes.push(`${write.path}: dropped unmatched file_globs [${grounded.dropped.join(", ")}]`);
|
|
19792
19912
|
}
|
|
19793
19913
|
}
|
|
19794
|
-
if ((0,
|
|
19914
|
+
if ((0, import_node_fs21.existsSync)(fullPath)) {
|
|
19795
19915
|
let existing = "";
|
|
19796
19916
|
try {
|
|
19797
19917
|
existing = await (0, import_promises9.readFile)(fullPath, "utf-8");
|
|
@@ -19807,7 +19927,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
|
|
|
19807
19927
|
notes.push(`${write.path}: updated from server (untouched here since the server delivered it)`);
|
|
19808
19928
|
}
|
|
19809
19929
|
}
|
|
19810
|
-
await (0, import_promises9.mkdir)((0,
|
|
19930
|
+
await (0, import_promises9.mkdir)((0, import_node_path19.dirname)(fullPath), { recursive: true });
|
|
19811
19931
|
await (0, import_promises9.writeFile)(fullPath, content);
|
|
19812
19932
|
return { written: true, syncedHash: hashContent(content), notes };
|
|
19813
19933
|
}
|
|
@@ -19848,8 +19968,8 @@ async function regenerateIndex() {
|
|
|
19848
19968
|
];
|
|
19849
19969
|
let totalNodes = 0;
|
|
19850
19970
|
for (const domain of DOMAINS2.filter((d) => d !== "_archive")) {
|
|
19851
|
-
const domainDir = (0,
|
|
19852
|
-
if (!(0,
|
|
19971
|
+
const domainDir = (0, import_node_path19.join)(memoryDir2(), domain);
|
|
19972
|
+
if (!(0, import_node_fs21.existsSync)(domainDir)) continue;
|
|
19853
19973
|
try {
|
|
19854
19974
|
const files = await (0, import_promises9.readdir)(domainDir);
|
|
19855
19975
|
const mdFiles = files.filter((f) => f.endsWith(".md"));
|
|
@@ -19859,7 +19979,7 @@ async function regenerateIndex() {
|
|
|
19859
19979
|
for (const file of mdFiles.sort()) {
|
|
19860
19980
|
const slug = file.replace(/\.md$/, "");
|
|
19861
19981
|
try {
|
|
19862
|
-
const content = await (0, import_promises9.readFile)((0,
|
|
19982
|
+
const content = await (0, import_promises9.readFile)((0, import_node_path19.join)(domainDir, file), "utf-8");
|
|
19863
19983
|
const title = pickFrontmatter(content, "title") ?? slug;
|
|
19864
19984
|
const kind = pickFrontmatter(content, "kind") ?? "-";
|
|
19865
19985
|
const confidence = pickFrontmatter(content, "confidence");
|
|
@@ -19883,7 +20003,7 @@ async function regenerateIndex() {
|
|
|
19883
20003
|
lines.push("No nodes yet. Run an analysis to start building the knowledge graph.");
|
|
19884
20004
|
}
|
|
19885
20005
|
const next = lines.join("\n") + "\n";
|
|
19886
|
-
const indexPath = (0,
|
|
20006
|
+
const indexPath = (0, import_node_path19.join)(memoryDir2(), "index.md");
|
|
19887
20007
|
let existing = null;
|
|
19888
20008
|
try {
|
|
19889
20009
|
existing = await (0, import_promises9.readFile)(indexPath, "utf-8");
|
|
@@ -20280,9 +20400,9 @@ function hasLegacyMemoryBlock(text) {
|
|
|
20280
20400
|
return findMarker(text, LEGACY_MD_START) !== -1;
|
|
20281
20401
|
}
|
|
20282
20402
|
async function ensureClaudeMdPointer(cwd = repoRoot()) {
|
|
20283
|
-
const claudeMdPath = (0,
|
|
20403
|
+
const claudeMdPath = (0, import_node_path19.join)(cwd, "CLAUDE.md");
|
|
20284
20404
|
let existing = "";
|
|
20285
|
-
if ((0,
|
|
20405
|
+
if ((0, import_node_fs21.existsSync)(claudeMdPath)) {
|
|
20286
20406
|
existing = await (0, import_promises9.readFile)(claudeMdPath, "utf-8");
|
|
20287
20407
|
}
|
|
20288
20408
|
let startTag = CLAUDE_MD_START;
|
|
@@ -20423,9 +20543,9 @@ Body content (\u22648KB). Use [[node-id]] wikilinks for cross-references.
|
|
|
20423
20543
|
`;
|
|
20424
20544
|
|
|
20425
20545
|
// src/lib/dossier-session.ts
|
|
20426
|
-
var
|
|
20546
|
+
var import_node_fs26 = require("node:fs");
|
|
20427
20547
|
var import_node_crypto8 = require("node:crypto");
|
|
20428
|
-
var
|
|
20548
|
+
var import_node_path22 = require("node:path");
|
|
20429
20549
|
|
|
20430
20550
|
// src/lib/pending-repeat.ts
|
|
20431
20551
|
var STOP = /* @__PURE__ */ new Set([
|
|
@@ -20530,8 +20650,8 @@ function statementAnchorKey(file, patternId) {
|
|
|
20530
20650
|
|
|
20531
20651
|
// src/lib/dossier/log.ts
|
|
20532
20652
|
var import_node_crypto5 = require("node:crypto");
|
|
20533
|
-
var
|
|
20534
|
-
var
|
|
20653
|
+
var import_node_fs22 = require("node:fs");
|
|
20654
|
+
var import_node_path20 = require("node:path");
|
|
20535
20655
|
var CRC_TABLE = (() => {
|
|
20536
20656
|
const t = new Int32Array(256);
|
|
20537
20657
|
for (let i2 = 0; i2 < 256; i2++) {
|
|
@@ -20550,13 +20670,13 @@ function crc32(s) {
|
|
|
20550
20670
|
function openDossier(identity) {
|
|
20551
20671
|
try {
|
|
20552
20672
|
const dir = dossierDir(identity);
|
|
20553
|
-
(0,
|
|
20673
|
+
(0, import_node_fs22.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
20554
20674
|
return {
|
|
20555
20675
|
dir,
|
|
20556
20676
|
identity,
|
|
20557
|
-
eventsPath: (0,
|
|
20558
|
-
foldPath: (0,
|
|
20559
|
-
rotatedDir: (0,
|
|
20677
|
+
eventsPath: (0, import_node_path20.join)(dir, "events.jsonl"),
|
|
20678
|
+
foldPath: (0, import_node_path20.join)(dir, "fold.json"),
|
|
20679
|
+
rotatedDir: (0, import_node_path20.join)(dir, "rotated")
|
|
20560
20680
|
};
|
|
20561
20681
|
} catch {
|
|
20562
20682
|
return null;
|
|
@@ -20618,7 +20738,7 @@ function appendEvent(d, ev) {
|
|
|
20618
20738
|
at: ev.at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
20619
20739
|
...ev
|
|
20620
20740
|
});
|
|
20621
|
-
(0,
|
|
20741
|
+
(0, import_node_fs22.appendFileSync)(d.eventsPath, line2, { mode: 384 });
|
|
20622
20742
|
return true;
|
|
20623
20743
|
} catch {
|
|
20624
20744
|
return false;
|
|
@@ -20626,14 +20746,14 @@ function appendEvent(d, ev) {
|
|
|
20626
20746
|
}
|
|
20627
20747
|
function rotateIfNeeded2(d) {
|
|
20628
20748
|
try {
|
|
20629
|
-
if (!(0,
|
|
20630
|
-
if ((0,
|
|
20631
|
-
(0,
|
|
20632
|
-
(0,
|
|
20633
|
-
const kept = (0,
|
|
20749
|
+
if (!(0, import_node_fs22.existsSync)(d.eventsPath)) return;
|
|
20750
|
+
if ((0, import_node_fs22.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
|
|
20751
|
+
(0, import_node_fs22.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
|
|
20752
|
+
(0, import_node_fs22.renameSync)(d.eventsPath, (0, import_node_path20.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
|
|
20753
|
+
const kept = (0, import_node_fs22.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
|
|
20634
20754
|
for (const stale of kept.slice(0, Math.max(0, kept.length - ROTATE_KEEP))) {
|
|
20635
20755
|
try {
|
|
20636
|
-
(0,
|
|
20756
|
+
(0, import_node_fs22.renameSync)((0, import_node_path20.join)(d.rotatedDir, stale), (0, import_node_path20.join)(d.rotatedDir, `${stale}.pruned`));
|
|
20637
20757
|
} catch {
|
|
20638
20758
|
}
|
|
20639
20759
|
}
|
|
@@ -20643,8 +20763,8 @@ function rotateIfNeeded2(d) {
|
|
|
20643
20763
|
|
|
20644
20764
|
// src/lib/dossier/fold-dossier.ts
|
|
20645
20765
|
var import_node_crypto6 = require("node:crypto");
|
|
20646
|
-
var
|
|
20647
|
-
var
|
|
20766
|
+
var import_node_fs23 = require("node:fs");
|
|
20767
|
+
var import_node_path21 = require("node:path");
|
|
20648
20768
|
var EMPTY_CAPABILITIES = () => ({
|
|
20649
20769
|
human_reachable: { value: "unknown", tier: "unknown" },
|
|
20650
20770
|
authorship_observability: { value: "unknown", tier: "unknown" },
|
|
@@ -20695,12 +20815,12 @@ function foldDossier(d, opts = {}) {
|
|
|
20695
20815
|
}
|
|
20696
20816
|
};
|
|
20697
20817
|
try {
|
|
20698
|
-
if ((0,
|
|
20699
|
-
const files = (0,
|
|
20818
|
+
if ((0, import_node_fs23.existsSync)(d.rotatedDir)) {
|
|
20819
|
+
const files = (0, import_node_fs23.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
|
|
20700
20820
|
state.meta.rotations = files.length;
|
|
20701
20821
|
for (const f of files) {
|
|
20702
20822
|
try {
|
|
20703
|
-
ingest((0,
|
|
20823
|
+
ingest((0, import_node_fs23.readFileSync)((0, import_node_path21.join)(d.rotatedDir, f), "utf8"));
|
|
20704
20824
|
} catch {
|
|
20705
20825
|
state.meta.dropped_lines++;
|
|
20706
20826
|
}
|
|
@@ -20709,9 +20829,9 @@ function foldDossier(d, opts = {}) {
|
|
|
20709
20829
|
} catch {
|
|
20710
20830
|
}
|
|
20711
20831
|
try {
|
|
20712
|
-
if ((0,
|
|
20713
|
-
state.meta.upto_offset = (0,
|
|
20714
|
-
ingest((0,
|
|
20832
|
+
if ((0, import_node_fs23.existsSync)(d.eventsPath)) {
|
|
20833
|
+
state.meta.upto_offset = (0, import_node_fs23.statSync)(d.eventsPath).size;
|
|
20834
|
+
ingest((0, import_node_fs23.readFileSync)(d.eventsPath, "utf8"));
|
|
20715
20835
|
}
|
|
20716
20836
|
} catch {
|
|
20717
20837
|
}
|
|
@@ -20982,7 +21102,7 @@ function applyBounds(state, input) {
|
|
|
20982
21102
|
}
|
|
20983
21103
|
|
|
20984
21104
|
// src/lib/dossier/cache.ts
|
|
20985
|
-
var
|
|
21105
|
+
var import_node_fs24 = require("node:fs");
|
|
20986
21106
|
function compactState(s) {
|
|
20987
21107
|
const ms = (iso) => Date.parse(iso) || 0;
|
|
20988
21108
|
return {
|
|
@@ -21111,20 +21231,20 @@ function encodeState(s) {
|
|
|
21111
21231
|
function writeFoldCache(d, state) {
|
|
21112
21232
|
try {
|
|
21113
21233
|
const tmp = `${d.foldPath}.${process.pid}.tmp`;
|
|
21114
|
-
(0,
|
|
21115
|
-
(0,
|
|
21234
|
+
(0, import_node_fs24.writeFileSync)(tmp, encodeState(state), { mode: 384 });
|
|
21235
|
+
(0, import_node_fs24.renameSync)(tmp, d.foldPath);
|
|
21116
21236
|
} catch {
|
|
21117
21237
|
}
|
|
21118
21238
|
}
|
|
21119
21239
|
function readFoldCache(d) {
|
|
21120
21240
|
try {
|
|
21121
|
-
if (!(0,
|
|
21122
|
-
const raw = JSON.parse((0,
|
|
21241
|
+
if (!(0, import_node_fs24.existsSync)(d.foldPath)) return null;
|
|
21242
|
+
const raw = JSON.parse((0, import_node_fs24.readFileSync)(d.foldPath, "utf8"));
|
|
21123
21243
|
if (raw?.v !== 1) return null;
|
|
21124
21244
|
const cached2 = expandState(raw);
|
|
21125
21245
|
if (!cached2?.meta) return null;
|
|
21126
|
-
const size = (0,
|
|
21127
|
-
const rotations = (0,
|
|
21246
|
+
const size = (0, import_node_fs24.existsSync)(d.eventsPath) ? (0, import_node_fs24.statSync)(d.eventsPath).size : 0;
|
|
21247
|
+
const rotations = (0, import_node_fs24.existsSync)(d.rotatedDir) ? (0, import_node_fs24.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
|
|
21128
21248
|
if (cached2.meta.upto_offset !== size || cached2.meta.rotations !== rotations) return null;
|
|
21129
21249
|
return cached2;
|
|
21130
21250
|
} catch {
|
|
@@ -21175,13 +21295,13 @@ function assessContinuity(i2) {
|
|
|
21175
21295
|
|
|
21176
21296
|
// src/lib/dossier/reanchor.ts
|
|
21177
21297
|
var import_node_crypto7 = require("node:crypto");
|
|
21178
|
-
var
|
|
21298
|
+
var import_node_fs25 = require("node:fs");
|
|
21179
21299
|
function lineSha(text) {
|
|
21180
21300
|
return (0, import_node_crypto7.createHash)("sha256").update(text.trim()).digest("hex").slice(0, HASH_WIDTH);
|
|
21181
21301
|
}
|
|
21182
21302
|
function fileHash(path) {
|
|
21183
21303
|
try {
|
|
21184
|
-
return (0, import_node_crypto7.createHash)("sha256").update((0,
|
|
21304
|
+
return (0, import_node_crypto7.createHash)("sha256").update((0, import_node_fs25.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
|
|
21185
21305
|
} catch {
|
|
21186
21306
|
return null;
|
|
21187
21307
|
}
|
|
@@ -21553,20 +21673,20 @@ function foreignAuthoredPaths(identity, opts = {}) {
|
|
|
21553
21673
|
let sessions = 0;
|
|
21554
21674
|
try {
|
|
21555
21675
|
const dir = treeDir(identity);
|
|
21556
|
-
if (!(0,
|
|
21557
|
-
for (const entry of (0,
|
|
21676
|
+
if (!(0, import_node_fs26.existsSync)(dir)) return { paths: [], sessions: 0 };
|
|
21677
|
+
for (const entry of (0, import_node_fs26.readdirSync)(dir, { withFileTypes: true })) {
|
|
21558
21678
|
if (!entry.isDirectory()) continue;
|
|
21559
21679
|
if (entry.name === identity.sessionKey) continue;
|
|
21560
|
-
const log = (0,
|
|
21680
|
+
const log = (0, import_node_path22.join)(dir, entry.name, "events.jsonl");
|
|
21561
21681
|
try {
|
|
21562
|
-
if (!(0,
|
|
21563
|
-
if (now - (0,
|
|
21682
|
+
if (!(0, import_node_fs26.existsSync)(log)) continue;
|
|
21683
|
+
if (now - (0, import_node_fs26.statSync)(log).mtimeMs > windowMs) continue;
|
|
21564
21684
|
const sib = {
|
|
21565
|
-
dir: (0,
|
|
21685
|
+
dir: (0, import_node_path22.join)(dir, entry.name),
|
|
21566
21686
|
identity,
|
|
21567
21687
|
eventsPath: log,
|
|
21568
|
-
foldPath: (0,
|
|
21569
|
-
rotatedDir: (0,
|
|
21688
|
+
foldPath: (0, import_node_path22.join)(dir, entry.name, "fold.json"),
|
|
21689
|
+
rotatedDir: (0, import_node_path22.join)(dir, entry.name, "rotated")
|
|
21570
21690
|
};
|
|
21571
21691
|
const state = readFoldCache(sib) ?? foldDossier(sib);
|
|
21572
21692
|
sessions++;
|
|
@@ -21594,25 +21714,25 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
|
|
|
21594
21714
|
let removed = 0;
|
|
21595
21715
|
try {
|
|
21596
21716
|
const mine = dossierDir(identity);
|
|
21597
|
-
const userDir = (0,
|
|
21598
|
-
if (!(0,
|
|
21717
|
+
const userDir = (0, import_node_path22.dirname)((0, import_node_path22.dirname)(mine));
|
|
21718
|
+
if (!(0, import_node_fs26.existsSync)(userDir)) return 0;
|
|
21599
21719
|
const cutoff = Date.now() - maxAgeMs;
|
|
21600
|
-
for (const tree of (0,
|
|
21720
|
+
for (const tree of (0, import_node_fs26.readdirSync)(userDir, { withFileTypes: true })) {
|
|
21601
21721
|
if (!tree.isDirectory()) continue;
|
|
21602
|
-
const treePath = (0,
|
|
21722
|
+
const treePath = (0, import_node_path22.join)(userDir, tree.name);
|
|
21603
21723
|
let live = 0;
|
|
21604
|
-
for (const entry of (0,
|
|
21724
|
+
for (const entry of (0, import_node_fs26.readdirSync)(treePath, { withFileTypes: true })) {
|
|
21605
21725
|
if (!entry.isDirectory()) continue;
|
|
21606
|
-
const dir = (0,
|
|
21726
|
+
const dir = (0, import_node_path22.join)(treePath, entry.name);
|
|
21607
21727
|
if (dir === mine) {
|
|
21608
21728
|
live++;
|
|
21609
21729
|
continue;
|
|
21610
21730
|
}
|
|
21611
21731
|
try {
|
|
21612
|
-
const log = (0,
|
|
21613
|
-
const at = (0,
|
|
21732
|
+
const log = (0, import_node_path22.join)(dir, "events.jsonl");
|
|
21733
|
+
const at = (0, import_node_fs26.existsSync)(log) ? (0, import_node_fs26.statSync)(log).mtimeMs : (0, import_node_fs26.statSync)(dir).mtimeMs;
|
|
21614
21734
|
if (at < cutoff) {
|
|
21615
|
-
(0,
|
|
21735
|
+
(0, import_node_fs26.rmSync)(dir, { recursive: true, force: true });
|
|
21616
21736
|
removed++;
|
|
21617
21737
|
} else {
|
|
21618
21738
|
live++;
|
|
@@ -21622,7 +21742,7 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
|
|
|
21622
21742
|
}
|
|
21623
21743
|
if (live === 0) {
|
|
21624
21744
|
try {
|
|
21625
|
-
(0,
|
|
21745
|
+
(0, import_node_fs26.rmSync)(treePath, { recursive: false, force: false });
|
|
21626
21746
|
} catch {
|
|
21627
21747
|
}
|
|
21628
21748
|
}
|
|
@@ -21639,8 +21759,8 @@ function sessionDossier(token, sessionId) {
|
|
|
21639
21759
|
}
|
|
21640
21760
|
function hasActiveGoal(d) {
|
|
21641
21761
|
try {
|
|
21642
|
-
if (!(0,
|
|
21643
|
-
return (0,
|
|
21762
|
+
if (!(0, import_node_fs26.existsSync)(d.eventsPath)) return false;
|
|
21763
|
+
return (0, import_node_fs26.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
|
|
21644
21764
|
} catch {
|
|
21645
21765
|
return false;
|
|
21646
21766
|
}
|
|
@@ -21664,7 +21784,7 @@ function recordTurn(d, t) {
|
|
|
21664
21784
|
for (const a of t.authored) {
|
|
21665
21785
|
const origin = a.owner === "subagent" ? "subagent" : "edit_tool";
|
|
21666
21786
|
const prior = t.known?.authored?.get(a.p);
|
|
21667
|
-
const hash = fileHash((0,
|
|
21787
|
+
const hash = fileHash((0, import_node_path22.join)(root, a.p));
|
|
21668
21788
|
const hunks = Math.max(0, a.h - (prior?.hunks ?? 0));
|
|
21669
21789
|
const adds = Math.max(0, a.a - (prior?.adds ?? 0));
|
|
21670
21790
|
const dels = Math.max(0, a.d - (prior?.dels ?? 0));
|
|
@@ -21697,7 +21817,7 @@ function recordTurn(d, t) {
|
|
|
21697
21817
|
}
|
|
21698
21818
|
const seenDivergence = t.known?.divergence ?? /* @__PURE__ */ new Set();
|
|
21699
21819
|
for (const u of t.unobserved) {
|
|
21700
|
-
const hash = fileHash((0,
|
|
21820
|
+
const hash = fileHash((0, import_node_path22.join)(root, u.p));
|
|
21701
21821
|
if (seenDivergence.has(divergenceKey(u.p, hash))) continue;
|
|
21702
21822
|
appendEvent(d, { k: "divergence", kind: "external_mutation", path: u.p, hash });
|
|
21703
21823
|
}
|
|
@@ -21732,8 +21852,8 @@ function recordVerdict(d, v) {
|
|
|
21732
21852
|
if (!sent.has(f.file)) continue;
|
|
21733
21853
|
if (!lines.has(f.file)) {
|
|
21734
21854
|
try {
|
|
21735
|
-
const abs = (0,
|
|
21736
|
-
lines.set(f.file, (0,
|
|
21855
|
+
const abs = (0, import_node_path22.join)(root, f.file);
|
|
21856
|
+
lines.set(f.file, (0, import_node_fs26.existsSync)(abs) ? (0, import_node_fs26.readFileSync)(abs, "utf8").split("\n") : null);
|
|
21737
21857
|
} catch {
|
|
21738
21858
|
lines.set(f.file, null);
|
|
21739
21859
|
}
|
|
@@ -21833,8 +21953,8 @@ function recallMemory(d, identity, opts) {
|
|
|
21833
21953
|
budgetBytes: opts.budgetBytes,
|
|
21834
21954
|
readFileLines: (file) => {
|
|
21835
21955
|
try {
|
|
21836
|
-
const abs = (0,
|
|
21837
|
-
return (0,
|
|
21956
|
+
const abs = (0, import_node_path22.join)(root, file);
|
|
21957
|
+
return (0, import_node_fs26.existsSync)(abs) ? (0, import_node_fs26.readFileSync)(abs, "utf8").split("\n") : null;
|
|
21838
21958
|
} catch {
|
|
21839
21959
|
return null;
|
|
21840
21960
|
}
|
|
@@ -22002,21 +22122,21 @@ async function fireClassify(prompt, sessionId, globals) {
|
|
|
22002
22122
|
}
|
|
22003
22123
|
|
|
22004
22124
|
// src/commands/lifecycle.ts
|
|
22005
|
-
var
|
|
22006
|
-
var
|
|
22125
|
+
var import_node_fs29 = require("node:fs");
|
|
22126
|
+
var import_node_path26 = require("node:path");
|
|
22007
22127
|
|
|
22008
22128
|
// src/lib/baseline.ts
|
|
22009
|
-
var
|
|
22010
|
-
var
|
|
22129
|
+
var import_node_fs28 = require("node:fs");
|
|
22130
|
+
var import_node_path25 = require("node:path");
|
|
22011
22131
|
var import_node_crypto10 = require("node:crypto");
|
|
22012
22132
|
|
|
22013
22133
|
// src/lib/snapshot.ts
|
|
22014
|
-
var
|
|
22015
|
-
var
|
|
22016
|
-
var
|
|
22134
|
+
var import_node_fs27 = require("node:fs");
|
|
22135
|
+
var import_node_path24 = require("node:path");
|
|
22136
|
+
var import_node_child_process8 = require("node:child_process");
|
|
22017
22137
|
|
|
22018
22138
|
// src/lib/files.ts
|
|
22019
|
-
var
|
|
22139
|
+
var import_node_path23 = require("node:path");
|
|
22020
22140
|
var LANG_MAP = {
|
|
22021
22141
|
// Analyzable (static analysis + Gemini)
|
|
22022
22142
|
ts: "typescript",
|
|
@@ -22084,7 +22204,7 @@ var LANG_MAP = {
|
|
|
22084
22204
|
mk: "make"
|
|
22085
22205
|
};
|
|
22086
22206
|
function detectLanguage(filepath) {
|
|
22087
|
-
const ext = (0,
|
|
22207
|
+
const ext = (0, import_node_path23.extname)(filepath).slice(1);
|
|
22088
22208
|
return LANG_MAP[ext] ?? ext;
|
|
22089
22209
|
}
|
|
22090
22210
|
function sortByMtime(files) {
|
|
@@ -22175,16 +22295,16 @@ function collectCodeDelta(files, opts) {
|
|
|
22175
22295
|
|
|
22176
22296
|
// src/lib/snapshot.ts
|
|
22177
22297
|
function generateSnapshotDiffs(files) {
|
|
22178
|
-
if (!(0,
|
|
22298
|
+
if (!(0, import_node_fs27.existsSync)(SNAPSHOT_DIR)) {
|
|
22179
22299
|
return { diffs: [], has_snapshots: false };
|
|
22180
22300
|
}
|
|
22181
22301
|
const diffs = [];
|
|
22182
22302
|
for (const file of files) {
|
|
22183
22303
|
if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
|
|
22184
|
-
const snapshotPath = (0,
|
|
22304
|
+
const snapshotPath = (0, import_node_path24.join)(SNAPSHOT_DIR, file.path);
|
|
22185
22305
|
const language = file.language ?? detectLanguage(file.path);
|
|
22186
|
-
if ((0,
|
|
22187
|
-
const oldContent = (0,
|
|
22306
|
+
if ((0, import_node_fs27.existsSync)(snapshotPath)) {
|
|
22307
|
+
const oldContent = (0, import_node_fs27.readFileSync)(snapshotPath, "utf-8");
|
|
22188
22308
|
if (oldContent === file.content) continue;
|
|
22189
22309
|
const diff = computeDiff(oldContent, file.content, file.path);
|
|
22190
22310
|
if (diff) {
|
|
@@ -22209,21 +22329,21 @@ function saveSnapshots(files) {
|
|
|
22209
22329
|
const snapshotPaths = /* @__PURE__ */ new Set();
|
|
22210
22330
|
for (const file of files) {
|
|
22211
22331
|
if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
|
|
22212
|
-
const snapshotPath = (0,
|
|
22332
|
+
const snapshotPath = (0, import_node_path24.join)(SNAPSHOT_DIR, file.path);
|
|
22213
22333
|
snapshotPaths.add(snapshotPath);
|
|
22214
|
-
(0,
|
|
22215
|
-
(0,
|
|
22334
|
+
(0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(snapshotPath), { recursive: true });
|
|
22335
|
+
(0, import_node_fs27.writeFileSync)(snapshotPath, file.content);
|
|
22216
22336
|
}
|
|
22217
22337
|
cleanStaleSnapshots(SNAPSHOT_DIR, snapshotPaths);
|
|
22218
22338
|
}
|
|
22219
22339
|
function computeDiff(oldContent, newContent, filePath) {
|
|
22220
|
-
const tmpOld = (0,
|
|
22221
|
-
const tmpNew = (0,
|
|
22340
|
+
const tmpOld = (0, import_node_path24.join)(SNAPSHOT_DIR, ".diff-old.tmp");
|
|
22341
|
+
const tmpNew = (0, import_node_path24.join)(SNAPSHOT_DIR, ".diff-new.tmp");
|
|
22222
22342
|
try {
|
|
22223
|
-
(0,
|
|
22224
|
-
(0,
|
|
22225
|
-
(0,
|
|
22226
|
-
const result = (0,
|
|
22343
|
+
(0, import_node_fs27.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
|
|
22344
|
+
(0, import_node_fs27.writeFileSync)(tmpOld, oldContent);
|
|
22345
|
+
(0, import_node_fs27.writeFileSync)(tmpNew, newContent);
|
|
22346
|
+
const result = (0, import_node_child_process8.execSync)(
|
|
22227
22347
|
`git diff --no-index --unified=10 -- "${tmpOld}" "${tmpNew}"`,
|
|
22228
22348
|
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
22229
22349
|
);
|
|
@@ -22236,32 +22356,32 @@ function computeDiff(oldContent, newContent, filePath) {
|
|
|
22236
22356
|
return null;
|
|
22237
22357
|
} finally {
|
|
22238
22358
|
try {
|
|
22239
|
-
(0,
|
|
22359
|
+
(0, import_node_fs27.unlinkSync)(tmpOld);
|
|
22240
22360
|
} catch {
|
|
22241
22361
|
}
|
|
22242
22362
|
try {
|
|
22243
|
-
(0,
|
|
22363
|
+
(0, import_node_fs27.unlinkSync)(tmpNew);
|
|
22244
22364
|
} catch {
|
|
22245
22365
|
}
|
|
22246
22366
|
}
|
|
22247
22367
|
}
|
|
22248
22368
|
function cleanStaleSnapshots(dir, keepSet) {
|
|
22249
|
-
if (!(0,
|
|
22369
|
+
if (!(0, import_node_fs27.existsSync)(dir)) return;
|
|
22250
22370
|
try {
|
|
22251
|
-
const entries = (0,
|
|
22371
|
+
const entries = (0, import_node_fs27.readdirSync)(dir, { withFileTypes: true });
|
|
22252
22372
|
for (const entry of entries) {
|
|
22253
22373
|
if (dir === SNAPSHOT_DIR && (entry.name === ".diff-old.tmp" || entry.name === ".diff-new.tmp")) continue;
|
|
22254
|
-
const fullPath = (0,
|
|
22374
|
+
const fullPath = (0, import_node_path24.join)(dir, entry.name);
|
|
22255
22375
|
if (entry.isDirectory()) {
|
|
22256
22376
|
cleanStaleSnapshots(fullPath, keepSet);
|
|
22257
22377
|
try {
|
|
22258
|
-
const remaining = (0,
|
|
22259
|
-
if (remaining.length === 0) (0,
|
|
22378
|
+
const remaining = (0, import_node_fs27.readdirSync)(fullPath);
|
|
22379
|
+
if (remaining.length === 0) (0, import_node_fs27.rmdirSync)(fullPath);
|
|
22260
22380
|
} catch {
|
|
22261
22381
|
}
|
|
22262
22382
|
} else if (!keepSet.has(fullPath)) {
|
|
22263
22383
|
try {
|
|
22264
|
-
(0,
|
|
22384
|
+
(0, import_node_fs27.unlinkSync)(fullPath);
|
|
22265
22385
|
} catch {
|
|
22266
22386
|
}
|
|
22267
22387
|
}
|
|
@@ -22280,20 +22400,20 @@ function sessionKey(sessionId) {
|
|
|
22280
22400
|
return (0, import_node_crypto10.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
|
|
22281
22401
|
}
|
|
22282
22402
|
function sessionDir(key) {
|
|
22283
|
-
return (0,
|
|
22403
|
+
return (0, import_node_path25.join)(projectPath(BASELINE_DIR), key);
|
|
22284
22404
|
}
|
|
22285
22405
|
function manifestPath(dir) {
|
|
22286
|
-
return (0,
|
|
22406
|
+
return (0, import_node_path25.join)(dir, "manifest.json");
|
|
22287
22407
|
}
|
|
22288
22408
|
function mirrorPath(dir, repoRelPath) {
|
|
22289
|
-
return (0,
|
|
22409
|
+
return (0, import_node_path25.join)(dir, "files", repoRelPath);
|
|
22290
22410
|
}
|
|
22291
22411
|
var CARRY_FILE = `${BASELINE_DIR}/.carry`;
|
|
22292
22412
|
var CARRY_WINDOW_MS = 12e4;
|
|
22293
22413
|
function writeCarry(sessionId, headSha) {
|
|
22294
22414
|
try {
|
|
22295
|
-
(0,
|
|
22296
|
-
(0,
|
|
22415
|
+
(0, import_node_fs28.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
|
|
22416
|
+
(0, import_node_fs28.writeFileSync)(
|
|
22297
22417
|
projectPath(CARRY_FILE),
|
|
22298
22418
|
JSON.stringify({ from_key: sessionKey(sessionId), head_sha: headSha, ts: Date.now() })
|
|
22299
22419
|
);
|
|
@@ -22303,10 +22423,10 @@ function writeCarry(sessionId, headSha) {
|
|
|
22303
22423
|
function claimCarry(newKey) {
|
|
22304
22424
|
const carryPath = projectPath(CARRY_FILE);
|
|
22305
22425
|
try {
|
|
22306
|
-
if (!(0,
|
|
22307
|
-
const carry = JSON.parse((0,
|
|
22426
|
+
if (!(0, import_node_fs28.existsSync)(carryPath)) return null;
|
|
22427
|
+
const carry = JSON.parse((0, import_node_fs28.readFileSync)(carryPath, "utf-8"));
|
|
22308
22428
|
try {
|
|
22309
|
-
(0,
|
|
22429
|
+
(0, import_node_fs28.rmSync)(carryPath, { force: true });
|
|
22310
22430
|
} catch {
|
|
22311
22431
|
}
|
|
22312
22432
|
if (!carry?.from_key || typeof carry.ts !== "number") return null;
|
|
@@ -22317,11 +22437,11 @@ function claimCarry(newKey) {
|
|
|
22317
22437
|
if (!prior) return null;
|
|
22318
22438
|
const toDir = sessionDir(newKey);
|
|
22319
22439
|
try {
|
|
22320
|
-
(0,
|
|
22440
|
+
(0, import_node_fs28.rmSync)(toDir, { recursive: true, force: true });
|
|
22321
22441
|
} catch {
|
|
22322
22442
|
}
|
|
22323
|
-
(0,
|
|
22324
|
-
(0,
|
|
22443
|
+
(0, import_node_fs28.renameSync)(fromDir, toDir);
|
|
22444
|
+
(0, import_node_fs28.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
|
|
22325
22445
|
return readManifest(toDir);
|
|
22326
22446
|
} catch {
|
|
22327
22447
|
return null;
|
|
@@ -22345,21 +22465,21 @@ function captureBaseline(opts = {}) {
|
|
|
22345
22465
|
const head_sha = getCurrentCommit();
|
|
22346
22466
|
const dirty = getDirtyFiles();
|
|
22347
22467
|
try {
|
|
22348
|
-
(0,
|
|
22468
|
+
(0, import_node_fs28.rmSync)(dir, { recursive: true, force: true });
|
|
22349
22469
|
} catch {
|
|
22350
22470
|
}
|
|
22351
|
-
const filesDir = (0,
|
|
22471
|
+
const filesDir = (0, import_node_path25.join)(dir, "files");
|
|
22352
22472
|
const mirrored = [];
|
|
22353
22473
|
try {
|
|
22354
|
-
(0,
|
|
22474
|
+
(0, import_node_fs28.mkdirSync)(filesDir, { recursive: true });
|
|
22355
22475
|
for (const p of dirty) {
|
|
22356
22476
|
if (p.includes("..")) continue;
|
|
22357
22477
|
const content = safeReadForMirror(projectPath(p));
|
|
22358
22478
|
if (content === null) continue;
|
|
22359
22479
|
const dest = mirrorPath(dir, p);
|
|
22360
22480
|
try {
|
|
22361
|
-
(0,
|
|
22362
|
-
(0,
|
|
22481
|
+
(0, import_node_fs28.mkdirSync)((0, import_node_path25.dirname)(dest), { recursive: true });
|
|
22482
|
+
(0, import_node_fs28.writeFileSync)(dest, content);
|
|
22363
22483
|
mirrored.push(p);
|
|
22364
22484
|
} catch {
|
|
22365
22485
|
}
|
|
@@ -22374,8 +22494,8 @@ function captureBaseline(opts = {}) {
|
|
|
22374
22494
|
version: BASELINE_VERSION
|
|
22375
22495
|
};
|
|
22376
22496
|
try {
|
|
22377
|
-
(0,
|
|
22378
|
-
(0,
|
|
22497
|
+
(0, import_node_fs28.mkdirSync)(dir, { recursive: true });
|
|
22498
|
+
(0, import_node_fs28.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
|
|
22379
22499
|
} catch {
|
|
22380
22500
|
}
|
|
22381
22501
|
pruneOldBaselines();
|
|
@@ -22386,9 +22506,9 @@ function readBaseline(sessionId) {
|
|
|
22386
22506
|
}
|
|
22387
22507
|
function readManifest(dir) {
|
|
22388
22508
|
const mp = manifestPath(dir);
|
|
22389
|
-
if (!(0,
|
|
22509
|
+
if (!(0, import_node_fs28.existsSync)(mp)) return null;
|
|
22390
22510
|
try {
|
|
22391
|
-
const parsed = JSON.parse((0,
|
|
22511
|
+
const parsed = JSON.parse((0, import_node_fs28.readFileSync)(mp, "utf-8"));
|
|
22392
22512
|
if (typeof parsed.head_sha !== "string" || typeof parsed.captured_at !== "number" || !Array.isArray(parsed.dirty_paths) || parsed.version !== BASELINE_VERSION) {
|
|
22393
22513
|
return null;
|
|
22394
22514
|
}
|
|
@@ -22419,9 +22539,9 @@ function preImage(repoRelPath, baseline) {
|
|
|
22419
22539
|
function resolvePreImage(repoRelPath, baseline) {
|
|
22420
22540
|
if (baseline.dirty_paths.includes(repoRelPath)) {
|
|
22421
22541
|
const mp = mirrorPath(sessionDir(sessionKey(baseline.session_id)), repoRelPath);
|
|
22422
|
-
if ((0,
|
|
22542
|
+
if ((0, import_node_fs28.existsSync)(mp)) {
|
|
22423
22543
|
try {
|
|
22424
|
-
return { content: (0,
|
|
22544
|
+
return { content: (0, import_node_fs28.readFileSync)(mp, "utf-8"), existed: true };
|
|
22425
22545
|
} catch {
|
|
22426
22546
|
}
|
|
22427
22547
|
}
|
|
@@ -22466,8 +22586,8 @@ function absorbIntoBaseline(paths, sessionId) {
|
|
|
22466
22586
|
const content = safeReadForMirror(projectPath(p));
|
|
22467
22587
|
if (content === null) continue;
|
|
22468
22588
|
const dest = mirrorPath(dir, p);
|
|
22469
|
-
(0,
|
|
22470
|
-
(0,
|
|
22589
|
+
(0, import_node_fs28.mkdirSync)((0, import_node_path25.dirname)(dest), { recursive: true });
|
|
22590
|
+
(0, import_node_fs28.writeFileSync)(dest, content);
|
|
22471
22591
|
dirty.add(p);
|
|
22472
22592
|
adopted++;
|
|
22473
22593
|
} catch {
|
|
@@ -22476,7 +22596,7 @@ function absorbIntoBaseline(paths, sessionId) {
|
|
|
22476
22596
|
if (adopted === 0) return 0;
|
|
22477
22597
|
try {
|
|
22478
22598
|
const updated = { ...baseline, dirty_paths: [...dirty] };
|
|
22479
|
-
(0,
|
|
22599
|
+
(0, import_node_fs28.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
|
|
22480
22600
|
preImageCache.delete(baseline);
|
|
22481
22601
|
} catch {
|
|
22482
22602
|
return 0;
|
|
@@ -22487,7 +22607,7 @@ function changedSinceBaseline(repoRelPath, baseline) {
|
|
|
22487
22607
|
const pre = preImage(repoRelPath, baseline);
|
|
22488
22608
|
let current;
|
|
22489
22609
|
try {
|
|
22490
|
-
current = (0,
|
|
22610
|
+
current = (0, import_node_fs28.readFileSync)(projectPath(repoRelPath), "utf-8");
|
|
22491
22611
|
} catch {
|
|
22492
22612
|
return pre.existed;
|
|
22493
22613
|
}
|
|
@@ -22496,8 +22616,8 @@ function changedSinceBaseline(repoRelPath, baseline) {
|
|
|
22496
22616
|
}
|
|
22497
22617
|
function safeReadForMirror(absPath) {
|
|
22498
22618
|
try {
|
|
22499
|
-
if ((0,
|
|
22500
|
-
const buf = (0,
|
|
22619
|
+
if ((0, import_node_fs28.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
|
|
22620
|
+
const buf = (0, import_node_fs28.readFileSync)(absPath);
|
|
22501
22621
|
if (buf.includes(0)) return null;
|
|
22502
22622
|
return buf.toString("utf-8");
|
|
22503
22623
|
} catch {
|
|
@@ -22508,18 +22628,18 @@ function pruneOldBaselines() {
|
|
|
22508
22628
|
const root = projectPath(BASELINE_DIR);
|
|
22509
22629
|
let entries;
|
|
22510
22630
|
try {
|
|
22511
|
-
entries = (0,
|
|
22631
|
+
entries = (0, import_node_fs28.readdirSync)(root);
|
|
22512
22632
|
} catch {
|
|
22513
22633
|
return;
|
|
22514
22634
|
}
|
|
22515
22635
|
const now = Date.now();
|
|
22516
22636
|
for (const name2 of entries) {
|
|
22517
|
-
const dir = (0,
|
|
22637
|
+
const dir = (0, import_node_path25.join)(root, name2);
|
|
22518
22638
|
const manifest = readManifest(dir);
|
|
22519
22639
|
if (!manifest) {
|
|
22520
22640
|
try {
|
|
22521
|
-
if (now - (0,
|
|
22522
|
-
(0,
|
|
22641
|
+
if (now - (0, import_node_fs28.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
|
|
22642
|
+
(0, import_node_fs28.rmSync)(dir, { recursive: true, force: true });
|
|
22523
22643
|
}
|
|
22524
22644
|
} catch {
|
|
22525
22645
|
}
|
|
@@ -22527,7 +22647,7 @@ function pruneOldBaselines() {
|
|
|
22527
22647
|
}
|
|
22528
22648
|
if (now - manifest.captured_at <= BASELINE_TTL_MS) continue;
|
|
22529
22649
|
try {
|
|
22530
|
-
(0,
|
|
22650
|
+
(0, import_node_fs28.rmSync)(dir, { recursive: true, force: true });
|
|
22531
22651
|
} catch {
|
|
22532
22652
|
}
|
|
22533
22653
|
}
|
|
@@ -22702,8 +22822,8 @@ function buildCompactionContext(session) {
|
|
|
22702
22822
|
commitsSince: commitsSincePaths(watermark, (state.authored ?? []).map((a) => a.path)),
|
|
22703
22823
|
readFileLines: (file) => {
|
|
22704
22824
|
try {
|
|
22705
|
-
const abs = (0,
|
|
22706
|
-
return (0,
|
|
22825
|
+
const abs = (0, import_node_path26.join)(root, file);
|
|
22826
|
+
return (0, import_node_fs29.existsSync)(abs) ? (0, import_node_fs29.readFileSync)(abs, "utf8").split("\n") : null;
|
|
22707
22827
|
} catch {
|
|
22708
22828
|
return null;
|
|
22709
22829
|
}
|
|
@@ -22760,24 +22880,24 @@ async function readHookStdin() {
|
|
|
22760
22880
|
|
|
22761
22881
|
// src/commands/standard.ts
|
|
22762
22882
|
var import_promises13 = require("node:fs/promises");
|
|
22763
|
-
var
|
|
22883
|
+
var import_node_fs36 = require("node:fs");
|
|
22764
22884
|
var import_yaml3 = __toESM2(require_dist());
|
|
22765
22885
|
|
|
22766
22886
|
// src/lib/synthesize.ts
|
|
22767
|
-
var
|
|
22768
|
-
var
|
|
22887
|
+
var import_node_child_process10 = require("node:child_process");
|
|
22888
|
+
var import_node_fs32 = require("node:fs");
|
|
22769
22889
|
var import_promises10 = require("node:fs/promises");
|
|
22770
|
-
var
|
|
22890
|
+
var import_node_path29 = require("node:path");
|
|
22771
22891
|
var import_yaml = __toESM2(require_dist());
|
|
22772
22892
|
|
|
22773
22893
|
// src/lib/data-dir.ts
|
|
22774
|
-
var
|
|
22775
|
-
var
|
|
22894
|
+
var import_node_fs30 = require("node:fs");
|
|
22895
|
+
var import_node_path27 = require("node:path");
|
|
22776
22896
|
function resolveDataDir() {
|
|
22777
22897
|
const candidates2 = [
|
|
22778
|
-
(0,
|
|
22898
|
+
(0, import_node_path27.join)(__dirname, "..", "data"),
|
|
22779
22899
|
// installed: node_modules/@codacy/verity-cli/data
|
|
22780
|
-
(0,
|
|
22900
|
+
(0, import_node_path27.join)(__dirname, "..", "..", "data"),
|
|
22781
22901
|
// edge case: nested resolution
|
|
22782
22902
|
// THE COMMITTED SOURCE, for a source checkout that has not been built.
|
|
22783
22903
|
// cli/data/skills/ is a BUILD ARTIFACT (scripts/build.js copies client/skills
|
|
@@ -22786,14 +22906,14 @@ function resolveDataDir() {
|
|
|
22786
22906
|
// without this the synthesizer throws "Could not find Verity skill data"
|
|
22787
22907
|
// for every test and every `verity` run from source. Resolved from this
|
|
22788
22908
|
// module's own location, never the cwd: see the warning below.
|
|
22789
|
-
(0,
|
|
22909
|
+
(0, import_node_path27.join)(__dirname, "..", "..", "client"),
|
|
22790
22910
|
// bundled: cli/bin/ → ../../client
|
|
22791
|
-
(0,
|
|
22911
|
+
(0, import_node_path27.join)(__dirname, "..", "..", "..", "client"),
|
|
22792
22912
|
// tsx: cli/src/lib/ → ../../../client
|
|
22793
22913
|
...process.env.VERITY_DEV_DATA_DIR ? [process.env.VERITY_DEV_DATA_DIR] : []
|
|
22794
22914
|
];
|
|
22795
22915
|
for (const candidate of candidates2) {
|
|
22796
|
-
if ((0,
|
|
22916
|
+
if ((0, import_node_fs30.existsSync)((0, import_node_path27.join)(candidate, "skills"))) {
|
|
22797
22917
|
return candidate;
|
|
22798
22918
|
}
|
|
22799
22919
|
}
|
|
@@ -22802,13 +22922,13 @@ function resolveDataDir() {
|
|
|
22802
22922
|
);
|
|
22803
22923
|
}
|
|
22804
22924
|
function setupDataPath(file) {
|
|
22805
|
-
return (0,
|
|
22925
|
+
return (0, import_node_path27.join)(resolveDataDir(), "skills", "verity-setup", file);
|
|
22806
22926
|
}
|
|
22807
22927
|
|
|
22808
22928
|
// src/lib/detect.ts
|
|
22809
|
-
var
|
|
22810
|
-
var
|
|
22811
|
-
var
|
|
22929
|
+
var import_node_child_process9 = require("node:child_process");
|
|
22930
|
+
var import_node_fs31 = require("node:fs");
|
|
22931
|
+
var import_node_path28 = require("node:path");
|
|
22812
22932
|
var TOOLED_LANGUAGES = /* @__PURE__ */ new Set([
|
|
22813
22933
|
"typescript",
|
|
22814
22934
|
"javascript",
|
|
@@ -22845,7 +22965,7 @@ function isIgnored2(path) {
|
|
|
22845
22965
|
}
|
|
22846
22966
|
function listProjectFiles(root) {
|
|
22847
22967
|
try {
|
|
22848
|
-
const out2 = (0,
|
|
22968
|
+
const out2 = (0, import_node_child_process9.execSync)("git ls-files -z", {
|
|
22849
22969
|
cwd: root,
|
|
22850
22970
|
encoding: "utf-8",
|
|
22851
22971
|
maxBuffer: 32 * 1024 * 1024,
|
|
@@ -22865,25 +22985,25 @@ function walk(root) {
|
|
|
22865
22985
|
if (depth > WALK_MAX_DEPTH || found.length >= WALK_MAX_FILES) return;
|
|
22866
22986
|
let entries;
|
|
22867
22987
|
try {
|
|
22868
|
-
entries = (0,
|
|
22988
|
+
entries = (0, import_node_fs31.readdirSync)(dir, { withFileTypes: true });
|
|
22869
22989
|
} catch {
|
|
22870
22990
|
return;
|
|
22871
22991
|
}
|
|
22872
22992
|
for (const entry of entries) {
|
|
22873
22993
|
if (found.length >= WALK_MAX_FILES) return;
|
|
22874
22994
|
if (IGNORED_SEGMENTS.includes(entry.name)) continue;
|
|
22875
|
-
const full = (0,
|
|
22995
|
+
const full = (0, import_node_path28.join)(dir, entry.name);
|
|
22876
22996
|
if (entry.isDirectory()) visit(full, depth + 1);
|
|
22877
|
-
else if (entry.isFile()) found.push((0,
|
|
22997
|
+
else if (entry.isFile()) found.push((0, import_node_path28.relative)(root, full));
|
|
22878
22998
|
}
|
|
22879
22999
|
};
|
|
22880
23000
|
visit(root, 0);
|
|
22881
23001
|
return found;
|
|
22882
23002
|
}
|
|
22883
23003
|
function languageOf(path) {
|
|
22884
|
-
const name2 = (0,
|
|
23004
|
+
const name2 = (0, import_node_path28.basename)(path);
|
|
22885
23005
|
if (/^Dockerfile(\..+)?$/i.test(name2)) return "dockerfile";
|
|
22886
|
-
if (!(0,
|
|
23006
|
+
if (!(0, import_node_path28.extname)(name2)) return null;
|
|
22887
23007
|
const lang = detectLanguage(path);
|
|
22888
23008
|
return lang || null;
|
|
22889
23009
|
}
|
|
@@ -22940,7 +23060,7 @@ var TOOL_CONFIG_MARKERS = [
|
|
|
22940
23060
|
];
|
|
22941
23061
|
function readJson2(path) {
|
|
22942
23062
|
try {
|
|
22943
|
-
return JSON.parse((0,
|
|
23063
|
+
return JSON.parse((0, import_node_fs31.readFileSync)(path, "utf-8"));
|
|
22944
23064
|
} catch {
|
|
22945
23065
|
return null;
|
|
22946
23066
|
}
|
|
@@ -22965,17 +23085,17 @@ function declaredDependencies(root, files) {
|
|
|
22965
23085
|
if (deps && typeof deps === "object") names2.push(...Object.keys(deps));
|
|
22966
23086
|
}
|
|
22967
23087
|
};
|
|
22968
|
-
readPackageJson((0,
|
|
22969
|
-
const nested = files.filter((f) => f.includes("/") && (0,
|
|
22970
|
-
for (const rel of nested) readPackageJson((0,
|
|
23088
|
+
readPackageJson((0, import_node_path28.join)(root, "package.json"));
|
|
23089
|
+
const nested = files.filter((f) => f.includes("/") && (0, import_node_path28.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
|
|
23090
|
+
for (const rel of nested) readPackageJson((0, import_node_path28.join)(root, rel));
|
|
22971
23091
|
const pythonManifests = [
|
|
22972
|
-
...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0,
|
|
22973
|
-
...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0,
|
|
23092
|
+
...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path28.join)(root, f)),
|
|
23093
|
+
...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path28.join)(root, f))
|
|
22974
23094
|
];
|
|
22975
23095
|
for (const path of pythonManifests) {
|
|
22976
|
-
if (!(0,
|
|
23096
|
+
if (!(0, import_node_fs31.existsSync)(path)) continue;
|
|
22977
23097
|
try {
|
|
22978
|
-
const text = (0,
|
|
23098
|
+
const text = (0, import_node_fs31.readFileSync)(path, "utf-8");
|
|
22979
23099
|
for (const m of text.matchAll(/^\s*["']?([A-Za-z][A-Za-z0-9._-]+)/gm)) names2.push(m[1]);
|
|
22980
23100
|
for (const line2 of text.split("\n")) {
|
|
22981
23101
|
if (!/dependencies\s*=/.test(line2)) continue;
|
|
@@ -22985,13 +23105,13 @@ function declaredDependencies(root, files) {
|
|
|
22985
23105
|
}
|
|
22986
23106
|
}
|
|
22987
23107
|
const goMods = [
|
|
22988
|
-
(0,
|
|
22989
|
-
...files.filter((f) => f.includes("/") && (0,
|
|
23108
|
+
(0, import_node_path28.join)(root, "go.mod"),
|
|
23109
|
+
...files.filter((f) => f.includes("/") && (0, import_node_path28.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path28.join)(root, f))
|
|
22990
23110
|
];
|
|
22991
23111
|
for (const path of goMods) {
|
|
22992
|
-
if (!(0,
|
|
23112
|
+
if (!(0, import_node_fs31.existsSync)(path)) continue;
|
|
22993
23113
|
try {
|
|
22994
|
-
const text = (0,
|
|
23114
|
+
const text = (0, import_node_fs31.readFileSync)(path, "utf-8");
|
|
22995
23115
|
for (const m of text.matchAll(/^\s+([\w.-]+\/[\w./-]+)\s+v/gm)) {
|
|
22996
23116
|
names2.push(m[1].replace(/^github\.com\//, ""));
|
|
22997
23117
|
}
|
|
@@ -22999,10 +23119,10 @@ function declaredDependencies(root, files) {
|
|
|
22999
23119
|
}
|
|
23000
23120
|
}
|
|
23001
23121
|
for (const file of ["pom.xml", "build.gradle", "build.gradle.kts", "Gemfile", "Cargo.toml"]) {
|
|
23002
|
-
const path = (0,
|
|
23003
|
-
if (!(0,
|
|
23122
|
+
const path = (0, import_node_path28.join)(root, file);
|
|
23123
|
+
if (!(0, import_node_fs31.existsSync)(path)) continue;
|
|
23004
23124
|
try {
|
|
23005
|
-
const text = (0,
|
|
23125
|
+
const text = (0, import_node_fs31.readFileSync)(path, "utf-8");
|
|
23006
23126
|
for (const m of text.matchAll(/["'<]([A-Za-z][A-Za-z0-9._-]{2,})["'>]/g)) names2.push(m[1]);
|
|
23007
23127
|
} catch {
|
|
23008
23128
|
}
|
|
@@ -23010,7 +23130,7 @@ function declaredDependencies(root, files) {
|
|
|
23010
23130
|
return names2;
|
|
23011
23131
|
}
|
|
23012
23132
|
function detectBuildSystem(root, files) {
|
|
23013
|
-
const has = (f) => (0,
|
|
23133
|
+
const has = (f) => (0, import_node_fs31.existsSync)((0, import_node_path28.join)(root, f)) || files.some((p) => (0, import_node_path28.basename)(p) === f);
|
|
23014
23134
|
if (has("pnpm-lock.yaml")) return "pnpm";
|
|
23015
23135
|
if (has("yarn.lock")) return "yarn";
|
|
23016
23136
|
if (has("bun.lock") || has("bun.lockb")) return "bun";
|
|
@@ -23027,8 +23147,8 @@ function detectBuildSystem(root, files) {
|
|
|
23027
23147
|
}
|
|
23028
23148
|
function detectArchitecture(root, files) {
|
|
23029
23149
|
const workspaceMarkers = ["lerna.json", "pnpm-workspace.yaml", "nx.json", "turbo.json", "rush.json"];
|
|
23030
|
-
if (workspaceMarkers.some((m) => (0,
|
|
23031
|
-
const pkg = readJson2((0,
|
|
23150
|
+
if (workspaceMarkers.some((m) => (0, import_node_fs31.existsSync)((0, import_node_path28.join)(root, m)))) return "monorepo";
|
|
23151
|
+
const pkg = readJson2((0, import_node_path28.join)(root, "package.json"));
|
|
23032
23152
|
if (pkg && "workspaces" in pkg) return "monorepo";
|
|
23033
23153
|
const manifests = files.filter((f) => /(^|\/)(package\.json|go\.mod|pyproject\.toml|Cargo\.toml|pom\.xml)$/.test(f));
|
|
23034
23154
|
const nested = manifests.filter((f) => f.includes("/"));
|
|
@@ -23050,10 +23170,10 @@ function measureAvgFileLength(root, files, languages) {
|
|
|
23050
23170
|
let total = 0;
|
|
23051
23171
|
let counted = 0;
|
|
23052
23172
|
for (let i2 = 0; i2 < candidates2.length; i2 += stride) {
|
|
23053
|
-
const path = (0,
|
|
23173
|
+
const path = (0, import_node_path28.join)(root, candidates2[i2]);
|
|
23054
23174
|
try {
|
|
23055
|
-
if ((0,
|
|
23056
|
-
total += (0,
|
|
23175
|
+
if ((0, import_node_fs31.statSync)(path).size > 2 * 1024 * 1024) continue;
|
|
23176
|
+
total += (0, import_node_fs31.readFileSync)(path, "utf-8").split("\n").length;
|
|
23057
23177
|
counted++;
|
|
23058
23178
|
} catch {
|
|
23059
23179
|
}
|
|
@@ -23083,14 +23203,14 @@ function detectProject(root = repoRoot()) {
|
|
|
23083
23203
|
const existingToolConfigs = [];
|
|
23084
23204
|
for (const [tool, markers] of TOOL_CONFIG_MARKERS) {
|
|
23085
23205
|
for (const marker of markers) {
|
|
23086
|
-
if ((0,
|
|
23206
|
+
if ((0, import_node_fs31.existsSync)((0, import_node_path28.join)(root, marker))) {
|
|
23087
23207
|
existingToolConfigs.push({ tool, path: `./${marker}` });
|
|
23088
23208
|
break;
|
|
23089
23209
|
}
|
|
23090
23210
|
}
|
|
23091
23211
|
}
|
|
23092
23212
|
return {
|
|
23093
|
-
projectName: (0,
|
|
23213
|
+
projectName: (0, import_node_path28.basename)(root),
|
|
23094
23214
|
languages,
|
|
23095
23215
|
languageCounts,
|
|
23096
23216
|
frameworks: matchAll(dependencies, FRAMEWORK_BY_DEPENDENCY),
|
|
@@ -23188,8 +23308,8 @@ ${closingNote(input.origin)}
|
|
|
23188
23308
|
|
|
23189
23309
|
// src/lib/synthesize.ts
|
|
23190
23310
|
function loadCatalog() {
|
|
23191
|
-
const catalog = (0, import_yaml.parse)((0,
|
|
23192
|
-
const template = (0, import_yaml.parse)((0,
|
|
23311
|
+
const catalog = (0, import_yaml.parse)((0, import_node_fs32.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
|
|
23312
|
+
const template = (0, import_yaml.parse)((0, import_node_fs32.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
|
|
23193
23313
|
return { catalog, template };
|
|
23194
23314
|
}
|
|
23195
23315
|
function selectTools(languages, intensity, catalog) {
|
|
@@ -23240,7 +23360,7 @@ var TRIVY_BY_INTENSITY = {
|
|
|
23240
23360
|
};
|
|
23241
23361
|
function adapterPatternIds(toolId) {
|
|
23242
23362
|
try {
|
|
23243
|
-
const out2 = (0,
|
|
23363
|
+
const out2 = (0, import_node_child_process10.execFileSync)(
|
|
23244
23364
|
process.execPath,
|
|
23245
23365
|
[setupDataPath("validate-patterns.mjs"), "--list", toolId],
|
|
23246
23366
|
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }
|
|
@@ -23270,7 +23390,7 @@ function resolvePatternId(toolId, curatedId, adapterIds) {
|
|
|
23270
23390
|
}
|
|
23271
23391
|
function trivyPatterns(intensity) {
|
|
23272
23392
|
try {
|
|
23273
|
-
const out2 = (0,
|
|
23393
|
+
const out2 = (0, import_node_child_process10.execFileSync)(
|
|
23274
23394
|
process.execPath,
|
|
23275
23395
|
[setupDataPath("validate-patterns.mjs"), "--emit", "Trivy", TRIVY_BY_INTENSITY[intensity].emit],
|
|
23276
23396
|
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }
|
|
@@ -23450,7 +23570,7 @@ export default tseslint.config(
|
|
|
23450
23570
|
function validatePatternIds() {
|
|
23451
23571
|
const configPath = projectPath(CODACY_CONFIG_FILE);
|
|
23452
23572
|
try {
|
|
23453
|
-
(0,
|
|
23573
|
+
(0, import_node_child_process10.execFileSync)(process.execPath, [setupDataPath("validate-patterns.mjs"), configPath], {
|
|
23454
23574
|
encoding: "utf-8",
|
|
23455
23575
|
stdio: ["pipe", "pipe", "pipe"],
|
|
23456
23576
|
timeout: 6e4
|
|
@@ -23467,7 +23587,7 @@ function validatePatternIds() {
|
|
|
23467
23587
|
}
|
|
23468
23588
|
async function runSynthesis(opts) {
|
|
23469
23589
|
const standardPath = projectPath(STANDARD_FILE);
|
|
23470
|
-
if ((0,
|
|
23590
|
+
if ((0, import_node_fs32.existsSync)(standardPath) && !opts.force) {
|
|
23471
23591
|
return { refused: `${STANDARD_FILE} already exists \u2014 pass --force to replace it.` };
|
|
23472
23592
|
}
|
|
23473
23593
|
const detected = opts.detected ?? detectProject();
|
|
@@ -23536,7 +23656,7 @@ async function correctVerityMdVersion(opts) {
|
|
|
23536
23656
|
}
|
|
23537
23657
|
async function writeFileTo(relative6, body2) {
|
|
23538
23658
|
const target = projectPath(relative6);
|
|
23539
|
-
await (0, import_promises10.mkdir)((0,
|
|
23659
|
+
await (0, import_promises10.mkdir)((0, import_node_path29.dirname)(target), { recursive: true });
|
|
23540
23660
|
await (0, import_promises10.writeFile)(target, body2);
|
|
23541
23661
|
}
|
|
23542
23662
|
async function deriveConfigForStandard(standard) {
|
|
@@ -23595,11 +23715,11 @@ ${validation.detail}`);
|
|
|
23595
23715
|
|
|
23596
23716
|
// src/lib/setup-state.ts
|
|
23597
23717
|
var import_promises11 = require("node:fs/promises");
|
|
23598
|
-
var
|
|
23718
|
+
var import_node_fs33 = require("node:fs");
|
|
23599
23719
|
var SETUP_STATE_FILE = `${VERITY_DIR}/setup.json`;
|
|
23600
23720
|
async function readSetupState() {
|
|
23601
23721
|
const path = projectPath(SETUP_STATE_FILE);
|
|
23602
|
-
if (!(0,
|
|
23722
|
+
if (!(0, import_node_fs33.existsSync)(path)) return null;
|
|
23603
23723
|
try {
|
|
23604
23724
|
const parsed = JSON.parse(await (0, import_promises11.readFile)(path, "utf-8"));
|
|
23605
23725
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
@@ -23615,12 +23735,12 @@ async function writeSetupState(patch) {
|
|
|
23615
23735
|
}
|
|
23616
23736
|
|
|
23617
23737
|
// src/lib/push-setup.ts
|
|
23618
|
-
var
|
|
23738
|
+
var import_node_fs35 = require("node:fs");
|
|
23619
23739
|
var import_promises12 = require("node:fs/promises");
|
|
23620
23740
|
var import_yaml2 = __toESM2(require_dist());
|
|
23621
23741
|
|
|
23622
23742
|
// src/lib/verityignore.ts
|
|
23623
|
-
var
|
|
23743
|
+
var import_node_fs34 = require("node:fs");
|
|
23624
23744
|
var EMPTY = { rules: [], securityOverlap: [], problems: [] };
|
|
23625
23745
|
var SECURITY_PROBES = [
|
|
23626
23746
|
".env",
|
|
@@ -23713,9 +23833,9 @@ function isIgnored3(ig, path) {
|
|
|
23713
23833
|
}
|
|
23714
23834
|
function loadVerityIgnore() {
|
|
23715
23835
|
const file = projectPath(VERITYIGNORE_FILE);
|
|
23716
|
-
if (!(0,
|
|
23836
|
+
if (!(0, import_node_fs34.existsSync)(file)) return EMPTY;
|
|
23717
23837
|
try {
|
|
23718
|
-
return parseVerityIgnore((0,
|
|
23838
|
+
return parseVerityIgnore((0, import_node_fs34.readFileSync)(file, "utf-8"));
|
|
23719
23839
|
} catch {
|
|
23720
23840
|
return EMPTY;
|
|
23721
23841
|
}
|
|
@@ -23753,9 +23873,9 @@ function buildStandardUpload(standard, ignoreRaw) {
|
|
|
23753
23873
|
}
|
|
23754
23874
|
function readVerityIgnoreRaw() {
|
|
23755
23875
|
const file = projectPath(VERITYIGNORE_FILE);
|
|
23756
|
-
if (!(0,
|
|
23876
|
+
if (!(0, import_node_fs34.existsSync)(file)) return null;
|
|
23757
23877
|
try {
|
|
23758
|
-
return (0,
|
|
23878
|
+
return (0, import_node_fs34.readFileSync)(file, "utf-8");
|
|
23759
23879
|
} catch {
|
|
23760
23880
|
return null;
|
|
23761
23881
|
}
|
|
@@ -23783,7 +23903,7 @@ async function pushStandardAndConfig(globals, what = {}) {
|
|
|
23783
23903
|
}
|
|
23784
23904
|
let standardVersion = null;
|
|
23785
23905
|
const standardPath = projectPath(STANDARD_FILE);
|
|
23786
|
-
if (pushStandard && (0,
|
|
23906
|
+
if (pushStandard && (0, import_node_fs35.existsSync)(standardPath)) {
|
|
23787
23907
|
try {
|
|
23788
23908
|
const content = (0, import_yaml2.parse)(await (0, import_promises12.readFile)(standardPath, "utf-8"));
|
|
23789
23909
|
const upload = buildStandardUpload(content, readVerityIgnoreRaw());
|
|
@@ -23808,7 +23928,7 @@ async function pushStandardAndConfig(globals, what = {}) {
|
|
|
23808
23928
|
}
|
|
23809
23929
|
let configPushed = false;
|
|
23810
23930
|
const configPath = projectPath(CODACY_CONFIG_FILE);
|
|
23811
|
-
if (pushConfig && (0,
|
|
23931
|
+
if (pushConfig && (0, import_node_fs35.existsSync)(configPath)) {
|
|
23812
23932
|
try {
|
|
23813
23933
|
const content = JSON.parse(await (0, import_promises12.readFile)(configPath, "utf-8"));
|
|
23814
23934
|
const result = await apiRequest({
|
|
@@ -23840,7 +23960,7 @@ function registerStandardCommands(program2) {
|
|
|
23840
23960
|
const state = await readSetupState();
|
|
23841
23961
|
if (opts.configOnly) {
|
|
23842
23962
|
const standardPath = projectPath(STANDARD_FILE);
|
|
23843
|
-
if (!(0,
|
|
23963
|
+
if (!(0, import_node_fs36.existsSync)(standardPath)) {
|
|
23844
23964
|
printError(`No ${STANDARD_FILE} here \u2014 run "verity standard synthesize" to create one.`);
|
|
23845
23965
|
process.exit(1);
|
|
23846
23966
|
}
|
|
@@ -24031,7 +24151,9 @@ function registerConfigCommands(program2) {
|
|
|
24031
24151
|
});
|
|
24032
24152
|
config.command("formal [state]").description('Get or set formal verification at push: "push" or "off" (needs Lean \u2014 verity lean status)').action((state) => {
|
|
24033
24153
|
if (state === void 0) {
|
|
24034
|
-
|
|
24154
|
+
const cfg = readProjectConfig();
|
|
24155
|
+
process.stdout.write((cfg.formal ?? "off") + "\n");
|
|
24156
|
+
if (cfg.formal_refused) printWarn(formalRefusalMessage(cfg.formal_refused));
|
|
24035
24157
|
return;
|
|
24036
24158
|
}
|
|
24037
24159
|
if (state !== "push" && state !== "off") {
|
|
@@ -24039,6 +24161,11 @@ function registerConfigCommands(program2) {
|
|
|
24039
24161
|
process.exit(1);
|
|
24040
24162
|
}
|
|
24041
24163
|
writeProjectConfig({ formal: state === "push" ? "push" : void 0 });
|
|
24164
|
+
const refused = state === "push" ? readProjectConfig().formal_refused : void 0;
|
|
24165
|
+
if (refused) {
|
|
24166
|
+
printWarn(`Formal verification at push: still off \u2014 ${formalRefusalMessage(refused)}`);
|
|
24167
|
+
return;
|
|
24168
|
+
}
|
|
24042
24169
|
printInfo(state === "push" ? "Formal verification at push: on for this checkout (Lean must be installed \u2014 verity lean status)" : "Formal verification at push: off");
|
|
24043
24170
|
if (state === "push") printInfo("The phase runs with your Verity login (a push without one is skipped and says so: not-logged-in)");
|
|
24044
24171
|
});
|
|
@@ -24186,10 +24313,10 @@ function formatRunDetail(run4) {
|
|
|
24186
24313
|
}
|
|
24187
24314
|
|
|
24188
24315
|
// src/lib/ignore-declaration.ts
|
|
24189
|
-
var
|
|
24316
|
+
var import_node_fs38 = require("node:fs");
|
|
24190
24317
|
|
|
24191
24318
|
// src/lib/debounce.ts
|
|
24192
|
-
var
|
|
24319
|
+
var import_node_fs37 = require("node:fs");
|
|
24193
24320
|
var import_node_crypto11 = require("node:crypto");
|
|
24194
24321
|
function scopedFile(base, sessionId) {
|
|
24195
24322
|
if (!sessionId) return base;
|
|
@@ -24197,9 +24324,9 @@ function scopedFile(base, sessionId) {
|
|
|
24197
24324
|
}
|
|
24198
24325
|
function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
|
|
24199
24326
|
const file = scopedFile(DEBOUNCE_FILE, sessionId);
|
|
24200
|
-
if (!(0,
|
|
24327
|
+
if (!(0, import_node_fs37.existsSync)(file)) return null;
|
|
24201
24328
|
try {
|
|
24202
|
-
const lastTs = parseInt((0,
|
|
24329
|
+
const lastTs = parseInt((0, import_node_fs37.readFileSync)(file, "utf-8").trim(), 10);
|
|
24203
24330
|
const nowTs = Math.floor(Date.now() / 1e3);
|
|
24204
24331
|
const elapsed = nowTs - lastTs;
|
|
24205
24332
|
if (elapsed < debounceSeconds) {
|
|
@@ -24212,10 +24339,10 @@ function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
|
|
|
24212
24339
|
function checkMtime(files, bypassForRecentCommits, sessionId) {
|
|
24213
24340
|
if (bypassForRecentCommits) return null;
|
|
24214
24341
|
const file = scopedFile(DEBOUNCE_FILE, sessionId);
|
|
24215
|
-
if (!(0,
|
|
24342
|
+
if (!(0, import_node_fs37.existsSync)(file)) return null;
|
|
24216
24343
|
let debounceTime;
|
|
24217
24344
|
try {
|
|
24218
|
-
debounceTime = (0,
|
|
24345
|
+
debounceTime = (0, import_node_fs37.statSync)(file).mtimeMs;
|
|
24219
24346
|
} catch {
|
|
24220
24347
|
return null;
|
|
24221
24348
|
}
|
|
@@ -24223,7 +24350,7 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
|
|
|
24223
24350
|
const resolved = resolveFile(f);
|
|
24224
24351
|
if (!resolved) continue;
|
|
24225
24352
|
try {
|
|
24226
|
-
const stat3 = (0,
|
|
24353
|
+
const stat3 = (0, import_node_fs37.statSync)(resolved);
|
|
24227
24354
|
if (stat3.mtimeMs > debounceTime) {
|
|
24228
24355
|
return null;
|
|
24229
24356
|
}
|
|
@@ -24239,8 +24366,8 @@ function computeContentHash(files) {
|
|
|
24239
24366
|
for (const f of sorted) {
|
|
24240
24367
|
const resolved = resolveFile(f) ?? f;
|
|
24241
24368
|
try {
|
|
24242
|
-
if ((0,
|
|
24243
|
-
hash.update((0,
|
|
24369
|
+
if ((0, import_node_fs37.existsSync)(resolved)) {
|
|
24370
|
+
hash.update((0, import_node_fs37.readFileSync)(resolved));
|
|
24244
24371
|
}
|
|
24245
24372
|
} catch {
|
|
24246
24373
|
}
|
|
@@ -24250,9 +24377,9 @@ function computeContentHash(files) {
|
|
|
24250
24377
|
function checkContentHash(files, sessionId) {
|
|
24251
24378
|
const hash = computeContentHash(files);
|
|
24252
24379
|
const file = scopedFile(HASH_FILE, sessionId);
|
|
24253
|
-
if ((0,
|
|
24380
|
+
if ((0, import_node_fs37.existsSync)(file)) {
|
|
24254
24381
|
try {
|
|
24255
|
-
const storedHash = (0,
|
|
24382
|
+
const storedHash = (0, import_node_fs37.readFileSync)(file, "utf-8").trim();
|
|
24256
24383
|
if (hash === storedHash) {
|
|
24257
24384
|
return { skip: "No source changes since last analysis", hash };
|
|
24258
24385
|
}
|
|
@@ -24262,24 +24389,24 @@ function checkContentHash(files, sessionId) {
|
|
|
24262
24389
|
return { skip: null, hash };
|
|
24263
24390
|
}
|
|
24264
24391
|
function recordAnalysisStart(sessionId) {
|
|
24265
|
-
(0,
|
|
24266
|
-
(0,
|
|
24392
|
+
(0, import_node_fs37.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
24393
|
+
(0, import_node_fs37.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
|
|
24267
24394
|
}
|
|
24268
24395
|
function recordPassHash(hash, sessionId) {
|
|
24269
|
-
(0,
|
|
24396
|
+
(0, import_node_fs37.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
|
|
24270
24397
|
}
|
|
24271
24398
|
function narrowToRecent(files, sessionId) {
|
|
24272
24399
|
const file = scopedFile(DEBOUNCE_FILE, sessionId);
|
|
24273
|
-
if (!(0,
|
|
24400
|
+
if (!(0, import_node_fs37.existsSync)(file)) return files;
|
|
24274
24401
|
let debounceTime;
|
|
24275
24402
|
try {
|
|
24276
|
-
debounceTime = (0,
|
|
24403
|
+
debounceTime = (0, import_node_fs37.statSync)(file).mtimeMs;
|
|
24277
24404
|
} catch {
|
|
24278
24405
|
return files;
|
|
24279
24406
|
}
|
|
24280
24407
|
const recent = files.filter((f) => {
|
|
24281
24408
|
try {
|
|
24282
|
-
return (0,
|
|
24409
|
+
return (0, import_node_fs37.existsSync)(f) && (0, import_node_fs37.statSync)(f).mtimeMs > debounceTime;
|
|
24283
24410
|
} catch {
|
|
24284
24411
|
return false;
|
|
24285
24412
|
}
|
|
@@ -24292,9 +24419,9 @@ function readIteration(currentCommit, _contentHash) {
|
|
|
24292
24419
|
var NO_BLOCKS = { attempts: 0, blocks: 0, fingerprint: null };
|
|
24293
24420
|
function readBlockState(currentCommit, opts) {
|
|
24294
24421
|
if (opts?.newUserPrompt) return NO_BLOCKS;
|
|
24295
|
-
if (!(0,
|
|
24422
|
+
if (!(0, import_node_fs37.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
|
|
24296
24423
|
try {
|
|
24297
|
-
const stored = (0,
|
|
24424
|
+
const stored = (0, import_node_fs37.readFileSync)(ITERATION_FILE, "utf-8").trim();
|
|
24298
24425
|
const parsed = stored.startsWith("{") ? parseJsonState(stored) : parseLegacyState(stored);
|
|
24299
24426
|
if (!parsed) return NO_BLOCKS;
|
|
24300
24427
|
if (parsed.commit !== currentCommit) return NO_BLOCKS;
|
|
@@ -24340,8 +24467,8 @@ function isSameProblem(previous, current) {
|
|
|
24340
24467
|
return current.split(",").some((k) => prev.has(k));
|
|
24341
24468
|
}
|
|
24342
24469
|
function writeBlockState(commit, state) {
|
|
24343
|
-
(0,
|
|
24344
|
-
(0,
|
|
24470
|
+
(0, import_node_fs37.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
24471
|
+
(0, import_node_fs37.writeFileSync)(
|
|
24345
24472
|
ITERATION_FILE,
|
|
24346
24473
|
JSON.stringify({
|
|
24347
24474
|
v: 2,
|
|
@@ -24446,9 +24573,9 @@ function resolveIgnoreState(keys) {
|
|
|
24446
24573
|
}
|
|
24447
24574
|
function readIgnoreState(sessionId) {
|
|
24448
24575
|
const file = stateFile(sessionId);
|
|
24449
|
-
if (!(0,
|
|
24576
|
+
if (!(0, import_node_fs38.existsSync)(file)) return null;
|
|
24450
24577
|
try {
|
|
24451
|
-
const o = JSON.parse((0,
|
|
24578
|
+
const o = JSON.parse((0, import_node_fs38.readFileSync)(file, "utf-8")) ?? {};
|
|
24452
24579
|
const spent = typeof o.spent === "number" ? o.spent : 0;
|
|
24453
24580
|
const raw = o.active;
|
|
24454
24581
|
let active = null;
|
|
@@ -24472,8 +24599,8 @@ function readIgnoreState(sessionId) {
|
|
|
24472
24599
|
}
|
|
24473
24600
|
function writeIgnoreState(state, sessionId) {
|
|
24474
24601
|
try {
|
|
24475
|
-
(0,
|
|
24476
|
-
(0,
|
|
24602
|
+
(0, import_node_fs38.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
|
|
24603
|
+
(0, import_node_fs38.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
|
|
24477
24604
|
} catch {
|
|
24478
24605
|
}
|
|
24479
24606
|
}
|
|
@@ -24856,85 +24983,10 @@ function createRun(opts, globals) {
|
|
|
24856
24983
|
}
|
|
24857
24984
|
|
|
24858
24985
|
// src/commands/analyze/index.ts
|
|
24859
|
-
var
|
|
24986
|
+
var import_node_fs52 = require("node:fs");
|
|
24860
24987
|
|
|
24861
24988
|
// src/lib/repo-context.ts
|
|
24862
24989
|
var import_node_child_process11 = require("node:child_process");
|
|
24863
|
-
|
|
24864
|
-
// src/lib/hardened-git.ts
|
|
24865
|
-
var import_node_child_process10 = require("node:child_process");
|
|
24866
|
-
var HARDENED_CONFIG_ARGS = [
|
|
24867
|
-
"-c",
|
|
24868
|
-
"core.fsmonitor=false",
|
|
24869
|
-
"-c",
|
|
24870
|
-
"core.pager=cat",
|
|
24871
|
-
"-c",
|
|
24872
|
-
"log.showSignature=false"
|
|
24873
|
-
];
|
|
24874
|
-
var DIFF_READ_FLAGS = ["--no-ext-diff", "--no-textconv"];
|
|
24875
|
-
var DEFAULT_GIT_TIMEOUT_MS = 6e4;
|
|
24876
|
-
var DEFAULT_GIT_MAX_BUFFER = 64 * 1024 * 1024;
|
|
24877
|
-
function hardenedGitEnv(base = process.env) {
|
|
24878
|
-
const env = {};
|
|
24879
|
-
for (const [key, value] of Object.entries(base)) {
|
|
24880
|
-
if (key.startsWith("GIT_")) continue;
|
|
24881
|
-
env[key] = value;
|
|
24882
|
-
}
|
|
24883
|
-
env.GIT_OPTIONAL_LOCKS = "0";
|
|
24884
|
-
env.GIT_TERMINAL_PROMPT = "0";
|
|
24885
|
-
return env;
|
|
24886
|
-
}
|
|
24887
|
-
function hardenedGitArgv(args2) {
|
|
24888
|
-
return [...HARDENED_CONFIG_ARGS, ...args2];
|
|
24889
|
-
}
|
|
24890
|
-
function classifyError(err2) {
|
|
24891
|
-
const e = err2;
|
|
24892
|
-
const stderr = typeof e?.stderr === "string" ? e.stderr : e?.stderr ? e.stderr.toString("utf-8") : "";
|
|
24893
|
-
if (e?.code === "ETIMEDOUT" || e?.killed && e?.signal === "SIGTERM") return { ok: false, error: "timeout", stderr };
|
|
24894
|
-
if (e?.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") return { ok: false, error: "too_large", stderr };
|
|
24895
|
-
return { ok: false, error: "failed", stderr };
|
|
24896
|
-
}
|
|
24897
|
-
function runGitSync(cwd, args2, opts = {}) {
|
|
24898
|
-
try {
|
|
24899
|
-
const stdout = (0, import_node_child_process10.execFileSync)("git", hardenedGitArgv(args2), {
|
|
24900
|
-
cwd,
|
|
24901
|
-
env: hardenedGitEnv(),
|
|
24902
|
-
encoding: "utf-8",
|
|
24903
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
24904
|
-
timeout: opts.timeoutMs ?? DEFAULT_GIT_TIMEOUT_MS,
|
|
24905
|
-
maxBuffer: opts.maxBuffer ?? DEFAULT_GIT_MAX_BUFFER
|
|
24906
|
-
});
|
|
24907
|
-
return { ok: true, stdout };
|
|
24908
|
-
} catch (err2) {
|
|
24909
|
-
return classifyError(err2);
|
|
24910
|
-
}
|
|
24911
|
-
}
|
|
24912
|
-
function runGit(cwd, args2, opts = {}) {
|
|
24913
|
-
return new Promise((resolvePromise) => {
|
|
24914
|
-
(0, import_node_child_process10.execFile)(
|
|
24915
|
-
"git",
|
|
24916
|
-
hardenedGitArgv(args2),
|
|
24917
|
-
{
|
|
24918
|
-
cwd,
|
|
24919
|
-
env: hardenedGitEnv(),
|
|
24920
|
-
encoding: "utf-8",
|
|
24921
|
-
timeout: opts.timeoutMs ?? DEFAULT_GIT_TIMEOUT_MS,
|
|
24922
|
-
maxBuffer: opts.maxBuffer ?? DEFAULT_GIT_MAX_BUFFER
|
|
24923
|
-
},
|
|
24924
|
-
(err2, stdout, stderr) => {
|
|
24925
|
-
if (err2) {
|
|
24926
|
-
const e = err2;
|
|
24927
|
-
e.stderr = stderr;
|
|
24928
|
-
resolvePromise(classifyError(e));
|
|
24929
|
-
return;
|
|
24930
|
-
}
|
|
24931
|
-
resolvePromise({ ok: true, stdout });
|
|
24932
|
-
}
|
|
24933
|
-
);
|
|
24934
|
-
});
|
|
24935
|
-
}
|
|
24936
|
-
|
|
24937
|
-
// src/lib/repo-context.ts
|
|
24938
24990
|
var import_node_os5 = require("node:os");
|
|
24939
24991
|
function rgInvocations(env = process.env) {
|
|
24940
24992
|
const out2 = [{ cmd: "rg" }];
|
|
@@ -25895,10 +25947,10 @@ function installRunEvidence(run4) {
|
|
|
25895
25947
|
}
|
|
25896
25948
|
|
|
25897
25949
|
// src/lib/git-frame.ts
|
|
25898
|
-
var
|
|
25950
|
+
var import_node_fs39 = require("node:fs");
|
|
25899
25951
|
var import_node_os6 = require("node:os");
|
|
25900
|
-
var import_node_path29 = require("node:path");
|
|
25901
25952
|
var import_node_path30 = require("node:path");
|
|
25953
|
+
var import_node_path31 = require("node:path");
|
|
25902
25954
|
var VALUE_TOKEN = `(?:'[^']*'|"[^"]*"|\\S+)`;
|
|
25903
25955
|
var GIT_GLOBAL_OPTS = `(?:\\s+(?:-[Cc]\\s+${VALUE_TOKEN}|--?[\\w-]+(?:=\\S+)?))*`;
|
|
25904
25956
|
var COMMIT_HEAD = `git${GIT_GLOBAL_OPTS}\\s+commit(?![\\w-])`;
|
|
@@ -25985,8 +26037,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
|
|
|
25985
26037
|
if (SHELL_DYNAMIC.test(raw) || raw === "-") {
|
|
25986
26038
|
return { dir: null, named: true, unresolvable: `cd target not statically resolvable: ${raw}` };
|
|
25987
26039
|
}
|
|
25988
|
-
const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0,
|
|
25989
|
-
dir = (0,
|
|
26040
|
+
const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path31.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
|
|
26041
|
+
dir = (0, import_node_path30.isAbsolute)(expanded) ? expanded : (0, import_node_path30.resolve)(dir, expanded);
|
|
25990
26042
|
}
|
|
25991
26043
|
const seg = segments[segmentIndex];
|
|
25992
26044
|
const overrideMatch = /--(?:git-dir|work-tree)(?:=|\s)|\bGIT_(?:DIR|WORK_TREE|INDEX_FILE)=/.exec(seg);
|
|
@@ -26004,8 +26056,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
|
|
|
26004
26056
|
if (SHELL_DYNAMIC.test(raw)) {
|
|
26005
26057
|
return { dir: null, named: true, unresolvable: `-C target not statically resolvable: ${raw}` };
|
|
26006
26058
|
}
|
|
26007
|
-
const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0,
|
|
26008
|
-
dir = (0,
|
|
26059
|
+
const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path31.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
|
|
26060
|
+
dir = (0, import_node_path30.isAbsolute)(expanded) ? expanded : (0, import_node_path30.resolve)(dir, expanded);
|
|
26009
26061
|
}
|
|
26010
26062
|
}
|
|
26011
26063
|
return { dir, named, unresolvable: null };
|
|
@@ -26065,14 +26117,14 @@ function gitAt(dir, args2) {
|
|
|
26065
26117
|
}
|
|
26066
26118
|
function realpathOr2(p) {
|
|
26067
26119
|
try {
|
|
26068
|
-
return
|
|
26120
|
+
return import_node_fs39.realpathSync.native(p);
|
|
26069
26121
|
} catch {
|
|
26070
|
-
return (0,
|
|
26122
|
+
return (0, import_node_path30.resolve)(p);
|
|
26071
26123
|
}
|
|
26072
26124
|
}
|
|
26073
26125
|
function resolveFrame(input) {
|
|
26074
26126
|
const found = findMomentSegment(input.command, input.on);
|
|
26075
|
-
const hookDirUsable = !!input.hookCwd && (0,
|
|
26127
|
+
const hookDirUsable = !!input.hookCwd && (0, import_node_fs39.existsSync)(input.hookCwd);
|
|
26076
26128
|
const baseDir = hookDirUsable ? input.hookCwd : process.cwd();
|
|
26077
26129
|
let anchor = hookDirUsable ? "hook-cwd" : "process-cwd";
|
|
26078
26130
|
const refuse = (refusal) => ({
|
|
@@ -26095,7 +26147,7 @@ function resolveFrame(input) {
|
|
|
26095
26147
|
if (dirs.size > 1) return refuse(`target:multiple ${found.moment} targets in one command`);
|
|
26096
26148
|
const targetDir = dirs.size === 1 ? [...dirs][0] : baseDir;
|
|
26097
26149
|
if (targetDir !== baseDir) {
|
|
26098
|
-
if (!(0,
|
|
26150
|
+
if (!(0, import_node_fs39.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
|
|
26099
26151
|
dir = targetDir;
|
|
26100
26152
|
}
|
|
26101
26153
|
}
|
|
@@ -26106,7 +26158,7 @@ function resolveFrame(input) {
|
|
|
26106
26158
|
const gitDirRaw = gitAt(dir, ["rev-parse", "--absolute-git-dir"]);
|
|
26107
26159
|
const commonRaw = gitAt(dir, ["rev-parse", "--git-common-dir"]);
|
|
26108
26160
|
const gitDir = gitDirRaw ? realpathOr2(gitDirRaw) : null;
|
|
26109
|
-
const commonDir = commonRaw ? realpathOr2((0,
|
|
26161
|
+
const commonDir = commonRaw ? realpathOr2((0, import_node_path30.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path30.resolve)(dir, commonRaw)) : null;
|
|
26110
26162
|
const branchRaw = gitAt(dir, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
26111
26163
|
return {
|
|
26112
26164
|
moment: found?.moment ?? null,
|
|
@@ -26281,8 +26333,8 @@ function stagedRange(frame, command) {
|
|
|
26281
26333
|
if (plan.kind === "unpredictable") {
|
|
26282
26334
|
return { kind: "staged", base: "HEAD", head: "INDEX", via: "staged-in-command", refusal: plan.reason };
|
|
26283
26335
|
}
|
|
26284
|
-
const mergeHead = frame.gitDir ? (0,
|
|
26285
|
-
if (mergeHead && (0,
|
|
26336
|
+
const mergeHead = frame.gitDir ? (0, import_node_path31.join)(frame.gitDir, "MERGE_HEAD") : null;
|
|
26337
|
+
if (mergeHead && (0, import_node_fs39.existsSync)(mergeHead)) {
|
|
26286
26338
|
const vsHead = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "HEAD"]).split("\n").filter(Boolean));
|
|
26287
26339
|
const vsMerge = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "MERGE_HEAD"]).split("\n").filter(Boolean));
|
|
26288
26340
|
const resolutions = new Set([...vsHead].filter((f) => vsMerge.has(f) && !isVerityOwnedPath(f)));
|
|
@@ -26416,7 +26468,7 @@ function truthy(v) {
|
|
|
26416
26468
|
}
|
|
26417
26469
|
|
|
26418
26470
|
// src/lib/transcript.ts
|
|
26419
|
-
var
|
|
26471
|
+
var import_node_fs40 = require("node:fs");
|
|
26420
26472
|
var MAX_READ_BYTES = 256 * 1024;
|
|
26421
26473
|
var SMALL_FILE_BYTES = 64 * 1024;
|
|
26422
26474
|
var MAX_FILES_LIST = 20;
|
|
@@ -26443,7 +26495,7 @@ async function extractActionSummary(transcriptPath) {
|
|
|
26443
26495
|
function readTurnLines(transcriptPath) {
|
|
26444
26496
|
let size;
|
|
26445
26497
|
try {
|
|
26446
|
-
size = (0,
|
|
26498
|
+
size = (0, import_node_fs40.statSync)(transcriptPath).size;
|
|
26447
26499
|
} catch {
|
|
26448
26500
|
return null;
|
|
26449
26501
|
}
|
|
@@ -26451,7 +26503,7 @@ function readTurnLines(transcriptPath) {
|
|
|
26451
26503
|
let raw;
|
|
26452
26504
|
let windowed = false;
|
|
26453
26505
|
if (size <= SMALL_FILE_BYTES) {
|
|
26454
|
-
raw = (0,
|
|
26506
|
+
raw = (0, import_node_fs40.readFileSync)(transcriptPath, "utf-8");
|
|
26455
26507
|
} else {
|
|
26456
26508
|
windowed = true;
|
|
26457
26509
|
const buf = Buffer.alloc(Math.min(MAX_READ_BYTES, size));
|
|
@@ -27021,7 +27073,7 @@ function channelSilence(input) {
|
|
|
27021
27073
|
// src/lib/cli-version.ts
|
|
27022
27074
|
function cliVersion() {
|
|
27023
27075
|
try {
|
|
27024
|
-
return true ? "0.34.0-experimental.
|
|
27076
|
+
return true ? "0.34.0-experimental.421a631" : "dev";
|
|
27025
27077
|
} catch {
|
|
27026
27078
|
return "dev";
|
|
27027
27079
|
}
|
|
@@ -27062,7 +27114,7 @@ async function sendSkipBeacon(ctx, reason) {
|
|
|
27062
27114
|
|
|
27063
27115
|
// src/lib/static-analysis.ts
|
|
27064
27116
|
var import_node_child_process12 = require("node:child_process");
|
|
27065
|
-
var
|
|
27117
|
+
var import_node_fs41 = require("node:fs");
|
|
27066
27118
|
var SEVERITY_ORDER = {
|
|
27067
27119
|
Error: 0,
|
|
27068
27120
|
Critical: 0,
|
|
@@ -27118,7 +27170,7 @@ function runCodacyAnalysis(files) {
|
|
|
27118
27170
|
if (files.length === 0) return empty;
|
|
27119
27171
|
const existingFiles = files.filter((f) => {
|
|
27120
27172
|
try {
|
|
27121
|
-
return (0,
|
|
27173
|
+
return (0, import_node_fs41.existsSync)(f);
|
|
27122
27174
|
} catch {
|
|
27123
27175
|
return false;
|
|
27124
27176
|
}
|
|
@@ -27387,8 +27439,8 @@ async function scope(run4) {
|
|
|
27387
27439
|
}
|
|
27388
27440
|
|
|
27389
27441
|
// src/lib/specs.ts
|
|
27390
|
-
var
|
|
27391
|
-
var
|
|
27442
|
+
var import_node_fs42 = require("node:fs");
|
|
27443
|
+
var import_node_path32 = require("node:path");
|
|
27392
27444
|
var SPEC_CANDIDATES = [
|
|
27393
27445
|
"CLAUDE.md",
|
|
27394
27446
|
"AGENTS.md",
|
|
@@ -27410,7 +27462,7 @@ var UNCONSULTED_TOTAL_BYTES = 30720;
|
|
|
27410
27462
|
function readSpecFiles(specsOpt, root) {
|
|
27411
27463
|
const out2 = [];
|
|
27412
27464
|
for (const raw of specsOpt.split(",").map((f) => f.trim()).filter(Boolean)) {
|
|
27413
|
-
const candidate = (0,
|
|
27465
|
+
const candidate = (0, import_node_path32.isAbsolute)(raw) ? (0, import_node_path32.relative)(root, raw) : raw;
|
|
27414
27466
|
const content = readFileInside(root, candidate, MAX_EXPLICIT_SPEC_FILE_BYTES);
|
|
27415
27467
|
if (content === null) continue;
|
|
27416
27468
|
out2.push({ path: raw, content });
|
|
@@ -27429,7 +27481,7 @@ function discoverSpecs(consulted = []) {
|
|
|
27429
27481
|
const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
|
|
27430
27482
|
if (totalBytes >= totalCap) return false;
|
|
27431
27483
|
if (seen.has(specPath)) return true;
|
|
27432
|
-
if (!(0,
|
|
27484
|
+
if (!(0, import_node_fs42.existsSync)(specPath)) return true;
|
|
27433
27485
|
seen.add(specPath);
|
|
27434
27486
|
const remaining = totalCap - totalBytes;
|
|
27435
27487
|
const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
|
|
@@ -27452,7 +27504,7 @@ function discoverSpecs(consulted = []) {
|
|
|
27452
27504
|
if (!addSpec(candidate)) break;
|
|
27453
27505
|
}
|
|
27454
27506
|
for (const dir of ["spec", "docs"]) {
|
|
27455
|
-
if (!(0,
|
|
27507
|
+
if (!(0, import_node_fs42.existsSync)(dir)) continue;
|
|
27456
27508
|
try {
|
|
27457
27509
|
const mdFiles = findMdFiles(dir, 2).sort();
|
|
27458
27510
|
for (const mdFile of mdFiles) {
|
|
@@ -27467,9 +27519,9 @@ function findMdFiles(dir, maxDepth, depth = 0) {
|
|
|
27467
27519
|
if (depth >= maxDepth) return [];
|
|
27468
27520
|
const result = [];
|
|
27469
27521
|
try {
|
|
27470
|
-
const entries = (0,
|
|
27522
|
+
const entries = (0, import_node_fs42.readdirSync)(dir, { withFileTypes: true });
|
|
27471
27523
|
for (const entry of entries) {
|
|
27472
|
-
const fullPath = (0,
|
|
27524
|
+
const fullPath = (0, import_node_path32.join)(dir, entry.name);
|
|
27473
27525
|
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
27474
27526
|
result.push(fullPath);
|
|
27475
27527
|
} else if (entry.isDirectory() && depth < maxDepth - 1) {
|
|
@@ -27482,25 +27534,25 @@ function findMdFiles(dir, maxDepth, depth = 0) {
|
|
|
27482
27534
|
}
|
|
27483
27535
|
function discoverPlans() {
|
|
27484
27536
|
const home = process.env.HOME ?? "";
|
|
27485
|
-
const homePlansDir = (0,
|
|
27537
|
+
const homePlansDir = (0, import_node_path32.join)(home, ".claude", "plans");
|
|
27486
27538
|
const sources = [];
|
|
27487
27539
|
if (isRealDirectoryChain(process.cwd(), [".claude", "plans"])) {
|
|
27488
|
-
sources.push({ root: process.cwd(), prefix: (0,
|
|
27540
|
+
sources.push({ root: process.cwd(), prefix: (0, import_node_path32.join)(".claude", "plans") });
|
|
27489
27541
|
}
|
|
27490
|
-
if (home && (0,
|
|
27542
|
+
if (home && (0, import_node_fs42.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
|
|
27491
27543
|
const candidates2 = [];
|
|
27492
27544
|
const seen = /* @__PURE__ */ new Set();
|
|
27493
27545
|
for (const source2 of sources) {
|
|
27494
27546
|
let names2;
|
|
27495
27547
|
try {
|
|
27496
|
-
names2 = (0,
|
|
27548
|
+
names2 = (0, import_node_fs42.readdirSync)(source2.prefix ? (0, import_node_path32.join)(source2.root, source2.prefix) : source2.root);
|
|
27497
27549
|
} catch {
|
|
27498
27550
|
continue;
|
|
27499
27551
|
}
|
|
27500
27552
|
for (const f of names2) {
|
|
27501
27553
|
if (!f.endsWith(".md") || seen.has(f)) continue;
|
|
27502
27554
|
seen.add(f);
|
|
27503
|
-
const relPath = source2.prefix ? (0,
|
|
27555
|
+
const relPath = source2.prefix ? (0, import_node_path32.join)(source2.prefix, f) : f;
|
|
27504
27556
|
const stat3 = statRegularInRoot(source2.root, relPath);
|
|
27505
27557
|
if (!stat3.ok) continue;
|
|
27506
27558
|
candidates2.push({ name: f, root: source2.root, relPath, mtime: stat3.mtimeMs, size: stat3.size });
|
|
@@ -27518,9 +27570,9 @@ function discoverPlans() {
|
|
|
27518
27570
|
function isRealDirectoryChain(root, parts2) {
|
|
27519
27571
|
let current = root;
|
|
27520
27572
|
for (const part of parts2) {
|
|
27521
|
-
current = (0,
|
|
27573
|
+
current = (0, import_node_path32.join)(current, part);
|
|
27522
27574
|
try {
|
|
27523
|
-
if (!(0,
|
|
27575
|
+
if (!(0, import_node_fs42.lstatSync)(current).isDirectory()) return false;
|
|
27524
27576
|
} catch {
|
|
27525
27577
|
return false;
|
|
27526
27578
|
}
|
|
@@ -27535,7 +27587,7 @@ function discoverGuardDocs(rangeFiles2) {
|
|
|
27535
27587
|
if (result.length >= MAX_SPEC_FILES) break;
|
|
27536
27588
|
if (!GUARD_DOC_EXT.test(path)) continue;
|
|
27537
27589
|
if (path.startsWith("/") || path.includes("..")) continue;
|
|
27538
|
-
if (!(0,
|
|
27590
|
+
if (!(0, import_node_fs42.existsSync)(path)) continue;
|
|
27539
27591
|
const opened = openRegularInRoot(process.cwd(), path);
|
|
27540
27592
|
if (!opened.ok) continue;
|
|
27541
27593
|
if (opened.size > MAX_PLAN_FILE_BYTES || totalBytes + opened.size > MAX_TOTAL_SPEC_BYTES) {
|
|
@@ -27721,8 +27773,8 @@ async function mode(run4) {
|
|
|
27721
27773
|
}
|
|
27722
27774
|
|
|
27723
27775
|
// src/lib/fold.ts
|
|
27724
|
-
var
|
|
27725
|
-
var
|
|
27776
|
+
var import_node_fs43 = require("node:fs");
|
|
27777
|
+
var import_node_path33 = require("node:path");
|
|
27726
27778
|
var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
|
|
27727
27779
|
"user",
|
|
27728
27780
|
"assistant",
|
|
@@ -27859,7 +27911,7 @@ function candidateRoots(repoRoot2) {
|
|
|
27859
27911
|
const norm2 = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
27860
27912
|
const out2 = [norm2];
|
|
27861
27913
|
try {
|
|
27862
|
-
const real =
|
|
27914
|
+
const real = import_node_fs43.realpathSync.native(norm2).replace(/\\/g, "/").replace(/\/+$/, "");
|
|
27863
27915
|
if (real !== norm2) out2.push(real);
|
|
27864
27916
|
} catch {
|
|
27865
27917
|
}
|
|
@@ -27947,31 +27999,31 @@ function fold(transcriptPath, opts = {}) {
|
|
|
27947
27999
|
}
|
|
27948
28000
|
};
|
|
27949
28001
|
try {
|
|
27950
|
-
if (!(0,
|
|
27951
|
-
ingest((0,
|
|
28002
|
+
if (!(0, import_node_fs43.existsSync)(transcriptPath)) return result;
|
|
28003
|
+
ingest((0, import_node_fs43.readFileSync)(transcriptPath, "utf8"), "agent");
|
|
27952
28004
|
result.coverage.complete = true;
|
|
27953
28005
|
} catch {
|
|
27954
28006
|
return result;
|
|
27955
28007
|
}
|
|
27956
28008
|
try {
|
|
27957
|
-
const sidecarDir = (0,
|
|
27958
|
-
(0,
|
|
27959
|
-
(0,
|
|
28009
|
+
const sidecarDir = (0, import_node_path33.join)(
|
|
28010
|
+
(0, import_node_path33.dirname)(transcriptPath),
|
|
28011
|
+
(0, import_node_path33.basename)(transcriptPath).replace(/\.jsonl$/, ""),
|
|
27960
28012
|
"subagents"
|
|
27961
28013
|
);
|
|
27962
|
-
if ((0,
|
|
28014
|
+
if ((0, import_node_fs43.existsSync)(sidecarDir)) {
|
|
27963
28015
|
const maxFiles = opts.maxSidecars ?? 200;
|
|
27964
28016
|
const maxBytes = opts.maxSidecarBytes ?? 16 * 1024 * 1024;
|
|
27965
28017
|
const found = [];
|
|
27966
28018
|
const walk2 = (d, depth) => {
|
|
27967
28019
|
if (depth > 4) return;
|
|
27968
|
-
for (const e of (0,
|
|
27969
|
-
const p = (0,
|
|
28020
|
+
for (const e of (0, import_node_fs43.readdirSync)(d, { withFileTypes: true })) {
|
|
28021
|
+
const p = (0, import_node_path33.join)(d, e.name);
|
|
27970
28022
|
if (e.isDirectory()) {
|
|
27971
28023
|
walk2(p, depth + 1);
|
|
27972
28024
|
} else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
|
|
27973
28025
|
try {
|
|
27974
|
-
const st = (0,
|
|
28026
|
+
const st = (0, import_node_fs43.statSync)(p);
|
|
27975
28027
|
found.push({ path: p, size: st.size, mtimeMs: st.mtimeMs });
|
|
27976
28028
|
} catch {
|
|
27977
28029
|
result.coverage.malformed++;
|
|
@@ -27988,7 +28040,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
27988
28040
|
continue;
|
|
27989
28041
|
}
|
|
27990
28042
|
try {
|
|
27991
|
-
ingest((0,
|
|
28043
|
+
ingest((0, import_node_fs43.readFileSync)(f.path, "utf8"), "subagent");
|
|
27992
28044
|
bytes += f.size;
|
|
27993
28045
|
result.coverage.subagentFiles++;
|
|
27994
28046
|
} catch {
|
|
@@ -28023,7 +28075,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
28023
28075
|
}
|
|
28024
28076
|
function classifyUnobserved(path) {
|
|
28025
28077
|
try {
|
|
28026
|
-
const st = (0,
|
|
28078
|
+
const st = (0, import_node_fs43.statSync)(path);
|
|
28027
28079
|
if (!st.isFile()) return "unreadable";
|
|
28028
28080
|
} catch {
|
|
28029
28081
|
return "unreadable";
|
|
@@ -28338,20 +28390,20 @@ async function evidence(run4) {
|
|
|
28338
28390
|
}
|
|
28339
28391
|
|
|
28340
28392
|
// src/lib/cache-cleanup.ts
|
|
28341
|
-
var
|
|
28342
|
-
var
|
|
28393
|
+
var import_node_fs44 = require("node:fs");
|
|
28394
|
+
var import_node_path34 = require("node:path");
|
|
28343
28395
|
var CACHE_TTL_DAYS = 7;
|
|
28344
28396
|
function pruneStaleCache() {
|
|
28345
28397
|
try {
|
|
28346
28398
|
const dir = projectPath(CACHE_DIR);
|
|
28347
28399
|
const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
|
|
28348
|
-
for (const entry of (0,
|
|
28400
|
+
for (const entry of (0, import_node_fs44.readdirSync)(dir)) {
|
|
28349
28401
|
if (!entry.startsWith("pending-")) continue;
|
|
28350
|
-
const path = (0,
|
|
28402
|
+
const path = (0, import_node_path34.join)(dir, entry);
|
|
28351
28403
|
try {
|
|
28352
|
-
const stat3 = (0,
|
|
28404
|
+
const stat3 = (0, import_node_fs44.statSync)(path);
|
|
28353
28405
|
if (stat3.mtimeMs < cutoff) {
|
|
28354
|
-
(0,
|
|
28406
|
+
(0, import_node_fs44.unlinkSync)(path);
|
|
28355
28407
|
logEvent("cache_entry_pruned", {
|
|
28356
28408
|
path: entry,
|
|
28357
28409
|
age_days: Math.round((Date.now() - stat3.mtimeMs) / 864e5)
|
|
@@ -28365,7 +28417,7 @@ function pruneStaleCache() {
|
|
|
28365
28417
|
}
|
|
28366
28418
|
|
|
28367
28419
|
// src/lib/context-files.ts
|
|
28368
|
-
var
|
|
28420
|
+
var import_node_fs45 = require("node:fs");
|
|
28369
28421
|
var import_node_os7 = require("node:os");
|
|
28370
28422
|
var MAX_CONTEXT_FILES = 10;
|
|
28371
28423
|
var MAX_CONTEXT_FILE_BYTES = 10240;
|
|
@@ -28423,7 +28475,7 @@ function gatherContextFiles(contextPaths, deltaFiles, opts) {
|
|
|
28423
28475
|
continue;
|
|
28424
28476
|
}
|
|
28425
28477
|
try {
|
|
28426
|
-
const content = (0,
|
|
28478
|
+
const content = (0, import_node_fs45.readFileSync)(safePath, "utf8");
|
|
28427
28479
|
const bytes = Buffer.byteLength(content);
|
|
28428
28480
|
if (bytes > MAX_CONTEXT_FILE_BYTES) {
|
|
28429
28481
|
logEvent("context_file_skipped", { path: filePath, reason: "too_large", bytes });
|
|
@@ -28581,8 +28633,8 @@ function languageOf2(path) {
|
|
|
28581
28633
|
}
|
|
28582
28634
|
|
|
28583
28635
|
// src/lib/code/runtime.ts
|
|
28584
|
-
var
|
|
28585
|
-
var
|
|
28636
|
+
var import_node_fs46 = require("node:fs");
|
|
28637
|
+
var import_node_path35 = require("node:path");
|
|
28586
28638
|
var import_web_tree_sitter2 = __toESM2(require_web_tree_sitter2());
|
|
28587
28639
|
|
|
28588
28640
|
// src/lib/code/grammars.json
|
|
@@ -28642,18 +28694,18 @@ var grammars_default = {
|
|
|
28642
28694
|
var MAX_PARSE_BYTES = 512 * 1024;
|
|
28643
28695
|
function grammarCandidates(file, pkg, env = process.env) {
|
|
28644
28696
|
return [
|
|
28645
|
-
...env.VERITY_GRAMMAR_DIR ? [(0,
|
|
28646
|
-
(0,
|
|
28697
|
+
...env.VERITY_GRAMMAR_DIR ? [(0, import_node_path35.join)(env.VERITY_GRAMMAR_DIR, file)] : [],
|
|
28698
|
+
(0, import_node_path35.join)(__dirname, "..", "data", "grammars", file),
|
|
28647
28699
|
// bundled: cli/bin/ → cli/data/grammars/
|
|
28648
|
-
(0,
|
|
28700
|
+
(0, import_node_path35.join)(__dirname, "..", "..", "..", "data", "grammars", file),
|
|
28649
28701
|
// tsx: cli/src/lib/code/ → cli/data/grammars/
|
|
28650
|
-
(0,
|
|
28702
|
+
(0, import_node_path35.join)(__dirname, "..", "..", "..", "node_modules", pkg, file)
|
|
28651
28703
|
// tsx, before a build: the pinned devDependency
|
|
28652
28704
|
];
|
|
28653
28705
|
}
|
|
28654
28706
|
function locateGrammar(id, env = process.env) {
|
|
28655
28707
|
const g = grammars_default[id];
|
|
28656
|
-
return grammarCandidates(g.file, g.package, env).find((p) => (0,
|
|
28708
|
+
return grammarCandidates(g.file, g.package, env).find((p) => (0, import_node_fs46.existsSync)(p)) ?? null;
|
|
28657
28709
|
}
|
|
28658
28710
|
var loading = null;
|
|
28659
28711
|
function loadRuntime(env = process.env) {
|
|
@@ -30982,8 +31034,8 @@ async function repoContext(run4) {
|
|
|
30982
31034
|
|
|
30983
31035
|
// src/lib/seed-runner.ts
|
|
30984
31036
|
var import_promises15 = require("node:fs/promises");
|
|
30985
|
-
var
|
|
30986
|
-
var
|
|
31037
|
+
var import_node_fs47 = require("node:fs");
|
|
31038
|
+
var import_node_path36 = require("node:path");
|
|
30987
31039
|
var import_yaml4 = __toESM2(require_dist());
|
|
30988
31040
|
|
|
30989
31041
|
// src/lib/seed.ts
|
|
@@ -31206,8 +31258,8 @@ function normalizeTitle(title) {
|
|
|
31206
31258
|
async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
|
|
31207
31259
|
const titles = /* @__PURE__ */ new Set();
|
|
31208
31260
|
for (const dir of NODE_DIRS) {
|
|
31209
|
-
const full = (0,
|
|
31210
|
-
if (!(0,
|
|
31261
|
+
const full = (0, import_node_path36.join)(memoryDir3, dir);
|
|
31262
|
+
if (!(0, import_node_fs47.existsSync)(full)) continue;
|
|
31211
31263
|
let files;
|
|
31212
31264
|
try {
|
|
31213
31265
|
files = await (0, import_promises15.readdir)(full);
|
|
@@ -31218,7 +31270,7 @@ async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
|
|
|
31218
31270
|
if (!file.endsWith(".md")) continue;
|
|
31219
31271
|
let content;
|
|
31220
31272
|
try {
|
|
31221
|
-
content = await (0, import_promises15.readFile)((0,
|
|
31273
|
+
content = await (0, import_promises15.readFile)((0, import_node_path36.join)(full, file), "utf-8");
|
|
31222
31274
|
} catch {
|
|
31223
31275
|
continue;
|
|
31224
31276
|
}
|
|
@@ -31289,7 +31341,7 @@ function renderNodeMarkdown(candidate, nodeId, createdAt) {
|
|
|
31289
31341
|
return fm;
|
|
31290
31342
|
}
|
|
31291
31343
|
async function runSeed(opts) {
|
|
31292
|
-
if (!(0,
|
|
31344
|
+
if (!(0, import_node_fs47.existsSync)(STANDARD_FILE)) {
|
|
31293
31345
|
return { created: 0, existing: 0, failed: 0, skipped: "no_standard", candidates: [] };
|
|
31294
31346
|
}
|
|
31295
31347
|
let standardDoc;
|
|
@@ -31301,7 +31353,7 @@ async function runSeed(opts) {
|
|
|
31301
31353
|
}
|
|
31302
31354
|
const knowledgeSpec = standardDoc.knowledge_spec ?? {};
|
|
31303
31355
|
let readmeContent;
|
|
31304
|
-
if ((0,
|
|
31356
|
+
if ((0, import_node_fs47.existsSync)("README.md")) {
|
|
31305
31357
|
try {
|
|
31306
31358
|
readmeContent = await (0, import_promises15.readFile)("README.md", "utf-8");
|
|
31307
31359
|
} catch {
|
|
@@ -31309,7 +31361,7 @@ async function runSeed(opts) {
|
|
|
31309
31361
|
}
|
|
31310
31362
|
let claudeMdContent;
|
|
31311
31363
|
for (const p of ["CLAUDE.md", ".claude/CLAUDE.md"]) {
|
|
31312
|
-
if ((0,
|
|
31364
|
+
if ((0, import_node_fs47.existsSync)(p)) {
|
|
31313
31365
|
try {
|
|
31314
31366
|
claudeMdContent = await (0, import_promises15.readFile)(p, "utf-8");
|
|
31315
31367
|
break;
|
|
@@ -31389,13 +31441,13 @@ async function runSeed(opts) {
|
|
|
31389
31441
|
continue;
|
|
31390
31442
|
}
|
|
31391
31443
|
const deduplicated = res.data.deduplicated === true;
|
|
31392
|
-
if (deduplicated && (0,
|
|
31444
|
+
if (deduplicated && (0, import_node_fs47.existsSync)(targetPath)) {
|
|
31393
31445
|
existing++;
|
|
31394
31446
|
continue;
|
|
31395
31447
|
}
|
|
31396
31448
|
const content = typeof res.data.content === "string" && res.data.content.length > 0 ? res.data.content : renderNodeMarkdown(c, nodeId, createdAt);
|
|
31397
31449
|
try {
|
|
31398
|
-
await (0, import_promises15.mkdir)((0,
|
|
31450
|
+
await (0, import_promises15.mkdir)((0, import_node_path36.dirname)(targetPath), { recursive: true });
|
|
31399
31451
|
await (0, import_promises15.writeFile)(targetPath, content);
|
|
31400
31452
|
if (deduplicated) existing++;
|
|
31401
31453
|
else {
|
|
@@ -31411,8 +31463,8 @@ async function runSeed(opts) {
|
|
|
31411
31463
|
}
|
|
31412
31464
|
|
|
31413
31465
|
// src/commands/analyze/phases/08-memory-manifest.ts
|
|
31414
|
-
var
|
|
31415
|
-
var
|
|
31466
|
+
var import_node_fs48 = require("node:fs");
|
|
31467
|
+
var import_node_path37 = require("node:path");
|
|
31416
31468
|
async function memoryManifest(run4) {
|
|
31417
31469
|
const { globals } = run4;
|
|
31418
31470
|
const { serviceUrl, token } = run4;
|
|
@@ -31422,9 +31474,9 @@ async function memoryManifest(run4) {
|
|
|
31422
31474
|
let autoSeedNotice = null;
|
|
31423
31475
|
try {
|
|
31424
31476
|
await ensureMemoryDir();
|
|
31425
|
-
const seedMarker = (0,
|
|
31426
|
-
const hasStandard = (0,
|
|
31427
|
-
const alreadyTried = (0,
|
|
31477
|
+
const seedMarker = (0, import_node_path37.join)(VERITY_DIR, ".seeded");
|
|
31478
|
+
const hasStandard = (0, import_node_fs48.existsSync)(STANDARD_FILE);
|
|
31479
|
+
const alreadyTried = (0, import_node_fs48.existsSync)(seedMarker);
|
|
31428
31480
|
if (hasStandard && !alreadyTried) {
|
|
31429
31481
|
const preManifest = await buildManifest();
|
|
31430
31482
|
if (preManifest.nodes.length === 0) {
|
|
@@ -31437,7 +31489,7 @@ async function memoryManifest(run4) {
|
|
|
31437
31489
|
dryRun: false
|
|
31438
31490
|
});
|
|
31439
31491
|
if (seedResult.created > 0 || seedResult.existing > 0) {
|
|
31440
|
-
(0,
|
|
31492
|
+
(0, import_node_fs48.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created} existing=${seedResult.existing}
|
|
31441
31493
|
`);
|
|
31442
31494
|
if (seedResult.created > 0) {
|
|
31443
31495
|
autoSeedNotice = `Seeded ${seedResult.created} knowledge node(s) from your existing Standard (one-time).`;
|
|
@@ -31448,7 +31500,7 @@ async function memoryManifest(run4) {
|
|
|
31448
31500
|
failed: seedResult.failed
|
|
31449
31501
|
});
|
|
31450
31502
|
} else if (seedResult.skipped === "already_seeded") {
|
|
31451
|
-
(0,
|
|
31503
|
+
(0, import_node_fs48.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
|
|
31452
31504
|
`);
|
|
31453
31505
|
} else {
|
|
31454
31506
|
logEvent("auto_seed_noop", {
|
|
@@ -31543,7 +31595,7 @@ function computeIncrement(reviewedPaths, hashOf, priorAuthored) {
|
|
|
31543
31595
|
}
|
|
31544
31596
|
|
|
31545
31597
|
// src/commands/analyze/phases/10-working-memory.ts
|
|
31546
|
-
var
|
|
31598
|
+
var import_node_path38 = require("node:path");
|
|
31547
31599
|
async function workingMemory(run4) {
|
|
31548
31600
|
const { opts } = run4;
|
|
31549
31601
|
const { allForReview, baseline, conversation, foldResult, sessionId, token, transcriptPath } = run4;
|
|
@@ -31555,7 +31607,7 @@ async function workingMemory(run4) {
|
|
|
31555
31607
|
const priorState = foldForMarks(memorySession.d);
|
|
31556
31608
|
incrementReport = computeIncrement(
|
|
31557
31609
|
allForReview,
|
|
31558
|
-
(p) => fileHash((0,
|
|
31610
|
+
(p) => fileHash((0, import_node_path38.join)(repoRoot(), p)),
|
|
31559
31611
|
priorState.authored_all.map((a) => ({
|
|
31560
31612
|
path: a.path,
|
|
31561
31613
|
hash_at_last_verdict: a.hash_at_last_verdict
|
|
@@ -31637,7 +31689,7 @@ async function workingMemory(run4) {
|
|
|
31637
31689
|
}
|
|
31638
31690
|
|
|
31639
31691
|
// src/lib/note-budget.ts
|
|
31640
|
-
var
|
|
31692
|
+
var import_node_fs49 = require("node:fs");
|
|
31641
31693
|
var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
|
|
31642
31694
|
var EPISODE_STALE_SECONDS = 30 * 60;
|
|
31643
31695
|
var FRESH = { delivered: 0, tasksCompleted: 0, ts: 0 };
|
|
@@ -31659,9 +31711,9 @@ function advisoryBudgetSpent(episode, rawDecision) {
|
|
|
31659
31711
|
}
|
|
31660
31712
|
function readAdvisoryEpisode(sessionId) {
|
|
31661
31713
|
const file = scopedFile(ADVISORY_EPISODE_FILE, sessionId);
|
|
31662
|
-
if (!(0,
|
|
31714
|
+
if (!(0, import_node_fs49.existsSync)(file)) return null;
|
|
31663
31715
|
try {
|
|
31664
|
-
const o = JSON.parse((0,
|
|
31716
|
+
const o = JSON.parse((0, import_node_fs49.readFileSync)(file, "utf-8")) ?? {};
|
|
31665
31717
|
const delivered = typeof o.delivered === "number" ? o.delivered : NaN;
|
|
31666
31718
|
if (isNaN(delivered)) return null;
|
|
31667
31719
|
return {
|
|
@@ -31675,8 +31727,8 @@ function readAdvisoryEpisode(sessionId) {
|
|
|
31675
31727
|
}
|
|
31676
31728
|
function writeAdvisoryEpisode(episode, sessionId) {
|
|
31677
31729
|
try {
|
|
31678
|
-
(0,
|
|
31679
|
-
(0,
|
|
31730
|
+
(0, import_node_fs49.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
31731
|
+
(0, import_node_fs49.writeFileSync)(
|
|
31680
31732
|
scopedFile(ADVISORY_EPISODE_FILE, sessionId),
|
|
31681
31733
|
JSON.stringify({ v: 1, ...episode })
|
|
31682
31734
|
);
|
|
@@ -32008,14 +32060,14 @@ async function buildRequest(run4) {
|
|
|
32008
32060
|
}
|
|
32009
32061
|
|
|
32010
32062
|
// src/lib/offline.ts
|
|
32011
|
-
var
|
|
32063
|
+
var import_node_fs50 = require("node:fs");
|
|
32012
32064
|
var import_node_crypto13 = require("node:crypto");
|
|
32013
32065
|
function cacheRequest(body2) {
|
|
32014
32066
|
try {
|
|
32015
|
-
(0,
|
|
32067
|
+
(0, import_node_fs50.mkdirSync)(CACHE_DIR, { recursive: true });
|
|
32016
32068
|
const suffix = (0, import_node_crypto13.randomBytes)(4).toString("hex");
|
|
32017
32069
|
const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
|
|
32018
|
-
(0,
|
|
32070
|
+
(0, import_node_fs50.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body2)));
|
|
32019
32071
|
} catch {
|
|
32020
32072
|
}
|
|
32021
32073
|
}
|
|
@@ -32134,8 +32186,8 @@ async function transmit(run4) {
|
|
|
32134
32186
|
}
|
|
32135
32187
|
|
|
32136
32188
|
// src/commands/analyze/phases/13-reconcile.ts
|
|
32137
|
-
var
|
|
32138
|
-
var
|
|
32189
|
+
var import_node_fs51 = require("node:fs");
|
|
32190
|
+
var import_node_path39 = require("node:path");
|
|
32139
32191
|
async function reconcile(run4) {
|
|
32140
32192
|
const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory: memory2, memorySession, response, reviewable, securityFiles, turnId } = run4;
|
|
32141
32193
|
const sentPaths = codeDelta.files.map((f) => f.path);
|
|
@@ -32164,7 +32216,7 @@ async function reconcile(run4) {
|
|
|
32164
32216
|
const st = foldDossier(memorySession.d);
|
|
32165
32217
|
openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line2) => {
|
|
32166
32218
|
try {
|
|
32167
|
-
const src = (0,
|
|
32219
|
+
const src = (0, import_node_fs51.readFileSync)((0, import_node_path39.join)(repoRoot(), file), "utf8").split("\n");
|
|
32168
32220
|
const at = src[line2 - 1];
|
|
32169
32221
|
return at === void 0 ? null : lineSha(at);
|
|
32170
32222
|
} catch {
|
|
@@ -32986,7 +33038,7 @@ function registerAnalyzeCommand(program2) {
|
|
|
32986
33038
|
var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
|
|
32987
33039
|
async function runAnalyze(opts, globals) {
|
|
32988
33040
|
if (!verityConfigured()) {
|
|
32989
|
-
(0,
|
|
33041
|
+
(0, import_node_fs52.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
|
|
32990
33042
|
process.exit(0);
|
|
32991
33043
|
}
|
|
32992
33044
|
const run4 = createRun(opts, globals);
|
|
@@ -33007,11 +33059,11 @@ async function runAnalyze(opts, globals) {
|
|
|
33007
33059
|
}
|
|
33008
33060
|
|
|
33009
33061
|
// src/commands/baseline.ts
|
|
33010
|
-
var
|
|
33062
|
+
var import_node_fs54 = require("node:fs");
|
|
33011
33063
|
|
|
33012
33064
|
// src/lib/project-skills.ts
|
|
33013
|
-
var
|
|
33014
|
-
var
|
|
33065
|
+
var import_node_fs53 = require("node:fs");
|
|
33066
|
+
var import_node_path40 = require("node:path");
|
|
33015
33067
|
var PROJECT_SKILL_NAMES = [
|
|
33016
33068
|
"verity-setup",
|
|
33017
33069
|
"verity-analyze",
|
|
@@ -33037,14 +33089,14 @@ var LEGACY_SKILL_NAMES = [
|
|
|
33037
33089
|
var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
|
|
33038
33090
|
function staleProjectSkills() {
|
|
33039
33091
|
const root = projectPath(".claude/skills");
|
|
33040
|
-
if (!(0,
|
|
33041
|
-
return ALL.filter((name2) => (0,
|
|
33092
|
+
if (!(0, import_node_fs53.existsSync)(root)) return [];
|
|
33093
|
+
return ALL.filter((name2) => (0, import_node_fs53.existsSync)((0, import_node_path40.join)(root, name2)));
|
|
33042
33094
|
}
|
|
33043
33095
|
function removeProjectSkills() {
|
|
33044
33096
|
const root = projectPath(".claude/skills");
|
|
33045
33097
|
const removed = [];
|
|
33046
33098
|
for (const name2 of staleProjectSkills()) {
|
|
33047
|
-
(0,
|
|
33099
|
+
(0, import_node_fs53.rmSync)((0, import_node_path40.join)(root, name2), { recursive: true, force: true });
|
|
33048
33100
|
removed.push(name2);
|
|
33049
33101
|
}
|
|
33050
33102
|
return removed;
|
|
@@ -33109,13 +33161,13 @@ function registerBaselineCommands(program2) {
|
|
|
33109
33161
|
let memoryMsg = null;
|
|
33110
33162
|
let memoryAgentLine = null;
|
|
33111
33163
|
const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
|
|
33112
|
-
if (realStart && !(0,
|
|
33164
|
+
if (realStart && !(0, import_node_fs54.existsSync)(memoryNotice)) {
|
|
33113
33165
|
const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
|
|
33114
33166
|
if (trackedGraph > 0) {
|
|
33115
33167
|
memoryMsg = `Verity: this project commits its knowledge base (${trackedGraph} files under .verity/memory/), so Verity's generated notes show up in every diff and pull request. Run \`verity memory untrack\` to keep them on disk but out of git, or \`verity memory track\` to keep committing them on purpose.`;
|
|
33116
33168
|
memoryAgentLine = `This project has ${trackedGraph} knowledge-graph files tracked in git under .verity/memory/. As of Verity 0.32.6 the graph is machine-local by default \u2014 it is rebuilt from the service, and committing it puts generated notes in every pull request. If the user wants that stopped, run \`verity memory untrack\` for them: it keeps every file on disk and stages their removal from the index, so they only need to commit \u2014 and their teammates' working copies will vanish on the next pull and re-sync from the service, which is expected. If they would rather keep committing it, \`verity memory track\` records that and nothing will offer again.`;
|
|
33117
33169
|
try {
|
|
33118
|
-
(0,
|
|
33170
|
+
(0, import_node_fs54.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
|
|
33119
33171
|
} catch {
|
|
33120
33172
|
}
|
|
33121
33173
|
}
|
|
@@ -33216,7 +33268,7 @@ function hookSource(value) {
|
|
|
33216
33268
|
}
|
|
33217
33269
|
|
|
33218
33270
|
// src/commands/review.ts
|
|
33219
|
-
var
|
|
33271
|
+
var import_node_fs55 = require("node:fs");
|
|
33220
33272
|
function registerReviewCommand(program2) {
|
|
33221
33273
|
program2.command("review").description("Run on-demand Verity analysis (advisory, never blocks)").requiredOption("--files <paths>", "Comma-separated file list").option("--changed <paths>", "Subset of --files that were modified").option("--intent <text>", "User intent description (max 2000 chars)").option("--specs <paths>", "Comma-separated spec file paths").option("--json", "Output raw JSON response").action(async (opts) => {
|
|
33222
33274
|
const globals = program2.opts();
|
|
@@ -33233,7 +33285,7 @@ async function runReview(opts, globals) {
|
|
|
33233
33285
|
const changedFiles = opts.changed ? opts.changed.split(",").map((f) => f.trim()).filter(Boolean) : allFiles;
|
|
33234
33286
|
const analyzable = filterAnalyzable(allFiles);
|
|
33235
33287
|
const securityFiles = filterSecurity(allFiles);
|
|
33236
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0,
|
|
33288
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs55.existsSync)(f) || resolveFile(f) !== null);
|
|
33237
33289
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
33238
33290
|
const codeDelta = collectCodeDelta(allFiles);
|
|
33239
33291
|
const tokenResult = await resolveToken(globals.token);
|
|
@@ -33299,8 +33351,8 @@ async function runReview(opts, globals) {
|
|
|
33299
33351
|
}
|
|
33300
33352
|
|
|
33301
33353
|
// src/commands/guard.ts
|
|
33302
|
-
var
|
|
33303
|
-
var
|
|
33354
|
+
var import_node_fs59 = require("node:fs");
|
|
33355
|
+
var import_node_path45 = require("node:path");
|
|
33304
33356
|
|
|
33305
33357
|
// src/lib/terminal-text.ts
|
|
33306
33358
|
var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/g;
|
|
@@ -33408,7 +33460,7 @@ async function runAgentReview(options) {
|
|
|
33408
33460
|
}
|
|
33409
33461
|
|
|
33410
33462
|
// src/lib/prove/auto.ts
|
|
33411
|
-
var
|
|
33463
|
+
var import_node_path44 = require("node:path");
|
|
33412
33464
|
var import_node_crypto18 = require("node:crypto");
|
|
33413
33465
|
|
|
33414
33466
|
// src/lib/prove/signals.ts
|
|
@@ -35130,18 +35182,18 @@ function renderReplay(model, property, r) {
|
|
|
35130
35182
|
// src/lib/prove/runner.ts
|
|
35131
35183
|
var import_node_child_process15 = require("node:child_process");
|
|
35132
35184
|
var import_node_os8 = require("node:os");
|
|
35133
|
-
var
|
|
35185
|
+
var import_node_fs58 = require("node:fs");
|
|
35134
35186
|
var import_node_os9 = require("node:os");
|
|
35135
|
-
var
|
|
35187
|
+
var import_node_path43 = require("node:path");
|
|
35136
35188
|
|
|
35137
35189
|
// src/lib/prove/scaffold.ts
|
|
35138
|
-
var
|
|
35139
|
-
var
|
|
35190
|
+
var import_node_fs57 = require("node:fs");
|
|
35191
|
+
var import_node_path42 = require("node:path");
|
|
35140
35192
|
|
|
35141
35193
|
// src/lib/prove/safe-write.ts
|
|
35142
|
-
var
|
|
35194
|
+
var import_node_fs56 = require("node:fs");
|
|
35143
35195
|
var import_node_crypto14 = require("node:crypto");
|
|
35144
|
-
var
|
|
35196
|
+
var import_node_path41 = require("node:path");
|
|
35145
35197
|
var SafeWriteError = class extends Error {
|
|
35146
35198
|
constructor(reason, path) {
|
|
35147
35199
|
super(`refusing to write ${path}: ${reason}`);
|
|
@@ -35150,10 +35202,10 @@ var SafeWriteError = class extends Error {
|
|
|
35150
35202
|
this.name = "SafeWriteError";
|
|
35151
35203
|
}
|
|
35152
35204
|
};
|
|
35153
|
-
var FLAGS3 =
|
|
35205
|
+
var FLAGS3 = import_node_fs56.constants;
|
|
35154
35206
|
var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
|
|
35155
35207
|
function assertPlainRelative(rel) {
|
|
35156
|
-
if (!rel || (0,
|
|
35208
|
+
if (!rel || (0, import_node_path41.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
|
|
35157
35209
|
for (const part of rel.split(/[\\/]/)) {
|
|
35158
35210
|
if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
|
|
35159
35211
|
}
|
|
@@ -35162,34 +35214,34 @@ function ensureDirsNoFollow(root, rel) {
|
|
|
35162
35214
|
const parts2 = rel.split(/[\\/]/);
|
|
35163
35215
|
let cur = root;
|
|
35164
35216
|
for (const part of parts2.slice(0, -1)) {
|
|
35165
|
-
cur = (0,
|
|
35217
|
+
cur = (0, import_node_path41.join)(cur, part);
|
|
35166
35218
|
let st;
|
|
35167
35219
|
try {
|
|
35168
|
-
st = (0,
|
|
35220
|
+
st = (0, import_node_fs56.lstatSync)(cur);
|
|
35169
35221
|
} catch {
|
|
35170
|
-
(0,
|
|
35222
|
+
(0, import_node_fs56.mkdirSync)(cur);
|
|
35171
35223
|
continue;
|
|
35172
35224
|
}
|
|
35173
35225
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
|
|
35174
35226
|
if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
|
|
35175
35227
|
}
|
|
35176
|
-
return (0,
|
|
35228
|
+
return (0, import_node_path41.join)(root, rel);
|
|
35177
35229
|
}
|
|
35178
35230
|
function insideRoot(realRoot, realPath) {
|
|
35179
|
-
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(
|
|
35231
|
+
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path41.sep) ? realRoot : realRoot + import_node_path41.sep);
|
|
35180
35232
|
}
|
|
35181
35233
|
function removeQuietly(path) {
|
|
35182
35234
|
try {
|
|
35183
|
-
(0,
|
|
35235
|
+
(0, import_node_fs56.unlinkSync)(path);
|
|
35184
35236
|
} catch {
|
|
35185
35237
|
}
|
|
35186
35238
|
}
|
|
35187
35239
|
function writeFileInRootNoFollow(root, rel, content) {
|
|
35188
35240
|
assertPlainRelative(rel);
|
|
35189
35241
|
const dest = ensureDirsNoFollow(root, rel);
|
|
35190
|
-
const dir = (0,
|
|
35242
|
+
const dir = (0, import_node_path41.dirname)(dest);
|
|
35191
35243
|
try {
|
|
35192
|
-
const st = (0,
|
|
35244
|
+
const st = (0, import_node_fs56.lstatSync)(dest);
|
|
35193
35245
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
|
|
35194
35246
|
if (!st.isFile()) throw new SafeWriteError("not-regular", dest);
|
|
35195
35247
|
} catch (err2) {
|
|
@@ -35197,41 +35249,41 @@ function writeFileInRootNoFollow(root, rel, content) {
|
|
|
35197
35249
|
}
|
|
35198
35250
|
let realRoot;
|
|
35199
35251
|
try {
|
|
35200
|
-
realRoot = (0,
|
|
35252
|
+
realRoot = (0, import_node_fs56.realpathSync)(root);
|
|
35201
35253
|
} catch {
|
|
35202
35254
|
throw new SafeWriteError("unwritable", root);
|
|
35203
35255
|
}
|
|
35204
|
-
const tmp = (0,
|
|
35256
|
+
const tmp = (0, import_node_path41.join)(dir, `.${(0, import_node_path41.basename)(dest)}.${(0, import_node_crypto14.randomBytes)(6).toString("hex")}.tmp`);
|
|
35205
35257
|
let fd;
|
|
35206
35258
|
try {
|
|
35207
|
-
fd = (0,
|
|
35259
|
+
fd = (0, import_node_fs56.openSync)(tmp, import_node_fs56.constants.O_WRONLY | import_node_fs56.constants.O_CREAT | import_node_fs56.constants.O_EXCL | NOFOLLOW2, 420);
|
|
35208
35260
|
} catch {
|
|
35209
35261
|
throw new SafeWriteError("unwritable", tmp);
|
|
35210
35262
|
}
|
|
35211
35263
|
try {
|
|
35212
|
-
const opened = (0,
|
|
35264
|
+
const opened = (0, import_node_fs56.fstatSync)(fd, { bigint: true });
|
|
35213
35265
|
let realTmp;
|
|
35214
35266
|
try {
|
|
35215
|
-
realTmp = (0,
|
|
35267
|
+
realTmp = (0, import_node_fs56.realpathSync)(tmp);
|
|
35216
35268
|
} catch {
|
|
35217
35269
|
throw new SafeWriteError("escaped", tmp);
|
|
35218
35270
|
}
|
|
35219
|
-
const there = (0,
|
|
35271
|
+
const there = (0, import_node_fs56.lstatSync)(realTmp, { bigint: true });
|
|
35220
35272
|
if (!opened.isFile() || there.ino !== opened.ino || there.dev !== opened.dev || !insideRoot(realRoot, realTmp)) {
|
|
35221
35273
|
throw new SafeWriteError("escaped", tmp);
|
|
35222
35274
|
}
|
|
35223
35275
|
const buf = Buffer.from(content, "utf-8");
|
|
35224
35276
|
let off = 0;
|
|
35225
|
-
while (off < buf.length) off += (0,
|
|
35277
|
+
while (off < buf.length) off += (0, import_node_fs56.writeSync)(fd, buf, off, buf.length - off);
|
|
35226
35278
|
} catch (err2) {
|
|
35227
|
-
(0,
|
|
35279
|
+
(0, import_node_fs56.closeSync)(fd);
|
|
35228
35280
|
removeQuietly(tmp);
|
|
35229
35281
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", tmp);
|
|
35230
35282
|
}
|
|
35231
|
-
(0,
|
|
35283
|
+
(0, import_node_fs56.closeSync)(fd);
|
|
35232
35284
|
try {
|
|
35233
|
-
if (!insideRoot(realRoot, (0,
|
|
35234
|
-
(0,
|
|
35285
|
+
if (!insideRoot(realRoot, (0, import_node_fs56.realpathSync)(dir)) || (0, import_node_fs56.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
|
|
35286
|
+
(0, import_node_fs56.renameSync)(tmp, dest);
|
|
35235
35287
|
} catch (err2) {
|
|
35236
35288
|
removeQuietly(tmp);
|
|
35237
35289
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", dest);
|
|
@@ -35245,9 +35297,9 @@ function pathHasNoLink(root, rel) {
|
|
|
35245
35297
|
}
|
|
35246
35298
|
let cur = root;
|
|
35247
35299
|
for (const part of rel.split(/[\\/]/)) {
|
|
35248
|
-
cur = cur +
|
|
35300
|
+
cur = cur + import_node_path41.sep + part;
|
|
35249
35301
|
try {
|
|
35250
|
-
if ((0,
|
|
35302
|
+
if ((0, import_node_fs56.lstatSync)(cur).isSymbolicLink()) return false;
|
|
35251
35303
|
} catch {
|
|
35252
35304
|
return true;
|
|
35253
35305
|
}
|
|
@@ -35557,20 +35609,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
|
|
|
35557
35609
|
never committed; what reaches the team is the bug report and the fix.
|
|
35558
35610
|
`;
|
|
35559
35611
|
function scaffoldProofs(root) {
|
|
35560
|
-
const proofsDir = (0,
|
|
35612
|
+
const proofsDir = (0, import_node_path42.join)(root, PROOFS_DIR);
|
|
35561
35613
|
const written = [];
|
|
35562
35614
|
const kept = [];
|
|
35563
35615
|
for (const stray of ["lakefile.lean"]) {
|
|
35564
35616
|
const rel = `${PROOFS_DIR}/${stray}`;
|
|
35565
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35617
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path42.join)(root, rel));
|
|
35566
35618
|
try {
|
|
35567
|
-
(0,
|
|
35619
|
+
(0, import_node_fs57.rmSync)((0, import_node_path42.join)(root, rel), { force: true });
|
|
35568
35620
|
} catch {
|
|
35569
35621
|
}
|
|
35570
35622
|
}
|
|
35571
35623
|
for (const f of PROOFS_TEMPLATE_FILES) {
|
|
35572
35624
|
const rel = `${PROOFS_DIR}/${f.path}`;
|
|
35573
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35625
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path42.join)(root, rel));
|
|
35574
35626
|
const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
|
|
35575
35627
|
if (current.ok && current.content === f.content) {
|
|
35576
35628
|
kept.push(rel);
|
|
@@ -35583,8 +35635,8 @@ function scaffoldProofs(root) {
|
|
|
35583
35635
|
[`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
|
|
35584
35636
|
[`${MODELS_DIR}/README.md`, MODELS_README]
|
|
35585
35637
|
]) {
|
|
35586
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
35587
|
-
if (existsNoFollow((0,
|
|
35638
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path42.join)(root, rel));
|
|
35639
|
+
if (existsNoFollow((0, import_node_path42.join)(root, rel))) {
|
|
35588
35640
|
kept.push(rel);
|
|
35589
35641
|
continue;
|
|
35590
35642
|
}
|
|
@@ -35595,7 +35647,7 @@ function scaffoldProofs(root) {
|
|
|
35595
35647
|
}
|
|
35596
35648
|
function existsNoFollow(abs) {
|
|
35597
35649
|
try {
|
|
35598
|
-
(0,
|
|
35650
|
+
(0, import_node_fs57.lstatSync)(abs);
|
|
35599
35651
|
return true;
|
|
35600
35652
|
} catch {
|
|
35601
35653
|
return false;
|
|
@@ -35853,16 +35905,16 @@ function renderReport(r) {
|
|
|
35853
35905
|
|
|
35854
35906
|
// src/lib/prove/runner.ts
|
|
35855
35907
|
function verityLeanHome(env = process.env) {
|
|
35856
|
-
return env.VERITY_LEAN_HOME ?? (0,
|
|
35908
|
+
return env.VERITY_LEAN_HOME ?? (0, import_node_path43.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
|
|
35857
35909
|
}
|
|
35858
35910
|
function findToolchain(env = process.env) {
|
|
35859
|
-
const managedBin = (0,
|
|
35860
|
-
const elanBin = (0,
|
|
35861
|
-
const path = [managedBin, elanBin, env.PATH ?? ""].filter(Boolean).join(
|
|
35911
|
+
const managedBin = (0, import_node_path43.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
|
|
35912
|
+
const elanBin = (0, import_node_path43.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
|
|
35913
|
+
const path = [managedBin, elanBin, env.PATH ?? ""].filter(Boolean).join(import_node_path43.delimiter);
|
|
35862
35914
|
const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
|
|
35863
|
-
const elanHas = (0,
|
|
35915
|
+
const elanHas = (0, import_node_fs58.existsSync)((0, import_node_path43.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
|
|
35864
35916
|
const exe = process.platform === "win32" ? "lake.exe" : "lake";
|
|
35865
|
-
const candidates2 = [(0,
|
|
35917
|
+
const candidates2 = [(0, import_node_path43.join)(managedBin, exe), ...elanHas ? [(0, import_node_path43.join)(elanBin, exe)] : [], exe];
|
|
35866
35918
|
for (const candidate of candidates2) {
|
|
35867
35919
|
try {
|
|
35868
35920
|
(0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
|
|
@@ -35938,41 +35990,41 @@ function runAsync(tc, cwd, args2, timeoutMs) {
|
|
|
35938
35990
|
var DEFAULT_BUILD_TIMEOUT_MS = 10 * 6e4;
|
|
35939
35991
|
var DEFAULT_CHECK_TIMEOUT_MS = 12e4;
|
|
35940
35992
|
function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
35941
|
-
return run2(tc, (0,
|
|
35993
|
+
return run2(tc, (0, import_node_path43.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
35942
35994
|
}
|
|
35943
35995
|
function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
35944
|
-
return runAsync(tc, (0,
|
|
35996
|
+
return runAsync(tc, (0, import_node_path43.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
35945
35997
|
}
|
|
35946
35998
|
function isModelInRoot(modelsAbs, rel) {
|
|
35947
|
-
if (!rel.endsWith(".lean") || (0,
|
|
35999
|
+
if (!rel.endsWith(".lean") || (0, import_node_path43.isAbsolute)(rel) || rel.startsWith("..")) return false;
|
|
35948
36000
|
return statRegularInRoot(modelsAbs, rel).ok;
|
|
35949
36001
|
}
|
|
35950
36002
|
function resolveModelFile(root, arg) {
|
|
35951
|
-
const modelsAbs = (0,
|
|
35952
|
-
const asPath = (0,
|
|
36003
|
+
const modelsAbs = (0, import_node_path43.join)(root, MODELS_DIR);
|
|
36004
|
+
const asPath = (0, import_node_path43.relative)(modelsAbs, (0, import_node_path43.isAbsolute)(arg) ? arg : (0, import_node_path43.resolve)(root, arg));
|
|
35953
36005
|
const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
|
|
35954
36006
|
for (const rel of candidates2) {
|
|
35955
|
-
if (isModelInRoot(modelsAbs, rel)) return (0,
|
|
36007
|
+
if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path43.join)(modelsAbs, rel);
|
|
35956
36008
|
}
|
|
35957
36009
|
return null;
|
|
35958
36010
|
}
|
|
35959
36011
|
function listModelFiles(root) {
|
|
35960
|
-
const modelsAbs = (0,
|
|
35961
|
-
if (!(0,
|
|
35962
|
-
return (0,
|
|
36012
|
+
const modelsAbs = (0, import_node_path43.join)(root, MODELS_DIR);
|
|
36013
|
+
if (!(0, import_node_fs58.existsSync)(modelsAbs)) return [];
|
|
36014
|
+
return (0, import_node_fs58.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path43.join)(modelsAbs, f));
|
|
35963
36015
|
}
|
|
35964
36016
|
function trimDiagnostics(text) {
|
|
35965
36017
|
return text.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
|
|
35966
36018
|
}
|
|
35967
36019
|
function checkModel(tc, root, modelFile, opts = {}) {
|
|
35968
|
-
const proofsAbs = (0,
|
|
35969
|
-
const rel = (0,
|
|
36020
|
+
const proofsAbs = (0, import_node_path43.join)(root, PROOFS_DIR);
|
|
36021
|
+
const rel = (0, import_node_path43.relative)(proofsAbs, modelFile);
|
|
35970
36022
|
const res = run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
35971
36023
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
35972
36024
|
}
|
|
35973
36025
|
async function checkModelAsync(tc, root, modelFile, opts = {}) {
|
|
35974
|
-
const proofsAbs = (0,
|
|
35975
|
-
const rel = (0,
|
|
36026
|
+
const proofsAbs = (0, import_node_path43.join)(root, PROOFS_DIR);
|
|
36027
|
+
const rel = (0, import_node_path43.relative)(proofsAbs, modelFile);
|
|
35976
36028
|
const res = await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
35977
36029
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
35978
36030
|
}
|
|
@@ -35980,10 +36032,10 @@ function toReport(res, root, modelFile, timeoutMs) {
|
|
|
35980
36032
|
const parsed = parseVerityLines(res.stdout);
|
|
35981
36033
|
const combined = `${res.stdout}
|
|
35982
36034
|
${res.stderr}`;
|
|
35983
|
-
const name2 = parsed.header?.model ?? (0,
|
|
36035
|
+
const name2 = parsed.header?.model ?? (0, import_node_path43.basename)(modelFile, ".lean");
|
|
35984
36036
|
const report = {
|
|
35985
36037
|
model: name2,
|
|
35986
|
-
file: (0,
|
|
36038
|
+
file: (0, import_node_path43.relative)(root, modelFile),
|
|
35987
36039
|
ok: res.ok,
|
|
35988
36040
|
header: parsed.header,
|
|
35989
36041
|
properties: parsed.properties,
|
|
@@ -36237,20 +36289,28 @@ function isEligible(s, largePush) {
|
|
|
36237
36289
|
function intersects(a, ranges) {
|
|
36238
36290
|
return ranges.some((b) => a.from <= b.to && b.from <= a.to);
|
|
36239
36291
|
}
|
|
36292
|
+
function isLocalState(root, rel) {
|
|
36293
|
+
return repoControlled(root, rel) === null;
|
|
36294
|
+
}
|
|
36295
|
+
function nonNegative(v) {
|
|
36296
|
+
return typeof v === "number" && Number.isFinite(v) && v > 0 ? v : 0;
|
|
36297
|
+
}
|
|
36240
36298
|
function readLedger(root) {
|
|
36241
36299
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
36242
36300
|
const empty = { day: today, models: 0, costUsd: 0 };
|
|
36301
|
+
if (!isLocalState(root, AUTO_LEDGER)) return empty;
|
|
36243
36302
|
const read2 = readRegularFileInRoot(root, AUTO_LEDGER, 4096);
|
|
36244
36303
|
if (!read2.ok) return empty;
|
|
36245
36304
|
try {
|
|
36246
36305
|
const o = JSON.parse(read2.content);
|
|
36247
36306
|
if (o.day !== today || typeof o.models !== "number") return empty;
|
|
36248
|
-
return { day: today, models: o.models, costUsd:
|
|
36307
|
+
return { day: today, models: nonNegative(o.models), costUsd: nonNegative(o.costUsd) };
|
|
36249
36308
|
} catch {
|
|
36250
36309
|
return empty;
|
|
36251
36310
|
}
|
|
36252
36311
|
}
|
|
36253
36312
|
function writeLedger(root, l) {
|
|
36313
|
+
if (!isLocalState(root, AUTO_LEDGER)) return;
|
|
36254
36314
|
try {
|
|
36255
36315
|
writeFileInRootNoFollow(root, AUTO_LEDGER, JSON.stringify(l) + "\n");
|
|
36256
36316
|
} catch {
|
|
@@ -36263,6 +36323,7 @@ function addLedgerCost(root, usd) {
|
|
|
36263
36323
|
}
|
|
36264
36324
|
var FINDINGS_FILE = `${PROOFS_DIR}/.results/.findings.json`;
|
|
36265
36325
|
function readPersistedFindings(root) {
|
|
36326
|
+
if (!isLocalState(root, FINDINGS_FILE)) return [];
|
|
36266
36327
|
const read2 = readRegularFileInRoot(root, FINDINGS_FILE, 256 * 1024);
|
|
36267
36328
|
if (!read2.ok) return [];
|
|
36268
36329
|
try {
|
|
@@ -36286,6 +36347,7 @@ function waiveFormalFindings(root, file, reason) {
|
|
|
36286
36347
|
return n;
|
|
36287
36348
|
}
|
|
36288
36349
|
function writePersistedFindings(root, findings) {
|
|
36350
|
+
if (!isLocalState(root, FINDINGS_FILE)) return;
|
|
36289
36351
|
try {
|
|
36290
36352
|
writeFileInRootNoFollow(root, FINDINGS_FILE, JSON.stringify({ findings: findings.slice(0, 50) }, null, 2) + "\n");
|
|
36291
36353
|
} catch {
|
|
@@ -36560,7 +36622,7 @@ async function runFormalPhase(input) {
|
|
|
36560
36622
|
modelName = gen.name;
|
|
36561
36623
|
const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
|
|
36562
36624
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
36563
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
36625
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path44.join)(root, rel);
|
|
36564
36626
|
progress.model = { name: gen.name, file: rel, rounds: round };
|
|
36565
36627
|
progress.step = "check";
|
|
36566
36628
|
report = await deps.check(root, abs);
|
|
@@ -36682,7 +36744,7 @@ async function runFormalPhase(input) {
|
|
|
36682
36744
|
return done({
|
|
36683
36745
|
status: "checked",
|
|
36684
36746
|
target,
|
|
36685
|
-
model: { name: modelName, file: (0,
|
|
36747
|
+
model: { name: modelName, file: (0, import_node_path44.relative)(root, (0, import_node_path44.join)(root, modelFile)), rounds },
|
|
36686
36748
|
properties: report.properties,
|
|
36687
36749
|
findings
|
|
36688
36750
|
});
|
|
@@ -36745,7 +36807,7 @@ async function generateAndCheck(root, req, opts) {
|
|
|
36745
36807
|
}
|
|
36746
36808
|
const rel = `${dir}/${gen.name}.lean`;
|
|
36747
36809
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
36748
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
36810
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path44.join)(root, rel);
|
|
36749
36811
|
const report = await opts.deps.check(root, abs);
|
|
36750
36812
|
const abstracts = report.header?.abstracts ?? [];
|
|
36751
36813
|
const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
|
|
@@ -36872,7 +36934,7 @@ var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
|
|
|
36872
36934
|
var WRITERS_BUDGET_MS = 1500;
|
|
36873
36935
|
var EXCERPT_MAX_LINES2 = 30;
|
|
36874
36936
|
var GUARD_BLOCK_CAP = 2;
|
|
36875
|
-
var GUARD_ITER_FILE = (0,
|
|
36937
|
+
var GUARD_ITER_FILE = (0, import_node_path45.join)(VERITY_DIR, ".guard-iteration");
|
|
36876
36938
|
function readPreToolUseStdin() {
|
|
36877
36939
|
const empty = { command: "", cwd: null, sessionId: null };
|
|
36878
36940
|
return new Promise((resolve8) => {
|
|
@@ -36917,7 +36979,7 @@ function readPreToolUseStdin() {
|
|
|
36917
36979
|
}
|
|
36918
36980
|
function readIterMap() {
|
|
36919
36981
|
try {
|
|
36920
|
-
const raw = JSON.parse((0,
|
|
36982
|
+
const raw = JSON.parse((0, import_node_fs59.readFileSync)(GUARD_ITER_FILE, "utf-8"));
|
|
36921
36983
|
if (raw && typeof raw === "object") {
|
|
36922
36984
|
if (typeof raw.moment === "string" && typeof raw.count === "number") {
|
|
36923
36985
|
return { [raw.moment]: raw.count };
|
|
@@ -36937,10 +36999,10 @@ function readIter(moment) {
|
|
|
36937
36999
|
}
|
|
36938
37000
|
function writeIter(moment, count) {
|
|
36939
37001
|
try {
|
|
36940
|
-
(0,
|
|
37002
|
+
(0, import_node_fs59.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
36941
37003
|
const map = readIterMap();
|
|
36942
37004
|
map[moment] = count;
|
|
36943
|
-
(0,
|
|
37005
|
+
(0, import_node_fs59.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
36944
37006
|
} catch {
|
|
36945
37007
|
}
|
|
36946
37008
|
}
|
|
@@ -36950,10 +37012,10 @@ function resetIter(moment) {
|
|
|
36950
37012
|
if (!(moment in map)) return;
|
|
36951
37013
|
delete map[moment];
|
|
36952
37014
|
if (Object.keys(map).length === 0) {
|
|
36953
|
-
if ((0,
|
|
37015
|
+
if ((0, import_node_fs59.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs59.unlinkSync)(GUARD_ITER_FILE);
|
|
36954
37016
|
} else {
|
|
36955
|
-
(0,
|
|
36956
|
-
(0,
|
|
37017
|
+
(0, import_node_fs59.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
37018
|
+
(0, import_node_fs59.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
36957
37019
|
}
|
|
36958
37020
|
} catch {
|
|
36959
37021
|
}
|
|
@@ -37023,7 +37085,7 @@ function hasBlockingFinding(response, sentFiles) {
|
|
|
37023
37085
|
function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
|
|
37024
37086
|
const analyzable = filterAnalyzable(files);
|
|
37025
37087
|
const securityFiles = filterSecurity(files);
|
|
37026
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0,
|
|
37088
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs59.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
|
|
37027
37089
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
37028
37090
|
const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
|
|
37029
37091
|
const requestBody = {
|
|
@@ -37643,7 +37705,7 @@ function registerIgnoreCommand(program2) {
|
|
|
37643
37705
|
|
|
37644
37706
|
// src/commands/waive.ts
|
|
37645
37707
|
var import_node_crypto19 = require("node:crypto");
|
|
37646
|
-
var
|
|
37708
|
+
var import_node_fs60 = require("node:fs");
|
|
37647
37709
|
function registerWaiveCommand(program2) {
|
|
37648
37710
|
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) => {
|
|
37649
37711
|
const globals = program2.opts();
|
|
@@ -37672,7 +37734,7 @@ function registerWaiveCommand(program2) {
|
|
|
37672
37734
|
if (opts.file) {
|
|
37673
37735
|
body2.file = opts.file;
|
|
37674
37736
|
try {
|
|
37675
|
-
body2.file_sha256 = (0, import_node_crypto19.createHash)("sha256").update((0,
|
|
37737
|
+
body2.file_sha256 = (0, import_node_crypto19.createHash)("sha256").update((0, import_node_fs60.readFileSync)(opts.file)).digest("hex");
|
|
37676
37738
|
} catch {
|
|
37677
37739
|
printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
|
|
37678
37740
|
process.exit(1);
|
|
@@ -37697,10 +37759,10 @@ function registerWaiveCommand(program2) {
|
|
|
37697
37759
|
}
|
|
37698
37760
|
|
|
37699
37761
|
// src/commands/init.ts
|
|
37700
|
-
var
|
|
37762
|
+
var import_node_fs65 = require("node:fs");
|
|
37701
37763
|
var import_promises20 = require("node:fs/promises");
|
|
37702
37764
|
var import_yaml6 = __toESM2(require_dist());
|
|
37703
|
-
var
|
|
37765
|
+
var import_node_path49 = require("node:path");
|
|
37704
37766
|
var import_node_child_process19 = require("node:child_process");
|
|
37705
37767
|
|
|
37706
37768
|
// src/lib/banner.ts
|
|
@@ -37779,7 +37841,7 @@ function printPhase(n, of, title, subtitle) {
|
|
|
37779
37841
|
}
|
|
37780
37842
|
|
|
37781
37843
|
// src/commands/doctor.ts
|
|
37782
|
-
var
|
|
37844
|
+
var import_node_fs61 = require("node:fs");
|
|
37783
37845
|
|
|
37784
37846
|
// src/lib/prereqs.ts
|
|
37785
37847
|
var import_node_child_process16 = require("node:child_process");
|
|
@@ -37987,11 +38049,11 @@ async function buildReport() {
|
|
|
37987
38049
|
const hooks = wiring.status;
|
|
37988
38050
|
const provenance = cliProvenance();
|
|
37989
38051
|
const telemetry = await checkTelemetry();
|
|
37990
|
-
const hasConfig = (0,
|
|
38052
|
+
const hasConfig = (0, import_node_fs61.existsSync)(projectPath(CODACY_CONFIG_FILE));
|
|
37991
38053
|
const artifacts = {
|
|
37992
|
-
standard: (0,
|
|
38054
|
+
standard: (0, import_node_fs61.existsSync)(projectPath(STANDARD_FILE)),
|
|
37993
38055
|
analysisConfig: hasConfig,
|
|
37994
|
-
verityMd: (0,
|
|
38056
|
+
verityMd: (0, import_node_fs61.existsSync)(projectPath(VERITY_MD_FILE)),
|
|
37995
38057
|
analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
|
|
37996
38058
|
};
|
|
37997
38059
|
const next = [];
|
|
@@ -38121,9 +38183,11 @@ function registerDoctorCommand(program2) {
|
|
|
38121
38183
|
printInfo(` Stop (verity analyze): ${report.hooks.stop ? plugin ? "on (plugin)" : "on" : "off"}`);
|
|
38122
38184
|
printInfo(` Git-moment gate: ${report.hooks.guardOn.length ? report.hooks.guardOn.join(", ") : "off"}`);
|
|
38123
38185
|
{
|
|
38124
|
-
const
|
|
38186
|
+
const cfg = readProjectConfig();
|
|
38187
|
+
const formal = cfg.formal === "push";
|
|
38125
38188
|
const tc = formal ? findToolchain() : null;
|
|
38126
38189
|
printInfo(` Formal verification (push): ${formal ? `on, Lean ${tc ? "\u2713" : "MISSING \u2014 verity lean install"} (ranking, model writing and replay run on the Verity service with your login)` : "off"}`);
|
|
38190
|
+
if (cfg.formal_refused) printWarn(` ${formalRefusalMessage(cfg.formal_refused)}`);
|
|
38127
38191
|
}
|
|
38128
38192
|
printInfo(` Infra (intent/baseline/compact/session-end): ${[report.hooks.intent, report.hooks.baseline, report.hooks.compact, report.hooks.sessionEnd].filter(Boolean).length}/4`);
|
|
38129
38193
|
printInfo(`Telemetry: ${report.telemetry.enabled ? `enabled \u2192 ${report.telemetry.endpoint}` : "disabled"}`);
|
|
@@ -38148,8 +38212,8 @@ function registerDoctorCommand(program2) {
|
|
|
38148
38212
|
}
|
|
38149
38213
|
|
|
38150
38214
|
// src/commands/migrate.ts
|
|
38151
|
-
var
|
|
38152
|
-
var
|
|
38215
|
+
var import_node_fs62 = require("node:fs");
|
|
38216
|
+
var import_node_path46 = require("node:path");
|
|
38153
38217
|
var import_node_child_process17 = require("node:child_process");
|
|
38154
38218
|
var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
|
|
38155
38219
|
function defaultNpmRemover(pkg) {
|
|
@@ -38186,12 +38250,12 @@ async function runMigration(opts = {}) {
|
|
|
38186
38250
|
return { actions, migrated: actions.length > 0 };
|
|
38187
38251
|
}
|
|
38188
38252
|
function migrateProjectDir(root, actions) {
|
|
38189
|
-
const gateDir = (0,
|
|
38190
|
-
const verityDir = (0,
|
|
38191
|
-
if ((0,
|
|
38253
|
+
const gateDir = (0, import_node_path46.join)(root, ".gate");
|
|
38254
|
+
const verityDir = (0, import_node_path46.join)(root, ".verity");
|
|
38255
|
+
if ((0, import_node_fs62.existsSync)(gateDir) && !(0, import_node_fs62.existsSync)(verityDir)) {
|
|
38192
38256
|
return migrateProjectDirRename(root, gateDir, verityDir, actions);
|
|
38193
38257
|
}
|
|
38194
|
-
if ((0,
|
|
38258
|
+
if ((0, import_node_fs62.existsSync)(gateDir) && (0, import_node_fs62.existsSync)(verityDir)) {
|
|
38195
38259
|
return migrateProjectDirCarry(gateDir, verityDir, actions);
|
|
38196
38260
|
}
|
|
38197
38261
|
return false;
|
|
@@ -38212,13 +38276,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
|
|
|
38212
38276
|
}
|
|
38213
38277
|
}
|
|
38214
38278
|
if (moved) {
|
|
38215
|
-
if ((0,
|
|
38279
|
+
if ((0, import_node_fs62.existsSync)(gateDir)) {
|
|
38216
38280
|
const carried = carryLegacyContents(gateDir, verityDir);
|
|
38217
38281
|
if (carried > 0) {
|
|
38218
38282
|
actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
|
|
38219
38283
|
}
|
|
38220
38284
|
try {
|
|
38221
|
-
(0,
|
|
38285
|
+
(0, import_node_fs62.rmSync)(gateDir, { recursive: true, force: true });
|
|
38222
38286
|
} catch {
|
|
38223
38287
|
}
|
|
38224
38288
|
}
|
|
@@ -38234,18 +38298,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
|
|
|
38234
38298
|
actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
|
|
38235
38299
|
}
|
|
38236
38300
|
try {
|
|
38237
|
-
(0,
|
|
38301
|
+
(0, import_node_fs62.rmSync)(gateDir, { recursive: true, force: true });
|
|
38238
38302
|
} catch {
|
|
38239
38303
|
}
|
|
38240
38304
|
return carried > 0;
|
|
38241
38305
|
}
|
|
38242
38306
|
function migrateGlobalCredentials(home, actions) {
|
|
38243
38307
|
if (!home) return;
|
|
38244
|
-
const gateCreds = (0,
|
|
38245
|
-
const verityCreds = (0,
|
|
38246
|
-
if (!(0,
|
|
38247
|
-
if (!(0,
|
|
38248
|
-
(0,
|
|
38308
|
+
const gateCreds = (0, import_node_path46.join)(home, ".gate", "credentials");
|
|
38309
|
+
const verityCreds = (0, import_node_path46.join)(home, ".verity", "credentials");
|
|
38310
|
+
if (!(0, import_node_fs62.existsSync)(gateCreds)) return;
|
|
38311
|
+
if (!(0, import_node_fs62.existsSync)(verityCreds)) {
|
|
38312
|
+
(0, import_node_fs62.mkdirSync)((0, import_node_path46.join)(home, ".verity"), { recursive: true });
|
|
38249
38313
|
moveFile(gateCreds, verityCreds);
|
|
38250
38314
|
actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
|
|
38251
38315
|
return;
|
|
@@ -38267,8 +38331,8 @@ async function migrateLegacyHooks(root, actions) {
|
|
|
38267
38331
|
}
|
|
38268
38332
|
}
|
|
38269
38333
|
async function migrateClaudeMd(root, actions) {
|
|
38270
|
-
const claudeMd = (0,
|
|
38271
|
-
const hadLegacyBlock = (0,
|
|
38334
|
+
const claudeMd = (0, import_node_path46.join)(root, "CLAUDE.md");
|
|
38335
|
+
const hadLegacyBlock = (0, import_node_fs62.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
|
|
38272
38336
|
if (!hadLegacyBlock) return;
|
|
38273
38337
|
try {
|
|
38274
38338
|
await ensureClaudeMdPointer(root);
|
|
@@ -38278,9 +38342,9 @@ async function migrateClaudeMd(root, actions) {
|
|
|
38278
38342
|
}
|
|
38279
38343
|
}
|
|
38280
38344
|
function migrateStandardFile(root, actions) {
|
|
38281
|
-
const gateMd = (0,
|
|
38282
|
-
const verityMd = (0,
|
|
38283
|
-
if (!(0,
|
|
38345
|
+
const gateMd = (0, import_node_path46.join)(root, "GATE.md");
|
|
38346
|
+
const verityMd = (0, import_node_path46.join)(root, "VERITY.md");
|
|
38347
|
+
if (!(0, import_node_fs62.existsSync)(gateMd) || (0, import_node_fs62.existsSync)(verityMd)) return;
|
|
38284
38348
|
let moved = false;
|
|
38285
38349
|
if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
|
|
38286
38350
|
try {
|
|
@@ -38292,12 +38356,12 @@ function migrateStandardFile(root, actions) {
|
|
|
38292
38356
|
if (!moved) moveFile(gateMd, verityMd);
|
|
38293
38357
|
const content = readFileSyncSafe(verityMd);
|
|
38294
38358
|
const refreshed = content.split("GATE.md").join("VERITY.md");
|
|
38295
|
-
if (refreshed !== content) (0,
|
|
38359
|
+
if (refreshed !== content) (0, import_node_fs62.writeFileSync)(verityMd, refreshed);
|
|
38296
38360
|
actions.push("Renamed GATE.md \u2192 VERITY.md");
|
|
38297
38361
|
}
|
|
38298
38362
|
async function migrateTelemetryHeaders(root, actions) {
|
|
38299
|
-
const file = (0,
|
|
38300
|
-
if (!(0,
|
|
38363
|
+
const file = (0, import_node_path46.join)(root, ".claude", "settings.local.json");
|
|
38364
|
+
if (!(0, import_node_fs62.existsSync)(file)) return;
|
|
38301
38365
|
let settings;
|
|
38302
38366
|
try {
|
|
38303
38367
|
settings = JSON.parse(readFileSyncSafe(file) || "{}");
|
|
@@ -38345,14 +38409,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
|
|
|
38345
38409
|
}
|
|
38346
38410
|
if (toAppend.length > 0) {
|
|
38347
38411
|
const sep5 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
|
|
38348
|
-
(0,
|
|
38412
|
+
(0, import_node_fs62.writeFileSync)(verityCreds, verityContent + sep5 + toAppend.join("\n") + "\n");
|
|
38349
38413
|
}
|
|
38350
|
-
(0,
|
|
38414
|
+
(0, import_node_fs62.rmSync)(gateCreds, { force: true });
|
|
38351
38415
|
return toAppend.length;
|
|
38352
38416
|
}
|
|
38353
38417
|
function readFileSyncSafe(path) {
|
|
38354
38418
|
try {
|
|
38355
|
-
return (0,
|
|
38419
|
+
return (0, import_node_fs62.readFileSync)(path, "utf-8");
|
|
38356
38420
|
} catch {
|
|
38357
38421
|
return "";
|
|
38358
38422
|
}
|
|
@@ -38367,35 +38431,35 @@ function hasStagedChanges(root) {
|
|
|
38367
38431
|
}
|
|
38368
38432
|
function moveDir(from, to) {
|
|
38369
38433
|
try {
|
|
38370
|
-
(0,
|
|
38434
|
+
(0, import_node_fs62.renameSync)(from, to);
|
|
38371
38435
|
} catch (err2) {
|
|
38372
38436
|
if (err2.code !== "EXDEV") throw err2;
|
|
38373
|
-
(0,
|
|
38374
|
-
(0,
|
|
38437
|
+
(0, import_node_fs62.cpSync)(from, to, { recursive: true });
|
|
38438
|
+
(0, import_node_fs62.rmSync)(from, { recursive: true, force: true });
|
|
38375
38439
|
}
|
|
38376
38440
|
}
|
|
38377
38441
|
function moveFile(from, to) {
|
|
38378
38442
|
try {
|
|
38379
|
-
(0,
|
|
38443
|
+
(0, import_node_fs62.renameSync)(from, to);
|
|
38380
38444
|
} catch (err2) {
|
|
38381
38445
|
if (err2.code !== "EXDEV") throw err2;
|
|
38382
|
-
(0,
|
|
38383
|
-
(0,
|
|
38446
|
+
(0, import_node_fs62.cpSync)(from, to);
|
|
38447
|
+
(0, import_node_fs62.rmSync)(from, { force: true });
|
|
38384
38448
|
}
|
|
38385
38449
|
}
|
|
38386
38450
|
function carryLegacyContents(gateDir, verityDir) {
|
|
38387
38451
|
let copied = 0;
|
|
38388
38452
|
const walk2 = (relDir) => {
|
|
38389
|
-
const srcDir = (0,
|
|
38390
|
-
for (const entry of (0,
|
|
38391
|
-
const rel = relDir ? (0,
|
|
38392
|
-
const src = (0,
|
|
38393
|
-
const dest = (0,
|
|
38394
|
-
if ((0,
|
|
38453
|
+
const srcDir = (0, import_node_path46.join)(gateDir, relDir);
|
|
38454
|
+
for (const entry of (0, import_node_fs62.readdirSync)(srcDir)) {
|
|
38455
|
+
const rel = relDir ? (0, import_node_path46.join)(relDir, entry) : entry;
|
|
38456
|
+
const src = (0, import_node_path46.join)(gateDir, rel);
|
|
38457
|
+
const dest = (0, import_node_path46.join)(verityDir, rel);
|
|
38458
|
+
if ((0, import_node_fs62.statSync)(src).isDirectory()) {
|
|
38395
38459
|
walk2(rel);
|
|
38396
|
-
} else if (!(0,
|
|
38397
|
-
(0,
|
|
38398
|
-
(0,
|
|
38460
|
+
} else if (!(0, import_node_fs62.existsSync)(dest)) {
|
|
38461
|
+
(0, import_node_fs62.mkdirSync)((0, import_node_path46.dirname)(dest), { recursive: true });
|
|
38462
|
+
(0, import_node_fs62.cpSync)(src, dest);
|
|
38399
38463
|
copied++;
|
|
38400
38464
|
}
|
|
38401
38465
|
}
|
|
@@ -38404,22 +38468,22 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
38404
38468
|
return copied;
|
|
38405
38469
|
}
|
|
38406
38470
|
async function needsMigration(root = repoRoot()) {
|
|
38407
|
-
const gateDir = (0,
|
|
38408
|
-
const verityDir = (0,
|
|
38409
|
-
if ((0,
|
|
38410
|
-
if ((0,
|
|
38411
|
-
if ((0,
|
|
38471
|
+
const gateDir = (0, import_node_path46.join)(root, ".gate");
|
|
38472
|
+
const verityDir = (0, import_node_path46.join)(root, ".verity");
|
|
38473
|
+
if ((0, import_node_fs62.existsSync)(gateDir) && !(0, import_node_fs62.existsSync)(verityDir)) return true;
|
|
38474
|
+
if ((0, import_node_fs62.existsSync)(gateDir) && (0, import_node_fs62.existsSync)(verityDir)) {
|
|
38475
|
+
if ((0, import_node_fs62.existsSync)((0, import_node_path46.join)(gateDir, "credentials")) && !(0, import_node_fs62.existsSync)((0, import_node_path46.join)(verityDir, "credentials"))) {
|
|
38412
38476
|
return true;
|
|
38413
38477
|
}
|
|
38414
|
-
if ((0,
|
|
38478
|
+
if ((0, import_node_fs62.existsSync)((0, import_node_path46.join)(gateDir, "memory")) && !(0, import_node_fs62.existsSync)((0, import_node_path46.join)(verityDir, "memory"))) {
|
|
38415
38479
|
return true;
|
|
38416
38480
|
}
|
|
38417
38481
|
}
|
|
38418
|
-
const claudeMd = (0,
|
|
38419
|
-
if ((0,
|
|
38482
|
+
const claudeMd = (0, import_node_path46.join)(root, "CLAUDE.md");
|
|
38483
|
+
if ((0, import_node_fs62.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
|
|
38420
38484
|
return true;
|
|
38421
38485
|
}
|
|
38422
|
-
if ((0,
|
|
38486
|
+
if ((0, import_node_fs62.existsSync)((0, import_node_path46.join)(root, "GATE.md")) && !(0, import_node_fs62.existsSync)((0, import_node_path46.join)(root, "VERITY.md"))) {
|
|
38423
38487
|
return true;
|
|
38424
38488
|
}
|
|
38425
38489
|
if (await hasLegacyHooksAt(root)) return true;
|
|
@@ -38700,11 +38764,11 @@ async function promptMultiSelect(question, choices, fallback) {
|
|
|
38700
38764
|
}
|
|
38701
38765
|
|
|
38702
38766
|
// src/lib/prove/lean-install.ts
|
|
38703
|
-
var
|
|
38767
|
+
var import_node_fs63 = require("node:fs");
|
|
38704
38768
|
var import_node_crypto20 = require("node:crypto");
|
|
38705
38769
|
var import_node_child_process18 = require("node:child_process");
|
|
38706
38770
|
var import_node_os10 = require("node:os");
|
|
38707
|
-
var
|
|
38771
|
+
var import_node_path47 = require("node:path");
|
|
38708
38772
|
var import_promises18 = require("node:stream/promises");
|
|
38709
38773
|
var import_node_stream = require("node:stream");
|
|
38710
38774
|
var RELEASES = "https://releases.lean-lang.org/lean4";
|
|
@@ -38724,7 +38788,7 @@ function expectedSha256(asset, version = pinnedVersion()) {
|
|
|
38724
38788
|
function sha256File(path) {
|
|
38725
38789
|
return new Promise((resolve8, reject) => {
|
|
38726
38790
|
const hash = (0, import_node_crypto20.createHash)("sha256");
|
|
38727
|
-
(0,
|
|
38791
|
+
(0, import_node_fs63.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve8(hash.digest("hex"))).on("error", reject);
|
|
38728
38792
|
});
|
|
38729
38793
|
}
|
|
38730
38794
|
async function verifyDownload(zip, asset, version = pinnedVersion()) {
|
|
@@ -38744,7 +38808,7 @@ function leanAssetName(version = pinnedVersion()) {
|
|
|
38744
38808
|
return suffix ? `lean-${v}-${suffix}.zip` : null;
|
|
38745
38809
|
}
|
|
38746
38810
|
function pinnedVersionDir(env = process.env) {
|
|
38747
|
-
return (0,
|
|
38811
|
+
return (0, import_node_path47.join)(verityLeanHome(env), pinnedVersion());
|
|
38748
38812
|
}
|
|
38749
38813
|
function lakeBinary() {
|
|
38750
38814
|
return (0, import_node_os10.platform)() === "win32" ? "lake.exe" : "lake";
|
|
@@ -38755,12 +38819,12 @@ function unzip(zip, dest) {
|
|
|
38755
38819
|
for (const [cmd, args2] of attempts) {
|
|
38756
38820
|
try {
|
|
38757
38821
|
(0, import_node_child_process18.execFileSync)(cmd, args2, { stdio: ["ignore", "ignore", "pipe"], timeout: 15 * 6e4 });
|
|
38758
|
-
if ((0,
|
|
38822
|
+
if ((0, import_node_fs63.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
|
|
38759
38823
|
errors.push(`${cmd}: produced nothing`);
|
|
38760
38824
|
} catch (err2) {
|
|
38761
38825
|
errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
|
|
38762
38826
|
try {
|
|
38763
|
-
for (const e of (0,
|
|
38827
|
+
for (const e of (0, import_node_fs63.readdirSync)(dest)) (0, import_node_fs63.rmSync)((0, import_node_path47.join)(dest, e), { recursive: true, force: true });
|
|
38764
38828
|
} catch {
|
|
38765
38829
|
}
|
|
38766
38830
|
}
|
|
@@ -38777,7 +38841,7 @@ async function download(url, dest, onProgress) {
|
|
|
38777
38841
|
seen += chunk.length;
|
|
38778
38842
|
onProgress(seen, total);
|
|
38779
38843
|
});
|
|
38780
|
-
await (0, import_promises18.pipeline)(stream, (0,
|
|
38844
|
+
await (0, import_promises18.pipeline)(stream, (0, import_node_fs63.createWriteStream)(dest));
|
|
38781
38845
|
}
|
|
38782
38846
|
function inPlaceProgress(label2, write = (s) => process.stderr.write(s)) {
|
|
38783
38847
|
let active = false;
|
|
@@ -38815,10 +38879,10 @@ async function installLean(opts = {}) {
|
|
|
38815
38879
|
const dir = pinnedVersionDir(env);
|
|
38816
38880
|
const url = `${RELEASES}/${pinnedVersion()}/${asset}`;
|
|
38817
38881
|
const home = verityLeanHome(env);
|
|
38818
|
-
const tmp = (0,
|
|
38819
|
-
(0,
|
|
38820
|
-
(0,
|
|
38821
|
-
const zip = (0,
|
|
38882
|
+
const tmp = (0, import_node_path47.join)(home, ".tmp");
|
|
38883
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
38884
|
+
(0, import_node_fs63.mkdirSync)(tmp, { recursive: true });
|
|
38885
|
+
const zip = (0, import_node_path47.join)(tmp, asset);
|
|
38822
38886
|
say(`downloading ${url}`);
|
|
38823
38887
|
let lastPct = -1;
|
|
38824
38888
|
try {
|
|
@@ -38831,40 +38895,40 @@ async function installLean(opts = {}) {
|
|
|
38831
38895
|
}
|
|
38832
38896
|
});
|
|
38833
38897
|
} catch (err2) {
|
|
38834
|
-
(0,
|
|
38898
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
38835
38899
|
return { ok: false, error: err2.message };
|
|
38836
38900
|
}
|
|
38837
38901
|
say("verifying checksum");
|
|
38838
38902
|
const verified = await verifyDownload(zip, asset);
|
|
38839
38903
|
if (!verified.ok) {
|
|
38840
|
-
(0,
|
|
38904
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
38841
38905
|
return { ok: false, error: verified.error };
|
|
38842
38906
|
}
|
|
38843
38907
|
say("unpacking (this takes a minute)");
|
|
38844
|
-
const unpack = (0,
|
|
38845
|
-
(0,
|
|
38908
|
+
const unpack = (0, import_node_path47.join)(tmp, "unpack");
|
|
38909
|
+
(0, import_node_fs63.mkdirSync)(unpack);
|
|
38846
38910
|
const unpacked = unzip(zip, unpack);
|
|
38847
38911
|
if (!unpacked.ok) {
|
|
38848
|
-
(0,
|
|
38912
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
38849
38913
|
return { ok: false, error: `unpack failed: ${unpacked.error}` };
|
|
38850
38914
|
}
|
|
38851
|
-
const entries = (0,
|
|
38852
|
-
const top = entries.length === 1 && (0,
|
|
38853
|
-
if (!(0,
|
|
38854
|
-
(0,
|
|
38915
|
+
const entries = (0, import_node_fs63.readdirSync)(unpack);
|
|
38916
|
+
const top = entries.length === 1 && (0, import_node_fs63.statSync)((0, import_node_path47.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path47.join)(unpack, entries[0]) : unpack;
|
|
38917
|
+
if (!(0, import_node_fs63.existsSync)((0, import_node_path47.join)(top, "bin", lakeBinary()))) {
|
|
38918
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
38855
38919
|
return { ok: false, error: "the archive did not contain bin/lake" };
|
|
38856
38920
|
}
|
|
38857
|
-
(0,
|
|
38858
|
-
(0,
|
|
38859
|
-
(0,
|
|
38860
|
-
(0,
|
|
38921
|
+
(0, import_node_fs63.rmSync)(dir, { recursive: true, force: true });
|
|
38922
|
+
(0, import_node_fs63.mkdirSync)(home, { recursive: true });
|
|
38923
|
+
(0, import_node_fs63.renameSync)(top, dir);
|
|
38924
|
+
(0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
|
|
38861
38925
|
return { ok: true, dir };
|
|
38862
38926
|
}
|
|
38863
38927
|
|
|
38864
38928
|
// src/lib/remote-config.ts
|
|
38865
|
-
var
|
|
38929
|
+
var import_node_fs64 = require("node:fs");
|
|
38866
38930
|
var import_promises19 = require("node:fs/promises");
|
|
38867
|
-
var
|
|
38931
|
+
var import_node_path48 = require("node:path");
|
|
38868
38932
|
var import_yaml5 = __toESM2(require_dist());
|
|
38869
38933
|
var IGNORE_RIDER = "verityignore";
|
|
38870
38934
|
async function fetchRemoteSetup(opts) {
|
|
@@ -38909,7 +38973,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
38909
38973
|
written.push(STANDARD_FILE);
|
|
38910
38974
|
if (rider !== null) {
|
|
38911
38975
|
const localIgnore = projectPath(VERITYIGNORE_FILE);
|
|
38912
|
-
if (!(0,
|
|
38976
|
+
if (!(0, import_node_fs64.existsSync)(localIgnore)) {
|
|
38913
38977
|
await writeOut(VERITYIGNORE_FILE, rider);
|
|
38914
38978
|
written.push(VERITYIGNORE_FILE);
|
|
38915
38979
|
} else {
|
|
@@ -38942,7 +39006,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
38942
39006
|
}
|
|
38943
39007
|
async function writeOut(relative6, body2) {
|
|
38944
39008
|
const target = projectPath(relative6);
|
|
38945
|
-
await (0, import_promises19.mkdir)((0,
|
|
39009
|
+
await (0, import_promises19.mkdir)((0, import_node_path48.dirname)(target), { recursive: true });
|
|
38946
39010
|
await (0, import_promises19.writeFile)(target, body2);
|
|
38947
39011
|
}
|
|
38948
39012
|
function describeRemote(found) {
|
|
@@ -39059,15 +39123,15 @@ async function runOptionalAuth(resolution, opts = {}) {
|
|
|
39059
39123
|
}
|
|
39060
39124
|
function resolveDataDir2() {
|
|
39061
39125
|
const candidates2 = [
|
|
39062
|
-
(0,
|
|
39126
|
+
(0, import_node_path49.join)(__dirname, "..", "data"),
|
|
39063
39127
|
// installed: node_modules/@codacy/verity-cli/data
|
|
39064
|
-
(0,
|
|
39128
|
+
(0, import_node_path49.join)(__dirname, "..", "..", "data"),
|
|
39065
39129
|
// edge case: nested resolution
|
|
39066
|
-
(0,
|
|
39130
|
+
(0, import_node_path49.join)(process.cwd(), "cli", "data")
|
|
39067
39131
|
// local dev: running from repo root
|
|
39068
39132
|
];
|
|
39069
39133
|
for (const candidate of candidates2) {
|
|
39070
|
-
if ((0,
|
|
39134
|
+
if ((0, import_node_fs65.existsSync)((0, import_node_path49.join)(candidate, "skills"))) {
|
|
39071
39135
|
return candidate;
|
|
39072
39136
|
}
|
|
39073
39137
|
}
|
|
@@ -39083,9 +39147,9 @@ async function skillIsCurrent(src, dest) {
|
|
|
39083
39147
|
const list2 = (dir) => {
|
|
39084
39148
|
const out2 = [];
|
|
39085
39149
|
const walk2 = (d, prefix) => {
|
|
39086
|
-
for (const e of (0,
|
|
39150
|
+
for (const e of (0, import_node_fs65.readdirSync)(d, { withFileTypes: true })) {
|
|
39087
39151
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
39088
|
-
if (e.isDirectory()) walk2((0,
|
|
39152
|
+
if (e.isDirectory()) walk2((0, import_node_path49.join)(d, e.name), rel);
|
|
39089
39153
|
else if (e.isFile()) out2.push(rel);
|
|
39090
39154
|
}
|
|
39091
39155
|
};
|
|
@@ -39096,8 +39160,8 @@ async function skillIsCurrent(src, dest) {
|
|
|
39096
39160
|
const shipped = list2(src);
|
|
39097
39161
|
if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
|
|
39098
39162
|
for (const rel of shipped) {
|
|
39099
|
-
const a = await (0, import_promises20.readFile)((0,
|
|
39100
|
-
const b = await (0, import_promises20.readFile)((0,
|
|
39163
|
+
const a = await (0, import_promises20.readFile)((0, import_node_path49.join)(src, rel), "utf-8");
|
|
39164
|
+
const b = await (0, import_promises20.readFile)((0, import_node_path49.join)(dest, rel), "utf-8");
|
|
39101
39165
|
if (a !== b) return false;
|
|
39102
39166
|
}
|
|
39103
39167
|
return true;
|
|
@@ -39298,7 +39362,7 @@ async function synthesizeLocally(opts) {
|
|
|
39298
39362
|
async function healStaleAnalysisConfig(globals) {
|
|
39299
39363
|
const configPath = projectPath(CODACY_CONFIG_FILE);
|
|
39300
39364
|
const standardPath = projectPath(STANDARD_FILE);
|
|
39301
|
-
if (!(0,
|
|
39365
|
+
if (!(0, import_node_fs65.existsSync)(configPath) || !(0, import_node_fs65.existsSync)(standardPath)) return;
|
|
39302
39366
|
const validation = validatePatternIds();
|
|
39303
39367
|
if (validation.status !== "invalid") return;
|
|
39304
39368
|
printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
|
|
@@ -39395,17 +39459,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
|
|
|
39395
39459
|
async function installSkills(force, step) {
|
|
39396
39460
|
step("Installing skills");
|
|
39397
39461
|
const dataDir = resolveDataDir2();
|
|
39398
|
-
const skillsSource = (0,
|
|
39462
|
+
const skillsSource = (0, import_node_path49.join)(dataDir, "skills");
|
|
39399
39463
|
const skillsDest = ".claude/skills";
|
|
39400
39464
|
let skillsInstalled = 0;
|
|
39401
39465
|
for (const skill of SKILLS) {
|
|
39402
|
-
const src = (0,
|
|
39403
|
-
const dest = (0,
|
|
39404
|
-
if (!(0,
|
|
39466
|
+
const src = (0, import_node_path49.join)(skillsSource, skill);
|
|
39467
|
+
const dest = (0, import_node_path49.join)(skillsDest, skill);
|
|
39468
|
+
if (!(0, import_node_fs65.existsSync)(src)) {
|
|
39405
39469
|
printWarn(` Skill data not found: ${skill}`);
|
|
39406
39470
|
continue;
|
|
39407
39471
|
}
|
|
39408
|
-
if ((0,
|
|
39472
|
+
if ((0, import_node_fs65.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
|
|
39409
39473
|
skillsInstalled++;
|
|
39410
39474
|
continue;
|
|
39411
39475
|
}
|
|
@@ -39526,6 +39590,10 @@ async function scaffoldProject(step, defaultsOnly, pluginMode, given = {}) {
|
|
|
39526
39590
|
}
|
|
39527
39591
|
async function offerFormalVerification(defaultsOnly, pluginMode) {
|
|
39528
39592
|
const cfg = readProjectConfig();
|
|
39593
|
+
if (cfg.formal_refused) {
|
|
39594
|
+
printWarn(` Formal verification: off \u2014 ${formalRefusalMessage(cfg.formal_refused)}`);
|
|
39595
|
+
return;
|
|
39596
|
+
}
|
|
39529
39597
|
const toolchain = findToolchain();
|
|
39530
39598
|
if (cfg.formal === "push") {
|
|
39531
39599
|
if (toolchain) printInfo(" Formal verification at push \u2713");
|
|
@@ -39596,7 +39664,7 @@ function registerInitCommand(program2) {
|
|
|
39596
39664
|
const staleMarker = clearStalePluginMarker();
|
|
39597
39665
|
const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
|
|
39598
39666
|
const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
|
|
39599
|
-
const isProject = projectMarkers.some((m) => (0,
|
|
39667
|
+
const isProject = projectMarkers.some((m) => (0, import_node_fs65.existsSync)(m));
|
|
39600
39668
|
if (!isProject) {
|
|
39601
39669
|
printError("No project detected in the current directory.");
|
|
39602
39670
|
printInfo('Run "verity init" from your project root.');
|
|
@@ -39699,7 +39767,7 @@ function registerInitCommand(program2) {
|
|
|
39699
39767
|
untrackMemory: opts.untrackMemory === true,
|
|
39700
39768
|
untrackState: opts.untrackState === true
|
|
39701
39769
|
});
|
|
39702
|
-
const globalVerityDir = (0,
|
|
39770
|
+
const globalVerityDir = (0, import_node_path49.join)(process.env.HOME ?? "", ".verity");
|
|
39703
39771
|
await (0, import_promises20.mkdir)(globalVerityDir, { recursive: true });
|
|
39704
39772
|
console.log("");
|
|
39705
39773
|
step("Wiring Claude Code hooks");
|
|
@@ -39774,7 +39842,7 @@ function registerInitCommand(program2) {
|
|
|
39774
39842
|
}
|
|
39775
39843
|
step("Your project's Standard");
|
|
39776
39844
|
let haveStandard = false;
|
|
39777
|
-
if ((0,
|
|
39845
|
+
if ((0, import_node_fs65.existsSync)(projectPath(STANDARD_FILE))) {
|
|
39778
39846
|
printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
|
|
39779
39847
|
haveStandard = true;
|
|
39780
39848
|
} else {
|
|
@@ -39804,7 +39872,7 @@ function registerInitCommand(program2) {
|
|
|
39804
39872
|
...telemetryChoice ? { telemetry: telemetryChoice } : {},
|
|
39805
39873
|
init: {
|
|
39806
39874
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
39807
|
-
cli_version: true ? "0.34.0-experimental.
|
|
39875
|
+
cli_version: true ? "0.34.0-experimental.421a631" : "dev"
|
|
39808
39876
|
}
|
|
39809
39877
|
});
|
|
39810
39878
|
} catch (err2) {
|
|
@@ -39854,8 +39922,8 @@ function registerInitCommand(program2) {
|
|
|
39854
39922
|
}
|
|
39855
39923
|
|
|
39856
39924
|
// src/commands/uninstall.ts
|
|
39857
|
-
var
|
|
39858
|
-
var
|
|
39925
|
+
var import_node_fs66 = require("node:fs");
|
|
39926
|
+
var import_node_path50 = require("node:path");
|
|
39859
39927
|
function registerUninstallCommand(program2) {
|
|
39860
39928
|
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) => {
|
|
39861
39929
|
const dryRun = opts.dryRun ?? false;
|
|
@@ -39864,11 +39932,11 @@ function registerUninstallCommand(program2) {
|
|
|
39864
39932
|
const actions = [];
|
|
39865
39933
|
const skillsRoot = projectPath(".claude/skills");
|
|
39866
39934
|
for (const name2 of PROJECT_SKILL_NAMES) {
|
|
39867
|
-
const dir = (0,
|
|
39868
|
-
if ((0,
|
|
39935
|
+
const dir = (0, import_node_path50.join)(skillsRoot, name2);
|
|
39936
|
+
if ((0, import_node_fs66.existsSync)(dir)) {
|
|
39869
39937
|
actions.push({
|
|
39870
39938
|
label: `Remove .claude/skills/${name2}/`,
|
|
39871
|
-
apply: () => (0,
|
|
39939
|
+
apply: () => (0, import_node_fs66.rmSync)(dir, { recursive: true, force: true })
|
|
39872
39940
|
});
|
|
39873
39941
|
}
|
|
39874
39942
|
}
|
|
@@ -39882,24 +39950,24 @@ function registerUninstallCommand(program2) {
|
|
|
39882
39950
|
});
|
|
39883
39951
|
}
|
|
39884
39952
|
const verityDir = projectPath(VERITY_DIR);
|
|
39885
|
-
if ((0,
|
|
39953
|
+
if ((0, import_node_fs66.existsSync)(verityDir)) {
|
|
39886
39954
|
actions.push({
|
|
39887
39955
|
label: `Remove ${VERITY_DIR}/`,
|
|
39888
|
-
apply: () => (0,
|
|
39956
|
+
apply: () => (0, import_node_fs66.rmSync)(verityDir, { recursive: true, force: true })
|
|
39889
39957
|
});
|
|
39890
39958
|
}
|
|
39891
39959
|
if (!keepVerityMd) {
|
|
39892
39960
|
const verityMd = projectPath(VERITY_MD_FILE);
|
|
39893
|
-
if ((0,
|
|
39961
|
+
if ((0, import_node_fs66.existsSync)(verityMd)) {
|
|
39894
39962
|
actions.push({
|
|
39895
39963
|
label: `Remove ${VERITY_MD_FILE}`,
|
|
39896
|
-
apply: () => (0,
|
|
39964
|
+
apply: () => (0, import_node_fs66.rmSync)(verityMd, { force: true })
|
|
39897
39965
|
});
|
|
39898
39966
|
}
|
|
39899
39967
|
}
|
|
39900
39968
|
const cleanupEmptyDir = (path) => {
|
|
39901
|
-
if ((0,
|
|
39902
|
-
(0,
|
|
39969
|
+
if ((0, import_node_fs66.existsSync)(path) && (0, import_node_fs66.statSync)(path).isDirectory() && (0, import_node_fs66.readdirSync)(path).length === 0) {
|
|
39970
|
+
(0, import_node_fs66.rmdirSync)(path);
|
|
39903
39971
|
}
|
|
39904
39972
|
};
|
|
39905
39973
|
actions.push({
|
|
@@ -39910,11 +39978,11 @@ function registerUninstallCommand(program2) {
|
|
|
39910
39978
|
}
|
|
39911
39979
|
});
|
|
39912
39980
|
const home = process.env.HOME ?? "";
|
|
39913
|
-
const globalVerityDir = (0,
|
|
39914
|
-
if (purgeGlobal && (0,
|
|
39981
|
+
const globalVerityDir = (0, import_node_path50.join)(home, ".verity");
|
|
39982
|
+
if (purgeGlobal && (0, import_node_fs66.existsSync)(globalVerityDir)) {
|
|
39915
39983
|
actions.push({
|
|
39916
39984
|
label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
|
|
39917
|
-
apply: () => (0,
|
|
39985
|
+
apply: () => (0, import_node_fs66.rmSync)(globalVerityDir, { recursive: true, force: true })
|
|
39918
39986
|
});
|
|
39919
39987
|
}
|
|
39920
39988
|
if (actions.length === 0) {
|
|
@@ -40108,8 +40176,8 @@ function registerTaskCommands(program2) {
|
|
|
40108
40176
|
}
|
|
40109
40177
|
|
|
40110
40178
|
// src/commands/reset.ts
|
|
40111
|
-
var
|
|
40112
|
-
var
|
|
40179
|
+
var import_node_fs67 = require("node:fs");
|
|
40180
|
+
var import_node_path51 = require("node:path");
|
|
40113
40181
|
function registerResetCommand(program2) {
|
|
40114
40182
|
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) => {
|
|
40115
40183
|
const globals = program2.opts();
|
|
@@ -40146,11 +40214,11 @@ function registerResetCommand(program2) {
|
|
|
40146
40214
|
}
|
|
40147
40215
|
const cacheDir = projectPath(CACHE_DIR);
|
|
40148
40216
|
let purged = 0;
|
|
40149
|
-
if ((0,
|
|
40150
|
-
for (const entry of (0,
|
|
40217
|
+
if ((0, import_node_fs67.existsSync)(cacheDir)) {
|
|
40218
|
+
for (const entry of (0, import_node_fs67.readdirSync)(cacheDir)) {
|
|
40151
40219
|
if (entry.startsWith("pending-")) {
|
|
40152
40220
|
try {
|
|
40153
|
-
(0,
|
|
40221
|
+
(0, import_node_fs67.unlinkSync)((0, import_node_path51.join)(cacheDir, entry));
|
|
40154
40222
|
purged++;
|
|
40155
40223
|
} catch {
|
|
40156
40224
|
}
|
|
@@ -40165,19 +40233,19 @@ function registerResetCommand(program2) {
|
|
|
40165
40233
|
projectPath(`${VERITY_DIR}/.last-analysis`)
|
|
40166
40234
|
];
|
|
40167
40235
|
for (const file of filesToClear) {
|
|
40168
|
-
if ((0,
|
|
40236
|
+
if ((0, import_node_fs67.existsSync)(file)) {
|
|
40169
40237
|
try {
|
|
40170
|
-
(0,
|
|
40238
|
+
(0, import_node_fs67.writeFileSync)(file, "");
|
|
40171
40239
|
} catch {
|
|
40172
40240
|
}
|
|
40173
40241
|
}
|
|
40174
40242
|
}
|
|
40175
40243
|
if (opts.all) {
|
|
40176
40244
|
const logsDir = projectPath(`${VERITY_DIR}/.logs`);
|
|
40177
|
-
if ((0,
|
|
40178
|
-
for (const entry of (0,
|
|
40245
|
+
if ((0, import_node_fs67.existsSync)(logsDir)) {
|
|
40246
|
+
for (const entry of (0, import_node_fs67.readdirSync)(logsDir)) {
|
|
40179
40247
|
try {
|
|
40180
|
-
(0,
|
|
40248
|
+
(0, import_node_fs67.unlinkSync)((0, import_node_path51.join)(logsDir, entry));
|
|
40181
40249
|
} catch {
|
|
40182
40250
|
}
|
|
40183
40251
|
}
|
|
@@ -40189,7 +40257,7 @@ function registerResetCommand(program2) {
|
|
|
40189
40257
|
}
|
|
40190
40258
|
|
|
40191
40259
|
// src/commands/reflect.ts
|
|
40192
|
-
var
|
|
40260
|
+
var import_node_fs68 = require("node:fs");
|
|
40193
40261
|
|
|
40194
40262
|
// src/lib/reflection-globs.ts
|
|
40195
40263
|
var MAX_GLOBS = 6;
|
|
@@ -40227,7 +40295,7 @@ async function writeNodeToDisk(args2) {
|
|
|
40227
40295
|
{ treePaths: listTrackedFiles(), recordBaseline: false }
|
|
40228
40296
|
);
|
|
40229
40297
|
if (written === 0) return false;
|
|
40230
|
-
return (0,
|
|
40298
|
+
return (0, import_node_fs68.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
|
|
40231
40299
|
} catch {
|
|
40232
40300
|
return false;
|
|
40233
40301
|
}
|
|
@@ -40659,9 +40727,9 @@ function registerRunCommand(program2) {
|
|
|
40659
40727
|
}
|
|
40660
40728
|
|
|
40661
40729
|
// src/commands/telemetry.ts
|
|
40662
|
-
var
|
|
40730
|
+
var import_node_fs69 = require("node:fs");
|
|
40663
40731
|
async function recordTelemetryChoice(choice) {
|
|
40664
|
-
if (!(0,
|
|
40732
|
+
if (!(0, import_node_fs69.existsSync)(projectPath(SETUP_STATE_FILE))) return;
|
|
40665
40733
|
try {
|
|
40666
40734
|
if ((await readSetupState())?.telemetry === choice) return;
|
|
40667
40735
|
await writeSetupState({ telemetry: choice });
|
|
@@ -40738,8 +40806,8 @@ function registerTelemetryCommands(program2) {
|
|
|
40738
40806
|
}
|
|
40739
40807
|
|
|
40740
40808
|
// src/commands/prove.ts
|
|
40741
|
-
var
|
|
40742
|
-
var
|
|
40809
|
+
var import_node_fs70 = require("node:fs");
|
|
40810
|
+
var import_node_path52 = require("node:path");
|
|
40743
40811
|
|
|
40744
40812
|
// src/lib/prove/hint-pool.ts
|
|
40745
40813
|
var STOP2 = /* @__PURE__ */ new Set([
|
|
@@ -40875,7 +40943,7 @@ function registerProveCommand(program2) {
|
|
|
40875
40943
|
process.exit(2);
|
|
40876
40944
|
}
|
|
40877
40945
|
const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
|
|
40878
|
-
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0,
|
|
40946
|
+
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path52.relative)(root, (0, import_node_path52.resolve)(p)) || ".") });
|
|
40879
40947
|
if (opts.hint && paths.length === 0) {
|
|
40880
40948
|
const hit = hintMatches(root, opts.hint);
|
|
40881
40949
|
if (hit.files.length > 0) {
|
|
@@ -40929,7 +40997,7 @@ function registerProveCommand(program2) {
|
|
|
40929
40997
|
});
|
|
40930
40998
|
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) => {
|
|
40931
40999
|
const root = repoRoot();
|
|
40932
|
-
if (!(0,
|
|
41000
|
+
if (!(0, import_node_fs70.existsSync)((0, import_node_path52.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
40933
41001
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
40934
41002
|
process.exit(2);
|
|
40935
41003
|
}
|
|
@@ -40953,7 +41021,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
40953
41021
|
const reports = [];
|
|
40954
41022
|
for (const f of files) {
|
|
40955
41023
|
const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
|
|
40956
|
-
report.file = (0,
|
|
41024
|
+
report.file = (0, import_node_path52.relative)(root, f);
|
|
40957
41025
|
reports.push(report);
|
|
40958
41026
|
try {
|
|
40959
41027
|
writeResult(root, report);
|
|
@@ -40991,7 +41059,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
40991
41059
|
printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
|
|
40992
41060
|
process.exit(2);
|
|
40993
41061
|
}
|
|
40994
|
-
if (!(0,
|
|
41062
|
+
if (!(0, import_node_fs70.existsSync)((0, import_node_path52.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
40995
41063
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
40996
41064
|
process.exit(2);
|
|
40997
41065
|
}
|
|
@@ -41022,7 +41090,7 @@ ${report.error ?? ""}`);
|
|
|
41022
41090
|
printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
|
|
41023
41091
|
return;
|
|
41024
41092
|
}
|
|
41025
|
-
const modelSource = readRegularFileInRoot(root, (0,
|
|
41093
|
+
const modelSource = readRegularFileInRoot(root, (0, import_node_path52.relative)(root, file), 512 * 1024);
|
|
41026
41094
|
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`);
|
|
41027
41095
|
const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
|
|
41028
41096
|
const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
|
|
@@ -41042,7 +41110,7 @@ ${report.error ?? ""}`);
|
|
|
41042
41110
|
});
|
|
41043
41111
|
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) => {
|
|
41044
41112
|
const root = repoRoot();
|
|
41045
|
-
let files = paths.map((p) => (0,
|
|
41113
|
+
let files = paths.map((p) => (0, import_node_path52.relative)(root, (0, import_node_path52.resolve)(p)));
|
|
41046
41114
|
if (files.length === 0) {
|
|
41047
41115
|
const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
|
|
41048
41116
|
const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
|
|
@@ -41102,7 +41170,7 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41102
41170
|
let revise;
|
|
41103
41171
|
if (opts.revise) {
|
|
41104
41172
|
const existing = resolveModelFile(root, opts.revise);
|
|
41105
|
-
const src = existing ? readRegularFileInRoot(root, (0,
|
|
41173
|
+
const src = existing ? readRegularFileInRoot(root, (0, import_node_path52.relative)(root, existing), 64 * 1024) : null;
|
|
41106
41174
|
if (!src || !src.ok || !opts.note) {
|
|
41107
41175
|
printError('--revise needs an existing model under Models/ and --note "<what the replay showed>"');
|
|
41108
41176
|
process.exit(2);
|
|
@@ -41141,8 +41209,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41141
41209
|
});
|
|
41142
41210
|
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) => {
|
|
41143
41211
|
const root = repoRoot();
|
|
41144
|
-
const rel0 = (0,
|
|
41145
|
-
const rel = rel0.startsWith("..") || (0,
|
|
41212
|
+
const rel0 = (0, import_node_path52.relative)(root, (0, import_node_path52.isAbsolute)(file) ? file : (0, import_node_path52.join)(root, file)).replace(/\\/g, "/");
|
|
41213
|
+
const rel = rel0.startsWith("..") || (0, import_node_path52.isAbsolute)(rel0) ? null : rel0;
|
|
41146
41214
|
if (!rel) {
|
|
41147
41215
|
printError(`${file} is not inside this repository`);
|
|
41148
41216
|
process.exit(2);
|
|
@@ -41158,8 +41226,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41158
41226
|
});
|
|
41159
41227
|
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) => {
|
|
41160
41228
|
const root = repoRoot();
|
|
41161
|
-
const rel = (0,
|
|
41162
|
-
const digest = rel.startsWith("..") || (0,
|
|
41229
|
+
const rel = (0, import_node_path52.relative)(root, (0, import_node_path52.isAbsolute)(file) ? file : (0, import_node_path52.join)(root, file));
|
|
41230
|
+
const digest = rel.startsWith("..") || (0, import_node_path52.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
|
|
41163
41231
|
if (!digest) {
|
|
41164
41232
|
printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
|
|
41165
41233
|
process.exit(2);
|
|
@@ -41193,10 +41261,10 @@ function refreshScaffold(root) {
|
|
|
41193
41261
|
}
|
|
41194
41262
|
|
|
41195
41263
|
// src/commands/lean.ts
|
|
41196
|
-
var
|
|
41264
|
+
var import_node_fs71 = require("node:fs");
|
|
41197
41265
|
var import_node_child_process20 = require("node:child_process");
|
|
41198
41266
|
var import_node_os11 = require("node:os");
|
|
41199
|
-
var
|
|
41267
|
+
var import_node_path53 = require("node:path");
|
|
41200
41268
|
function registerLeanCommand(program2) {
|
|
41201
41269
|
const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
|
|
41202
41270
|
lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
|
|
@@ -41213,7 +41281,7 @@ function registerLeanCommand(program2) {
|
|
|
41213
41281
|
const managed = pinnedVersionDir();
|
|
41214
41282
|
const matches = version ? version.includes(pin) : false;
|
|
41215
41283
|
if (opts.json) {
|
|
41216
|
-
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0,
|
|
41284
|
+
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs71.existsSync)((0, import_node_path53.join)(managed, "bin")), asset: leanAssetName() });
|
|
41217
41285
|
return;
|
|
41218
41286
|
}
|
|
41219
41287
|
printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
|
|
@@ -41231,7 +41299,7 @@ function registerLeanCommand(program2) {
|
|
|
41231
41299
|
process.exit(2);
|
|
41232
41300
|
}
|
|
41233
41301
|
const dir = pinnedVersionDir();
|
|
41234
|
-
if ((0,
|
|
41302
|
+
if ((0, import_node_fs71.existsSync)((0, import_node_path53.join)(dir, "bin", "lake")) && !opts.force) {
|
|
41235
41303
|
printInfo(`already installed at ${dir}`);
|
|
41236
41304
|
return;
|
|
41237
41305
|
}
|
|
@@ -41267,18 +41335,18 @@ function registerLeanCommand(program2) {
|
|
|
41267
41335
|
});
|
|
41268
41336
|
lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
|
|
41269
41337
|
const dir = pinnedVersionDir();
|
|
41270
|
-
if (!(0,
|
|
41338
|
+
if (!(0, import_node_fs71.existsSync)(dir)) {
|
|
41271
41339
|
printInfo("nothing to remove");
|
|
41272
41340
|
return;
|
|
41273
41341
|
}
|
|
41274
|
-
(0,
|
|
41342
|
+
(0, import_node_fs71.rmSync)(dir, { recursive: true, force: true });
|
|
41275
41343
|
printInfo(`removed ${dir}`);
|
|
41276
41344
|
});
|
|
41277
41345
|
}
|
|
41278
41346
|
|
|
41279
41347
|
// src/cli.ts
|
|
41280
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.
|
|
41281
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.
|
|
41348
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.421a631").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) => {
|
|
41349
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.421a631");
|
|
41282
41350
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
41283
41351
|
try {
|
|
41284
41352
|
await foldLegacyLocalCredential();
|