@codacy/verity-cli 0.33.3-experimental.53cd005 → 0.33.3-experimental.5a3f573

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 CHANGED
@@ -15677,9 +15677,34 @@ async function githubCanSeeRepo(owner, repo, token) {
15677
15677
  if (res.ok) return { ok: true, data: true };
15678
15678
  return { ok: false, error: `GitHub repo lookup failed (HTTP ${res.status})` };
15679
15679
  }
15680
- async function githubDeviceFlow() {
15681
- const override = process.env.VERITY_PROVIDER_TOKEN;
15682
- if (override) return { ok: true, data: override };
15680
+ var CONTROL_CHARS = /[\u0000-\u001f\u007f]/;
15681
+ function isSafeText(v) {
15682
+ return typeof v === "string" && v.length > 0 && v.length < 2048 && !CONTROL_CHARS.test(v);
15683
+ }
15684
+ var GITHUB_DEVICE_VERIFICATION_URL = "https://github.com/login/device";
15685
+ function isGithubDeviceUrl(v) {
15686
+ if (!isSafeText(v)) return false;
15687
+ let url;
15688
+ try {
15689
+ url = new URL(v);
15690
+ } catch {
15691
+ return false;
15692
+ }
15693
+ return url.protocol === "https:" && url.hostname === "github.com" && url.port === "" && url.username === "" && url.password === "" && url.pathname === "/login/device" && url.search === "" && url.hash === "";
15694
+ }
15695
+ async function requestDeviceCode() {
15696
+ if (process.env.VERITY_PROVIDER_TOKEN) {
15697
+ return {
15698
+ ok: true,
15699
+ data: {
15700
+ device_code: "provider-token-override",
15701
+ user_code: "OVER-RIDE",
15702
+ verification_uri: GITHUB_DEVICE_VERIFICATION_URL,
15703
+ expires_in: 900,
15704
+ interval: 0
15705
+ }
15706
+ };
15707
+ }
15683
15708
  let dc;
15684
15709
  try {
15685
15710
  const res = await fetch(GITHUB_DEVICE_CODE_URL, {
@@ -15700,15 +15725,40 @@ async function githubDeviceFlow() {
15700
15725
  error: "GitHub did not return a device code (is Device Flow enabled on the OAuth app?)"
15701
15726
  };
15702
15727
  }
15703
- printInfo("");
15704
- printInfo(`To authorize Verity, open: ${dc.verification_uri}`);
15705
- printInfo(`And enter the code: ${dc.user_code}`);
15728
+ if (!isSafeText(dc.device_code) || !isSafeText(dc.user_code) || !isGithubDeviceUrl(dc.verification_uri)) {
15729
+ return { ok: false, error: "GitHub returned invalid device-flow data" };
15730
+ }
15731
+ const num = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : null;
15732
+ if (dc.expires_in != null && num(dc.expires_in) === null) {
15733
+ return { ok: false, error: "GitHub returned invalid device-flow data" };
15734
+ }
15735
+ if (dc.interval != null && num(dc.interval) === null) {
15736
+ return { ok: false, error: "GitHub returned invalid device-flow data" };
15737
+ }
15738
+ return {
15739
+ ok: true,
15740
+ data: {
15741
+ device_code: dc.device_code,
15742
+ user_code: dc.user_code,
15743
+ // The canonical form, not the string as received: what is shown and saved
15744
+ // is exactly the page the check above accepted.
15745
+ verification_uri: GITHUB_DEVICE_VERIFICATION_URL,
15746
+ // || (not ??) so a falsy/zero value from the provider floors to a safe
15747
+ // default — a 0 interval would otherwise spin a tight polling loop.
15748
+ expires_in: dc.expires_in || 900,
15749
+ interval: dc.interval || 5
15750
+ }
15751
+ };
15752
+ }
15753
+ async function pollDeviceToken(dc, opts) {
15754
+ const override = process.env.VERITY_PROVIDER_TOKEN;
15755
+ if (override) return { ok: true, data: override };
15756
+ const waitUntil = Math.min(opts.waitUntil ?? opts.codeExpiresAt, opts.codeExpiresAt);
15706
15757
  const spinner = startSpinner(`Waiting for you to approve in the browser \xB7 code ${dc.user_code}`);
15707
- const deadline = Date.now() + (dc.expires_in || 900) * 1e3;
15708
15758
  let interval = dc.interval || 5;
15709
15759
  try {
15710
- while (Date.now() < deadline) {
15711
- await sleep(interval * 1e3);
15760
+ while (Date.now() < waitUntil) {
15761
+ await sleep(Math.min(interval * 1e3, Math.max(0, waitUntil - Date.now())));
15712
15762
  let data;
15713
15763
  try {
15714
15764
  const res = await fetch(GITHUB_ACCESS_TOKEN_URL, {
@@ -15736,18 +15786,36 @@ async function githubDeviceFlow() {
15736
15786
  interval += 5;
15737
15787
  break;
15738
15788
  case "access_denied":
15739
- return { ok: false, error: "Authorization was denied on GitHub." };
15789
+ return { ok: false, error: "Authorization was denied on GitHub.", reason: "denied" };
15740
15790
  case "expired_token":
15741
- return { ok: false, error: "The authorization code expired. Re-run register." };
15791
+ return { ok: false, error: 'The authorization code expired. Run "verity login" again.', reason: "expired" };
15742
15792
  default:
15743
- if (data.error) return { ok: false, error: `GitHub auth error: ${data.error}` };
15793
+ if (data.error) return { ok: false, error: `GitHub auth error: ${data.error}`, reason: "error" };
15744
15794
  }
15745
15795
  }
15746
- return { ok: false, error: "Timed out waiting for GitHub authorization." };
15796
+ if (Date.now() >= opts.codeExpiresAt) {
15797
+ return { ok: false, error: 'The authorization code expired. Run "verity login" again.', reason: "expired" };
15798
+ }
15799
+ return { ok: false, error: "Still waiting for approval on GitHub.", reason: "waiting" };
15747
15800
  } finally {
15748
15801
  spinner.stop();
15749
15802
  }
15750
15803
  }
15804
+ async function githubDeviceFlow() {
15805
+ const override = process.env.VERITY_PROVIDER_TOKEN;
15806
+ if (override) return { ok: true, data: override };
15807
+ const code = await requestDeviceCode();
15808
+ if (!code.ok) return code;
15809
+ const dc = code.data;
15810
+ printInfo("");
15811
+ printInfo(`To authorize Verity, open: ${dc.verification_uri}`);
15812
+ printInfo(`And enter the code: ${dc.user_code}`);
15813
+ const polled = await pollDeviceToken(dc, { codeExpiresAt: Date.now() + dc.expires_in * 1e3 });
15814
+ if (!polled.ok) {
15815
+ return { ok: false, error: polled.reason === "waiting" ? "Timed out waiting for GitHub authorization." : polled.error };
15816
+ }
15817
+ return { ok: true, data: polled.data };
15818
+ }
15751
15819
 
15752
15820
  // src/lib/register.ts
15753
15821
  var isInteractive = () => Boolean(process.stdin.isTTY && process.stdout.isTTY);
@@ -15842,11 +15910,14 @@ function deviceLabel() {
15842
15910
  }
15843
15911
  async function loginOnce(opts) {
15844
15912
  const usingTokenOverride = Boolean(process.env.VERITY_PROVIDER_TOKEN);
15845
- const providerAuth = await githubDeviceFlow();
15846
- if (!providerAuth.ok) {
15847
- return { ok: false, error: providerAuth.error };
15913
+ let providerToken = opts.providerToken;
15914
+ if (!providerToken) {
15915
+ const providerAuth = await githubDeviceFlow();
15916
+ if (!providerAuth.ok) {
15917
+ return { ok: false, error: providerAuth.error };
15918
+ }
15919
+ providerToken = providerAuth.data;
15848
15920
  }
15849
- const providerToken = providerAuth.data;
15850
15921
  const parsed = opts.remote ? parseRemote(opts.remote) : null;
15851
15922
  if (!usingTokenOverride && parsed && parsed.provider === "github") {
15852
15923
  const installed2 = await ensureAppInstalled(parsed.owner, parsed.repo, providerToken);
@@ -15989,6 +16060,71 @@ function registerAuthCommands(program2) {
15989
16060
  });
15990
16061
  }
15991
16062
 
16063
+ // src/lib/pending-login.ts
16064
+ var import_node_fs4 = require("node:fs");
16065
+ var import_node_path4 = require("node:path");
16066
+ function pendingLoginPath() {
16067
+ return `${process.env.HOME}/.verity/pending-login.json`;
16068
+ }
16069
+ function savePendingLogin(dc, serviceUrl, now = Date.now()) {
16070
+ const record = {
16071
+ version: 1,
16072
+ device_code: dc.device_code,
16073
+ user_code: dc.user_code,
16074
+ verification_uri: dc.verification_uri,
16075
+ interval: dc.interval,
16076
+ expires_at: new Date(now + dc.expires_in * 1e3).toISOString(),
16077
+ service_url: serviceUrl,
16078
+ created_at: new Date(now).toISOString()
16079
+ };
16080
+ const path = pendingLoginPath();
16081
+ (0, import_node_fs4.mkdirSync)((0, import_node_path4.dirname)(path), { recursive: true });
16082
+ clearPendingLogin();
16083
+ (0, import_node_fs4.writeFileSync)(path, JSON.stringify(record, null, 2) + "\n", { mode: 384, flag: "wx" });
16084
+ try {
16085
+ (0, import_node_fs4.chmodSync)(path, 384);
16086
+ } catch {
16087
+ }
16088
+ return record;
16089
+ }
16090
+ function readPendingLogin(now = Date.now()) {
16091
+ const path = pendingLoginPath();
16092
+ if (!(0, import_node_fs4.existsSync)(path)) return { status: "none" };
16093
+ try {
16094
+ if ((0, import_node_fs4.lstatSync)(path).isSymbolicLink()) return { status: "invalid", reason: "it is a symlink" };
16095
+ } catch {
16096
+ return { status: "none" };
16097
+ }
16098
+ let parsed;
16099
+ try {
16100
+ parsed = JSON.parse((0, import_node_fs4.readFileSync)(path, "utf-8"));
16101
+ } catch {
16102
+ return { status: "invalid", reason: "it is not valid JSON" };
16103
+ }
16104
+ const r = parsed;
16105
+ const str3 = isSafeText;
16106
+ if (!r || typeof r !== "object" || r.version !== 1 || !str3(r.device_code) || !str3(r.user_code) || !str3(r.verification_uri) || !str3(r.service_url) || !str3(r.expires_at) || // ⚠ A NEGATIVE INTERVAL IS A TIGHT LOOP. pollDeviceToken floors only a falsy
16107
+ // one, so -1 would poll GitHub back to back until it answered slow_down.
16108
+ typeof r.interval !== "number" || !Number.isFinite(r.interval) || r.interval < 0) {
16109
+ return { status: "invalid", reason: "it is missing fields" };
16110
+ }
16111
+ if (!isGithubDeviceUrl(r.verification_uri)) {
16112
+ return { status: "invalid", reason: "its verification link is not GitHub's device page" };
16113
+ }
16114
+ const expires = Date.parse(r.expires_at);
16115
+ if (!Number.isFinite(expires)) return { status: "invalid", reason: "its expiry is not a date" };
16116
+ const record = r;
16117
+ return expires <= now ? { status: "expired", record } : { status: "ok", record };
16118
+ }
16119
+ function clearPendingLogin() {
16120
+ try {
16121
+ (0, import_node_fs4.unlinkSync)(pendingLoginPath());
16122
+ return true;
16123
+ } catch {
16124
+ return false;
16125
+ }
16126
+ }
16127
+
15992
16128
  // src/lib/login-report.ts
15993
16129
  async function reportLoginOutcome(out2, opts = {}) {
15994
16130
  const identity = out2.email ?? (out2.userId != null ? `user #${out2.userId}` : "your account");
@@ -16055,8 +16191,24 @@ async function reportLoginOutcome(out2, opts = {}) {
16055
16191
 
16056
16192
  // src/commands/login.ts
16057
16193
  function registerLoginCommand(program2) {
16058
- program2.command("login").description("Log in to Verity (one GitHub login grants access to all your repositories)").option("--force", "Re-authenticate even if already logged in").action(async (opts) => {
16194
+ program2.command("login").description("Log in to Verity (one GitHub login grants access to all your repositories)").option("--force", "Re-authenticate even if already logged in").option("--start", "Show the GitHub code and return at once (finish with --finish); prints JSON").option("--finish", "Wait for approval of the code --start showed, then log in; prints JSON").option("--wait <seconds>", "With --finish: how long to wait for approval before returning", "100").option("--cancel", "Discard a code --start showed that will not be approved").action(async (opts) => {
16059
16195
  const globals = program2.opts();
16196
+ const modes = [opts.start, opts.finish, opts.cancel].filter(Boolean).length;
16197
+ if (modes > 1) {
16198
+ printError("Use one of --start, --finish or --cancel.");
16199
+ process.exit(1);
16200
+ }
16201
+ if (opts.cancel) {
16202
+ const removed = clearPendingLogin();
16203
+ printInfo(removed ? "Discarded the pending sign-in." : "No sign-in was pending.");
16204
+ printJson({ status: removed ? "cancelled" : "no_pending" });
16205
+ return;
16206
+ }
16207
+ const split = !!(opts.start || opts.finish);
16208
+ if (!split && !process.stdin.isTTY && (process.env.CLAUDECODE || process.env.CLAUDE_SESSION_ID)) {
16209
+ printWarn("Inside a Claude Code session the code below may not be visible until this command ends.");
16210
+ printWarn(' Use "verity login --start", then "verity login --finish" once it is approved.');
16211
+ }
16060
16212
  const resolution = await resolveServiceUrlForAuth(globals.serviceUrl);
16061
16213
  if (resolution.source === "default") {
16062
16214
  printInfo(`No Verity service configured on this machine \u2014 using the default: ${resolution.url}`);
@@ -16069,6 +16221,10 @@ function registerLoginCommand(program2) {
16069
16221
  printInfo(" Completing login updates ~/.verity/credentials against the live service.");
16070
16222
  }
16071
16223
  const remote = currentRemote();
16224
+ if (opts.finish) {
16225
+ await finishSplitLogin({ serviceUrl, remote, verbose: globals.verbose, waitSeconds: opts.wait });
16226
+ return;
16227
+ }
16072
16228
  if (remote && !parseRemote(remote)) {
16073
16229
  printWarn(`This repository's origin remote is not a recognizable git URL: ${remote}`);
16074
16230
  printInfo(" Verity cannot identify the repository from it, so runs here will not be saved.");
@@ -16083,6 +16239,14 @@ function registerLoginCommand(program2) {
16083
16239
  if (!nudge && !upgrade) {
16084
16240
  printInfo(`Already logged in as ${who.data.email ?? `user #${who.data.user_id}`}. \u2713`);
16085
16241
  printInfo(" Re-authenticate with: verity login --force");
16242
+ if (split) {
16243
+ printJson({
16244
+ status: "logged_in",
16245
+ email: who.data.email ?? null,
16246
+ repo_covered: who.data.grant_status != null,
16247
+ already: true
16248
+ });
16249
+ }
16086
16250
  return;
16087
16251
  }
16088
16252
  if (nudge) {
@@ -16098,6 +16262,34 @@ function registerLoginCommand(program2) {
16098
16262
  printWarn("Could not confirm your current login state with the service \u2014 proceeding to log in.");
16099
16263
  }
16100
16264
  }
16265
+ if (opts.start) {
16266
+ const code = await requestDeviceCode();
16267
+ if (!code.ok) {
16268
+ printError(`Login failed: ${code.error}`);
16269
+ printJson({ status: "failed", error: code.error });
16270
+ process.exit(1);
16271
+ }
16272
+ let pending;
16273
+ try {
16274
+ pending = savePendingLogin(code.data, serviceUrl);
16275
+ } catch (err2) {
16276
+ const error = `could not save the pending sign-in: ${err2.message}`;
16277
+ printError(`Login failed: ${error}`);
16278
+ printJson({ status: "failed", error });
16279
+ process.exit(1);
16280
+ }
16281
+ printInfo(`To authorize Verity, open: ${pending.verification_uri}`);
16282
+ printInfo(`And enter the code: ${pending.user_code}`);
16283
+ printInfo(` Then run "verity login --finish". The code expires at ${pending.expires_at}.`);
16284
+ printJson({
16285
+ status: "pending",
16286
+ verification_uri: pending.verification_uri,
16287
+ user_code: pending.user_code,
16288
+ expires_at: pending.expires_at,
16289
+ service_url: pending.service_url
16290
+ });
16291
+ return;
16292
+ }
16101
16293
  printInfo("Authenticating with GitHub\u2026");
16102
16294
  const result = await loginOnce({ serviceUrl, remote: remote || void 0, verbose: globals.verbose });
16103
16295
  if (!result.ok) {
@@ -16107,6 +16299,64 @@ function registerLoginCommand(program2) {
16107
16299
  await reportLoginOutcome(result.data, { remote: remote || void 0, verbose: globals.verbose });
16108
16300
  });
16109
16301
  }
16302
+ var MAX_WAIT_SECONDS = 600;
16303
+ async function finishSplitLogin(opts) {
16304
+ function fail(status, error, clear) {
16305
+ if (clear) clearPendingLogin();
16306
+ printError(`Login failed: ${error}`);
16307
+ printJson({ status, error });
16308
+ process.exit(1);
16309
+ }
16310
+ const wait = Number(String(opts.waitSeconds ?? "100").trim());
16311
+ if (!Number.isInteger(wait) || wait < 0 || wait > MAX_WAIT_SECONDS) {
16312
+ fail("invalid", `--wait must be a whole number of seconds from 0 to ${MAX_WAIT_SECONDS}`, false);
16313
+ }
16314
+ const read2 = readPendingLogin();
16315
+ if (read2.status === "none") fail("no_pending", 'no sign-in is pending \u2014 run "verity login --start" first', false);
16316
+ if (read2.status === "invalid") fail("invalid", `the pending sign-in is unusable (${read2.reason}) \u2014 run "verity login --start" again`, true);
16317
+ if (read2.status === "expired") fail("expired", 'the code expired before it was approved \u2014 run "verity login --start" again', true);
16318
+ const pending = read2.record;
16319
+ if (pending.service_url !== opts.serviceUrl) {
16320
+ fail(
16321
+ "service_changed",
16322
+ `the sign-in was started for ${pending.service_url}, but this machine now resolves ${opts.serviceUrl} \u2014 run "verity login --start" again`,
16323
+ true
16324
+ );
16325
+ }
16326
+ const polled = await pollDeviceToken(pending, {
16327
+ codeExpiresAt: Date.parse(pending.expires_at),
16328
+ waitUntil: Date.now() + wait * 1e3
16329
+ });
16330
+ if (!polled.ok) {
16331
+ if (polled.reason === "waiting") {
16332
+ printInfo(`Not approved yet. Enter ${pending.user_code} at ${pending.verification_uri}, then run "verity login --finish" again.`);
16333
+ printJson({
16334
+ status: "pending",
16335
+ verification_uri: pending.verification_uri,
16336
+ user_code: pending.user_code,
16337
+ expires_at: pending.expires_at
16338
+ });
16339
+ process.exit(2);
16340
+ }
16341
+ fail(polled.reason, polled.error, true);
16342
+ }
16343
+ clearPendingLogin();
16344
+ const result = await loginOnce({
16345
+ serviceUrl: opts.serviceUrl,
16346
+ remote: opts.remote || void 0,
16347
+ verbose: opts.verbose,
16348
+ providerToken: polled.data
16349
+ });
16350
+ if (!result.ok) fail("failed", result.error, false);
16351
+ const data = result.data;
16352
+ await reportLoginOutcome(data, { remote: opts.remote || void 0, verbose: opts.verbose });
16353
+ printJson({
16354
+ status: "logged_in",
16355
+ email: data.email ?? null,
16356
+ repo_count: data.repoCount,
16357
+ expires_at: data.expiresAt ?? null
16358
+ });
16359
+ }
16110
16360
 
16111
16361
  // src/commands/token.ts
16112
16362
  function registerTokenCommand(program2) {
@@ -16424,11 +16674,11 @@ function registerLogoutCommand(program2) {
16424
16674
 
16425
16675
  // src/lib/hooks.ts
16426
16676
  var import_promises4 = require("node:fs/promises");
16427
- var import_node_path5 = require("node:path");
16677
+ var import_node_path6 = require("node:path");
16428
16678
 
16429
16679
  // src/lib/json-file.ts
16430
16680
  var import_promises3 = require("node:fs/promises");
16431
- var import_node_path4 = require("node:path");
16681
+ var import_node_path5 = require("node:path");
16432
16682
  function jsonSemanticEqual(a, b) {
16433
16683
  if (a === b) return true;
16434
16684
  if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
@@ -16474,7 +16724,7 @@ async function writeJsonFilePreservingStyle(file, value) {
16474
16724
  const indent = currentRaw !== null ? detectJsonIndent(currentRaw) : 2;
16475
16725
  const next = JSON.stringify(value, null, indent) + "\n";
16476
16726
  if (next === currentRaw) return false;
16477
- await (0, import_promises3.mkdir)((0, import_node_path4.dirname)(file), { recursive: true });
16727
+ await (0, import_promises3.mkdir)((0, import_node_path5.dirname)(file), { recursive: true });
16478
16728
  await (0, import_promises3.writeFile)(file, next);
16479
16729
  return true;
16480
16730
  }
@@ -16659,13 +16909,13 @@ async function writeSettings(settings) {
16659
16909
  }
16660
16910
  async function readSettingsAt(root) {
16661
16911
  try {
16662
- return JSON.parse(await (0, import_promises4.readFile)((0, import_node_path5.join)(root, CLAUDE_SETTINGS_FILE), "utf-8"));
16912
+ return JSON.parse(await (0, import_promises4.readFile)((0, import_node_path6.join)(root, CLAUDE_SETTINGS_FILE), "utf-8"));
16663
16913
  } catch {
16664
16914
  return {};
16665
16915
  }
16666
16916
  }
16667
16917
  async function writeSettingsAt(root, settings) {
16668
- await writeJsonFilePreservingStyle((0, import_node_path5.join)(root, CLAUDE_SETTINGS_FILE), settings);
16918
+ await writeJsonFilePreservingStyle((0, import_node_path6.join)(root, CLAUDE_SETTINGS_FILE), settings);
16669
16919
  }
16670
16920
  async function hasLegacyHooksAt(root) {
16671
16921
  const settings = await readSettingsAt(root);
@@ -16854,8 +17104,8 @@ async function applyMomentSelection(moments) {
16854
17104
  }
16855
17105
 
16856
17106
  // src/lib/project-config.ts
16857
- var import_node_fs4 = require("node:fs");
16858
- var import_node_path6 = require("node:path");
17107
+ var import_node_fs5 = require("node:fs");
17108
+ var import_node_path7 = require("node:path");
16859
17109
  var DEFAULTS = { git_moments: [] };
16860
17110
  function isMoment(value) {
16861
17111
  return value === "commit" || value === "push";
@@ -16865,8 +17115,8 @@ function parseMoments(raw) {
16865
17115
  }
16866
17116
  function readConfigFile(path) {
16867
17117
  try {
16868
- if (!(0, import_node_fs4.existsSync)(path)) return null;
16869
- const raw = JSON.parse((0, import_node_fs4.readFileSync)(path, "utf-8"));
17118
+ if (!(0, import_node_fs5.existsSync)(path)) return null;
17119
+ const raw = JSON.parse((0, import_node_fs5.readFileSync)(path, "utf-8"));
16870
17120
  const moments = Array.isArray(raw.git_moments) ? raw.git_moments.filter(isMoment) : [];
16871
17121
  const source2 = raw.git_moments_source === "user" || raw.git_moments_source === "init" ? raw.git_moments_source : void 0;
16872
17122
  return {
@@ -16883,7 +17133,7 @@ function candidates() {
16883
17133
  const out2 = [{ path: local, source: "local" }];
16884
17134
  const main = mainWorktreeRoot();
16885
17135
  if (main) {
16886
- const inherited = (0, import_node_path6.join)(main, PROJECT_CONFIG_FILE);
17136
+ const inherited = (0, import_node_path7.join)(main, PROJECT_CONFIG_FILE);
16887
17137
  if (inherited !== local) out2.push({ path: inherited, source: "main-worktree" });
16888
17138
  }
16889
17139
  return out2;
@@ -16904,8 +17154,8 @@ function writeProjectConfig(patch) {
16904
17154
  ...patch
16905
17155
  };
16906
17156
  const target = projectPath(PROJECT_CONFIG_FILE);
16907
- (0, import_node_fs4.mkdirSync)((0, import_node_path6.dirname)(target), { recursive: true });
16908
- (0, import_node_fs4.writeFileSync)(target, JSON.stringify(next, null, 2) + "\n");
17157
+ (0, import_node_fs5.mkdirSync)((0, import_node_path7.dirname)(target), { recursive: true });
17158
+ (0, import_node_fs5.writeFileSync)(target, JSON.stringify(next, null, 2) + "\n");
16909
17159
  return next;
16910
17160
  }
16911
17161
  function resolveGuardMoments(explicit) {
@@ -16914,11 +17164,11 @@ function resolveGuardMoments(explicit) {
16914
17164
  }
16915
17165
 
16916
17166
  // src/lib/plugin-ownership.ts
16917
- var import_node_fs7 = require("node:fs");
17167
+ var import_node_fs8 = require("node:fs");
16918
17168
 
16919
17169
  // src/lib/which.ts
16920
- var import_node_fs5 = require("node:fs");
16921
- var import_node_path7 = require("node:path");
17170
+ var import_node_fs6 = require("node:fs");
17171
+ var import_node_path8 = require("node:path");
16922
17172
  function executableExtensions(platform4, pathext) {
16923
17173
  if (platform4 !== "win32") return [""];
16924
17174
  const raw = (pathext ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean);
@@ -16936,14 +17186,14 @@ function whichSync(bin, opts = {}) {
16936
17186
  if (!rawPath) return null;
16937
17187
  const exts = executableExtensions(platform4, opts.pathext ?? process.env.PATHEXT);
16938
17188
  const real = opts.real ?? true;
16939
- for (const dir of rawPath.split(import_node_path7.delimiter)) {
17189
+ for (const dir of rawPath.split(import_node_path8.delimiter)) {
16940
17190
  if (!dir) continue;
16941
17191
  for (const ext of exts) {
16942
- const candidate = (0, import_node_path7.join)(dir, bin + ext);
17192
+ const candidate = (0, import_node_path8.join)(dir, bin + ext);
16943
17193
  try {
16944
- if (!(0, import_node_fs5.statSync)(candidate).isFile()) continue;
16945
- if (platform4 !== "win32") (0, import_node_fs5.accessSync)(candidate, import_node_fs5.constants.X_OK);
16946
- return real ? (0, import_node_fs5.realpathSync)(candidate) : candidate;
17194
+ if (!(0, import_node_fs6.statSync)(candidate).isFile()) continue;
17195
+ if (platform4 !== "win32") (0, import_node_fs6.accessSync)(candidate, import_node_fs6.constants.X_OK);
17196
+ return real ? (0, import_node_fs6.realpathSync)(candidate) : candidate;
16947
17197
  } catch {
16948
17198
  continue;
16949
17199
  }
@@ -16954,10 +17204,10 @@ function whichSync(bin, opts = {}) {
16954
17204
 
16955
17205
  // src/lib/plugin-ownership.ts
16956
17206
  var import_node_os2 = require("node:os");
16957
- var import_node_path8 = require("node:path");
17207
+ var import_node_path9 = require("node:path");
16958
17208
 
16959
17209
  // src/lib/stderr-log.ts
16960
- var import_node_fs6 = require("node:fs");
17210
+ var import_node_fs7 = require("node:fs");
16961
17211
  var TOKEN_RE2 = /verity_[0-9a-f]{16,}/g;
16962
17212
  var ANSI_RE = /\u001b\[[0-?]*[ -/]*[@-~]/g;
16963
17213
  function scrub(s) {
@@ -16970,9 +17220,9 @@ function append(text) {
16970
17220
  try {
16971
17221
  const dir = projectPath(DEBUG_LOG_DIR);
16972
17222
  const file = projectPath(STDERR_LOG_FILE);
16973
- (0, import_node_fs6.mkdirSync)(dir, { recursive: true });
17223
+ (0, import_node_fs7.mkdirSync)(dir, { recursive: true });
16974
17224
  rotateIfNeeded(file);
16975
- (0, import_node_fs6.appendFileSync)(file, text);
17225
+ (0, import_node_fs7.appendFileSync)(file, text);
16976
17226
  } catch {
16977
17227
  }
16978
17228
  }
@@ -17011,7 +17261,7 @@ function logToFileOnly(text) {
17011
17261
  }
17012
17262
 
17013
17263
  // src/lib/plugin-ownership.ts
17014
- var CONTROL_CHARS = /[\u0000-\u001f\u007f]/;
17264
+ var CONTROL_CHARS2 = /[\u0000-\u001f\u007f]/;
17015
17265
  function isPluginInvocation() {
17016
17266
  return !!process.env.VERITY_PLUGIN_ROOT;
17017
17267
  }
@@ -17020,11 +17270,11 @@ function markerPath() {
17020
17270
  }
17021
17271
  function readMarker() {
17022
17272
  try {
17023
- if (!(0, import_node_fs7.existsSync)(markerPath())) return null;
17024
- const raw = JSON.parse((0, import_node_fs7.readFileSync)(markerPath(), "utf-8"));
17273
+ if (!(0, import_node_fs8.existsSync)(markerPath())) return null;
17274
+ const raw = JSON.parse((0, import_node_fs8.readFileSync)(markerPath(), "utf-8"));
17025
17275
  const pluginRoot = typeof raw.plugin_root === "string" ? raw.plugin_root : "";
17026
- if (!pluginRoot || CONTROL_CHARS.test(pluginRoot)) return null;
17027
- const version = typeof raw.version === "string" && !CONTROL_CHARS.test(raw.version) ? raw.version : null;
17276
+ if (!pluginRoot || CONTROL_CHARS2.test(pluginRoot)) return null;
17277
+ const version = typeof raw.version === "string" && !CONTROL_CHARS2.test(raw.version) ? raw.version : null;
17028
17278
  return {
17029
17279
  session_id: typeof raw.session_id === "string" ? raw.session_id : null,
17030
17280
  plugin_root: pluginRoot,
@@ -17039,23 +17289,23 @@ function recordPluginOwnership(sessionId) {
17039
17289
  const pluginRoot = process.env.VERITY_PLUGIN_ROOT;
17040
17290
  if (!pluginRoot) return;
17041
17291
  try {
17042
- (0, import_node_fs7.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
17292
+ (0, import_node_fs8.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
17043
17293
  const marker = {
17044
17294
  session_id: sessionId,
17045
17295
  plugin_root: pluginRoot,
17046
17296
  version: process.env.VERITY_PLUGIN_VERSION || null,
17047
17297
  ts: Math.floor(Date.now() / 1e3)
17048
17298
  };
17049
- (0, import_node_fs7.writeFileSync)(markerPath(), JSON.stringify(marker));
17299
+ (0, import_node_fs8.writeFileSync)(markerPath(), JSON.stringify(marker));
17050
17300
  } catch {
17051
17301
  }
17052
17302
  }
17053
17303
  function claudeConfigDir() {
17054
- return process.env.CLAUDE_CONFIG_DIR || (0, import_node_path8.join)((0, import_node_os2.homedir)(), ".claude");
17304
+ return process.env.CLAUDE_CONFIG_DIR || (0, import_node_path9.join)((0, import_node_os2.homedir)(), ".claude");
17055
17305
  }
17056
17306
  function readJsonFile(path) {
17057
17307
  try {
17058
- const parsed = JSON.parse((0, import_node_fs7.readFileSync)(path, "utf-8"));
17308
+ const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path, "utf-8"));
17059
17309
  return parsed && typeof parsed === "object" ? parsed : null;
17060
17310
  } catch {
17061
17311
  return null;
@@ -17063,9 +17313,9 @@ function readJsonFile(path) {
17063
17313
  }
17064
17314
  function enabledPluginSetting(key) {
17065
17315
  const files = [
17066
- projectPath((0, import_node_path8.join)(".claude", "settings.local.json")),
17067
- projectPath((0, import_node_path8.join)(".claude", "settings.json")),
17068
- (0, import_node_path8.join)(claudeConfigDir(), "settings.json")
17316
+ projectPath((0, import_node_path9.join)(".claude", "settings.local.json")),
17317
+ projectPath((0, import_node_path9.join)(".claude", "settings.json")),
17318
+ (0, import_node_path9.join)(claudeConfigDir(), "settings.json")
17069
17319
  ];
17070
17320
  for (const file of files) {
17071
17321
  const map = readJsonFile(file)?.enabledPlugins;
@@ -17077,11 +17327,11 @@ function enabledPluginSetting(key) {
17077
17327
  }
17078
17328
  function marketplaceLocations() {
17079
17329
  const out2 = /* @__PURE__ */ new Map();
17080
- const known = readJsonFile((0, import_node_path8.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
17330
+ const known = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
17081
17331
  if (!known) return out2;
17082
17332
  for (const [name2, entry] of Object.entries(known)) {
17083
17333
  const loc2 = entry?.installLocation;
17084
- if (typeof loc2 === "string" && loc2) out2.set(name2, (0, import_node_path8.resolve)(loc2));
17334
+ if (typeof loc2 === "string" && loc2) out2.set(name2, (0, import_node_path9.resolve)(loc2));
17085
17335
  }
17086
17336
  return out2;
17087
17337
  }
@@ -17095,7 +17345,7 @@ function globalVerityVersion() {
17095
17345
  const entry = verityPathEntry();
17096
17346
  if (!entry) return null;
17097
17347
  try {
17098
- const pkg = readJsonFile((0, import_node_path8.join)((0, import_node_path8.dirname)((0, import_node_fs7.realpathSync)(entry)), "..", "package.json"));
17348
+ const pkg = readJsonFile((0, import_node_path9.join)((0, import_node_path9.dirname)((0, import_node_fs8.realpathSync)(entry)), "..", "package.json"));
17099
17349
  if (pkg?.name !== "@codacy/verity-cli" || typeof pkg.version !== "string") return null;
17100
17350
  return pkg.version;
17101
17351
  } catch {
@@ -17112,7 +17362,7 @@ var VERITY_MARKETPLACE_REPO = "codacy/verity";
17112
17362
  function marketplaceConflict() {
17113
17363
  const wanted = VERITY_MARKETPLACE;
17114
17364
  for (const file of ["settings.json", "settings.local.json"]) {
17115
- const path = (0, import_node_path8.join)(claudeConfigDir(), file);
17365
+ const path = (0, import_node_path9.join)(claudeConfigDir(), file);
17116
17366
  const declared = readJsonFile(path)?.extraKnownMarketplaces ?? null;
17117
17367
  const entry2 = declared && typeof declared === "object" ? declared[wanted] : void 0;
17118
17368
  if (entry2 && typeof entry2 === "object") {
@@ -17122,7 +17372,7 @@ function marketplaceConflict() {
17122
17372
  }
17123
17373
  }
17124
17374
  }
17125
- const known = readJsonFile((0, import_node_path8.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
17375
+ const known = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
17126
17376
  const entry = known?.[wanted];
17127
17377
  if (entry && typeof entry === "object" && !pointsAtVerity(entry.source)) {
17128
17378
  return { name: wanted, declaredAs: describeSource(entry.source) };
@@ -17143,7 +17393,7 @@ function describeSource(src) {
17143
17393
  return target ? `${kind} \u2192 ${target}` : kind;
17144
17394
  }
17145
17395
  function legacyMarketplaceInstall() {
17146
- const plugins = readJsonFile((0, import_node_path8.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17396
+ const plugins = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17147
17397
  if (!plugins || typeof plugins !== "object") return null;
17148
17398
  for (const key of Object.keys(plugins)) {
17149
17399
  const at = key.lastIndexOf("@");
@@ -17155,13 +17405,13 @@ function legacyMarketplaceInstall() {
17155
17405
  }
17156
17406
  function realpathOr(p) {
17157
17407
  try {
17158
- return import_node_fs7.realpathSync.native(p);
17408
+ return import_node_fs8.realpathSync.native(p);
17159
17409
  } catch {
17160
- return (0, import_node_path8.resolve)(p);
17410
+ return (0, import_node_path9.resolve)(p);
17161
17411
  }
17162
17412
  }
17163
17413
  function isWithin(want, dir) {
17164
- return want === dir || want.startsWith(dir + import_node_path8.sep);
17414
+ return want === dir || want.startsWith(dir + import_node_path9.sep);
17165
17415
  }
17166
17416
  function entryAppliesHere(entry, here) {
17167
17417
  const e = entry;
@@ -17171,9 +17421,9 @@ function entryAppliesHere(entry, here) {
17171
17421
  return forProject === here;
17172
17422
  }
17173
17423
  function registrySays(pluginRoot) {
17174
- const plugins = readJsonFile((0, import_node_path8.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17424
+ const plugins = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17175
17425
  if (!plugins || typeof plugins !== "object") return "unverified";
17176
- const want = (0, import_node_path8.resolve)(pluginRoot);
17426
+ const want = (0, import_node_path9.resolve)(pluginRoot);
17177
17427
  const here = realpathOr(repoRoot());
17178
17428
  const markets = marketplaceLocations();
17179
17429
  for (const [key, value] of Object.entries(plugins)) {
@@ -17182,15 +17432,15 @@ function registrySays(pluginRoot) {
17182
17432
  const applicable = (Array.isArray(value) ? value : []).filter((entry) => entryAppliesHere(entry, here));
17183
17433
  const claims = applicable.some((entry) => {
17184
17434
  const installPath = entry?.installPath;
17185
- return typeof installPath === "string" && (0, import_node_path8.resolve)(installPath) === want;
17435
+ return typeof installPath === "string" && (0, import_node_path9.resolve)(installPath) === want;
17186
17436
  }) || source2 !== void 0 && applicable.length > 0 && isWithin(want, source2);
17187
17437
  if (claims) {
17188
17438
  if (enabledPluginSetting(key) === false) return "gone";
17189
- return (0, import_node_fs7.existsSync)(pluginRoot) ? "live" : "gone";
17439
+ return (0, import_node_fs8.existsSync)(pluginRoot) ? "live" : "gone";
17190
17440
  }
17191
17441
  }
17192
- const managed = (0, import_node_path8.resolve)((0, import_node_path8.join)(claudeConfigDir(), "plugins", "cache"));
17193
- return want === managed || want.startsWith(managed + import_node_path8.sep) ? "gone" : "unverified";
17442
+ const managed = (0, import_node_path9.resolve)((0, import_node_path9.join)(claudeConfigDir(), "plugins", "cache"));
17443
+ return want === managed || want.startsWith(managed + import_node_path9.sep) ? "gone" : "unverified";
17194
17444
  }
17195
17445
  var _live = /* @__PURE__ */ new Map();
17196
17446
  function pluginLiveness(pluginRoot) {
@@ -17204,7 +17454,7 @@ function clearStalePluginMarker() {
17204
17454
  const marker = readMarker();
17205
17455
  if (!marker || pluginLiveness(marker.plugin_root) !== "gone") return null;
17206
17456
  try {
17207
- (0, import_node_fs7.rmSync)(markerPath(), { force: true });
17457
+ (0, import_node_fs8.rmSync)(markerPath(), { force: true });
17208
17458
  } catch {
17209
17459
  return null;
17210
17460
  }
@@ -17232,7 +17482,7 @@ function pluginActiveHere() {
17232
17482
  return activePluginInstall() !== null;
17233
17483
  }
17234
17484
  function registeredVerityPlugin() {
17235
- const plugins = readJsonFile((0, import_node_path8.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17485
+ const plugins = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17236
17486
  if (!plugins || typeof plugins !== "object") return null;
17237
17487
  const here = realpathOr(repoRoot());
17238
17488
  for (const [key, value] of Object.entries(plugins)) {
@@ -17242,7 +17492,7 @@ function registeredVerityPlugin() {
17242
17492
  for (const entry of Array.isArray(value) ? value : []) {
17243
17493
  const e = entry;
17244
17494
  const installPath = typeof e.installPath === "string" ? e.installPath : "";
17245
- if (!installPath || !(0, import_node_fs7.existsSync)(installPath)) continue;
17495
+ if (!installPath || !(0, import_node_fs8.existsSync)(installPath)) continue;
17246
17496
  if (!entryAppliesHere(entry, here)) continue;
17247
17497
  return { pluginRoot: installPath, version: typeof e.version === "string" ? e.version : null };
17248
17498
  }
@@ -17294,28 +17544,28 @@ async function resolveHookWiring() {
17294
17544
  }
17295
17545
 
17296
17546
  // src/lib/cli-provenance.ts
17297
- var import_node_fs8 = require("node:fs");
17547
+ var import_node_fs9 = require("node:fs");
17298
17548
  var import_node_os3 = require("node:os");
17299
- var import_node_path9 = require("node:path");
17549
+ var import_node_path10 = require("node:path");
17300
17550
  var CLI_PACKAGE = "@codacy/verity-cli";
17301
- var CLI_ENTRY = (0, import_node_path9.join)("node_modules", CLI_PACKAGE, "bin", "verity.js");
17551
+ var CLI_ENTRY = (0, import_node_path10.join)("node_modules", CLI_PACKAGE, "bin", "verity.js");
17302
17552
  function readJson(path) {
17303
17553
  try {
17304
- const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path, "utf-8"));
17554
+ const parsed = JSON.parse((0, import_node_fs9.readFileSync)(path, "utf-8"));
17305
17555
  return parsed && typeof parsed === "object" ? parsed : null;
17306
17556
  } catch {
17307
17557
  return null;
17308
17558
  }
17309
17559
  }
17310
17560
  function versionUnder(base) {
17311
- const entry = (0, import_node_path9.join)(base, CLI_ENTRY);
17312
- if (!(0, import_node_fs8.existsSync)(entry)) return null;
17313
- const pkg = readJson((0, import_node_path9.join)(base, "node_modules", CLI_PACKAGE, "package.json"));
17561
+ const entry = (0, import_node_path10.join)(base, CLI_ENTRY);
17562
+ if (!(0, import_node_fs9.existsSync)(entry)) return null;
17563
+ const pkg = readJson((0, import_node_path10.join)(base, "node_modules", CLI_PACKAGE, "package.json"));
17314
17564
  return typeof pkg?.version === "string" ? pkg.version : null;
17315
17565
  }
17316
17566
  function versionForEntry(entry) {
17317
17567
  try {
17318
- const pkg = readJson((0, import_node_path9.join)((0, import_node_path9.dirname)((0, import_node_fs8.realpathSync)(entry)), "..", "package.json"));
17568
+ const pkg = readJson((0, import_node_path10.join)((0, import_node_path10.dirname)((0, import_node_fs9.realpathSync)(entry)), "..", "package.json"));
17319
17569
  return typeof pkg?.version === "string" ? pkg.version : null;
17320
17570
  } catch {
17321
17571
  return null;
@@ -17323,16 +17573,16 @@ function versionForEntry(entry) {
17323
17573
  }
17324
17574
  function resolveHooksCli(pluginRoot) {
17325
17575
  const override = process.env.VERITY_CLI_PATH;
17326
- if (override && (0, import_node_fs8.existsSync)(override)) {
17576
+ if (override && (0, import_node_fs9.existsSync)(override)) {
17327
17577
  return { version: versionForEntry(override), rung: "override" };
17328
17578
  }
17329
17579
  const fromPlugin = versionUnder(pluginRoot);
17330
17580
  if (fromPlugin !== null) return { version: fromPlugin, rung: "plugin" };
17331
- if ((0, import_node_fs8.existsSync)((0, import_node_path9.join)(pluginRoot, CLI_ENTRY))) return { version: null, rung: "plugin" };
17332
- const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".verity", "plugin-cli");
17581
+ if ((0, import_node_fs9.existsSync)((0, import_node_path10.join)(pluginRoot, CLI_ENTRY))) return { version: null, rung: "plugin" };
17582
+ const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0, import_node_path10.join)((0, import_node_os3.homedir)(), ".verity", "plugin-cli");
17333
17583
  const fromData = versionUnder(dataDir);
17334
17584
  if (fromData !== null) return { version: fromData, rung: "plugin-data" };
17335
- if ((0, import_node_fs8.existsSync)((0, import_node_path9.join)(dataDir, CLI_ENTRY))) return { version: null, rung: "plugin-data" };
17585
+ if ((0, import_node_fs9.existsSync)((0, import_node_path10.join)(dataDir, CLI_ENTRY))) return { version: null, rung: "plugin-data" };
17336
17586
  const global = globalVerityVersion();
17337
17587
  if (global !== null) return { version: global, rung: "global" };
17338
17588
  return null;
@@ -17434,7 +17684,7 @@ function pluginCliInvocation() {
17434
17684
  return resolverCommand(root);
17435
17685
  }
17436
17686
  function resolverCommand(root) {
17437
- return `node ${JSON.stringify((0, import_node_path9.join)(root, "scripts", "verity.mjs"))}`;
17687
+ return `node ${JSON.stringify((0, import_node_path10.join)(root, "scripts", "verity.mjs"))}`;
17438
17688
  }
17439
17689
 
17440
17690
  // src/commands/hooks.ts
@@ -17574,7 +17824,7 @@ var import_node_crypto9 = require("node:crypto");
17574
17824
 
17575
17825
  // src/lib/conversation-buffer.ts
17576
17826
  var import_promises5 = require("node:fs/promises");
17577
- var import_node_fs9 = require("node:fs");
17827
+ var import_node_fs10 = require("node:fs");
17578
17828
  var import_node_child_process5 = require("node:child_process");
17579
17829
  var import_node_crypto = require("node:crypto");
17580
17830
  function stripImageReferences(text) {
@@ -17610,7 +17860,7 @@ async function appendToConversationBuffer(prompt, sessionId) {
17610
17860
  }
17611
17861
  async function readAndClearConversationBuffer(currentSessionId) {
17612
17862
  try {
17613
- if ((0, import_node_fs9.existsSync)(CONVERSATION_BUFFER_FILE)) {
17863
+ if ((0, import_node_fs10.existsSync)(CONVERSATION_BUFFER_FILE)) {
17614
17864
  const entries = await readBufferEntries();
17615
17865
  let mine = entries;
17616
17866
  let others = [];
@@ -17634,7 +17884,7 @@ async function readAndClearConversationBuffer(currentSessionId) {
17634
17884
  };
17635
17885
  }
17636
17886
  }
17637
- if ((0, import_node_fs9.existsSync)(INTENT_FILE)) {
17887
+ if ((0, import_node_fs10.existsSync)(INTENT_FILE)) {
17638
17888
  try {
17639
17889
  const content = await (0, import_promises5.readFile)(INTENT_FILE, "utf-8");
17640
17890
  await (0, import_promises5.unlink)(INTENT_FILE).catch(() => {
@@ -17927,9 +18177,9 @@ function isCommandOnlyTurn(input) {
17927
18177
 
17928
18178
  // src/lib/context-identity.ts
17929
18179
  var import_node_crypto2 = require("node:crypto");
17930
- var import_node_fs10 = require("node:fs");
18180
+ var import_node_fs11 = require("node:fs");
17931
18181
  var import_node_os4 = require("node:os");
17932
- var import_node_path10 = require("node:path");
18182
+ var import_node_path11 = require("node:path");
17933
18183
  var SHARED_SENTINELS = /* @__PURE__ */ new Set([
17934
18184
  "",
17935
18185
  "-",
@@ -17967,7 +18217,7 @@ function contextIdentity(input) {
17967
18217
  if (rawTree && !isSharedSentinel(rawTree)) {
17968
18218
  let resolved = rawTree;
17969
18219
  try {
17970
- resolved = import_node_fs10.realpathSync.native(rawTree);
18220
+ resolved = import_node_fs11.realpathSync.native(rawTree);
17971
18221
  } catch {
17972
18222
  }
17973
18223
  treeKey = (0, import_node_crypto2.createHash)("sha256").update(resolved).digest("hex").slice(0, 12);
@@ -17983,13 +18233,13 @@ function contextIdentity(input) {
17983
18233
  }
17984
18234
  function verityHome() {
17985
18235
  const override = process.env.VERITY_HOME;
17986
- return override && override.trim() ? (0, import_node_path10.resolve)(override) : (0, import_node_path10.join)((0, import_node_os4.homedir)(), ".verity");
18236
+ return override && override.trim() ? (0, import_node_path11.resolve)(override) : (0, import_node_path11.join)((0, import_node_os4.homedir)(), ".verity");
17987
18237
  }
17988
18238
  function dossierDir(identity) {
17989
- return (0, import_node_path10.join)(verityHome(), "sessions", identity.userKey, identity.treeKey, identity.sessionKey);
18239
+ return (0, import_node_path11.join)(verityHome(), "sessions", identity.userKey, identity.treeKey, identity.sessionKey);
17990
18240
  }
17991
18241
  function treeDir(identity) {
17992
- return (0, import_node_path10.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
18242
+ return (0, import_node_path11.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
17993
18243
  }
17994
18244
  function scopeIdentity(token, sessionId) {
17995
18245
  const t = (token ?? "").trim();
@@ -18004,8 +18254,8 @@ function sessionScopeKey(token, sessionId) {
18004
18254
 
18005
18255
  // src/lib/task-context-buffer.ts
18006
18256
  var import_promises6 = require("node:fs/promises");
18007
- var import_node_fs11 = require("node:fs");
18008
- var import_node_path11 = require("node:path");
18257
+ var import_node_fs12 = require("node:fs");
18258
+ var import_node_path12 = require("node:path");
18009
18259
  var TASK_CONTEXT_DIR = `${VERITY_DIR}/.task-context`;
18010
18260
  var MAX_BUFFER_BYTES = 500 * 1024;
18011
18261
  var MAX_PROMPT_CHARS = 2e3;
@@ -18044,7 +18294,7 @@ async function appendResponseToTaskBuffer(taskId, assistantResponse, actionSumma
18044
18294
  }
18045
18295
  async function readTaskContextBuffer(taskId) {
18046
18296
  const filePath = bufferPath(taskId);
18047
- if (!(0, import_node_fs11.existsSync)(filePath)) return null;
18297
+ if (!(0, import_node_fs12.existsSync)(filePath)) return null;
18048
18298
  try {
18049
18299
  const content = await (0, import_promises6.readFile)(filePath, "utf-8");
18050
18300
  if (!content.trim()) return null;
@@ -18078,12 +18328,12 @@ async function readTaskContextBuffer(taskId) {
18078
18328
  }
18079
18329
  async function cleanupTaskContextBuffers() {
18080
18330
  try {
18081
- if (!(0, import_node_fs11.existsSync)(TASK_CONTEXT_DIR)) return;
18331
+ if (!(0, import_node_fs12.existsSync)(TASK_CONTEXT_DIR)) return;
18082
18332
  const files = await (0, import_promises6.readdir)(TASK_CONTEXT_DIR);
18083
18333
  const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1e3;
18084
18334
  for (const file of files) {
18085
18335
  if (!file.endsWith(".jsonl")) continue;
18086
- const filePath = (0, import_node_path11.join)(TASK_CONTEXT_DIR, file);
18336
+ const filePath = (0, import_node_path12.join)(TASK_CONTEXT_DIR, file);
18087
18337
  try {
18088
18338
  const stats = await (0, import_promises6.stat)(filePath);
18089
18339
  if (stats.mtimeMs < cutoffMs) {
@@ -18097,13 +18347,13 @@ async function cleanupTaskContextBuffers() {
18097
18347
  }
18098
18348
  function bufferPath(taskId) {
18099
18349
  const safe = taskId.replace(/[^a-zA-Z0-9_-]/g, "");
18100
- return (0, import_node_path11.join)(TASK_CONTEXT_DIR, `${safe}.jsonl`);
18350
+ return (0, import_node_path12.join)(TASK_CONTEXT_DIR, `${safe}.jsonl`);
18101
18351
  }
18102
18352
  async function appendEntry(taskId, entry) {
18103
18353
  try {
18104
18354
  await (0, import_promises6.mkdir)(TASK_CONTEXT_DIR, { recursive: true });
18105
18355
  const filePath = bufferPath(taskId);
18106
- if ((0, import_node_fs11.existsSync)(filePath)) {
18356
+ if ((0, import_node_fs12.existsSync)(filePath)) {
18107
18357
  const stats = await (0, import_promises6.stat)(filePath);
18108
18358
  if (stats.size >= MAX_BUFFER_BYTES) {
18109
18359
  const content = await (0, import_promises6.readFile)(filePath, "utf-8");
@@ -18114,7 +18364,7 @@ async function appendEntry(taskId, entry) {
18114
18364
  }
18115
18365
  }
18116
18366
  const line2 = JSON.stringify(entry) + "\n";
18117
- const existing = (0, import_node_fs11.existsSync)(filePath) ? await (0, import_promises6.readFile)(filePath, "utf-8") : "";
18367
+ const existing = (0, import_node_fs12.existsSync)(filePath) ? await (0, import_promises6.readFile)(filePath, "utf-8") : "";
18118
18368
  await (0, import_promises6.writeFile)(filePath, existing + line2);
18119
18369
  } catch {
18120
18370
  }
@@ -18122,20 +18372,20 @@ async function appendEntry(taskId, entry) {
18122
18372
 
18123
18373
  // src/lib/memory-retrieval.ts
18124
18374
  var import_promises8 = require("node:fs/promises");
18125
- var import_node_fs14 = require("node:fs");
18126
- var import_node_path14 = require("node:path");
18375
+ var import_node_fs15 = require("node:fs");
18376
+ var import_node_path15 = require("node:path");
18127
18377
 
18128
18378
  // src/lib/org-mirror.ts
18129
- var import_node_fs12 = require("node:fs");
18379
+ var import_node_fs13 = require("node:fs");
18130
18380
  var import_promises7 = require("node:fs/promises");
18131
- var import_node_path12 = require("node:path");
18381
+ var import_node_path13 = require("node:path");
18132
18382
  var ORG_KINDS = ["decision", "security", "gotcha", "pattern", "domain", "integration"];
18133
18383
  var STATE_FILE = ".org-pull-state.json";
18134
18384
  var BODY_MAX = 8192;
18135
18385
  function orgMirrorDir(remote = requestRemote()) {
18136
18386
  const parsed = parseRemote(remote);
18137
18387
  if (!parsed) return null;
18138
- return (0, import_node_path12.join)(verityHome(), "orgs", parsed.host, parsed.owner.toLowerCase(), "memory");
18388
+ return (0, import_node_path13.join)(verityHome(), "orgs", parsed.host, parsed.owner.toLowerCase(), "memory");
18139
18389
  }
18140
18390
  function slugify(s) {
18141
18391
  return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
@@ -18201,7 +18451,7 @@ function parseOrgNode(content) {
18201
18451
  }
18202
18452
  async function readState(dir) {
18203
18453
  try {
18204
- const parsed = JSON.parse(await (0, import_promises7.readFile)((0, import_node_path12.join)(dir, STATE_FILE), "utf-8"));
18454
+ const parsed = JSON.parse(await (0, import_promises7.readFile)((0, import_node_path13.join)(dir, STATE_FILE), "utf-8"));
18205
18455
  return {
18206
18456
  version: typeof parsed?.version === "string" ? parsed.version : null,
18207
18457
  organization: parsed?.organization && typeof parsed.organization.id === "string" ? parsed.organization : null,
@@ -18213,7 +18463,7 @@ async function readState(dir) {
18213
18463
  }
18214
18464
  async function writeState(dir, state) {
18215
18465
  await (0, import_promises7.mkdir)(dir, { recursive: true });
18216
- await (0, import_promises7.writeFile)((0, import_node_path12.join)(dir, STATE_FILE), JSON.stringify({
18466
+ await (0, import_promises7.writeFile)((0, import_node_path13.join)(dir, STATE_FILE), JSON.stringify({
18217
18467
  ...state.version ? { version: state.version } : {},
18218
18468
  organization: state.organization,
18219
18469
  pulled_at: (/* @__PURE__ */ new Date()).toISOString(),
@@ -18278,24 +18528,24 @@ async function pullOrgKnowledge(opts) {
18278
18528
  for (const n of nodes) {
18279
18529
  const rel = orgNodePath(n);
18280
18530
  if (written.has(rel)) continue;
18281
- await (0, import_promises7.mkdir)((0, import_node_path12.join)(dir, rel.split("/")[0]), { recursive: true });
18282
- await (0, import_promises7.writeFile)((0, import_node_path12.join)(dir, rel), renderOrgNode(n, org?.name ?? ""));
18531
+ await (0, import_promises7.mkdir)((0, import_node_path13.join)(dir, rel.split("/")[0]), { recursive: true });
18532
+ await (0, import_promises7.writeFile)((0, import_node_path13.join)(dir, rel), renderOrgNode(n, org?.name ?? ""));
18283
18533
  written.add(rel);
18284
18534
  }
18285
18535
  for (const rel of state.files) {
18286
- if (!written.has(rel)) await (0, import_promises7.rm)((0, import_node_path12.join)(dir, rel), { force: true });
18536
+ if (!written.has(rel)) await (0, import_promises7.rm)((0, import_node_path13.join)(dir, rel), { force: true });
18287
18537
  }
18288
- await (0, import_promises7.writeFile)((0, import_node_path12.join)(dir, "index.md"), renderIndex(org?.name ?? "no organization", nodes));
18538
+ await (0, import_promises7.writeFile)((0, import_node_path13.join)(dir, "index.md"), renderIndex(org?.name ?? "no organization", nodes));
18289
18539
  await writeState(dir, { version: org ? page.version : null, organization: org, files: [...written].sort() });
18290
18540
  return { ok: true, status: org ? "pulled" : "none", received: nodes.length, dir };
18291
18541
  }
18292
18542
  async function readOrgMirror(remote = requestRemote()) {
18293
18543
  const dir = orgMirrorDir(remote);
18294
- if (!dir || !(0, import_node_fs12.existsSync)(dir)) return [];
18544
+ if (!dir || !(0, import_node_fs13.existsSync)(dir)) return [];
18295
18545
  const out2 = [];
18296
18546
  for (const kind of ORG_KINDS) {
18297
- const kindDir = (0, import_node_path12.join)(dir, kind);
18298
- if (!(0, import_node_fs12.existsSync)(kindDir)) continue;
18547
+ const kindDir = (0, import_node_path13.join)(dir, kind);
18548
+ if (!(0, import_node_fs13.existsSync)(kindDir)) continue;
18299
18549
  let files;
18300
18550
  try {
18301
18551
  files = await (0, import_promises7.readdir)(kindDir);
@@ -18305,7 +18555,7 @@ async function readOrgMirror(remote = requestRemote()) {
18305
18555
  for (const file of files) {
18306
18556
  if (!file.endsWith(".md")) continue;
18307
18557
  try {
18308
- const node = parseOrgNode(await (0, import_promises7.readFile)((0, import_node_path12.join)(kindDir, file), "utf-8"));
18558
+ const node = parseOrgNode(await (0, import_promises7.readFile)((0, import_node_path13.join)(kindDir, file), "utf-8"));
18309
18559
  if (node) out2.push(node);
18310
18560
  } catch {
18311
18561
  }
@@ -18315,29 +18565,29 @@ async function readOrgMirror(remote = requestRemote()) {
18315
18565
  }
18316
18566
 
18317
18567
  // src/lib/safe-read.ts
18318
- var import_node_fs13 = require("node:fs");
18319
- var import_node_path13 = require("node:path");
18320
- var FLAGS = import_node_fs13.constants;
18568
+ var import_node_fs14 = require("node:fs");
18569
+ var import_node_path14 = require("node:path");
18570
+ var FLAGS = import_node_fs14.constants;
18321
18571
  var NOFOLLOW = FLAGS.O_NOFOLLOW;
18322
18572
  var NONBLOCK = FLAGS.O_NONBLOCK;
18323
18573
  function closeOpened(fd) {
18324
18574
  try {
18325
- (0, import_node_fs13.closeSync)(fd);
18575
+ (0, import_node_fs14.closeSync)(fd);
18326
18576
  } catch {
18327
18577
  }
18328
18578
  }
18329
18579
  function isInsideRoot(realRoot, realPath) {
18330
- return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path13.sep) ? realRoot : realRoot + import_node_path13.sep);
18580
+ return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path14.sep) ? realRoot : realRoot + import_node_path14.sep);
18331
18581
  }
18332
18582
  function sameOpenedFile(opened, current, nofollowAvailable) {
18333
18583
  if (!nofollowAvailable && (opened.ino === 0n || current.ino === 0n)) return false;
18334
18584
  return opened.ino === current.ino && opened.dev === current.dev;
18335
18585
  }
18336
18586
  function openRegularInRoot(root, path) {
18337
- const full = (0, import_node_path13.isAbsolute)(path) ? path : (0, import_node_path13.join)(root, path);
18587
+ const full = (0, import_node_path14.isAbsolute)(path) ? path : (0, import_node_path14.join)(root, path);
18338
18588
  let fd;
18339
18589
  try {
18340
- fd = (0, import_node_fs13.openSync)(full, import_node_fs13.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
18590
+ fd = (0, import_node_fs14.openSync)(full, import_node_fs14.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
18341
18591
  } catch (err2) {
18342
18592
  const code = err2.code;
18343
18593
  if (code === "ELOOP" || code === "EMLINK" || code === "EFTYPE") return { ok: false, reason: "symlink" };
@@ -18345,18 +18595,18 @@ function openRegularInRoot(root, path) {
18345
18595
  return { ok: false, reason: "unreadable" };
18346
18596
  }
18347
18597
  try {
18348
- const opened = (0, import_node_fs13.fstatSync)(fd, { bigint: true });
18598
+ const opened = (0, import_node_fs14.fstatSync)(fd, { bigint: true });
18349
18599
  if (!opened.isFile()) {
18350
18600
  closeOpened(fd);
18351
18601
  return { ok: false, reason: "not-regular" };
18352
18602
  }
18353
- const realRoot = import_node_fs13.realpathSync.native(root);
18354
- const realPath = import_node_fs13.realpathSync.native(full);
18603
+ const realRoot = import_node_fs14.realpathSync.native(root);
18604
+ const realPath = import_node_fs14.realpathSync.native(full);
18355
18605
  if (!isInsideRoot(realRoot, realPath)) {
18356
18606
  closeOpened(fd);
18357
18607
  return { ok: false, reason: "outside-root" };
18358
18608
  }
18359
- const current = (0, import_node_fs13.statSync)(realPath, { bigint: true });
18609
+ const current = (0, import_node_fs14.statSync)(realPath, { bigint: true });
18360
18610
  if (!sameOpenedFile(opened, current, NOFOLLOW !== void 0)) {
18361
18611
  closeOpened(fd);
18362
18612
  return { ok: false, reason: NOFOLLOW === void 0 ? "unreadable" : "outside-root" };
@@ -18378,7 +18628,7 @@ function readOpened(fd, size) {
18378
18628
  const buffer = Buffer.alloc(size);
18379
18629
  let offset = 0;
18380
18630
  while (offset < size) {
18381
- const n = (0, import_node_fs13.readSync)(fd, buffer, offset, size - offset, offset);
18631
+ const n = (0, import_node_fs14.readSync)(fd, buffer, offset, size - offset, offset);
18382
18632
  if (n === 0) break;
18383
18633
  offset += n;
18384
18634
  }
@@ -18693,14 +18943,14 @@ function parseFrontmatter(content) {
18693
18943
  return { fm, body: match[2].trim() };
18694
18944
  }
18695
18945
  async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = DEFAULT_BUDGET_TOKENS) {
18696
- const hasRepoGraph = (0, import_node_fs14.existsSync)(memoryDir());
18946
+ const hasRepoGraph = (0, import_node_fs15.existsSync)(memoryDir());
18697
18947
  const budget = Math.min(budgetTokens, MAX_BUDGET_TOKENS);
18698
18948
  const promptTokens = tokenize(promptText);
18699
18949
  const orgPromptTerms = orgTerms(promptText);
18700
18950
  const nodes = [];
18701
18951
  for (const domain of hasRepoGraph ? DOMAINS : []) {
18702
- const domainDir = (0, import_node_path14.join)(memoryDir(), domain);
18703
- if (!(0, import_node_fs14.existsSync)(domainDir)) continue;
18952
+ const domainDir = (0, import_node_path15.join)(memoryDir(), domain);
18953
+ if (!(0, import_node_fs15.existsSync)(domainDir)) continue;
18704
18954
  try {
18705
18955
  const files = await (0, import_promises8.readdir)(domainDir);
18706
18956
  for (const file of files) {
@@ -18774,27 +19024,27 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
18774
19024
  }
18775
19025
 
18776
19026
  // src/lib/injection-record.ts
18777
- var import_node_fs16 = require("node:fs");
19027
+ var import_node_fs17 = require("node:fs");
18778
19028
  var import_node_crypto3 = require("node:crypto");
18779
19029
 
18780
19030
  // src/lib/safe-write.ts
18781
- var import_node_fs15 = require("node:fs");
18782
- var import_node_path15 = require("node:path");
18783
- var FLAGS2 = import_node_fs15.constants;
19031
+ var import_node_fs16 = require("node:fs");
19032
+ var import_node_path16 = require("node:path");
19033
+ var FLAGS2 = import_node_fs16.constants;
18784
19034
  var O_NOFOLLOW = FLAGS2.O_NOFOLLOW ?? 0;
18785
19035
  var NOFOLLOW_AVAILABLE = O_NOFOLLOW !== 0;
18786
19036
  function validateRoot(root) {
18787
19037
  try {
18788
- const parentReal = (0, import_node_fs15.realpathSync)((0, import_node_path15.dirname)(root));
18789
- const expected = (0, import_node_path15.join)(parentReal, (0, import_node_path15.basename)(root));
19038
+ const parentReal = (0, import_node_fs16.realpathSync)((0, import_node_path16.dirname)(root));
19039
+ const expected = (0, import_node_path16.join)(parentReal, (0, import_node_path16.basename)(root));
18790
19040
  try {
18791
- (0, import_node_fs15.mkdirSync)(expected);
19041
+ (0, import_node_fs16.mkdirSync)(expected);
18792
19042
  } catch (e) {
18793
19043
  if (e.code !== "EEXIST") return null;
18794
19044
  }
18795
- const st = (0, import_node_fs15.lstatSync)(expected, { bigint: true });
19045
+ const st = (0, import_node_fs16.lstatSync)(expected, { bigint: true });
18796
19046
  if (st.isSymbolicLink() || !st.isDirectory()) return null;
18797
- if ((0, import_node_fs15.realpathSync)(expected) !== expected) return null;
19047
+ if ((0, import_node_fs16.realpathSync)(expected) !== expected) return null;
18798
19048
  return { real: expected, dev: st.dev, ino: st.ino };
18799
19049
  } catch {
18800
19050
  return null;
@@ -18802,18 +19052,18 @@ function validateRoot(root) {
18802
19052
  }
18803
19053
  function rootUnchanged(root) {
18804
19054
  try {
18805
- const st = (0, import_node_fs15.lstatSync)(root.real, { bigint: true });
19055
+ const st = (0, import_node_fs16.lstatSync)(root.real, { bigint: true });
18806
19056
  return !st.isSymbolicLink() && st.isDirectory() && st.dev === root.dev && st.ino === root.ino;
18807
19057
  } catch {
18808
19058
  return false;
18809
19059
  }
18810
19060
  }
18811
19061
  function bareName(name2) {
18812
- return !!name2 && name2 === (0, import_node_path15.basename)(name2) && name2 !== "." && name2 !== ".." && !name2.includes("\0");
19062
+ return !!name2 && name2 === (0, import_node_path16.basename)(name2) && name2 !== "." && name2 !== ".." && !name2.includes("\0");
18813
19063
  }
18814
19064
  function absentOrRegular(path) {
18815
19065
  try {
18816
- const st = (0, import_node_fs15.lstatSync)(path);
19066
+ const st = (0, import_node_fs16.lstatSync)(path);
18817
19067
  return st.isFile() && !st.isSymbolicLink();
18818
19068
  } catch (e) {
18819
19069
  return e.code === "ENOENT";
@@ -18821,11 +19071,11 @@ function absentOrRegular(path) {
18821
19071
  }
18822
19072
  function verifyOpened(fd, path, root) {
18823
19073
  try {
18824
- const opened = (0, import_node_fs15.fstatSync)(fd, { bigint: true });
19074
+ const opened = (0, import_node_fs16.fstatSync)(fd, { bigint: true });
18825
19075
  if (!opened.isFile() || opened.nlink !== 1n) return false;
18826
- const real = (0, import_node_fs15.realpathSync)(path);
19076
+ const real = (0, import_node_fs16.realpathSync)(path);
18827
19077
  if (!isInsideRoot(root.real, real)) return false;
18828
- const current = (0, import_node_fs15.statSync)(real, { bigint: true });
19078
+ const current = (0, import_node_fs16.statSync)(real, { bigint: true });
18829
19079
  if (!sameOpenedFile(opened, current, NOFOLLOW_AVAILABLE)) return false;
18830
19080
  return rootUnchanged(root);
18831
19081
  } catch {
@@ -18834,21 +19084,21 @@ function verifyOpened(fd, path, root) {
18834
19084
  }
18835
19085
  function removeIfOurs(fd, path) {
18836
19086
  try {
18837
- const opened = (0, import_node_fs15.fstatSync)(fd, { bigint: true });
18838
- const at = (0, import_node_fs15.lstatSync)(path, { bigint: true });
18839
- if (!at.isSymbolicLink() && at.dev === opened.dev && at.ino === opened.ino) (0, import_node_fs15.unlinkSync)(path);
19087
+ const opened = (0, import_node_fs16.fstatSync)(fd, { bigint: true });
19088
+ const at = (0, import_node_fs16.lstatSync)(path, { bigint: true });
19089
+ if (!at.isSymbolicLink() && at.dev === opened.dev && at.ino === opened.ino) (0, import_node_fs16.unlinkSync)(path);
18840
19090
  } catch {
18841
19091
  }
18842
19092
  }
18843
19093
  function openTarget(path, append2) {
18844
- const base = import_node_fs15.constants.O_WRONLY | (append2 ? import_node_fs15.constants.O_APPEND : 0) | O_NOFOLLOW;
19094
+ const base = import_node_fs16.constants.O_WRONLY | (append2 ? import_node_fs16.constants.O_APPEND : 0) | O_NOFOLLOW;
18845
19095
  try {
18846
- return { fd: (0, import_node_fs15.openSync)(path, base), created: false };
19096
+ return { fd: (0, import_node_fs16.openSync)(path, base), created: false };
18847
19097
  } catch (e) {
18848
19098
  if (e.code !== "ENOENT") return null;
18849
19099
  }
18850
19100
  try {
18851
- return { fd: (0, import_node_fs15.openSync)(path, base | import_node_fs15.constants.O_CREAT | import_node_fs15.constants.O_EXCL, 384), created: true };
19101
+ return { fd: (0, import_node_fs16.openSync)(path, base | import_node_fs16.constants.O_CREAT | import_node_fs16.constants.O_EXCL, 384), created: true };
18852
19102
  } catch {
18853
19103
  return null;
18854
19104
  }
@@ -18856,7 +19106,7 @@ function openTarget(path, append2) {
18856
19106
  function writeVerified(root, name2, hooks, append2, write) {
18857
19107
  const r = validateRoot(root);
18858
19108
  if (!r || !bareName(name2)) return false;
18859
- const path = (0, import_node_path15.join)(r.real, name2);
19109
+ const path = (0, import_node_path16.join)(r.real, name2);
18860
19110
  if (!absentOrRegular(path)) return false;
18861
19111
  if (!runHook(hooks)) return false;
18862
19112
  const opened = openTarget(path, append2);
@@ -18872,7 +19122,7 @@ function writeVerified(root, name2, hooks, append2, write) {
18872
19122
  return false;
18873
19123
  } finally {
18874
19124
  try {
18875
- (0, import_node_fs15.closeSync)(opened.fd);
19125
+ (0, import_node_fs16.closeSync)(opened.fd);
18876
19126
  } catch {
18877
19127
  }
18878
19128
  }
@@ -18887,13 +19137,13 @@ function runHook(hooks) {
18887
19137
  }
18888
19138
  function appendInRoot(root, name2, text, hooks = {}) {
18889
19139
  return writeVerified(root, name2, hooks, true, (fd) => {
18890
- (0, import_node_fs15.writeSync)(fd, text);
19140
+ (0, import_node_fs16.writeSync)(fd, text);
18891
19141
  });
18892
19142
  }
18893
19143
  function replaceInRoot(root, name2, text, hooks = {}) {
18894
19144
  return writeVerified(root, name2, hooks, false, (fd) => {
18895
- (0, import_node_fs15.ftruncateSync)(fd, 0);
18896
- (0, import_node_fs15.writeSync)(fd, text, 0);
19145
+ (0, import_node_fs16.ftruncateSync)(fd, 0);
19146
+ (0, import_node_fs16.writeSync)(fd, text, 0);
18897
19147
  });
18898
19148
  }
18899
19149
 
@@ -18941,7 +19191,7 @@ function hashPrompt(prompt) {
18941
19191
  function recordInjection(event) {
18942
19192
  if (!appendInRoot(projectPath(VERITY_DIR), "injections.jsonl", JSON.stringify(event) + "\n")) return;
18943
19193
  try {
18944
- if ((0, import_node_fs16.lstatSync)(recordPath()).size > COMPACT_AT_BYTES) writeEvents(readPendingInjections());
19194
+ if ((0, import_node_fs17.lstatSync)(recordPath()).size > COMPACT_AT_BYTES) writeEvents(readPendingInjections());
18945
19195
  } catch {
18946
19196
  }
18947
19197
  }
@@ -18951,7 +19201,7 @@ function writeEvents(events) {
18951
19201
  function readPendingInjections() {
18952
19202
  try {
18953
19203
  const p = recordPath();
18954
- if (!(0, import_node_fs16.existsSync)(p)) return [];
19204
+ if (!(0, import_node_fs17.existsSync)(p)) return [];
18955
19205
  const read2 = readRegularFileInRoot(projectPath(VERITY_DIR), "injections.jsonl", MAX_RECORD_BYTES);
18956
19206
  if (!read2.ok) return [];
18957
19207
  const out2 = [];
@@ -18971,13 +19221,13 @@ function readPendingInjections() {
18971
19221
 
18972
19222
  // src/lib/memory-sync.ts
18973
19223
  var import_promises9 = require("node:fs/promises");
18974
- var import_node_fs19 = require("node:fs");
18975
- var import_node_path17 = require("node:path");
19224
+ var import_node_fs20 = require("node:fs");
19225
+ var import_node_path18 = require("node:path");
18976
19226
  var import_node_crypto4 = require("node:crypto");
18977
19227
 
18978
19228
  // src/lib/gitignore.ts
18979
19229
  var import_node_child_process6 = require("node:child_process");
18980
- var import_node_fs17 = require("node:fs");
19230
+ var import_node_fs18 = require("node:fs");
18981
19231
  var VERITY_GITIGNORE_MARKER = "# Verity \u2014 machine-local state.";
18982
19232
  var SETTINGS_LOCAL_IGNORE_ENTRY = ".claude/settings.local.json";
18983
19233
  var VERITY_GITIGNORE_BLOCK = [
@@ -19061,7 +19311,7 @@ function fenceMemoryLines(lines) {
19061
19311
  function ensureVerityGitignore() {
19062
19312
  let content = "";
19063
19313
  try {
19064
- content = (0, import_node_fs17.readFileSync)(".gitignore", "utf-8");
19314
+ content = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
19065
19315
  } catch {
19066
19316
  }
19067
19317
  const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
@@ -19088,7 +19338,7 @@ function ensureVerityGitignore() {
19088
19338
  const sep5 = text === "" ? "" : text.endsWith("\n") ? "\n" : "\n\n";
19089
19339
  text = text + sep5 + VERITY_GITIGNORE_BLOCK;
19090
19340
  }
19091
- if (text !== content) (0, import_node_fs17.writeFileSync)(".gitignore", text);
19341
+ if (text !== content) (0, import_node_fs18.writeFileSync)(".gitignore", text);
19092
19342
  return verified(
19093
19343
  memoryIsCommitted ? "memory-tracked" : hasSupersededMemory ? "memory-fenced" : needsRepair ? "repaired" : "added"
19094
19344
  );
@@ -19108,7 +19358,7 @@ function untrackMemory() {
19108
19358
  function writeFencedBlock() {
19109
19359
  let content = "";
19110
19360
  try {
19111
- content = (0, import_node_fs17.readFileSync)(".gitignore", "utf-8");
19361
+ content = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
19112
19362
  } catch {
19113
19363
  }
19114
19364
  const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
@@ -19120,7 +19370,7 @@ function writeFencedBlock() {
19120
19370
  text = text + sep5 + VERITY_GITIGNORE_BLOCK;
19121
19371
  }
19122
19372
  try {
19123
- (0, import_node_fs17.writeFileSync)(".gitignore", text);
19373
+ (0, import_node_fs18.writeFileSync)(".gitignore", text);
19124
19374
  return true;
19125
19375
  } catch {
19126
19376
  return false;
@@ -19129,14 +19379,14 @@ function writeFencedBlock() {
19129
19379
  function fenceMemory() {
19130
19380
  let original = null;
19131
19381
  try {
19132
- original = (0, import_node_fs17.readFileSync)(".gitignore", "utf-8");
19382
+ original = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
19133
19383
  } catch {
19134
19384
  original = null;
19135
19385
  }
19136
19386
  const restore = () => {
19137
19387
  try {
19138
- if (original === null) (0, import_node_fs17.rmSync)(".gitignore", { force: true });
19139
- else (0, import_node_fs17.writeFileSync)(".gitignore", original);
19388
+ if (original === null) (0, import_node_fs18.rmSync)(".gitignore", { force: true });
19389
+ else (0, import_node_fs18.writeFileSync)(".gitignore", original);
19140
19390
  } catch {
19141
19391
  }
19142
19392
  };
@@ -19154,7 +19404,7 @@ function fenceMemory() {
19154
19404
  }
19155
19405
  function memoryOptOut() {
19156
19406
  try {
19157
- return (0, import_node_fs17.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
19407
+ return (0, import_node_fs18.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
19158
19408
  } catch {
19159
19409
  return false;
19160
19410
  }
@@ -19162,13 +19412,13 @@ function memoryOptOut() {
19162
19412
  function keepMemoryTracked() {
19163
19413
  let content = "";
19164
19414
  try {
19165
- content = (0, import_node_fs17.readFileSync)(".gitignore", "utf-8");
19415
+ content = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
19166
19416
  } catch {
19167
19417
  }
19168
19418
  if (content.includes(MEMORY_OPT_OUT_MARKER)) return "already";
19169
19419
  try {
19170
19420
  const sep5 = content === "" ? "" : content.endsWith("\n") ? "\n" : "\n\n";
19171
- (0, import_node_fs17.writeFileSync)(".gitignore", content + sep5 + MEMORY_OPT_OUT_STANZA);
19421
+ (0, import_node_fs18.writeFileSync)(".gitignore", content + sep5 + MEMORY_OPT_OUT_STANZA);
19172
19422
  } catch {
19173
19423
  return "failed";
19174
19424
  }
@@ -19203,26 +19453,26 @@ function untrackVerityState() {
19203
19453
  }
19204
19454
 
19205
19455
  // src/lib/safe-path.ts
19206
- var import_node_fs18 = require("node:fs");
19207
- var import_node_path16 = require("node:path");
19456
+ var import_node_fs19 = require("node:fs");
19457
+ var import_node_path17 = require("node:path");
19208
19458
  function resolveInside(baseDir, candidate) {
19209
19459
  if (typeof candidate !== "string" || candidate.length === 0) return null;
19210
- if ((0, import_node_path16.isAbsolute)(candidate)) return null;
19211
- const baseAbs = (0, import_node_path16.resolve)(baseDir);
19212
- const full = (0, import_node_path16.resolve)(baseAbs, candidate);
19213
- const baseSep = baseAbs.endsWith(import_node_path16.sep) ? baseAbs : baseAbs + import_node_path16.sep;
19460
+ if ((0, import_node_path17.isAbsolute)(candidate)) return null;
19461
+ const baseAbs = (0, import_node_path17.resolve)(baseDir);
19462
+ const full = (0, import_node_path17.resolve)(baseAbs, candidate);
19463
+ const baseSep = baseAbs.endsWith(import_node_path17.sep) ? baseAbs : baseAbs + import_node_path17.sep;
19214
19464
  if (full !== baseAbs && !full.startsWith(baseSep)) return null;
19215
19465
  try {
19216
- if ((0, import_node_fs18.existsSync)(baseAbs)) {
19217
- const realBase = (0, import_node_fs18.realpathSync)(baseAbs);
19218
- const realBaseSep = realBase.endsWith(import_node_path16.sep) ? realBase : realBase + import_node_path16.sep;
19466
+ if ((0, import_node_fs19.existsSync)(baseAbs)) {
19467
+ const realBase = (0, import_node_fs19.realpathSync)(baseAbs);
19468
+ const realBaseSep = realBase.endsWith(import_node_path17.sep) ? realBase : realBase + import_node_path17.sep;
19219
19469
  let probe = full;
19220
- while (!(0, import_node_fs18.existsSync)(probe)) {
19221
- const parent = (0, import_node_path16.dirname)(probe);
19470
+ while (!(0, import_node_fs19.existsSync)(probe)) {
19471
+ const parent = (0, import_node_path17.dirname)(probe);
19222
19472
  if (parent === probe) break;
19223
19473
  probe = parent;
19224
19474
  }
19225
- const realProbe = (0, import_node_fs18.realpathSync)(probe);
19475
+ const realProbe = (0, import_node_fs19.realpathSync)(probe);
19226
19476
  if (realProbe !== realBase && !realProbe.startsWith(realBaseSep)) return null;
19227
19477
  }
19228
19478
  } catch {
@@ -19230,37 +19480,37 @@ function resolveInside(baseDir, candidate) {
19230
19480
  }
19231
19481
  return full;
19232
19482
  }
19233
- var O_NOFOLLOW2 = typeof import_node_fs18.constants.O_NOFOLLOW === "number" ? import_node_fs18.constants.O_NOFOLLOW : 0;
19483
+ var O_NOFOLLOW2 = typeof import_node_fs19.constants.O_NOFOLLOW === "number" ? import_node_fs19.constants.O_NOFOLLOW : 0;
19234
19484
  function readFileInside(baseDir, candidate, maxBytes) {
19235
19485
  const full = resolveInside(baseDir, candidate);
19236
19486
  if (!full) return null;
19237
19487
  let realParent;
19238
19488
  let realBase;
19239
19489
  try {
19240
- realParent = (0, import_node_fs18.realpathSync)((0, import_node_path16.dirname)(full));
19241
- realBase = (0, import_node_fs18.realpathSync)((0, import_node_path16.resolve)(baseDir));
19490
+ realParent = (0, import_node_fs19.realpathSync)((0, import_node_path17.dirname)(full));
19491
+ realBase = (0, import_node_fs19.realpathSync)((0, import_node_path17.resolve)(baseDir));
19242
19492
  } catch {
19243
19493
  return null;
19244
19494
  }
19245
- const realBaseSep = realBase.endsWith(import_node_path16.sep) ? realBase : realBase + import_node_path16.sep;
19495
+ const realBaseSep = realBase.endsWith(import_node_path17.sep) ? realBase : realBase + import_node_path17.sep;
19246
19496
  if (realParent !== realBase && !realParent.startsWith(realBaseSep)) return null;
19247
- const target = (0, import_node_path16.join)(realParent, (0, import_node_path16.basename)(full));
19497
+ const target = (0, import_node_path17.join)(realParent, (0, import_node_path17.basename)(full));
19248
19498
  let fd = null;
19249
19499
  try {
19250
- fd = (0, import_node_fs18.openSync)(target, import_node_fs18.constants.O_RDONLY | O_NOFOLLOW2);
19251
- const st = (0, import_node_fs18.fstatSync)(fd);
19500
+ fd = (0, import_node_fs19.openSync)(target, import_node_fs19.constants.O_RDONLY | O_NOFOLLOW2);
19501
+ const st = (0, import_node_fs19.fstatSync)(fd);
19252
19502
  if (!st.isFile()) return null;
19253
19503
  const cap2 = Math.min(maxBytes, st.size);
19254
19504
  if (cap2 <= 0) return "";
19255
19505
  const buf = Buffer.alloc(cap2);
19256
- const bytesRead = (0, import_node_fs18.readSync)(fd, buf, 0, cap2, 0);
19506
+ const bytesRead = (0, import_node_fs19.readSync)(fd, buf, 0, cap2, 0);
19257
19507
  return buf.subarray(0, bytesRead).toString("utf-8");
19258
19508
  } catch {
19259
19509
  return null;
19260
19510
  } finally {
19261
19511
  if (fd !== null) {
19262
19512
  try {
19263
- (0, import_node_fs18.closeSync)(fd);
19513
+ (0, import_node_fs19.closeSync)(fd);
19264
19514
  } catch {
19265
19515
  }
19266
19516
  }
@@ -19343,32 +19593,32 @@ var syncStateFile = () => projectPath(`${VERITY_DIR}/.memory-sync-state.json`);
19343
19593
  async function ensureMemoryDir() {
19344
19594
  await (0, import_promises9.mkdir)(memoryDir2(), { recursive: true });
19345
19595
  for (const domain of DOMAINS2) {
19346
- await (0, import_promises9.mkdir)((0, import_node_path17.join)(memoryDir2(), domain), { recursive: true });
19596
+ await (0, import_promises9.mkdir)((0, import_node_path18.join)(memoryDir2(), domain), { recursive: true });
19347
19597
  }
19348
- if (!(0, import_node_fs19.existsSync)((0, import_node_path17.join)(memoryDir2(), "SCHEMA.md"))) {
19349
- await (0, import_promises9.writeFile)((0, import_node_path17.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
19598
+ if (!(0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "SCHEMA.md"))) {
19599
+ await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
19350
19600
  }
19351
- if (!(0, import_node_fs19.existsSync)((0, import_node_path17.join)(memoryDir2(), "index.md"))) {
19352
- await (0, import_promises9.writeFile)((0, import_node_path17.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
19601
+ if (!(0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "index.md"))) {
19602
+ await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
19353
19603
  }
19354
- if (!(0, import_node_fs19.existsSync)((0, import_node_path17.join)(memoryDir2(), "log.md"))) {
19355
- await (0, import_promises9.writeFile)((0, import_node_path17.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
19604
+ if (!(0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "log.md"))) {
19605
+ await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
19356
19606
  }
19357
19607
  }
19358
19608
  async function buildManifest() {
19359
- if (!(0, import_node_fs19.existsSync)(memoryDir2())) {
19609
+ if (!(0, import_node_fs20.existsSync)(memoryDir2())) {
19360
19610
  return { schema_version: 1, nodes: [], index_hash: null, log_length: 0 };
19361
19611
  }
19362
19612
  const nodes = [];
19363
19613
  for (const domain of DOMAINS2) {
19364
- const domainDir = (0, import_node_path17.join)(memoryDir2(), domain);
19365
- if (!(0, import_node_fs19.existsSync)(domainDir)) continue;
19614
+ const domainDir = (0, import_node_path18.join)(memoryDir2(), domain);
19615
+ if (!(0, import_node_fs20.existsSync)(domainDir)) continue;
19366
19616
  try {
19367
19617
  const files = await (0, import_promises9.readdir)(domainDir);
19368
19618
  for (const file of files) {
19369
19619
  if (!file.endsWith(".md")) continue;
19370
19620
  const filePath = `${domain}/${file}`;
19371
- const fullPath = (0, import_node_path17.join)(memoryDir2(), filePath);
19621
+ const fullPath = (0, import_node_path18.join)(memoryDir2(), filePath);
19372
19622
  try {
19373
19623
  const content = await (0, import_promises9.readFile)(fullPath, "utf-8");
19374
19624
  const hash = (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex").slice(0, 16);
@@ -19381,13 +19631,13 @@ async function buildManifest() {
19381
19631
  }
19382
19632
  let indexHash = null;
19383
19633
  try {
19384
- const indexContent = await (0, import_promises9.readFile)((0, import_node_path17.join)(memoryDir2(), "index.md"), "utf-8");
19634
+ const indexContent = await (0, import_promises9.readFile)((0, import_node_path18.join)(memoryDir2(), "index.md"), "utf-8");
19385
19635
  indexHash = `sha256:${(0, import_node_crypto4.createHash)("sha256").update(indexContent).digest("hex").slice(0, 16)}`;
19386
19636
  } catch {
19387
19637
  }
19388
19638
  let logLength = 0;
19389
19639
  try {
19390
- const logContent = await (0, import_promises9.readFile)((0, import_node_path17.join)(memoryDir2(), "log.md"), "utf-8");
19640
+ const logContent = await (0, import_promises9.readFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), "utf-8");
19391
19641
  logLength = logContent.split("\n").length;
19392
19642
  } catch {
19393
19643
  }
@@ -19398,15 +19648,15 @@ function hashContent(content) {
19398
19648
  }
19399
19649
  async function readOnDiskNodes() {
19400
19650
  const out2 = /* @__PURE__ */ new Map();
19401
- if (!(0, import_node_fs19.existsSync)(memoryDir2())) return out2;
19651
+ if (!(0, import_node_fs20.existsSync)(memoryDir2())) return out2;
19402
19652
  for (const domain of DOMAINS2) {
19403
- const domainDir = (0, import_node_path17.join)(memoryDir2(), domain);
19404
- if (!(0, import_node_fs19.existsSync)(domainDir)) continue;
19653
+ const domainDir = (0, import_node_path18.join)(memoryDir2(), domain);
19654
+ if (!(0, import_node_fs20.existsSync)(domainDir)) continue;
19405
19655
  try {
19406
19656
  for (const file of await (0, import_promises9.readdir)(domainDir)) {
19407
19657
  if (!file.endsWith(".md")) continue;
19408
19658
  try {
19409
- out2.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0, import_node_path17.join)(domainDir, file), "utf-8")));
19659
+ out2.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0, import_node_path18.join)(domainDir, file), "utf-8")));
19410
19660
  } catch {
19411
19661
  }
19412
19662
  }
@@ -19443,7 +19693,7 @@ async function recordSyncedNodePaths() {
19443
19693
  }
19444
19694
  }
19445
19695
  async function writeFileAtomic(path, content) {
19446
- await (0, import_promises9.mkdir)((0, import_node_path17.dirname)(path), { recursive: true });
19696
+ await (0, import_promises9.mkdir)((0, import_node_path18.dirname)(path), { recursive: true });
19447
19697
  const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
19448
19698
  await (0, import_promises9.writeFile)(tmp, content);
19449
19699
  await (0, import_promises9.rename)(tmp, path);
@@ -19457,8 +19707,8 @@ async function computeEditedNodeUploads() {
19457
19707
  const uploads = [];
19458
19708
  for (const [path, prevHash] of prev) {
19459
19709
  if (prevHash == null) continue;
19460
- const full = (0, import_node_path17.join)(memoryDir2(), path);
19461
- if (!(0, import_node_fs19.existsSync)(full)) continue;
19710
+ const full = (0, import_node_path18.join)(memoryDir2(), path);
19711
+ if (!(0, import_node_fs20.existsSync)(full)) continue;
19462
19712
  let content;
19463
19713
  try {
19464
19714
  content = await (0, import_promises9.readFile)(full, "utf-8");
@@ -19502,8 +19752,8 @@ async function applyMemoryWrites(writes, opts = {}) {
19502
19752
  const logLines = [`- ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 16)} \u2014 Applied ${count} write(s) from server`];
19503
19753
  for (const n of notes) logLines.push(` - ${n}`);
19504
19754
  try {
19505
- const existing = (0, import_node_fs19.existsSync)((0, import_node_path17.join)(memoryDir2(), "log.md")) ? await (0, import_promises9.readFile)((0, import_node_path17.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
19506
- await (0, import_promises9.writeFile)((0, import_node_path17.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
19755
+ const existing = (0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "log.md")) ? await (0, import_promises9.readFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
19756
+ await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
19507
19757
  } catch {
19508
19758
  }
19509
19759
  if (opts.baseline === "written") await mergeSyncBaseline(synced);
@@ -19513,7 +19763,7 @@ async function applyMemoryWrites(writes, opts = {}) {
19513
19763
  async function mergeSyncBaseline(entries) {
19514
19764
  if (entries.size === 0) return;
19515
19765
  try {
19516
- if ((0, import_node_fs19.existsSync)(syncStateFile())) {
19766
+ if ((0, import_node_fs20.existsSync)(syncStateFile())) {
19517
19767
  try {
19518
19768
  JSON.parse(await (0, import_promises9.readFile)(syncStateFile(), "utf-8"));
19519
19769
  } catch {
@@ -19541,7 +19791,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
19541
19791
  notes.push(`${write.path}: dropped unmatched file_globs [${grounded.dropped.join(", ")}]`);
19542
19792
  }
19543
19793
  }
19544
- if ((0, import_node_fs19.existsSync)(fullPath)) {
19794
+ if ((0, import_node_fs20.existsSync)(fullPath)) {
19545
19795
  let existing = "";
19546
19796
  try {
19547
19797
  existing = await (0, import_promises9.readFile)(fullPath, "utf-8");
@@ -19557,7 +19807,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
19557
19807
  notes.push(`${write.path}: updated from server (untouched here since the server delivered it)`);
19558
19808
  }
19559
19809
  }
19560
- await (0, import_promises9.mkdir)((0, import_node_path17.dirname)(fullPath), { recursive: true });
19810
+ await (0, import_promises9.mkdir)((0, import_node_path18.dirname)(fullPath), { recursive: true });
19561
19811
  await (0, import_promises9.writeFile)(fullPath, content);
19562
19812
  return { written: true, syncedHash: hashContent(content), notes };
19563
19813
  }
@@ -19598,8 +19848,8 @@ async function regenerateIndex() {
19598
19848
  ];
19599
19849
  let totalNodes = 0;
19600
19850
  for (const domain of DOMAINS2.filter((d) => d !== "_archive")) {
19601
- const domainDir = (0, import_node_path17.join)(memoryDir2(), domain);
19602
- if (!(0, import_node_fs19.existsSync)(domainDir)) continue;
19851
+ const domainDir = (0, import_node_path18.join)(memoryDir2(), domain);
19852
+ if (!(0, import_node_fs20.existsSync)(domainDir)) continue;
19603
19853
  try {
19604
19854
  const files = await (0, import_promises9.readdir)(domainDir);
19605
19855
  const mdFiles = files.filter((f) => f.endsWith(".md"));
@@ -19609,7 +19859,7 @@ async function regenerateIndex() {
19609
19859
  for (const file of mdFiles.sort()) {
19610
19860
  const slug = file.replace(/\.md$/, "");
19611
19861
  try {
19612
- const content = await (0, import_promises9.readFile)((0, import_node_path17.join)(domainDir, file), "utf-8");
19862
+ const content = await (0, import_promises9.readFile)((0, import_node_path18.join)(domainDir, file), "utf-8");
19613
19863
  const title = pickFrontmatter(content, "title") ?? slug;
19614
19864
  const kind = pickFrontmatter(content, "kind") ?? "-";
19615
19865
  const confidence = pickFrontmatter(content, "confidence");
@@ -19633,7 +19883,7 @@ async function regenerateIndex() {
19633
19883
  lines.push("No nodes yet. Run an analysis to start building the knowledge graph.");
19634
19884
  }
19635
19885
  const next = lines.join("\n") + "\n";
19636
- const indexPath = (0, import_node_path17.join)(memoryDir2(), "index.md");
19886
+ const indexPath = (0, import_node_path18.join)(memoryDir2(), "index.md");
19637
19887
  let existing = null;
19638
19888
  try {
19639
19889
  existing = await (0, import_promises9.readFile)(indexPath, "utf-8");
@@ -20030,9 +20280,9 @@ function hasLegacyMemoryBlock(text) {
20030
20280
  return findMarker(text, LEGACY_MD_START) !== -1;
20031
20281
  }
20032
20282
  async function ensureClaudeMdPointer(cwd = repoRoot()) {
20033
- const claudeMdPath = (0, import_node_path17.join)(cwd, "CLAUDE.md");
20283
+ const claudeMdPath = (0, import_node_path18.join)(cwd, "CLAUDE.md");
20034
20284
  let existing = "";
20035
- if ((0, import_node_fs19.existsSync)(claudeMdPath)) {
20285
+ if ((0, import_node_fs20.existsSync)(claudeMdPath)) {
20036
20286
  existing = await (0, import_promises9.readFile)(claudeMdPath, "utf-8");
20037
20287
  }
20038
20288
  let startTag = CLAUDE_MD_START;
@@ -20173,9 +20423,9 @@ Body content (\u22648KB). Use [[node-id]] wikilinks for cross-references.
20173
20423
  `;
20174
20424
 
20175
20425
  // src/lib/dossier-session.ts
20176
- var import_node_fs24 = require("node:fs");
20426
+ var import_node_fs25 = require("node:fs");
20177
20427
  var import_node_crypto8 = require("node:crypto");
20178
- var import_node_path20 = require("node:path");
20428
+ var import_node_path21 = require("node:path");
20179
20429
 
20180
20430
  // src/lib/pending-repeat.ts
20181
20431
  var STOP = /* @__PURE__ */ new Set([
@@ -20280,8 +20530,8 @@ function statementAnchorKey(file, patternId) {
20280
20530
 
20281
20531
  // src/lib/dossier/log.ts
20282
20532
  var import_node_crypto5 = require("node:crypto");
20283
- var import_node_fs20 = require("node:fs");
20284
- var import_node_path18 = require("node:path");
20533
+ var import_node_fs21 = require("node:fs");
20534
+ var import_node_path19 = require("node:path");
20285
20535
  var CRC_TABLE = (() => {
20286
20536
  const t = new Int32Array(256);
20287
20537
  for (let i2 = 0; i2 < 256; i2++) {
@@ -20300,13 +20550,13 @@ function crc32(s) {
20300
20550
  function openDossier(identity) {
20301
20551
  try {
20302
20552
  const dir = dossierDir(identity);
20303
- (0, import_node_fs20.mkdirSync)(dir, { recursive: true, mode: 448 });
20553
+ (0, import_node_fs21.mkdirSync)(dir, { recursive: true, mode: 448 });
20304
20554
  return {
20305
20555
  dir,
20306
20556
  identity,
20307
- eventsPath: (0, import_node_path18.join)(dir, "events.jsonl"),
20308
- foldPath: (0, import_node_path18.join)(dir, "fold.json"),
20309
- rotatedDir: (0, import_node_path18.join)(dir, "rotated")
20557
+ eventsPath: (0, import_node_path19.join)(dir, "events.jsonl"),
20558
+ foldPath: (0, import_node_path19.join)(dir, "fold.json"),
20559
+ rotatedDir: (0, import_node_path19.join)(dir, "rotated")
20310
20560
  };
20311
20561
  } catch {
20312
20562
  return null;
@@ -20368,7 +20618,7 @@ function appendEvent(d, ev) {
20368
20618
  at: ev.at ?? (/* @__PURE__ */ new Date()).toISOString(),
20369
20619
  ...ev
20370
20620
  });
20371
- (0, import_node_fs20.appendFileSync)(d.eventsPath, line2, { mode: 384 });
20621
+ (0, import_node_fs21.appendFileSync)(d.eventsPath, line2, { mode: 384 });
20372
20622
  return true;
20373
20623
  } catch {
20374
20624
  return false;
@@ -20376,14 +20626,14 @@ function appendEvent(d, ev) {
20376
20626
  }
20377
20627
  function rotateIfNeeded2(d) {
20378
20628
  try {
20379
- if (!(0, import_node_fs20.existsSync)(d.eventsPath)) return;
20380
- if ((0, import_node_fs20.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
20381
- (0, import_node_fs20.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
20382
- (0, import_node_fs20.renameSync)(d.eventsPath, (0, import_node_path18.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
20383
- const kept = (0, import_node_fs20.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
20629
+ if (!(0, import_node_fs21.existsSync)(d.eventsPath)) return;
20630
+ if ((0, import_node_fs21.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
20631
+ (0, import_node_fs21.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
20632
+ (0, import_node_fs21.renameSync)(d.eventsPath, (0, import_node_path19.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
20633
+ const kept = (0, import_node_fs21.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
20384
20634
  for (const stale of kept.slice(0, Math.max(0, kept.length - ROTATE_KEEP))) {
20385
20635
  try {
20386
- (0, import_node_fs20.renameSync)((0, import_node_path18.join)(d.rotatedDir, stale), (0, import_node_path18.join)(d.rotatedDir, `${stale}.pruned`));
20636
+ (0, import_node_fs21.renameSync)((0, import_node_path19.join)(d.rotatedDir, stale), (0, import_node_path19.join)(d.rotatedDir, `${stale}.pruned`));
20387
20637
  } catch {
20388
20638
  }
20389
20639
  }
@@ -20393,8 +20643,8 @@ function rotateIfNeeded2(d) {
20393
20643
 
20394
20644
  // src/lib/dossier/fold-dossier.ts
20395
20645
  var import_node_crypto6 = require("node:crypto");
20396
- var import_node_fs21 = require("node:fs");
20397
- var import_node_path19 = require("node:path");
20646
+ var import_node_fs22 = require("node:fs");
20647
+ var import_node_path20 = require("node:path");
20398
20648
  var EMPTY_CAPABILITIES = () => ({
20399
20649
  human_reachable: { value: "unknown", tier: "unknown" },
20400
20650
  authorship_observability: { value: "unknown", tier: "unknown" },
@@ -20445,12 +20695,12 @@ function foldDossier(d, opts = {}) {
20445
20695
  }
20446
20696
  };
20447
20697
  try {
20448
- if ((0, import_node_fs21.existsSync)(d.rotatedDir)) {
20449
- const files = (0, import_node_fs21.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
20698
+ if ((0, import_node_fs22.existsSync)(d.rotatedDir)) {
20699
+ const files = (0, import_node_fs22.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
20450
20700
  state.meta.rotations = files.length;
20451
20701
  for (const f of files) {
20452
20702
  try {
20453
- ingest((0, import_node_fs21.readFileSync)((0, import_node_path19.join)(d.rotatedDir, f), "utf8"));
20703
+ ingest((0, import_node_fs22.readFileSync)((0, import_node_path20.join)(d.rotatedDir, f), "utf8"));
20454
20704
  } catch {
20455
20705
  state.meta.dropped_lines++;
20456
20706
  }
@@ -20459,9 +20709,9 @@ function foldDossier(d, opts = {}) {
20459
20709
  } catch {
20460
20710
  }
20461
20711
  try {
20462
- if ((0, import_node_fs21.existsSync)(d.eventsPath)) {
20463
- state.meta.upto_offset = (0, import_node_fs21.statSync)(d.eventsPath).size;
20464
- ingest((0, import_node_fs21.readFileSync)(d.eventsPath, "utf8"));
20712
+ if ((0, import_node_fs22.existsSync)(d.eventsPath)) {
20713
+ state.meta.upto_offset = (0, import_node_fs22.statSync)(d.eventsPath).size;
20714
+ ingest((0, import_node_fs22.readFileSync)(d.eventsPath, "utf8"));
20465
20715
  }
20466
20716
  } catch {
20467
20717
  }
@@ -20732,7 +20982,7 @@ function applyBounds(state, input) {
20732
20982
  }
20733
20983
 
20734
20984
  // src/lib/dossier/cache.ts
20735
- var import_node_fs22 = require("node:fs");
20985
+ var import_node_fs23 = require("node:fs");
20736
20986
  function compactState(s) {
20737
20987
  const ms = (iso) => Date.parse(iso) || 0;
20738
20988
  return {
@@ -20861,20 +21111,20 @@ function encodeState(s) {
20861
21111
  function writeFoldCache(d, state) {
20862
21112
  try {
20863
21113
  const tmp = `${d.foldPath}.${process.pid}.tmp`;
20864
- (0, import_node_fs22.writeFileSync)(tmp, encodeState(state), { mode: 384 });
20865
- (0, import_node_fs22.renameSync)(tmp, d.foldPath);
21114
+ (0, import_node_fs23.writeFileSync)(tmp, encodeState(state), { mode: 384 });
21115
+ (0, import_node_fs23.renameSync)(tmp, d.foldPath);
20866
21116
  } catch {
20867
21117
  }
20868
21118
  }
20869
21119
  function readFoldCache(d) {
20870
21120
  try {
20871
- if (!(0, import_node_fs22.existsSync)(d.foldPath)) return null;
20872
- const raw = JSON.parse((0, import_node_fs22.readFileSync)(d.foldPath, "utf8"));
21121
+ if (!(0, import_node_fs23.existsSync)(d.foldPath)) return null;
21122
+ const raw = JSON.parse((0, import_node_fs23.readFileSync)(d.foldPath, "utf8"));
20873
21123
  if (raw?.v !== 1) return null;
20874
21124
  const cached2 = expandState(raw);
20875
21125
  if (!cached2?.meta) return null;
20876
- const size = (0, import_node_fs22.existsSync)(d.eventsPath) ? (0, import_node_fs22.statSync)(d.eventsPath).size : 0;
20877
- const rotations = (0, import_node_fs22.existsSync)(d.rotatedDir) ? (0, import_node_fs22.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
21126
+ const size = (0, import_node_fs23.existsSync)(d.eventsPath) ? (0, import_node_fs23.statSync)(d.eventsPath).size : 0;
21127
+ const rotations = (0, import_node_fs23.existsSync)(d.rotatedDir) ? (0, import_node_fs23.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
20878
21128
  if (cached2.meta.upto_offset !== size || cached2.meta.rotations !== rotations) return null;
20879
21129
  return cached2;
20880
21130
  } catch {
@@ -20925,13 +21175,13 @@ function assessContinuity(i2) {
20925
21175
 
20926
21176
  // src/lib/dossier/reanchor.ts
20927
21177
  var import_node_crypto7 = require("node:crypto");
20928
- var import_node_fs23 = require("node:fs");
21178
+ var import_node_fs24 = require("node:fs");
20929
21179
  function lineSha(text) {
20930
21180
  return (0, import_node_crypto7.createHash)("sha256").update(text.trim()).digest("hex").slice(0, HASH_WIDTH);
20931
21181
  }
20932
21182
  function fileHash(path) {
20933
21183
  try {
20934
- return (0, import_node_crypto7.createHash)("sha256").update((0, import_node_fs23.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
21184
+ return (0, import_node_crypto7.createHash)("sha256").update((0, import_node_fs24.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
20935
21185
  } catch {
20936
21186
  return null;
20937
21187
  }
@@ -21303,20 +21553,20 @@ function foreignAuthoredPaths(identity, opts = {}) {
21303
21553
  let sessions = 0;
21304
21554
  try {
21305
21555
  const dir = treeDir(identity);
21306
- if (!(0, import_node_fs24.existsSync)(dir)) return { paths: [], sessions: 0 };
21307
- for (const entry of (0, import_node_fs24.readdirSync)(dir, { withFileTypes: true })) {
21556
+ if (!(0, import_node_fs25.existsSync)(dir)) return { paths: [], sessions: 0 };
21557
+ for (const entry of (0, import_node_fs25.readdirSync)(dir, { withFileTypes: true })) {
21308
21558
  if (!entry.isDirectory()) continue;
21309
21559
  if (entry.name === identity.sessionKey) continue;
21310
- const log = (0, import_node_path20.join)(dir, entry.name, "events.jsonl");
21560
+ const log = (0, import_node_path21.join)(dir, entry.name, "events.jsonl");
21311
21561
  try {
21312
- if (!(0, import_node_fs24.existsSync)(log)) continue;
21313
- if (now - (0, import_node_fs24.statSync)(log).mtimeMs > windowMs) continue;
21562
+ if (!(0, import_node_fs25.existsSync)(log)) continue;
21563
+ if (now - (0, import_node_fs25.statSync)(log).mtimeMs > windowMs) continue;
21314
21564
  const sib = {
21315
- dir: (0, import_node_path20.join)(dir, entry.name),
21565
+ dir: (0, import_node_path21.join)(dir, entry.name),
21316
21566
  identity,
21317
21567
  eventsPath: log,
21318
- foldPath: (0, import_node_path20.join)(dir, entry.name, "fold.json"),
21319
- rotatedDir: (0, import_node_path20.join)(dir, entry.name, "rotated")
21568
+ foldPath: (0, import_node_path21.join)(dir, entry.name, "fold.json"),
21569
+ rotatedDir: (0, import_node_path21.join)(dir, entry.name, "rotated")
21320
21570
  };
21321
21571
  const state = readFoldCache(sib) ?? foldDossier(sib);
21322
21572
  sessions++;
@@ -21344,25 +21594,25 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
21344
21594
  let removed = 0;
21345
21595
  try {
21346
21596
  const mine = dossierDir(identity);
21347
- const userDir = (0, import_node_path20.dirname)((0, import_node_path20.dirname)(mine));
21348
- if (!(0, import_node_fs24.existsSync)(userDir)) return 0;
21597
+ const userDir = (0, import_node_path21.dirname)((0, import_node_path21.dirname)(mine));
21598
+ if (!(0, import_node_fs25.existsSync)(userDir)) return 0;
21349
21599
  const cutoff = Date.now() - maxAgeMs;
21350
- for (const tree of (0, import_node_fs24.readdirSync)(userDir, { withFileTypes: true })) {
21600
+ for (const tree of (0, import_node_fs25.readdirSync)(userDir, { withFileTypes: true })) {
21351
21601
  if (!tree.isDirectory()) continue;
21352
- const treePath = (0, import_node_path20.join)(userDir, tree.name);
21602
+ const treePath = (0, import_node_path21.join)(userDir, tree.name);
21353
21603
  let live = 0;
21354
- for (const entry of (0, import_node_fs24.readdirSync)(treePath, { withFileTypes: true })) {
21604
+ for (const entry of (0, import_node_fs25.readdirSync)(treePath, { withFileTypes: true })) {
21355
21605
  if (!entry.isDirectory()) continue;
21356
- const dir = (0, import_node_path20.join)(treePath, entry.name);
21606
+ const dir = (0, import_node_path21.join)(treePath, entry.name);
21357
21607
  if (dir === mine) {
21358
21608
  live++;
21359
21609
  continue;
21360
21610
  }
21361
21611
  try {
21362
- const log = (0, import_node_path20.join)(dir, "events.jsonl");
21363
- const at = (0, import_node_fs24.existsSync)(log) ? (0, import_node_fs24.statSync)(log).mtimeMs : (0, import_node_fs24.statSync)(dir).mtimeMs;
21612
+ const log = (0, import_node_path21.join)(dir, "events.jsonl");
21613
+ const at = (0, import_node_fs25.existsSync)(log) ? (0, import_node_fs25.statSync)(log).mtimeMs : (0, import_node_fs25.statSync)(dir).mtimeMs;
21364
21614
  if (at < cutoff) {
21365
- (0, import_node_fs24.rmSync)(dir, { recursive: true, force: true });
21615
+ (0, import_node_fs25.rmSync)(dir, { recursive: true, force: true });
21366
21616
  removed++;
21367
21617
  } else {
21368
21618
  live++;
@@ -21372,7 +21622,7 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
21372
21622
  }
21373
21623
  if (live === 0) {
21374
21624
  try {
21375
- (0, import_node_fs24.rmSync)(treePath, { recursive: false, force: false });
21625
+ (0, import_node_fs25.rmSync)(treePath, { recursive: false, force: false });
21376
21626
  } catch {
21377
21627
  }
21378
21628
  }
@@ -21389,8 +21639,8 @@ function sessionDossier(token, sessionId) {
21389
21639
  }
21390
21640
  function hasActiveGoal(d) {
21391
21641
  try {
21392
- if (!(0, import_node_fs24.existsSync)(d.eventsPath)) return false;
21393
- return (0, import_node_fs24.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
21642
+ if (!(0, import_node_fs25.existsSync)(d.eventsPath)) return false;
21643
+ return (0, import_node_fs25.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
21394
21644
  } catch {
21395
21645
  return false;
21396
21646
  }
@@ -21414,7 +21664,7 @@ function recordTurn(d, t) {
21414
21664
  for (const a of t.authored) {
21415
21665
  const origin = a.owner === "subagent" ? "subagent" : "edit_tool";
21416
21666
  const prior = t.known?.authored?.get(a.p);
21417
- const hash = fileHash((0, import_node_path20.join)(root, a.p));
21667
+ const hash = fileHash((0, import_node_path21.join)(root, a.p));
21418
21668
  const hunks = Math.max(0, a.h - (prior?.hunks ?? 0));
21419
21669
  const adds = Math.max(0, a.a - (prior?.adds ?? 0));
21420
21670
  const dels = Math.max(0, a.d - (prior?.dels ?? 0));
@@ -21447,7 +21697,7 @@ function recordTurn(d, t) {
21447
21697
  }
21448
21698
  const seenDivergence = t.known?.divergence ?? /* @__PURE__ */ new Set();
21449
21699
  for (const u of t.unobserved) {
21450
- const hash = fileHash((0, import_node_path20.join)(root, u.p));
21700
+ const hash = fileHash((0, import_node_path21.join)(root, u.p));
21451
21701
  if (seenDivergence.has(divergenceKey(u.p, hash))) continue;
21452
21702
  appendEvent(d, { k: "divergence", kind: "external_mutation", path: u.p, hash });
21453
21703
  }
@@ -21482,8 +21732,8 @@ function recordVerdict(d, v) {
21482
21732
  if (!sent.has(f.file)) continue;
21483
21733
  if (!lines.has(f.file)) {
21484
21734
  try {
21485
- const abs = (0, import_node_path20.join)(root, f.file);
21486
- lines.set(f.file, (0, import_node_fs24.existsSync)(abs) ? (0, import_node_fs24.readFileSync)(abs, "utf8").split("\n") : null);
21735
+ const abs = (0, import_node_path21.join)(root, f.file);
21736
+ lines.set(f.file, (0, import_node_fs25.existsSync)(abs) ? (0, import_node_fs25.readFileSync)(abs, "utf8").split("\n") : null);
21487
21737
  } catch {
21488
21738
  lines.set(f.file, null);
21489
21739
  }
@@ -21583,8 +21833,8 @@ function recallMemory(d, identity, opts) {
21583
21833
  budgetBytes: opts.budgetBytes,
21584
21834
  readFileLines: (file) => {
21585
21835
  try {
21586
- const abs = (0, import_node_path20.join)(root, file);
21587
- return (0, import_node_fs24.existsSync)(abs) ? (0, import_node_fs24.readFileSync)(abs, "utf8").split("\n") : null;
21836
+ const abs = (0, import_node_path21.join)(root, file);
21837
+ return (0, import_node_fs25.existsSync)(abs) ? (0, import_node_fs25.readFileSync)(abs, "utf8").split("\n") : null;
21588
21838
  } catch {
21589
21839
  return null;
21590
21840
  }
@@ -21752,21 +22002,21 @@ async function fireClassify(prompt, sessionId, globals) {
21752
22002
  }
21753
22003
 
21754
22004
  // src/commands/lifecycle.ts
21755
- var import_node_fs27 = require("node:fs");
21756
- var import_node_path24 = require("node:path");
22005
+ var import_node_fs28 = require("node:fs");
22006
+ var import_node_path25 = require("node:path");
21757
22007
 
21758
22008
  // src/lib/baseline.ts
21759
- var import_node_fs26 = require("node:fs");
21760
- var import_node_path23 = require("node:path");
22009
+ var import_node_fs27 = require("node:fs");
22010
+ var import_node_path24 = require("node:path");
21761
22011
  var import_node_crypto10 = require("node:crypto");
21762
22012
 
21763
22013
  // src/lib/snapshot.ts
21764
- var import_node_fs25 = require("node:fs");
21765
- var import_node_path22 = require("node:path");
22014
+ var import_node_fs26 = require("node:fs");
22015
+ var import_node_path23 = require("node:path");
21766
22016
  var import_node_child_process7 = require("node:child_process");
21767
22017
 
21768
22018
  // src/lib/files.ts
21769
- var import_node_path21 = require("node:path");
22019
+ var import_node_path22 = require("node:path");
21770
22020
  var LANG_MAP = {
21771
22021
  // Analyzable (static analysis + Gemini)
21772
22022
  ts: "typescript",
@@ -21834,7 +22084,7 @@ var LANG_MAP = {
21834
22084
  mk: "make"
21835
22085
  };
21836
22086
  function detectLanguage(filepath) {
21837
- const ext = (0, import_node_path21.extname)(filepath).slice(1);
22087
+ const ext = (0, import_node_path22.extname)(filepath).slice(1);
21838
22088
  return LANG_MAP[ext] ?? ext;
21839
22089
  }
21840
22090
  function sortByMtime(files) {
@@ -21925,16 +22175,16 @@ function collectCodeDelta(files, opts) {
21925
22175
 
21926
22176
  // src/lib/snapshot.ts
21927
22177
  function generateSnapshotDiffs(files) {
21928
- if (!(0, import_node_fs25.existsSync)(SNAPSHOT_DIR)) {
22178
+ if (!(0, import_node_fs26.existsSync)(SNAPSHOT_DIR)) {
21929
22179
  return { diffs: [], has_snapshots: false };
21930
22180
  }
21931
22181
  const diffs = [];
21932
22182
  for (const file of files) {
21933
22183
  if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
21934
- const snapshotPath = (0, import_node_path22.join)(SNAPSHOT_DIR, file.path);
22184
+ const snapshotPath = (0, import_node_path23.join)(SNAPSHOT_DIR, file.path);
21935
22185
  const language = file.language ?? detectLanguage(file.path);
21936
- if ((0, import_node_fs25.existsSync)(snapshotPath)) {
21937
- const oldContent = (0, import_node_fs25.readFileSync)(snapshotPath, "utf-8");
22186
+ if ((0, import_node_fs26.existsSync)(snapshotPath)) {
22187
+ const oldContent = (0, import_node_fs26.readFileSync)(snapshotPath, "utf-8");
21938
22188
  if (oldContent === file.content) continue;
21939
22189
  const diff = computeDiff(oldContent, file.content, file.path);
21940
22190
  if (diff) {
@@ -21959,20 +22209,20 @@ function saveSnapshots(files) {
21959
22209
  const snapshotPaths = /* @__PURE__ */ new Set();
21960
22210
  for (const file of files) {
21961
22211
  if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
21962
- const snapshotPath = (0, import_node_path22.join)(SNAPSHOT_DIR, file.path);
22212
+ const snapshotPath = (0, import_node_path23.join)(SNAPSHOT_DIR, file.path);
21963
22213
  snapshotPaths.add(snapshotPath);
21964
- (0, import_node_fs25.mkdirSync)((0, import_node_path22.dirname)(snapshotPath), { recursive: true });
21965
- (0, import_node_fs25.writeFileSync)(snapshotPath, file.content);
22214
+ (0, import_node_fs26.mkdirSync)((0, import_node_path23.dirname)(snapshotPath), { recursive: true });
22215
+ (0, import_node_fs26.writeFileSync)(snapshotPath, file.content);
21966
22216
  }
21967
22217
  cleanStaleSnapshots(SNAPSHOT_DIR, snapshotPaths);
21968
22218
  }
21969
22219
  function computeDiff(oldContent, newContent, filePath) {
21970
- const tmpOld = (0, import_node_path22.join)(SNAPSHOT_DIR, ".diff-old.tmp");
21971
- const tmpNew = (0, import_node_path22.join)(SNAPSHOT_DIR, ".diff-new.tmp");
22220
+ const tmpOld = (0, import_node_path23.join)(SNAPSHOT_DIR, ".diff-old.tmp");
22221
+ const tmpNew = (0, import_node_path23.join)(SNAPSHOT_DIR, ".diff-new.tmp");
21972
22222
  try {
21973
- (0, import_node_fs25.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
21974
- (0, import_node_fs25.writeFileSync)(tmpOld, oldContent);
21975
- (0, import_node_fs25.writeFileSync)(tmpNew, newContent);
22223
+ (0, import_node_fs26.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
22224
+ (0, import_node_fs26.writeFileSync)(tmpOld, oldContent);
22225
+ (0, import_node_fs26.writeFileSync)(tmpNew, newContent);
21976
22226
  const result = (0, import_node_child_process7.execSync)(
21977
22227
  `git diff --no-index --unified=10 -- "${tmpOld}" "${tmpNew}"`,
21978
22228
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
@@ -21986,32 +22236,32 @@ function computeDiff(oldContent, newContent, filePath) {
21986
22236
  return null;
21987
22237
  } finally {
21988
22238
  try {
21989
- (0, import_node_fs25.unlinkSync)(tmpOld);
22239
+ (0, import_node_fs26.unlinkSync)(tmpOld);
21990
22240
  } catch {
21991
22241
  }
21992
22242
  try {
21993
- (0, import_node_fs25.unlinkSync)(tmpNew);
22243
+ (0, import_node_fs26.unlinkSync)(tmpNew);
21994
22244
  } catch {
21995
22245
  }
21996
22246
  }
21997
22247
  }
21998
22248
  function cleanStaleSnapshots(dir, keepSet) {
21999
- if (!(0, import_node_fs25.existsSync)(dir)) return;
22249
+ if (!(0, import_node_fs26.existsSync)(dir)) return;
22000
22250
  try {
22001
- const entries = (0, import_node_fs25.readdirSync)(dir, { withFileTypes: true });
22251
+ const entries = (0, import_node_fs26.readdirSync)(dir, { withFileTypes: true });
22002
22252
  for (const entry of entries) {
22003
22253
  if (dir === SNAPSHOT_DIR && (entry.name === ".diff-old.tmp" || entry.name === ".diff-new.tmp")) continue;
22004
- const fullPath = (0, import_node_path22.join)(dir, entry.name);
22254
+ const fullPath = (0, import_node_path23.join)(dir, entry.name);
22005
22255
  if (entry.isDirectory()) {
22006
22256
  cleanStaleSnapshots(fullPath, keepSet);
22007
22257
  try {
22008
- const remaining = (0, import_node_fs25.readdirSync)(fullPath);
22009
- if (remaining.length === 0) (0, import_node_fs25.rmdirSync)(fullPath);
22258
+ const remaining = (0, import_node_fs26.readdirSync)(fullPath);
22259
+ if (remaining.length === 0) (0, import_node_fs26.rmdirSync)(fullPath);
22010
22260
  } catch {
22011
22261
  }
22012
22262
  } else if (!keepSet.has(fullPath)) {
22013
22263
  try {
22014
- (0, import_node_fs25.unlinkSync)(fullPath);
22264
+ (0, import_node_fs26.unlinkSync)(fullPath);
22015
22265
  } catch {
22016
22266
  }
22017
22267
  }
@@ -22030,20 +22280,20 @@ function sessionKey(sessionId) {
22030
22280
  return (0, import_node_crypto10.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
22031
22281
  }
22032
22282
  function sessionDir(key) {
22033
- return (0, import_node_path23.join)(projectPath(BASELINE_DIR), key);
22283
+ return (0, import_node_path24.join)(projectPath(BASELINE_DIR), key);
22034
22284
  }
22035
22285
  function manifestPath(dir) {
22036
- return (0, import_node_path23.join)(dir, "manifest.json");
22286
+ return (0, import_node_path24.join)(dir, "manifest.json");
22037
22287
  }
22038
22288
  function mirrorPath(dir, repoRelPath) {
22039
- return (0, import_node_path23.join)(dir, "files", repoRelPath);
22289
+ return (0, import_node_path24.join)(dir, "files", repoRelPath);
22040
22290
  }
22041
22291
  var CARRY_FILE = `${BASELINE_DIR}/.carry`;
22042
22292
  var CARRY_WINDOW_MS = 12e4;
22043
22293
  function writeCarry(sessionId, headSha) {
22044
22294
  try {
22045
- (0, import_node_fs26.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
22046
- (0, import_node_fs26.writeFileSync)(
22295
+ (0, import_node_fs27.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
22296
+ (0, import_node_fs27.writeFileSync)(
22047
22297
  projectPath(CARRY_FILE),
22048
22298
  JSON.stringify({ from_key: sessionKey(sessionId), head_sha: headSha, ts: Date.now() })
22049
22299
  );
@@ -22053,10 +22303,10 @@ function writeCarry(sessionId, headSha) {
22053
22303
  function claimCarry(newKey) {
22054
22304
  const carryPath = projectPath(CARRY_FILE);
22055
22305
  try {
22056
- if (!(0, import_node_fs26.existsSync)(carryPath)) return null;
22057
- const carry = JSON.parse((0, import_node_fs26.readFileSync)(carryPath, "utf-8"));
22306
+ if (!(0, import_node_fs27.existsSync)(carryPath)) return null;
22307
+ const carry = JSON.parse((0, import_node_fs27.readFileSync)(carryPath, "utf-8"));
22058
22308
  try {
22059
- (0, import_node_fs26.rmSync)(carryPath, { force: true });
22309
+ (0, import_node_fs27.rmSync)(carryPath, { force: true });
22060
22310
  } catch {
22061
22311
  }
22062
22312
  if (!carry?.from_key || typeof carry.ts !== "number") return null;
@@ -22067,11 +22317,11 @@ function claimCarry(newKey) {
22067
22317
  if (!prior) return null;
22068
22318
  const toDir = sessionDir(newKey);
22069
22319
  try {
22070
- (0, import_node_fs26.rmSync)(toDir, { recursive: true, force: true });
22320
+ (0, import_node_fs27.rmSync)(toDir, { recursive: true, force: true });
22071
22321
  } catch {
22072
22322
  }
22073
- (0, import_node_fs26.renameSync)(fromDir, toDir);
22074
- (0, import_node_fs26.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
22323
+ (0, import_node_fs27.renameSync)(fromDir, toDir);
22324
+ (0, import_node_fs27.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
22075
22325
  return readManifest(toDir);
22076
22326
  } catch {
22077
22327
  return null;
@@ -22095,21 +22345,21 @@ function captureBaseline(opts = {}) {
22095
22345
  const head_sha = getCurrentCommit();
22096
22346
  const dirty = getDirtyFiles();
22097
22347
  try {
22098
- (0, import_node_fs26.rmSync)(dir, { recursive: true, force: true });
22348
+ (0, import_node_fs27.rmSync)(dir, { recursive: true, force: true });
22099
22349
  } catch {
22100
22350
  }
22101
- const filesDir = (0, import_node_path23.join)(dir, "files");
22351
+ const filesDir = (0, import_node_path24.join)(dir, "files");
22102
22352
  const mirrored = [];
22103
22353
  try {
22104
- (0, import_node_fs26.mkdirSync)(filesDir, { recursive: true });
22354
+ (0, import_node_fs27.mkdirSync)(filesDir, { recursive: true });
22105
22355
  for (const p of dirty) {
22106
22356
  if (p.includes("..")) continue;
22107
22357
  const content = safeReadForMirror(projectPath(p));
22108
22358
  if (content === null) continue;
22109
22359
  const dest = mirrorPath(dir, p);
22110
22360
  try {
22111
- (0, import_node_fs26.mkdirSync)((0, import_node_path23.dirname)(dest), { recursive: true });
22112
- (0, import_node_fs26.writeFileSync)(dest, content);
22361
+ (0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(dest), { recursive: true });
22362
+ (0, import_node_fs27.writeFileSync)(dest, content);
22113
22363
  mirrored.push(p);
22114
22364
  } catch {
22115
22365
  }
@@ -22124,8 +22374,8 @@ function captureBaseline(opts = {}) {
22124
22374
  version: BASELINE_VERSION
22125
22375
  };
22126
22376
  try {
22127
- (0, import_node_fs26.mkdirSync)(dir, { recursive: true });
22128
- (0, import_node_fs26.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
22377
+ (0, import_node_fs27.mkdirSync)(dir, { recursive: true });
22378
+ (0, import_node_fs27.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
22129
22379
  } catch {
22130
22380
  }
22131
22381
  pruneOldBaselines();
@@ -22136,9 +22386,9 @@ function readBaseline(sessionId) {
22136
22386
  }
22137
22387
  function readManifest(dir) {
22138
22388
  const mp = manifestPath(dir);
22139
- if (!(0, import_node_fs26.existsSync)(mp)) return null;
22389
+ if (!(0, import_node_fs27.existsSync)(mp)) return null;
22140
22390
  try {
22141
- const parsed = JSON.parse((0, import_node_fs26.readFileSync)(mp, "utf-8"));
22391
+ const parsed = JSON.parse((0, import_node_fs27.readFileSync)(mp, "utf-8"));
22142
22392
  if (typeof parsed.head_sha !== "string" || typeof parsed.captured_at !== "number" || !Array.isArray(parsed.dirty_paths) || parsed.version !== BASELINE_VERSION) {
22143
22393
  return null;
22144
22394
  }
@@ -22169,9 +22419,9 @@ function preImage(repoRelPath, baseline) {
22169
22419
  function resolvePreImage(repoRelPath, baseline) {
22170
22420
  if (baseline.dirty_paths.includes(repoRelPath)) {
22171
22421
  const mp = mirrorPath(sessionDir(sessionKey(baseline.session_id)), repoRelPath);
22172
- if ((0, import_node_fs26.existsSync)(mp)) {
22422
+ if ((0, import_node_fs27.existsSync)(mp)) {
22173
22423
  try {
22174
- return { content: (0, import_node_fs26.readFileSync)(mp, "utf-8"), existed: true };
22424
+ return { content: (0, import_node_fs27.readFileSync)(mp, "utf-8"), existed: true };
22175
22425
  } catch {
22176
22426
  }
22177
22427
  }
@@ -22216,8 +22466,8 @@ function absorbIntoBaseline(paths, sessionId) {
22216
22466
  const content = safeReadForMirror(projectPath(p));
22217
22467
  if (content === null) continue;
22218
22468
  const dest = mirrorPath(dir, p);
22219
- (0, import_node_fs26.mkdirSync)((0, import_node_path23.dirname)(dest), { recursive: true });
22220
- (0, import_node_fs26.writeFileSync)(dest, content);
22469
+ (0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(dest), { recursive: true });
22470
+ (0, import_node_fs27.writeFileSync)(dest, content);
22221
22471
  dirty.add(p);
22222
22472
  adopted++;
22223
22473
  } catch {
@@ -22226,7 +22476,7 @@ function absorbIntoBaseline(paths, sessionId) {
22226
22476
  if (adopted === 0) return 0;
22227
22477
  try {
22228
22478
  const updated = { ...baseline, dirty_paths: [...dirty] };
22229
- (0, import_node_fs26.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
22479
+ (0, import_node_fs27.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
22230
22480
  preImageCache.delete(baseline);
22231
22481
  } catch {
22232
22482
  return 0;
@@ -22237,7 +22487,7 @@ function changedSinceBaseline(repoRelPath, baseline) {
22237
22487
  const pre = preImage(repoRelPath, baseline);
22238
22488
  let current;
22239
22489
  try {
22240
- current = (0, import_node_fs26.readFileSync)(projectPath(repoRelPath), "utf-8");
22490
+ current = (0, import_node_fs27.readFileSync)(projectPath(repoRelPath), "utf-8");
22241
22491
  } catch {
22242
22492
  return pre.existed;
22243
22493
  }
@@ -22246,8 +22496,8 @@ function changedSinceBaseline(repoRelPath, baseline) {
22246
22496
  }
22247
22497
  function safeReadForMirror(absPath) {
22248
22498
  try {
22249
- if ((0, import_node_fs26.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
22250
- const buf = (0, import_node_fs26.readFileSync)(absPath);
22499
+ if ((0, import_node_fs27.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
22500
+ const buf = (0, import_node_fs27.readFileSync)(absPath);
22251
22501
  if (buf.includes(0)) return null;
22252
22502
  return buf.toString("utf-8");
22253
22503
  } catch {
@@ -22258,18 +22508,18 @@ function pruneOldBaselines() {
22258
22508
  const root = projectPath(BASELINE_DIR);
22259
22509
  let entries;
22260
22510
  try {
22261
- entries = (0, import_node_fs26.readdirSync)(root);
22511
+ entries = (0, import_node_fs27.readdirSync)(root);
22262
22512
  } catch {
22263
22513
  return;
22264
22514
  }
22265
22515
  const now = Date.now();
22266
22516
  for (const name2 of entries) {
22267
- const dir = (0, import_node_path23.join)(root, name2);
22517
+ const dir = (0, import_node_path24.join)(root, name2);
22268
22518
  const manifest = readManifest(dir);
22269
22519
  if (!manifest) {
22270
22520
  try {
22271
- if (now - (0, import_node_fs26.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
22272
- (0, import_node_fs26.rmSync)(dir, { recursive: true, force: true });
22521
+ if (now - (0, import_node_fs27.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
22522
+ (0, import_node_fs27.rmSync)(dir, { recursive: true, force: true });
22273
22523
  }
22274
22524
  } catch {
22275
22525
  }
@@ -22277,7 +22527,7 @@ function pruneOldBaselines() {
22277
22527
  }
22278
22528
  if (now - manifest.captured_at <= BASELINE_TTL_MS) continue;
22279
22529
  try {
22280
- (0, import_node_fs26.rmSync)(dir, { recursive: true, force: true });
22530
+ (0, import_node_fs27.rmSync)(dir, { recursive: true, force: true });
22281
22531
  } catch {
22282
22532
  }
22283
22533
  }
@@ -22452,8 +22702,8 @@ function buildCompactionContext(session) {
22452
22702
  commitsSince: commitsSincePaths(watermark, (state.authored ?? []).map((a) => a.path)),
22453
22703
  readFileLines: (file) => {
22454
22704
  try {
22455
- const abs = (0, import_node_path24.join)(root, file);
22456
- return (0, import_node_fs27.existsSync)(abs) ? (0, import_node_fs27.readFileSync)(abs, "utf8").split("\n") : null;
22705
+ const abs = (0, import_node_path25.join)(root, file);
22706
+ return (0, import_node_fs28.existsSync)(abs) ? (0, import_node_fs28.readFileSync)(abs, "utf8").split("\n") : null;
22457
22707
  } catch {
22458
22708
  return null;
22459
22709
  }
@@ -22510,24 +22760,24 @@ async function readHookStdin() {
22510
22760
 
22511
22761
  // src/commands/standard.ts
22512
22762
  var import_promises13 = require("node:fs/promises");
22513
- var import_node_fs34 = require("node:fs");
22763
+ var import_node_fs35 = require("node:fs");
22514
22764
  var import_yaml3 = __toESM2(require_dist());
22515
22765
 
22516
22766
  // src/lib/synthesize.ts
22517
22767
  var import_node_child_process9 = require("node:child_process");
22518
- var import_node_fs30 = require("node:fs");
22768
+ var import_node_fs31 = require("node:fs");
22519
22769
  var import_promises10 = require("node:fs/promises");
22520
- var import_node_path27 = require("node:path");
22770
+ var import_node_path28 = require("node:path");
22521
22771
  var import_yaml = __toESM2(require_dist());
22522
22772
 
22523
22773
  // src/lib/data-dir.ts
22524
- var import_node_fs28 = require("node:fs");
22525
- var import_node_path25 = require("node:path");
22774
+ var import_node_fs29 = require("node:fs");
22775
+ var import_node_path26 = require("node:path");
22526
22776
  function resolveDataDir() {
22527
22777
  const candidates2 = [
22528
- (0, import_node_path25.join)(__dirname, "..", "data"),
22778
+ (0, import_node_path26.join)(__dirname, "..", "data"),
22529
22779
  // installed: node_modules/@codacy/verity-cli/data
22530
- (0, import_node_path25.join)(__dirname, "..", "..", "data"),
22780
+ (0, import_node_path26.join)(__dirname, "..", "..", "data"),
22531
22781
  // edge case: nested resolution
22532
22782
  // THE COMMITTED SOURCE, for a source checkout that has not been built.
22533
22783
  // cli/data/skills/ is a BUILD ARTIFACT (scripts/build.js copies client/skills
@@ -22536,14 +22786,14 @@ function resolveDataDir() {
22536
22786
  // without this the synthesizer throws "Could not find Verity skill data"
22537
22787
  // for every test and every `verity` run from source. Resolved from this
22538
22788
  // module's own location, never the cwd: see the warning below.
22539
- (0, import_node_path25.join)(__dirname, "..", "..", "client"),
22789
+ (0, import_node_path26.join)(__dirname, "..", "..", "client"),
22540
22790
  // bundled: cli/bin/ → ../../client
22541
- (0, import_node_path25.join)(__dirname, "..", "..", "..", "client"),
22791
+ (0, import_node_path26.join)(__dirname, "..", "..", "..", "client"),
22542
22792
  // tsx: cli/src/lib/ → ../../../client
22543
22793
  ...process.env.VERITY_DEV_DATA_DIR ? [process.env.VERITY_DEV_DATA_DIR] : []
22544
22794
  ];
22545
22795
  for (const candidate of candidates2) {
22546
- if ((0, import_node_fs28.existsSync)((0, import_node_path25.join)(candidate, "skills"))) {
22796
+ if ((0, import_node_fs29.existsSync)((0, import_node_path26.join)(candidate, "skills"))) {
22547
22797
  return candidate;
22548
22798
  }
22549
22799
  }
@@ -22552,13 +22802,13 @@ function resolveDataDir() {
22552
22802
  );
22553
22803
  }
22554
22804
  function setupDataPath(file) {
22555
- return (0, import_node_path25.join)(resolveDataDir(), "skills", "verity-setup", file);
22805
+ return (0, import_node_path26.join)(resolveDataDir(), "skills", "verity-setup", file);
22556
22806
  }
22557
22807
 
22558
22808
  // src/lib/detect.ts
22559
22809
  var import_node_child_process8 = require("node:child_process");
22560
- var import_node_fs29 = require("node:fs");
22561
- var import_node_path26 = require("node:path");
22810
+ var import_node_fs30 = require("node:fs");
22811
+ var import_node_path27 = require("node:path");
22562
22812
  var TOOLED_LANGUAGES = /* @__PURE__ */ new Set([
22563
22813
  "typescript",
22564
22814
  "javascript",
@@ -22615,25 +22865,25 @@ function walk(root) {
22615
22865
  if (depth > WALK_MAX_DEPTH || found.length >= WALK_MAX_FILES) return;
22616
22866
  let entries;
22617
22867
  try {
22618
- entries = (0, import_node_fs29.readdirSync)(dir, { withFileTypes: true });
22868
+ entries = (0, import_node_fs30.readdirSync)(dir, { withFileTypes: true });
22619
22869
  } catch {
22620
22870
  return;
22621
22871
  }
22622
22872
  for (const entry of entries) {
22623
22873
  if (found.length >= WALK_MAX_FILES) return;
22624
22874
  if (IGNORED_SEGMENTS.includes(entry.name)) continue;
22625
- const full = (0, import_node_path26.join)(dir, entry.name);
22875
+ const full = (0, import_node_path27.join)(dir, entry.name);
22626
22876
  if (entry.isDirectory()) visit(full, depth + 1);
22627
- else if (entry.isFile()) found.push((0, import_node_path26.relative)(root, full));
22877
+ else if (entry.isFile()) found.push((0, import_node_path27.relative)(root, full));
22628
22878
  }
22629
22879
  };
22630
22880
  visit(root, 0);
22631
22881
  return found;
22632
22882
  }
22633
22883
  function languageOf(path) {
22634
- const name2 = (0, import_node_path26.basename)(path);
22884
+ const name2 = (0, import_node_path27.basename)(path);
22635
22885
  if (/^Dockerfile(\..+)?$/i.test(name2)) return "dockerfile";
22636
- if (!(0, import_node_path26.extname)(name2)) return null;
22886
+ if (!(0, import_node_path27.extname)(name2)) return null;
22637
22887
  const lang = detectLanguage(path);
22638
22888
  return lang || null;
22639
22889
  }
@@ -22690,7 +22940,7 @@ var TOOL_CONFIG_MARKERS = [
22690
22940
  ];
22691
22941
  function readJson2(path) {
22692
22942
  try {
22693
- return JSON.parse((0, import_node_fs29.readFileSync)(path, "utf-8"));
22943
+ return JSON.parse((0, import_node_fs30.readFileSync)(path, "utf-8"));
22694
22944
  } catch {
22695
22945
  return null;
22696
22946
  }
@@ -22715,17 +22965,17 @@ function declaredDependencies(root, files) {
22715
22965
  if (deps && typeof deps === "object") names2.push(...Object.keys(deps));
22716
22966
  }
22717
22967
  };
22718
- readPackageJson((0, import_node_path26.join)(root, "package.json"));
22719
- const nested = files.filter((f) => f.includes("/") && (0, import_node_path26.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
22720
- for (const rel of nested) readPackageJson((0, import_node_path26.join)(root, rel));
22968
+ readPackageJson((0, import_node_path27.join)(root, "package.json"));
22969
+ const nested = files.filter((f) => f.includes("/") && (0, import_node_path27.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
22970
+ for (const rel of nested) readPackageJson((0, import_node_path27.join)(root, rel));
22721
22971
  const pythonManifests = [
22722
- ...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path26.join)(root, f)),
22723
- ...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path26.join)(root, f))
22972
+ ...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path27.join)(root, f)),
22973
+ ...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path27.join)(root, f))
22724
22974
  ];
22725
22975
  for (const path of pythonManifests) {
22726
- if (!(0, import_node_fs29.existsSync)(path)) continue;
22976
+ if (!(0, import_node_fs30.existsSync)(path)) continue;
22727
22977
  try {
22728
- const text = (0, import_node_fs29.readFileSync)(path, "utf-8");
22978
+ const text = (0, import_node_fs30.readFileSync)(path, "utf-8");
22729
22979
  for (const m of text.matchAll(/^\s*["']?([A-Za-z][A-Za-z0-9._-]+)/gm)) names2.push(m[1]);
22730
22980
  for (const line2 of text.split("\n")) {
22731
22981
  if (!/dependencies\s*=/.test(line2)) continue;
@@ -22735,13 +22985,13 @@ function declaredDependencies(root, files) {
22735
22985
  }
22736
22986
  }
22737
22987
  const goMods = [
22738
- (0, import_node_path26.join)(root, "go.mod"),
22739
- ...files.filter((f) => f.includes("/") && (0, import_node_path26.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path26.join)(root, f))
22988
+ (0, import_node_path27.join)(root, "go.mod"),
22989
+ ...files.filter((f) => f.includes("/") && (0, import_node_path27.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path27.join)(root, f))
22740
22990
  ];
22741
22991
  for (const path of goMods) {
22742
- if (!(0, import_node_fs29.existsSync)(path)) continue;
22992
+ if (!(0, import_node_fs30.existsSync)(path)) continue;
22743
22993
  try {
22744
- const text = (0, import_node_fs29.readFileSync)(path, "utf-8");
22994
+ const text = (0, import_node_fs30.readFileSync)(path, "utf-8");
22745
22995
  for (const m of text.matchAll(/^\s+([\w.-]+\/[\w./-]+)\s+v/gm)) {
22746
22996
  names2.push(m[1].replace(/^github\.com\//, ""));
22747
22997
  }
@@ -22749,10 +22999,10 @@ function declaredDependencies(root, files) {
22749
22999
  }
22750
23000
  }
22751
23001
  for (const file of ["pom.xml", "build.gradle", "build.gradle.kts", "Gemfile", "Cargo.toml"]) {
22752
- const path = (0, import_node_path26.join)(root, file);
22753
- if (!(0, import_node_fs29.existsSync)(path)) continue;
23002
+ const path = (0, import_node_path27.join)(root, file);
23003
+ if (!(0, import_node_fs30.existsSync)(path)) continue;
22754
23004
  try {
22755
- const text = (0, import_node_fs29.readFileSync)(path, "utf-8");
23005
+ const text = (0, import_node_fs30.readFileSync)(path, "utf-8");
22756
23006
  for (const m of text.matchAll(/["'<]([A-Za-z][A-Za-z0-9._-]{2,})["'>]/g)) names2.push(m[1]);
22757
23007
  } catch {
22758
23008
  }
@@ -22760,7 +23010,7 @@ function declaredDependencies(root, files) {
22760
23010
  return names2;
22761
23011
  }
22762
23012
  function detectBuildSystem(root, files) {
22763
- const has = (f) => (0, import_node_fs29.existsSync)((0, import_node_path26.join)(root, f)) || files.some((p) => (0, import_node_path26.basename)(p) === f);
23013
+ const has = (f) => (0, import_node_fs30.existsSync)((0, import_node_path27.join)(root, f)) || files.some((p) => (0, import_node_path27.basename)(p) === f);
22764
23014
  if (has("pnpm-lock.yaml")) return "pnpm";
22765
23015
  if (has("yarn.lock")) return "yarn";
22766
23016
  if (has("bun.lock") || has("bun.lockb")) return "bun";
@@ -22777,8 +23027,8 @@ function detectBuildSystem(root, files) {
22777
23027
  }
22778
23028
  function detectArchitecture(root, files) {
22779
23029
  const workspaceMarkers = ["lerna.json", "pnpm-workspace.yaml", "nx.json", "turbo.json", "rush.json"];
22780
- if (workspaceMarkers.some((m) => (0, import_node_fs29.existsSync)((0, import_node_path26.join)(root, m)))) return "monorepo";
22781
- const pkg = readJson2((0, import_node_path26.join)(root, "package.json"));
23030
+ if (workspaceMarkers.some((m) => (0, import_node_fs30.existsSync)((0, import_node_path27.join)(root, m)))) return "monorepo";
23031
+ const pkg = readJson2((0, import_node_path27.join)(root, "package.json"));
22782
23032
  if (pkg && "workspaces" in pkg) return "monorepo";
22783
23033
  const manifests = files.filter((f) => /(^|\/)(package\.json|go\.mod|pyproject\.toml|Cargo\.toml|pom\.xml)$/.test(f));
22784
23034
  const nested = manifests.filter((f) => f.includes("/"));
@@ -22800,10 +23050,10 @@ function measureAvgFileLength(root, files, languages) {
22800
23050
  let total = 0;
22801
23051
  let counted = 0;
22802
23052
  for (let i2 = 0; i2 < candidates2.length; i2 += stride) {
22803
- const path = (0, import_node_path26.join)(root, candidates2[i2]);
23053
+ const path = (0, import_node_path27.join)(root, candidates2[i2]);
22804
23054
  try {
22805
- if ((0, import_node_fs29.statSync)(path).size > 2 * 1024 * 1024) continue;
22806
- total += (0, import_node_fs29.readFileSync)(path, "utf-8").split("\n").length;
23055
+ if ((0, import_node_fs30.statSync)(path).size > 2 * 1024 * 1024) continue;
23056
+ total += (0, import_node_fs30.readFileSync)(path, "utf-8").split("\n").length;
22807
23057
  counted++;
22808
23058
  } catch {
22809
23059
  }
@@ -22833,14 +23083,14 @@ function detectProject(root = repoRoot()) {
22833
23083
  const existingToolConfigs = [];
22834
23084
  for (const [tool, markers] of TOOL_CONFIG_MARKERS) {
22835
23085
  for (const marker of markers) {
22836
- if ((0, import_node_fs29.existsSync)((0, import_node_path26.join)(root, marker))) {
23086
+ if ((0, import_node_fs30.existsSync)((0, import_node_path27.join)(root, marker))) {
22837
23087
  existingToolConfigs.push({ tool, path: `./${marker}` });
22838
23088
  break;
22839
23089
  }
22840
23090
  }
22841
23091
  }
22842
23092
  return {
22843
- projectName: (0, import_node_path26.basename)(root),
23093
+ projectName: (0, import_node_path27.basename)(root),
22844
23094
  languages,
22845
23095
  languageCounts,
22846
23096
  frameworks: matchAll(dependencies, FRAMEWORK_BY_DEPENDENCY),
@@ -22938,8 +23188,8 @@ ${closingNote(input.origin)}
22938
23188
 
22939
23189
  // src/lib/synthesize.ts
22940
23190
  function loadCatalog() {
22941
- const catalog = (0, import_yaml.parse)((0, import_node_fs30.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
22942
- const template = (0, import_yaml.parse)((0, import_node_fs30.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
23191
+ const catalog = (0, import_yaml.parse)((0, import_node_fs31.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
23192
+ const template = (0, import_yaml.parse)((0, import_node_fs31.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
22943
23193
  return { catalog, template };
22944
23194
  }
22945
23195
  function selectTools(languages, intensity, catalog) {
@@ -23217,7 +23467,7 @@ function validatePatternIds() {
23217
23467
  }
23218
23468
  async function runSynthesis(opts) {
23219
23469
  const standardPath = projectPath(STANDARD_FILE);
23220
- if ((0, import_node_fs30.existsSync)(standardPath) && !opts.force) {
23470
+ if ((0, import_node_fs31.existsSync)(standardPath) && !opts.force) {
23221
23471
  return { refused: `${STANDARD_FILE} already exists \u2014 pass --force to replace it.` };
23222
23472
  }
23223
23473
  const detected = opts.detected ?? detectProject();
@@ -23286,7 +23536,7 @@ async function correctVerityMdVersion(opts) {
23286
23536
  }
23287
23537
  async function writeFileTo(relative6, body2) {
23288
23538
  const target = projectPath(relative6);
23289
- await (0, import_promises10.mkdir)((0, import_node_path27.dirname)(target), { recursive: true });
23539
+ await (0, import_promises10.mkdir)((0, import_node_path28.dirname)(target), { recursive: true });
23290
23540
  await (0, import_promises10.writeFile)(target, body2);
23291
23541
  }
23292
23542
  async function deriveConfigForStandard(standard) {
@@ -23345,11 +23595,11 @@ ${validation.detail}`);
23345
23595
 
23346
23596
  // src/lib/setup-state.ts
23347
23597
  var import_promises11 = require("node:fs/promises");
23348
- var import_node_fs31 = require("node:fs");
23598
+ var import_node_fs32 = require("node:fs");
23349
23599
  var SETUP_STATE_FILE = `${VERITY_DIR}/setup.json`;
23350
23600
  async function readSetupState() {
23351
23601
  const path = projectPath(SETUP_STATE_FILE);
23352
- if (!(0, import_node_fs31.existsSync)(path)) return null;
23602
+ if (!(0, import_node_fs32.existsSync)(path)) return null;
23353
23603
  try {
23354
23604
  const parsed = JSON.parse(await (0, import_promises11.readFile)(path, "utf-8"));
23355
23605
  return parsed && typeof parsed === "object" ? parsed : null;
@@ -23365,12 +23615,12 @@ async function writeSetupState(patch) {
23365
23615
  }
23366
23616
 
23367
23617
  // src/lib/push-setup.ts
23368
- var import_node_fs33 = require("node:fs");
23618
+ var import_node_fs34 = require("node:fs");
23369
23619
  var import_promises12 = require("node:fs/promises");
23370
23620
  var import_yaml2 = __toESM2(require_dist());
23371
23621
 
23372
23622
  // src/lib/verityignore.ts
23373
- var import_node_fs32 = require("node:fs");
23623
+ var import_node_fs33 = require("node:fs");
23374
23624
  var EMPTY = { rules: [], securityOverlap: [], problems: [] };
23375
23625
  var SECURITY_PROBES = [
23376
23626
  ".env",
@@ -23463,9 +23713,9 @@ function isIgnored3(ig, path) {
23463
23713
  }
23464
23714
  function loadVerityIgnore() {
23465
23715
  const file = projectPath(VERITYIGNORE_FILE);
23466
- if (!(0, import_node_fs32.existsSync)(file)) return EMPTY;
23716
+ if (!(0, import_node_fs33.existsSync)(file)) return EMPTY;
23467
23717
  try {
23468
- return parseVerityIgnore((0, import_node_fs32.readFileSync)(file, "utf-8"));
23718
+ return parseVerityIgnore((0, import_node_fs33.readFileSync)(file, "utf-8"));
23469
23719
  } catch {
23470
23720
  return EMPTY;
23471
23721
  }
@@ -23503,9 +23753,9 @@ function buildStandardUpload(standard, ignoreRaw) {
23503
23753
  }
23504
23754
  function readVerityIgnoreRaw() {
23505
23755
  const file = projectPath(VERITYIGNORE_FILE);
23506
- if (!(0, import_node_fs32.existsSync)(file)) return null;
23756
+ if (!(0, import_node_fs33.existsSync)(file)) return null;
23507
23757
  try {
23508
- return (0, import_node_fs32.readFileSync)(file, "utf-8");
23758
+ return (0, import_node_fs33.readFileSync)(file, "utf-8");
23509
23759
  } catch {
23510
23760
  return null;
23511
23761
  }
@@ -23533,7 +23783,7 @@ async function pushStandardAndConfig(globals, what = {}) {
23533
23783
  }
23534
23784
  let standardVersion = null;
23535
23785
  const standardPath = projectPath(STANDARD_FILE);
23536
- if (pushStandard && (0, import_node_fs33.existsSync)(standardPath)) {
23786
+ if (pushStandard && (0, import_node_fs34.existsSync)(standardPath)) {
23537
23787
  try {
23538
23788
  const content = (0, import_yaml2.parse)(await (0, import_promises12.readFile)(standardPath, "utf-8"));
23539
23789
  const upload = buildStandardUpload(content, readVerityIgnoreRaw());
@@ -23558,7 +23808,7 @@ async function pushStandardAndConfig(globals, what = {}) {
23558
23808
  }
23559
23809
  let configPushed = false;
23560
23810
  const configPath = projectPath(CODACY_CONFIG_FILE);
23561
- if (pushConfig && (0, import_node_fs33.existsSync)(configPath)) {
23811
+ if (pushConfig && (0, import_node_fs34.existsSync)(configPath)) {
23562
23812
  try {
23563
23813
  const content = JSON.parse(await (0, import_promises12.readFile)(configPath, "utf-8"));
23564
23814
  const result = await apiRequest({
@@ -23590,7 +23840,7 @@ function registerStandardCommands(program2) {
23590
23840
  const state = await readSetupState();
23591
23841
  if (opts.configOnly) {
23592
23842
  const standardPath = projectPath(STANDARD_FILE);
23593
- if (!(0, import_node_fs34.existsSync)(standardPath)) {
23843
+ if (!(0, import_node_fs35.existsSync)(standardPath)) {
23594
23844
  printError(`No ${STANDARD_FILE} here \u2014 run "verity standard synthesize" to create one.`);
23595
23845
  process.exit(1);
23596
23846
  }
@@ -23936,10 +24186,10 @@ function formatRunDetail(run4) {
23936
24186
  }
23937
24187
 
23938
24188
  // src/lib/ignore-declaration.ts
23939
- var import_node_fs36 = require("node:fs");
24189
+ var import_node_fs37 = require("node:fs");
23940
24190
 
23941
24191
  // src/lib/debounce.ts
23942
- var import_node_fs35 = require("node:fs");
24192
+ var import_node_fs36 = require("node:fs");
23943
24193
  var import_node_crypto11 = require("node:crypto");
23944
24194
  function scopedFile(base, sessionId) {
23945
24195
  if (!sessionId) return base;
@@ -23947,9 +24197,9 @@ function scopedFile(base, sessionId) {
23947
24197
  }
23948
24198
  function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
23949
24199
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
23950
- if (!(0, import_node_fs35.existsSync)(file)) return null;
24200
+ if (!(0, import_node_fs36.existsSync)(file)) return null;
23951
24201
  try {
23952
- const lastTs = parseInt((0, import_node_fs35.readFileSync)(file, "utf-8").trim(), 10);
24202
+ const lastTs = parseInt((0, import_node_fs36.readFileSync)(file, "utf-8").trim(), 10);
23953
24203
  const nowTs = Math.floor(Date.now() / 1e3);
23954
24204
  const elapsed = nowTs - lastTs;
23955
24205
  if (elapsed < debounceSeconds) {
@@ -23962,10 +24212,10 @@ function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
23962
24212
  function checkMtime(files, bypassForRecentCommits, sessionId) {
23963
24213
  if (bypassForRecentCommits) return null;
23964
24214
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
23965
- if (!(0, import_node_fs35.existsSync)(file)) return null;
24215
+ if (!(0, import_node_fs36.existsSync)(file)) return null;
23966
24216
  let debounceTime;
23967
24217
  try {
23968
- debounceTime = (0, import_node_fs35.statSync)(file).mtimeMs;
24218
+ debounceTime = (0, import_node_fs36.statSync)(file).mtimeMs;
23969
24219
  } catch {
23970
24220
  return null;
23971
24221
  }
@@ -23973,7 +24223,7 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
23973
24223
  const resolved = resolveFile(f);
23974
24224
  if (!resolved) continue;
23975
24225
  try {
23976
- const stat3 = (0, import_node_fs35.statSync)(resolved);
24226
+ const stat3 = (0, import_node_fs36.statSync)(resolved);
23977
24227
  if (stat3.mtimeMs > debounceTime) {
23978
24228
  return null;
23979
24229
  }
@@ -23989,8 +24239,8 @@ function computeContentHash(files) {
23989
24239
  for (const f of sorted) {
23990
24240
  const resolved = resolveFile(f) ?? f;
23991
24241
  try {
23992
- if ((0, import_node_fs35.existsSync)(resolved)) {
23993
- hash.update((0, import_node_fs35.readFileSync)(resolved));
24242
+ if ((0, import_node_fs36.existsSync)(resolved)) {
24243
+ hash.update((0, import_node_fs36.readFileSync)(resolved));
23994
24244
  }
23995
24245
  } catch {
23996
24246
  }
@@ -24000,9 +24250,9 @@ function computeContentHash(files) {
24000
24250
  function checkContentHash(files, sessionId) {
24001
24251
  const hash = computeContentHash(files);
24002
24252
  const file = scopedFile(HASH_FILE, sessionId);
24003
- if ((0, import_node_fs35.existsSync)(file)) {
24253
+ if ((0, import_node_fs36.existsSync)(file)) {
24004
24254
  try {
24005
- const storedHash = (0, import_node_fs35.readFileSync)(file, "utf-8").trim();
24255
+ const storedHash = (0, import_node_fs36.readFileSync)(file, "utf-8").trim();
24006
24256
  if (hash === storedHash) {
24007
24257
  return { skip: "No source changes since last analysis", hash };
24008
24258
  }
@@ -24012,24 +24262,24 @@ function checkContentHash(files, sessionId) {
24012
24262
  return { skip: null, hash };
24013
24263
  }
24014
24264
  function recordAnalysisStart(sessionId) {
24015
- (0, import_node_fs35.mkdirSync)(VERITY_DIR, { recursive: true });
24016
- (0, import_node_fs35.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
24265
+ (0, import_node_fs36.mkdirSync)(VERITY_DIR, { recursive: true });
24266
+ (0, import_node_fs36.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
24017
24267
  }
24018
24268
  function recordPassHash(hash, sessionId) {
24019
- (0, import_node_fs35.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
24269
+ (0, import_node_fs36.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
24020
24270
  }
24021
24271
  function narrowToRecent(files, sessionId) {
24022
24272
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
24023
- if (!(0, import_node_fs35.existsSync)(file)) return files;
24273
+ if (!(0, import_node_fs36.existsSync)(file)) return files;
24024
24274
  let debounceTime;
24025
24275
  try {
24026
- debounceTime = (0, import_node_fs35.statSync)(file).mtimeMs;
24276
+ debounceTime = (0, import_node_fs36.statSync)(file).mtimeMs;
24027
24277
  } catch {
24028
24278
  return files;
24029
24279
  }
24030
24280
  const recent = files.filter((f) => {
24031
24281
  try {
24032
- return (0, import_node_fs35.existsSync)(f) && (0, import_node_fs35.statSync)(f).mtimeMs > debounceTime;
24282
+ return (0, import_node_fs36.existsSync)(f) && (0, import_node_fs36.statSync)(f).mtimeMs > debounceTime;
24033
24283
  } catch {
24034
24284
  return false;
24035
24285
  }
@@ -24042,9 +24292,9 @@ function readIteration(currentCommit, _contentHash) {
24042
24292
  var NO_BLOCKS = { attempts: 0, blocks: 0, fingerprint: null };
24043
24293
  function readBlockState(currentCommit, opts) {
24044
24294
  if (opts?.newUserPrompt) return NO_BLOCKS;
24045
- if (!(0, import_node_fs35.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
24295
+ if (!(0, import_node_fs36.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
24046
24296
  try {
24047
- const stored = (0, import_node_fs35.readFileSync)(ITERATION_FILE, "utf-8").trim();
24297
+ const stored = (0, import_node_fs36.readFileSync)(ITERATION_FILE, "utf-8").trim();
24048
24298
  const parsed = stored.startsWith("{") ? parseJsonState(stored) : parseLegacyState(stored);
24049
24299
  if (!parsed) return NO_BLOCKS;
24050
24300
  if (parsed.commit !== currentCommit) return NO_BLOCKS;
@@ -24090,8 +24340,8 @@ function isSameProblem(previous, current) {
24090
24340
  return current.split(",").some((k) => prev.has(k));
24091
24341
  }
24092
24342
  function writeBlockState(commit, state) {
24093
- (0, import_node_fs35.mkdirSync)(VERITY_DIR, { recursive: true });
24094
- (0, import_node_fs35.writeFileSync)(
24343
+ (0, import_node_fs36.mkdirSync)(VERITY_DIR, { recursive: true });
24344
+ (0, import_node_fs36.writeFileSync)(
24095
24345
  ITERATION_FILE,
24096
24346
  JSON.stringify({
24097
24347
  v: 2,
@@ -24196,9 +24446,9 @@ function resolveIgnoreState(keys) {
24196
24446
  }
24197
24447
  function readIgnoreState(sessionId) {
24198
24448
  const file = stateFile(sessionId);
24199
- if (!(0, import_node_fs36.existsSync)(file)) return null;
24449
+ if (!(0, import_node_fs37.existsSync)(file)) return null;
24200
24450
  try {
24201
- const o = JSON.parse((0, import_node_fs36.readFileSync)(file, "utf-8")) ?? {};
24451
+ const o = JSON.parse((0, import_node_fs37.readFileSync)(file, "utf-8")) ?? {};
24202
24452
  const spent = typeof o.spent === "number" ? o.spent : 0;
24203
24453
  const raw = o.active;
24204
24454
  let active = null;
@@ -24222,8 +24472,8 @@ function readIgnoreState(sessionId) {
24222
24472
  }
24223
24473
  function writeIgnoreState(state, sessionId) {
24224
24474
  try {
24225
- (0, import_node_fs36.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
24226
- (0, import_node_fs36.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
24475
+ (0, import_node_fs37.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
24476
+ (0, import_node_fs37.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
24227
24477
  } catch {
24228
24478
  }
24229
24479
  }
@@ -24606,7 +24856,7 @@ function createRun(opts, globals) {
24606
24856
  }
24607
24857
 
24608
24858
  // src/commands/analyze/index.ts
24609
- var import_node_fs50 = require("node:fs");
24859
+ var import_node_fs51 = require("node:fs");
24610
24860
 
24611
24861
  // src/lib/repo-context.ts
24612
24862
  var import_node_child_process11 = require("node:child_process");
@@ -25645,10 +25895,10 @@ function installRunEvidence(run4) {
25645
25895
  }
25646
25896
 
25647
25897
  // src/lib/git-frame.ts
25648
- var import_node_fs37 = require("node:fs");
25898
+ var import_node_fs38 = require("node:fs");
25649
25899
  var import_node_os6 = require("node:os");
25650
- var import_node_path28 = require("node:path");
25651
25900
  var import_node_path29 = require("node:path");
25901
+ var import_node_path30 = require("node:path");
25652
25902
  var VALUE_TOKEN = `(?:'[^']*'|"[^"]*"|\\S+)`;
25653
25903
  var GIT_GLOBAL_OPTS = `(?:\\s+(?:-[Cc]\\s+${VALUE_TOKEN}|--?[\\w-]+(?:=\\S+)?))*`;
25654
25904
  var COMMIT_HEAD = `git${GIT_GLOBAL_OPTS}\\s+commit(?![\\w-])`;
@@ -25735,8 +25985,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
25735
25985
  if (SHELL_DYNAMIC.test(raw) || raw === "-") {
25736
25986
  return { dir: null, named: true, unresolvable: `cd target not statically resolvable: ${raw}` };
25737
25987
  }
25738
- const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path29.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
25739
- dir = (0, import_node_path28.isAbsolute)(expanded) ? expanded : (0, import_node_path28.resolve)(dir, expanded);
25988
+ const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path30.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
25989
+ dir = (0, import_node_path29.isAbsolute)(expanded) ? expanded : (0, import_node_path29.resolve)(dir, expanded);
25740
25990
  }
25741
25991
  const seg = segments[segmentIndex];
25742
25992
  const overrideMatch = /--(?:git-dir|work-tree)(?:=|\s)|\bGIT_(?:DIR|WORK_TREE|INDEX_FILE)=/.exec(seg);
@@ -25754,8 +26004,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
25754
26004
  if (SHELL_DYNAMIC.test(raw)) {
25755
26005
  return { dir: null, named: true, unresolvable: `-C target not statically resolvable: ${raw}` };
25756
26006
  }
25757
- const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path29.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
25758
- dir = (0, import_node_path28.isAbsolute)(expanded) ? expanded : (0, import_node_path28.resolve)(dir, expanded);
26007
+ const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path30.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
26008
+ dir = (0, import_node_path29.isAbsolute)(expanded) ? expanded : (0, import_node_path29.resolve)(dir, expanded);
25759
26009
  }
25760
26010
  }
25761
26011
  return { dir, named, unresolvable: null };
@@ -25815,14 +26065,14 @@ function gitAt(dir, args2) {
25815
26065
  }
25816
26066
  function realpathOr2(p) {
25817
26067
  try {
25818
- return import_node_fs37.realpathSync.native(p);
26068
+ return import_node_fs38.realpathSync.native(p);
25819
26069
  } catch {
25820
- return (0, import_node_path28.resolve)(p);
26070
+ return (0, import_node_path29.resolve)(p);
25821
26071
  }
25822
26072
  }
25823
26073
  function resolveFrame(input) {
25824
26074
  const found = findMomentSegment(input.command, input.on);
25825
- const hookDirUsable = !!input.hookCwd && (0, import_node_fs37.existsSync)(input.hookCwd);
26075
+ const hookDirUsable = !!input.hookCwd && (0, import_node_fs38.existsSync)(input.hookCwd);
25826
26076
  const baseDir = hookDirUsable ? input.hookCwd : process.cwd();
25827
26077
  let anchor = hookDirUsable ? "hook-cwd" : "process-cwd";
25828
26078
  const refuse = (refusal) => ({
@@ -25845,7 +26095,7 @@ function resolveFrame(input) {
25845
26095
  if (dirs.size > 1) return refuse(`target:multiple ${found.moment} targets in one command`);
25846
26096
  const targetDir = dirs.size === 1 ? [...dirs][0] : baseDir;
25847
26097
  if (targetDir !== baseDir) {
25848
- if (!(0, import_node_fs37.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
26098
+ if (!(0, import_node_fs38.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
25849
26099
  dir = targetDir;
25850
26100
  }
25851
26101
  }
@@ -25856,7 +26106,7 @@ function resolveFrame(input) {
25856
26106
  const gitDirRaw = gitAt(dir, ["rev-parse", "--absolute-git-dir"]);
25857
26107
  const commonRaw = gitAt(dir, ["rev-parse", "--git-common-dir"]);
25858
26108
  const gitDir = gitDirRaw ? realpathOr2(gitDirRaw) : null;
25859
- const commonDir = commonRaw ? realpathOr2((0, import_node_path28.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path28.resolve)(dir, commonRaw)) : null;
26109
+ const commonDir = commonRaw ? realpathOr2((0, import_node_path29.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path29.resolve)(dir, commonRaw)) : null;
25860
26110
  const branchRaw = gitAt(dir, ["rev-parse", "--abbrev-ref", "HEAD"]);
25861
26111
  return {
25862
26112
  moment: found?.moment ?? null,
@@ -26031,8 +26281,8 @@ function stagedRange(frame, command) {
26031
26281
  if (plan.kind === "unpredictable") {
26032
26282
  return { kind: "staged", base: "HEAD", head: "INDEX", via: "staged-in-command", refusal: plan.reason };
26033
26283
  }
26034
- const mergeHead = frame.gitDir ? (0, import_node_path29.join)(frame.gitDir, "MERGE_HEAD") : null;
26035
- if (mergeHead && (0, import_node_fs37.existsSync)(mergeHead)) {
26284
+ const mergeHead = frame.gitDir ? (0, import_node_path30.join)(frame.gitDir, "MERGE_HEAD") : null;
26285
+ if (mergeHead && (0, import_node_fs38.existsSync)(mergeHead)) {
26036
26286
  const vsHead = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "HEAD"]).split("\n").filter(Boolean));
26037
26287
  const vsMerge = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "MERGE_HEAD"]).split("\n").filter(Boolean));
26038
26288
  const resolutions = new Set([...vsHead].filter((f) => vsMerge.has(f) && !isVerityOwnedPath(f)));
@@ -26166,7 +26416,7 @@ function truthy(v) {
26166
26416
  }
26167
26417
 
26168
26418
  // src/lib/transcript.ts
26169
- var import_node_fs38 = require("node:fs");
26419
+ var import_node_fs39 = require("node:fs");
26170
26420
  var MAX_READ_BYTES = 256 * 1024;
26171
26421
  var SMALL_FILE_BYTES = 64 * 1024;
26172
26422
  var MAX_FILES_LIST = 20;
@@ -26193,7 +26443,7 @@ async function extractActionSummary(transcriptPath) {
26193
26443
  function readTurnLines(transcriptPath) {
26194
26444
  let size;
26195
26445
  try {
26196
- size = (0, import_node_fs38.statSync)(transcriptPath).size;
26446
+ size = (0, import_node_fs39.statSync)(transcriptPath).size;
26197
26447
  } catch {
26198
26448
  return null;
26199
26449
  }
@@ -26201,7 +26451,7 @@ function readTurnLines(transcriptPath) {
26201
26451
  let raw;
26202
26452
  let windowed = false;
26203
26453
  if (size <= SMALL_FILE_BYTES) {
26204
- raw = (0, import_node_fs38.readFileSync)(transcriptPath, "utf-8");
26454
+ raw = (0, import_node_fs39.readFileSync)(transcriptPath, "utf-8");
26205
26455
  } else {
26206
26456
  windowed = true;
26207
26457
  const buf = Buffer.alloc(Math.min(MAX_READ_BYTES, size));
@@ -26771,7 +27021,7 @@ function channelSilence(input) {
26771
27021
  // src/lib/cli-version.ts
26772
27022
  function cliVersion() {
26773
27023
  try {
26774
- return true ? "0.33.3-experimental.53cd005" : "dev";
27024
+ return true ? "0.33.3-experimental.5a3f573" : "dev";
26775
27025
  } catch {
26776
27026
  return "dev";
26777
27027
  }
@@ -26812,7 +27062,7 @@ async function sendSkipBeacon(ctx, reason) {
26812
27062
 
26813
27063
  // src/lib/static-analysis.ts
26814
27064
  var import_node_child_process12 = require("node:child_process");
26815
- var import_node_fs39 = require("node:fs");
27065
+ var import_node_fs40 = require("node:fs");
26816
27066
  var SEVERITY_ORDER = {
26817
27067
  Error: 0,
26818
27068
  Critical: 0,
@@ -26868,7 +27118,7 @@ function runCodacyAnalysis(files) {
26868
27118
  if (files.length === 0) return empty;
26869
27119
  const existingFiles = files.filter((f) => {
26870
27120
  try {
26871
- return (0, import_node_fs39.existsSync)(f);
27121
+ return (0, import_node_fs40.existsSync)(f);
26872
27122
  } catch {
26873
27123
  return false;
26874
27124
  }
@@ -27137,8 +27387,8 @@ async function scope(run4) {
27137
27387
  }
27138
27388
 
27139
27389
  // src/lib/specs.ts
27140
- var import_node_fs40 = require("node:fs");
27141
- var import_node_path30 = require("node:path");
27390
+ var import_node_fs41 = require("node:fs");
27391
+ var import_node_path31 = require("node:path");
27142
27392
  var SPEC_CANDIDATES = [
27143
27393
  "CLAUDE.md",
27144
27394
  "AGENTS.md",
@@ -27160,7 +27410,7 @@ var UNCONSULTED_TOTAL_BYTES = 30720;
27160
27410
  function readSpecFiles(specsOpt, root) {
27161
27411
  const out2 = [];
27162
27412
  for (const raw of specsOpt.split(",").map((f) => f.trim()).filter(Boolean)) {
27163
- const candidate = (0, import_node_path30.isAbsolute)(raw) ? (0, import_node_path30.relative)(root, raw) : raw;
27413
+ const candidate = (0, import_node_path31.isAbsolute)(raw) ? (0, import_node_path31.relative)(root, raw) : raw;
27164
27414
  const content = readFileInside(root, candidate, MAX_EXPLICIT_SPEC_FILE_BYTES);
27165
27415
  if (content === null) continue;
27166
27416
  out2.push({ path: raw, content });
@@ -27179,7 +27429,7 @@ function discoverSpecs(consulted = []) {
27179
27429
  const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
27180
27430
  if (totalBytes >= totalCap) return false;
27181
27431
  if (seen.has(specPath)) return true;
27182
- if (!(0, import_node_fs40.existsSync)(specPath)) return true;
27432
+ if (!(0, import_node_fs41.existsSync)(specPath)) return true;
27183
27433
  seen.add(specPath);
27184
27434
  const remaining = totalCap - totalBytes;
27185
27435
  const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
@@ -27202,7 +27452,7 @@ function discoverSpecs(consulted = []) {
27202
27452
  if (!addSpec(candidate)) break;
27203
27453
  }
27204
27454
  for (const dir of ["spec", "docs"]) {
27205
- if (!(0, import_node_fs40.existsSync)(dir)) continue;
27455
+ if (!(0, import_node_fs41.existsSync)(dir)) continue;
27206
27456
  try {
27207
27457
  const mdFiles = findMdFiles(dir, 2).sort();
27208
27458
  for (const mdFile of mdFiles) {
@@ -27217,9 +27467,9 @@ function findMdFiles(dir, maxDepth, depth = 0) {
27217
27467
  if (depth >= maxDepth) return [];
27218
27468
  const result = [];
27219
27469
  try {
27220
- const entries = (0, import_node_fs40.readdirSync)(dir, { withFileTypes: true });
27470
+ const entries = (0, import_node_fs41.readdirSync)(dir, { withFileTypes: true });
27221
27471
  for (const entry of entries) {
27222
- const fullPath = (0, import_node_path30.join)(dir, entry.name);
27472
+ const fullPath = (0, import_node_path31.join)(dir, entry.name);
27223
27473
  if (entry.isFile() && entry.name.endsWith(".md")) {
27224
27474
  result.push(fullPath);
27225
27475
  } else if (entry.isDirectory() && depth < maxDepth - 1) {
@@ -27232,25 +27482,25 @@ function findMdFiles(dir, maxDepth, depth = 0) {
27232
27482
  }
27233
27483
  function discoverPlans() {
27234
27484
  const home = process.env.HOME ?? "";
27235
- const homePlansDir = (0, import_node_path30.join)(home, ".claude", "plans");
27485
+ const homePlansDir = (0, import_node_path31.join)(home, ".claude", "plans");
27236
27486
  const sources = [];
27237
27487
  if (isRealDirectoryChain(process.cwd(), [".claude", "plans"])) {
27238
- sources.push({ root: process.cwd(), prefix: (0, import_node_path30.join)(".claude", "plans") });
27488
+ sources.push({ root: process.cwd(), prefix: (0, import_node_path31.join)(".claude", "plans") });
27239
27489
  }
27240
- if (home && (0, import_node_fs40.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
27490
+ if (home && (0, import_node_fs41.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
27241
27491
  const candidates2 = [];
27242
27492
  const seen = /* @__PURE__ */ new Set();
27243
27493
  for (const source2 of sources) {
27244
27494
  let names2;
27245
27495
  try {
27246
- names2 = (0, import_node_fs40.readdirSync)(source2.prefix ? (0, import_node_path30.join)(source2.root, source2.prefix) : source2.root);
27496
+ names2 = (0, import_node_fs41.readdirSync)(source2.prefix ? (0, import_node_path31.join)(source2.root, source2.prefix) : source2.root);
27247
27497
  } catch {
27248
27498
  continue;
27249
27499
  }
27250
27500
  for (const f of names2) {
27251
27501
  if (!f.endsWith(".md") || seen.has(f)) continue;
27252
27502
  seen.add(f);
27253
- const relPath = source2.prefix ? (0, import_node_path30.join)(source2.prefix, f) : f;
27503
+ const relPath = source2.prefix ? (0, import_node_path31.join)(source2.prefix, f) : f;
27254
27504
  const stat3 = statRegularInRoot(source2.root, relPath);
27255
27505
  if (!stat3.ok) continue;
27256
27506
  candidates2.push({ name: f, root: source2.root, relPath, mtime: stat3.mtimeMs, size: stat3.size });
@@ -27268,9 +27518,9 @@ function discoverPlans() {
27268
27518
  function isRealDirectoryChain(root, parts2) {
27269
27519
  let current = root;
27270
27520
  for (const part of parts2) {
27271
- current = (0, import_node_path30.join)(current, part);
27521
+ current = (0, import_node_path31.join)(current, part);
27272
27522
  try {
27273
- if (!(0, import_node_fs40.lstatSync)(current).isDirectory()) return false;
27523
+ if (!(0, import_node_fs41.lstatSync)(current).isDirectory()) return false;
27274
27524
  } catch {
27275
27525
  return false;
27276
27526
  }
@@ -27285,7 +27535,7 @@ function discoverGuardDocs(rangeFiles2) {
27285
27535
  if (result.length >= MAX_SPEC_FILES) break;
27286
27536
  if (!GUARD_DOC_EXT.test(path)) continue;
27287
27537
  if (path.startsWith("/") || path.includes("..")) continue;
27288
- if (!(0, import_node_fs40.existsSync)(path)) continue;
27538
+ if (!(0, import_node_fs41.existsSync)(path)) continue;
27289
27539
  const opened = openRegularInRoot(process.cwd(), path);
27290
27540
  if (!opened.ok) continue;
27291
27541
  if (opened.size > MAX_PLAN_FILE_BYTES || totalBytes + opened.size > MAX_TOTAL_SPEC_BYTES) {
@@ -27471,8 +27721,8 @@ async function mode(run4) {
27471
27721
  }
27472
27722
 
27473
27723
  // src/lib/fold.ts
27474
- var import_node_fs41 = require("node:fs");
27475
- var import_node_path31 = require("node:path");
27724
+ var import_node_fs42 = require("node:fs");
27725
+ var import_node_path32 = require("node:path");
27476
27726
  var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
27477
27727
  "user",
27478
27728
  "assistant",
@@ -27609,7 +27859,7 @@ function candidateRoots(repoRoot2) {
27609
27859
  const norm = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
27610
27860
  const out2 = [norm];
27611
27861
  try {
27612
- const real = import_node_fs41.realpathSync.native(norm).replace(/\\/g, "/").replace(/\/+$/, "");
27862
+ const real = import_node_fs42.realpathSync.native(norm).replace(/\\/g, "/").replace(/\/+$/, "");
27613
27863
  if (real !== norm) out2.push(real);
27614
27864
  } catch {
27615
27865
  }
@@ -27697,31 +27947,31 @@ function fold(transcriptPath, opts = {}) {
27697
27947
  }
27698
27948
  };
27699
27949
  try {
27700
- if (!(0, import_node_fs41.existsSync)(transcriptPath)) return result;
27701
- ingest((0, import_node_fs41.readFileSync)(transcriptPath, "utf8"), "agent");
27950
+ if (!(0, import_node_fs42.existsSync)(transcriptPath)) return result;
27951
+ ingest((0, import_node_fs42.readFileSync)(transcriptPath, "utf8"), "agent");
27702
27952
  result.coverage.complete = true;
27703
27953
  } catch {
27704
27954
  return result;
27705
27955
  }
27706
27956
  try {
27707
- const sidecarDir = (0, import_node_path31.join)(
27708
- (0, import_node_path31.dirname)(transcriptPath),
27709
- (0, import_node_path31.basename)(transcriptPath).replace(/\.jsonl$/, ""),
27957
+ const sidecarDir = (0, import_node_path32.join)(
27958
+ (0, import_node_path32.dirname)(transcriptPath),
27959
+ (0, import_node_path32.basename)(transcriptPath).replace(/\.jsonl$/, ""),
27710
27960
  "subagents"
27711
27961
  );
27712
- if ((0, import_node_fs41.existsSync)(sidecarDir)) {
27962
+ if ((0, import_node_fs42.existsSync)(sidecarDir)) {
27713
27963
  const maxFiles = opts.maxSidecars ?? 200;
27714
27964
  const maxBytes = opts.maxSidecarBytes ?? 16 * 1024 * 1024;
27715
27965
  const found = [];
27716
27966
  const walk2 = (d, depth) => {
27717
27967
  if (depth > 4) return;
27718
- for (const e of (0, import_node_fs41.readdirSync)(d, { withFileTypes: true })) {
27719
- const p = (0, import_node_path31.join)(d, e.name);
27968
+ for (const e of (0, import_node_fs42.readdirSync)(d, { withFileTypes: true })) {
27969
+ const p = (0, import_node_path32.join)(d, e.name);
27720
27970
  if (e.isDirectory()) {
27721
27971
  walk2(p, depth + 1);
27722
27972
  } else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
27723
27973
  try {
27724
- const st = (0, import_node_fs41.statSync)(p);
27974
+ const st = (0, import_node_fs42.statSync)(p);
27725
27975
  found.push({ path: p, size: st.size, mtimeMs: st.mtimeMs });
27726
27976
  } catch {
27727
27977
  result.coverage.malformed++;
@@ -27738,7 +27988,7 @@ function fold(transcriptPath, opts = {}) {
27738
27988
  continue;
27739
27989
  }
27740
27990
  try {
27741
- ingest((0, import_node_fs41.readFileSync)(f.path, "utf8"), "subagent");
27991
+ ingest((0, import_node_fs42.readFileSync)(f.path, "utf8"), "subagent");
27742
27992
  bytes += f.size;
27743
27993
  result.coverage.subagentFiles++;
27744
27994
  } catch {
@@ -27773,7 +28023,7 @@ function fold(transcriptPath, opts = {}) {
27773
28023
  }
27774
28024
  function classifyUnobserved(path) {
27775
28025
  try {
27776
- const st = (0, import_node_fs41.statSync)(path);
28026
+ const st = (0, import_node_fs42.statSync)(path);
27777
28027
  if (!st.isFile()) return "unreadable";
27778
28028
  } catch {
27779
28029
  return "unreadable";
@@ -28088,20 +28338,20 @@ async function evidence(run4) {
28088
28338
  }
28089
28339
 
28090
28340
  // src/lib/cache-cleanup.ts
28091
- var import_node_fs42 = require("node:fs");
28092
- var import_node_path32 = require("node:path");
28341
+ var import_node_fs43 = require("node:fs");
28342
+ var import_node_path33 = require("node:path");
28093
28343
  var CACHE_TTL_DAYS = 7;
28094
28344
  function pruneStaleCache() {
28095
28345
  try {
28096
28346
  const dir = projectPath(CACHE_DIR);
28097
28347
  const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
28098
- for (const entry of (0, import_node_fs42.readdirSync)(dir)) {
28348
+ for (const entry of (0, import_node_fs43.readdirSync)(dir)) {
28099
28349
  if (!entry.startsWith("pending-")) continue;
28100
- const path = (0, import_node_path32.join)(dir, entry);
28350
+ const path = (0, import_node_path33.join)(dir, entry);
28101
28351
  try {
28102
- const stat3 = (0, import_node_fs42.statSync)(path);
28352
+ const stat3 = (0, import_node_fs43.statSync)(path);
28103
28353
  if (stat3.mtimeMs < cutoff) {
28104
- (0, import_node_fs42.unlinkSync)(path);
28354
+ (0, import_node_fs43.unlinkSync)(path);
28105
28355
  logEvent("cache_entry_pruned", {
28106
28356
  path: entry,
28107
28357
  age_days: Math.round((Date.now() - stat3.mtimeMs) / 864e5)
@@ -28115,7 +28365,7 @@ function pruneStaleCache() {
28115
28365
  }
28116
28366
 
28117
28367
  // src/lib/context-files.ts
28118
- var import_node_fs43 = require("node:fs");
28368
+ var import_node_fs44 = require("node:fs");
28119
28369
  var import_node_os7 = require("node:os");
28120
28370
  var MAX_CONTEXT_FILES = 10;
28121
28371
  var MAX_CONTEXT_FILE_BYTES = 10240;
@@ -28173,7 +28423,7 @@ function gatherContextFiles(contextPaths, deltaFiles, opts) {
28173
28423
  continue;
28174
28424
  }
28175
28425
  try {
28176
- const content = (0, import_node_fs43.readFileSync)(safePath, "utf8");
28426
+ const content = (0, import_node_fs44.readFileSync)(safePath, "utf8");
28177
28427
  const bytes = Buffer.byteLength(content);
28178
28428
  if (bytes > MAX_CONTEXT_FILE_BYTES) {
28179
28429
  logEvent("context_file_skipped", { path: filePath, reason: "too_large", bytes });
@@ -28331,8 +28581,8 @@ function languageOf2(path) {
28331
28581
  }
28332
28582
 
28333
28583
  // src/lib/code/runtime.ts
28334
- var import_node_fs44 = require("node:fs");
28335
- var import_node_path33 = require("node:path");
28584
+ var import_node_fs45 = require("node:fs");
28585
+ var import_node_path34 = require("node:path");
28336
28586
  var import_web_tree_sitter2 = __toESM2(require_web_tree_sitter2());
28337
28587
 
28338
28588
  // src/lib/code/grammars.json
@@ -28392,18 +28642,18 @@ var grammars_default = {
28392
28642
  var MAX_PARSE_BYTES = 512 * 1024;
28393
28643
  function grammarCandidates(file, pkg, env = process.env) {
28394
28644
  return [
28395
- ...env.VERITY_GRAMMAR_DIR ? [(0, import_node_path33.join)(env.VERITY_GRAMMAR_DIR, file)] : [],
28396
- (0, import_node_path33.join)(__dirname, "..", "data", "grammars", file),
28645
+ ...env.VERITY_GRAMMAR_DIR ? [(0, import_node_path34.join)(env.VERITY_GRAMMAR_DIR, file)] : [],
28646
+ (0, import_node_path34.join)(__dirname, "..", "data", "grammars", file),
28397
28647
  // bundled: cli/bin/ → cli/data/grammars/
28398
- (0, import_node_path33.join)(__dirname, "..", "..", "..", "data", "grammars", file),
28648
+ (0, import_node_path34.join)(__dirname, "..", "..", "..", "data", "grammars", file),
28399
28649
  // tsx: cli/src/lib/code/ → cli/data/grammars/
28400
- (0, import_node_path33.join)(__dirname, "..", "..", "..", "node_modules", pkg, file)
28650
+ (0, import_node_path34.join)(__dirname, "..", "..", "..", "node_modules", pkg, file)
28401
28651
  // tsx, before a build: the pinned devDependency
28402
28652
  ];
28403
28653
  }
28404
28654
  function locateGrammar(id, env = process.env) {
28405
28655
  const g = grammars_default[id];
28406
- return grammarCandidates(g.file, g.package, env).find((p) => (0, import_node_fs44.existsSync)(p)) ?? null;
28656
+ return grammarCandidates(g.file, g.package, env).find((p) => (0, import_node_fs45.existsSync)(p)) ?? null;
28407
28657
  }
28408
28658
  var loading = null;
28409
28659
  function loadRuntime(env = process.env) {
@@ -29530,7 +29780,7 @@ var MAX_CALLERS = 30;
29530
29780
  var MAX_READ_BYTES4 = 512 * 1024;
29531
29781
  var IDENT = /^[A-Za-z_$][\w$]*$/;
29532
29782
  var TEST_OR_TOOLING = /(^|\/)(tests?|__tests__|spec|specs|fixtures?|e2e|testdata|experiments|scripts)\/|\.(test|spec)\.[cm]?[jt]sx?$|_test\.(py|go)$|(^|\/)test_[^/]+\.py$/;
29533
- var dirname16 = (p) => p.includes("/") ? p.slice(0, p.lastIndexOf("/")) : "";
29783
+ var dirname17 = (p) => p.includes("/") ? p.slice(0, p.lastIndexOf("/")) : "";
29534
29784
  function joinPath(dir, rel) {
29535
29785
  const out2 = dir ? dir.split("/") : [];
29536
29786
  for (const part of rel.split("/")) {
@@ -29655,7 +29905,7 @@ function parseJsonc(text) {
29655
29905
  return JSON.parse(out2.replace(/,(\s*[}\]])/g, "$1"));
29656
29906
  }
29657
29907
  function tsconfigFor(source2, fromPath, cache) {
29658
- for (let dir = dirname16(fromPath); ; dir = dirname16(dir)) {
29908
+ for (let dir = dirname17(fromPath); ; dir = dirname17(dir)) {
29659
29909
  const file = dir ? `${dir}/tsconfig.json` : "tsconfig.json";
29660
29910
  if (!cache.has(file)) {
29661
29911
  const read2 = source2.read(file, 256 * 1024);
@@ -29679,7 +29929,7 @@ function tsconfigFor(source2, fromPath, cache) {
29679
29929
  function tsCandidates(spec, fromPath, cfg) {
29680
29930
  const bases = [];
29681
29931
  if (spec.startsWith(".")) {
29682
- const b = joinPath(dirname16(fromPath), spec);
29932
+ const b = joinPath(dirname17(fromPath), spec);
29683
29933
  if (b !== null) bases.push(b);
29684
29934
  } else if (cfg) {
29685
29935
  const root = cfg.baseUrl !== null ? joinPath(cfg.dir, cfg.baseUrl) : cfg.dir;
@@ -29711,8 +29961,8 @@ function pyCandidates(spec, fromPath) {
29711
29961
  const mod = spec.slice(dots).replace(/\./g, "/");
29712
29962
  const out2 = [];
29713
29963
  if (dots > 0) {
29714
- let dir = dirname16(fromPath);
29715
- for (let i2 = 1; i2 < dots; i2++) dir = dirname16(dir);
29964
+ let dir = dirname17(fromPath);
29965
+ for (let i2 = 1; i2 < dots; i2++) dir = dirname17(dir);
29716
29966
  const b = mod ? joinPath(dir, mod) : dir;
29717
29967
  if (b !== null) out2.push(`${b}.py`, `${b}/__init__.py`);
29718
29968
  } else {
@@ -29739,7 +29989,7 @@ function moduleFiles(source2, spec, fromPath, lang, cache = /* @__PURE__ */ new
29739
29989
  const module2 = mod.ok ? /^\s*module\s+(\S+)/m.exec(mod.content)?.[1] : void 0;
29740
29990
  if (!module2 || !(spec === module2 || spec.startsWith(`${module2}/`))) return [];
29741
29991
  const dir = spec.slice(module2.length + 1);
29742
- return source2.list(dir || void 0).filter((p) => dirname16(p) === dir && p.endsWith(".go") && !p.endsWith("_test.go"));
29992
+ return source2.list(dir || void 0).filter((p) => dirname17(p) === dir && p.endsWith(".go") && !p.endsWith("_test.go"));
29743
29993
  }
29744
29994
  if (lang === "java") {
29745
29995
  const suffix = `${spec.replace(/\./g, "/")}.java`;
@@ -29790,7 +30040,7 @@ function definitionOf(input) {
29790
30040
  if (type?.startsWith(RESULT_OF)) {
29791
30041
  const [fnName, idx] = type.slice(RESULT_OF.length).split("#");
29792
30042
  type = null;
29793
- const others = lang === "go" ? source2.list(dirname16(path) || void 0).filter((p) => dirname16(p) === dirname16(path) && p.endsWith(".go") && p !== path) : (() => {
30043
+ const others = lang === "go" ? source2.list(dirname17(path) || void 0).filter((p) => dirname17(p) === dirname17(path) && p.endsWith(".go") && p !== path) : (() => {
29794
30044
  const imp = importOf(content, lang, fnName, null);
29795
30045
  return imp ? moduleFiles(source2, imp.spec, path, lang, tsCache) : [];
29796
30046
  })();
@@ -29837,7 +30087,7 @@ function definitionOf(input) {
29837
30087
  }
29838
30088
  }
29839
30089
  if (out2.length === 0 && lang === "go" && !receiver) {
29840
- for (const f of source2.list(dirname16(path) || void 0).filter((p) => dirname16(p) === dirname16(path) && p.endsWith(".go") && p !== path)) {
30090
+ for (const f of source2.list(dirname17(path) || void 0).filter((p) => dirname17(p) === dirname17(path) && p.endsWith(".go") && p !== path)) {
29841
30091
  add(functionsNamed(outlineOf2(f), name2), "package");
29842
30092
  if (Date.now() > input.deadlineAt) break;
29843
30093
  }
@@ -30732,8 +30982,8 @@ async function repoContext(run4) {
30732
30982
 
30733
30983
  // src/lib/seed-runner.ts
30734
30984
  var import_promises15 = require("node:fs/promises");
30735
- var import_node_fs45 = require("node:fs");
30736
- var import_node_path34 = require("node:path");
30985
+ var import_node_fs46 = require("node:fs");
30986
+ var import_node_path35 = require("node:path");
30737
30987
  var import_yaml4 = __toESM2(require_dist());
30738
30988
 
30739
30989
  // src/lib/seed.ts
@@ -30956,8 +31206,8 @@ function normalizeTitle(title) {
30956
31206
  async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
30957
31207
  const titles = /* @__PURE__ */ new Set();
30958
31208
  for (const dir of NODE_DIRS) {
30959
- const full = (0, import_node_path34.join)(memoryDir3, dir);
30960
- if (!(0, import_node_fs45.existsSync)(full)) continue;
31209
+ const full = (0, import_node_path35.join)(memoryDir3, dir);
31210
+ if (!(0, import_node_fs46.existsSync)(full)) continue;
30961
31211
  let files;
30962
31212
  try {
30963
31213
  files = await (0, import_promises15.readdir)(full);
@@ -30968,7 +31218,7 @@ async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
30968
31218
  if (!file.endsWith(".md")) continue;
30969
31219
  let content;
30970
31220
  try {
30971
- content = await (0, import_promises15.readFile)((0, import_node_path34.join)(full, file), "utf-8");
31221
+ content = await (0, import_promises15.readFile)((0, import_node_path35.join)(full, file), "utf-8");
30972
31222
  } catch {
30973
31223
  continue;
30974
31224
  }
@@ -31039,7 +31289,7 @@ function renderNodeMarkdown(candidate, nodeId, createdAt) {
31039
31289
  return fm;
31040
31290
  }
31041
31291
  async function runSeed(opts) {
31042
- if (!(0, import_node_fs45.existsSync)(STANDARD_FILE)) {
31292
+ if (!(0, import_node_fs46.existsSync)(STANDARD_FILE)) {
31043
31293
  return { created: 0, existing: 0, failed: 0, skipped: "no_standard", candidates: [] };
31044
31294
  }
31045
31295
  let standardDoc;
@@ -31051,7 +31301,7 @@ async function runSeed(opts) {
31051
31301
  }
31052
31302
  const knowledgeSpec = standardDoc.knowledge_spec ?? {};
31053
31303
  let readmeContent;
31054
- if ((0, import_node_fs45.existsSync)("README.md")) {
31304
+ if ((0, import_node_fs46.existsSync)("README.md")) {
31055
31305
  try {
31056
31306
  readmeContent = await (0, import_promises15.readFile)("README.md", "utf-8");
31057
31307
  } catch {
@@ -31059,7 +31309,7 @@ async function runSeed(opts) {
31059
31309
  }
31060
31310
  let claudeMdContent;
31061
31311
  for (const p of ["CLAUDE.md", ".claude/CLAUDE.md"]) {
31062
- if ((0, import_node_fs45.existsSync)(p)) {
31312
+ if ((0, import_node_fs46.existsSync)(p)) {
31063
31313
  try {
31064
31314
  claudeMdContent = await (0, import_promises15.readFile)(p, "utf-8");
31065
31315
  break;
@@ -31139,13 +31389,13 @@ async function runSeed(opts) {
31139
31389
  continue;
31140
31390
  }
31141
31391
  const deduplicated = res.data.deduplicated === true;
31142
- if (deduplicated && (0, import_node_fs45.existsSync)(targetPath)) {
31392
+ if (deduplicated && (0, import_node_fs46.existsSync)(targetPath)) {
31143
31393
  existing++;
31144
31394
  continue;
31145
31395
  }
31146
31396
  const content = typeof res.data.content === "string" && res.data.content.length > 0 ? res.data.content : renderNodeMarkdown(c, nodeId, createdAt);
31147
31397
  try {
31148
- await (0, import_promises15.mkdir)((0, import_node_path34.dirname)(targetPath), { recursive: true });
31398
+ await (0, import_promises15.mkdir)((0, import_node_path35.dirname)(targetPath), { recursive: true });
31149
31399
  await (0, import_promises15.writeFile)(targetPath, content);
31150
31400
  if (deduplicated) existing++;
31151
31401
  else {
@@ -31161,8 +31411,8 @@ async function runSeed(opts) {
31161
31411
  }
31162
31412
 
31163
31413
  // src/commands/analyze/phases/08-memory-manifest.ts
31164
- var import_node_fs46 = require("node:fs");
31165
- var import_node_path35 = require("node:path");
31414
+ var import_node_fs47 = require("node:fs");
31415
+ var import_node_path36 = require("node:path");
31166
31416
  async function memoryManifest(run4) {
31167
31417
  const { globals } = run4;
31168
31418
  const { serviceUrl, token } = run4;
@@ -31172,9 +31422,9 @@ async function memoryManifest(run4) {
31172
31422
  let autoSeedNotice = null;
31173
31423
  try {
31174
31424
  await ensureMemoryDir();
31175
- const seedMarker = (0, import_node_path35.join)(VERITY_DIR, ".seeded");
31176
- const hasStandard = (0, import_node_fs46.existsSync)(STANDARD_FILE);
31177
- const alreadyTried = (0, import_node_fs46.existsSync)(seedMarker);
31425
+ const seedMarker = (0, import_node_path36.join)(VERITY_DIR, ".seeded");
31426
+ const hasStandard = (0, import_node_fs47.existsSync)(STANDARD_FILE);
31427
+ const alreadyTried = (0, import_node_fs47.existsSync)(seedMarker);
31178
31428
  if (hasStandard && !alreadyTried) {
31179
31429
  const preManifest = await buildManifest();
31180
31430
  if (preManifest.nodes.length === 0) {
@@ -31187,7 +31437,7 @@ async function memoryManifest(run4) {
31187
31437
  dryRun: false
31188
31438
  });
31189
31439
  if (seedResult.created > 0 || seedResult.existing > 0) {
31190
- (0, import_node_fs46.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created} existing=${seedResult.existing}
31440
+ (0, import_node_fs47.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created} existing=${seedResult.existing}
31191
31441
  `);
31192
31442
  if (seedResult.created > 0) {
31193
31443
  autoSeedNotice = `Seeded ${seedResult.created} knowledge node(s) from your existing Standard (one-time).`;
@@ -31198,7 +31448,7 @@ async function memoryManifest(run4) {
31198
31448
  failed: seedResult.failed
31199
31449
  });
31200
31450
  } else if (seedResult.skipped === "already_seeded") {
31201
- (0, import_node_fs46.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
31451
+ (0, import_node_fs47.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
31202
31452
  `);
31203
31453
  } else {
31204
31454
  logEvent("auto_seed_noop", {
@@ -31293,7 +31543,7 @@ function computeIncrement(reviewedPaths, hashOf, priorAuthored) {
31293
31543
  }
31294
31544
 
31295
31545
  // src/commands/analyze/phases/10-working-memory.ts
31296
- var import_node_path36 = require("node:path");
31546
+ var import_node_path37 = require("node:path");
31297
31547
  async function workingMemory(run4) {
31298
31548
  const { opts } = run4;
31299
31549
  const { allForReview, baseline, conversation, foldResult, sessionId, token, transcriptPath } = run4;
@@ -31305,7 +31555,7 @@ async function workingMemory(run4) {
31305
31555
  const priorState = foldForMarks(memorySession.d);
31306
31556
  incrementReport = computeIncrement(
31307
31557
  allForReview,
31308
- (p) => fileHash((0, import_node_path36.join)(repoRoot(), p)),
31558
+ (p) => fileHash((0, import_node_path37.join)(repoRoot(), p)),
31309
31559
  priorState.authored_all.map((a) => ({
31310
31560
  path: a.path,
31311
31561
  hash_at_last_verdict: a.hash_at_last_verdict
@@ -31387,7 +31637,7 @@ async function workingMemory(run4) {
31387
31637
  }
31388
31638
 
31389
31639
  // src/lib/note-budget.ts
31390
- var import_node_fs47 = require("node:fs");
31640
+ var import_node_fs48 = require("node:fs");
31391
31641
  var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
31392
31642
  var EPISODE_STALE_SECONDS = 30 * 60;
31393
31643
  var FRESH = { delivered: 0, tasksCompleted: 0, ts: 0 };
@@ -31409,9 +31659,9 @@ function advisoryBudgetSpent(episode, rawDecision) {
31409
31659
  }
31410
31660
  function readAdvisoryEpisode(sessionId) {
31411
31661
  const file = scopedFile(ADVISORY_EPISODE_FILE, sessionId);
31412
- if (!(0, import_node_fs47.existsSync)(file)) return null;
31662
+ if (!(0, import_node_fs48.existsSync)(file)) return null;
31413
31663
  try {
31414
- const o = JSON.parse((0, import_node_fs47.readFileSync)(file, "utf-8")) ?? {};
31664
+ const o = JSON.parse((0, import_node_fs48.readFileSync)(file, "utf-8")) ?? {};
31415
31665
  const delivered = typeof o.delivered === "number" ? o.delivered : NaN;
31416
31666
  if (isNaN(delivered)) return null;
31417
31667
  return {
@@ -31425,8 +31675,8 @@ function readAdvisoryEpisode(sessionId) {
31425
31675
  }
31426
31676
  function writeAdvisoryEpisode(episode, sessionId) {
31427
31677
  try {
31428
- (0, import_node_fs47.mkdirSync)(VERITY_DIR, { recursive: true });
31429
- (0, import_node_fs47.writeFileSync)(
31678
+ (0, import_node_fs48.mkdirSync)(VERITY_DIR, { recursive: true });
31679
+ (0, import_node_fs48.writeFileSync)(
31430
31680
  scopedFile(ADVISORY_EPISODE_FILE, sessionId),
31431
31681
  JSON.stringify({ v: 1, ...episode })
31432
31682
  );
@@ -31758,14 +32008,14 @@ async function buildRequest(run4) {
31758
32008
  }
31759
32009
 
31760
32010
  // src/lib/offline.ts
31761
- var import_node_fs48 = require("node:fs");
32011
+ var import_node_fs49 = require("node:fs");
31762
32012
  var import_node_crypto13 = require("node:crypto");
31763
32013
  function cacheRequest(body2) {
31764
32014
  try {
31765
- (0, import_node_fs48.mkdirSync)(CACHE_DIR, { recursive: true });
32015
+ (0, import_node_fs49.mkdirSync)(CACHE_DIR, { recursive: true });
31766
32016
  const suffix = (0, import_node_crypto13.randomBytes)(4).toString("hex");
31767
32017
  const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
31768
- (0, import_node_fs48.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body2)));
32018
+ (0, import_node_fs49.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body2)));
31769
32019
  } catch {
31770
32020
  }
31771
32021
  }
@@ -31884,8 +32134,8 @@ async function transmit(run4) {
31884
32134
  }
31885
32135
 
31886
32136
  // src/commands/analyze/phases/13-reconcile.ts
31887
- var import_node_fs49 = require("node:fs");
31888
- var import_node_path37 = require("node:path");
32137
+ var import_node_fs50 = require("node:fs");
32138
+ var import_node_path38 = require("node:path");
31889
32139
  async function reconcile(run4) {
31890
32140
  const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory: memory2, memorySession, response, reviewable, securityFiles, turnId } = run4;
31891
32141
  const sentPaths = codeDelta.files.map((f) => f.path);
@@ -31914,7 +32164,7 @@ async function reconcile(run4) {
31914
32164
  const st = foldDossier(memorySession.d);
31915
32165
  openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line2) => {
31916
32166
  try {
31917
- const src = (0, import_node_fs49.readFileSync)((0, import_node_path37.join)(repoRoot(), file), "utf8").split("\n");
32167
+ const src = (0, import_node_fs50.readFileSync)((0, import_node_path38.join)(repoRoot(), file), "utf8").split("\n");
31918
32168
  const at = src[line2 - 1];
31919
32169
  return at === void 0 ? null : lineSha(at);
31920
32170
  } catch {
@@ -32736,7 +32986,7 @@ function registerAnalyzeCommand(program2) {
32736
32986
  var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
32737
32987
  async function runAnalyze(opts, globals) {
32738
32988
  if (!verityConfigured()) {
32739
- (0, import_node_fs50.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
32989
+ (0, import_node_fs51.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
32740
32990
  process.exit(0);
32741
32991
  }
32742
32992
  const run4 = createRun(opts, globals);
@@ -32757,11 +33007,11 @@ async function runAnalyze(opts, globals) {
32757
33007
  }
32758
33008
 
32759
33009
  // src/commands/baseline.ts
32760
- var import_node_fs52 = require("node:fs");
33010
+ var import_node_fs53 = require("node:fs");
32761
33011
 
32762
33012
  // src/lib/project-skills.ts
32763
- var import_node_fs51 = require("node:fs");
32764
- var import_node_path38 = require("node:path");
33013
+ var import_node_fs52 = require("node:fs");
33014
+ var import_node_path39 = require("node:path");
32765
33015
  var PROJECT_SKILL_NAMES = [
32766
33016
  "verity-setup",
32767
33017
  "verity-analyze",
@@ -32787,14 +33037,14 @@ var LEGACY_SKILL_NAMES = [
32787
33037
  var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
32788
33038
  function staleProjectSkills() {
32789
33039
  const root = projectPath(".claude/skills");
32790
- if (!(0, import_node_fs51.existsSync)(root)) return [];
32791
- return ALL.filter((name2) => (0, import_node_fs51.existsSync)((0, import_node_path38.join)(root, name2)));
33040
+ if (!(0, import_node_fs52.existsSync)(root)) return [];
33041
+ return ALL.filter((name2) => (0, import_node_fs52.existsSync)((0, import_node_path39.join)(root, name2)));
32792
33042
  }
32793
33043
  function removeProjectSkills() {
32794
33044
  const root = projectPath(".claude/skills");
32795
33045
  const removed = [];
32796
33046
  for (const name2 of staleProjectSkills()) {
32797
- (0, import_node_fs51.rmSync)((0, import_node_path38.join)(root, name2), { recursive: true, force: true });
33047
+ (0, import_node_fs52.rmSync)((0, import_node_path39.join)(root, name2), { recursive: true, force: true });
32798
33048
  removed.push(name2);
32799
33049
  }
32800
33050
  return removed;
@@ -32859,13 +33109,13 @@ function registerBaselineCommands(program2) {
32859
33109
  let memoryMsg = null;
32860
33110
  let memoryAgentLine = null;
32861
33111
  const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
32862
- if (realStart && !(0, import_node_fs52.existsSync)(memoryNotice)) {
33112
+ if (realStart && !(0, import_node_fs53.existsSync)(memoryNotice)) {
32863
33113
  const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
32864
33114
  if (trackedGraph > 0) {
32865
33115
  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.`;
32866
33116
  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.`;
32867
33117
  try {
32868
- (0, import_node_fs52.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
33118
+ (0, import_node_fs53.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
32869
33119
  } catch {
32870
33120
  }
32871
33121
  }
@@ -32884,7 +33134,7 @@ function registerBaselineCommands(program2) {
32884
33134
  if (needsSetup) {
32885
33135
  userMsg = stale.length > 0 ? `Verity: the plugin is installed \u2014 run /verity:init to finish setting it up here (it will also clear ${stale.length} duplicate skills).` : "Verity: the plugin is installed \u2014 run /verity:init to finish setting it up here.";
32886
33136
  notices.push(
32887
- "The Verity plugin is installed here but /verity:init has not been run for this project. Installing the plugin cannot repair a project on its own \u2014 Claude Code has no post-install hook \u2014 so tell the user to run /verity:init (they type it; it is not a skill you can invoke). It asks how they want reviews to run, then does the repair."
33137
+ "The Verity plugin is installed here but /verity:init has not been run for this project. Installing the plugin cannot repair a project on its own \u2014 Claude Code has no post-install hook \u2014 so tell the user to run /verity:init (they type it; it is not a skill you can invoke). It asks how they want reviews to run, about telemetry and whether to sign in \u2014 all in the session \u2014 then does the repair and the sign-in."
32888
33138
  );
32889
33139
  if (stale.length > 0) {
32890
33140
  notices.push(
@@ -32966,7 +33216,7 @@ function hookSource(value) {
32966
33216
  }
32967
33217
 
32968
33218
  // src/commands/review.ts
32969
- var import_node_fs53 = require("node:fs");
33219
+ var import_node_fs54 = require("node:fs");
32970
33220
  function registerReviewCommand(program2) {
32971
33221
  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) => {
32972
33222
  const globals = program2.opts();
@@ -32983,7 +33233,7 @@ async function runReview(opts, globals) {
32983
33233
  const changedFiles = opts.changed ? opts.changed.split(",").map((f) => f.trim()).filter(Boolean) : allFiles;
32984
33234
  const analyzable = filterAnalyzable(allFiles);
32985
33235
  const securityFiles = filterSecurity(allFiles);
32986
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs53.existsSync)(f) || resolveFile(f) !== null);
33236
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs54.existsSync)(f) || resolveFile(f) !== null);
32987
33237
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
32988
33238
  const codeDelta = collectCodeDelta(allFiles);
32989
33239
  const tokenResult = await resolveToken(globals.token);
@@ -33049,8 +33299,8 @@ async function runReview(opts, globals) {
33049
33299
  }
33050
33300
 
33051
33301
  // src/commands/guard.ts
33052
- var import_node_fs57 = require("node:fs");
33053
- var import_node_path43 = require("node:path");
33302
+ var import_node_fs58 = require("node:fs");
33303
+ var import_node_path44 = require("node:path");
33054
33304
 
33055
33305
  // src/lib/terminal-text.ts
33056
33306
  var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/g;
@@ -33158,7 +33408,7 @@ async function runAgentReview(options) {
33158
33408
  }
33159
33409
 
33160
33410
  // src/lib/prove/auto.ts
33161
- var import_node_path42 = require("node:path");
33411
+ var import_node_path43 = require("node:path");
33162
33412
  var import_node_crypto18 = require("node:crypto");
33163
33413
 
33164
33414
  // src/lib/prove/signals.ts
@@ -34824,18 +35074,18 @@ function renderReplay(model, property, r) {
34824
35074
  // src/lib/prove/runner.ts
34825
35075
  var import_node_child_process15 = require("node:child_process");
34826
35076
  var import_node_os8 = require("node:os");
34827
- var import_node_fs56 = require("node:fs");
35077
+ var import_node_fs57 = require("node:fs");
34828
35078
  var import_node_os9 = require("node:os");
34829
- var import_node_path41 = require("node:path");
35079
+ var import_node_path42 = require("node:path");
34830
35080
 
34831
35081
  // src/lib/prove/scaffold.ts
34832
- var import_node_fs55 = require("node:fs");
34833
- var import_node_path40 = require("node:path");
35082
+ var import_node_fs56 = require("node:fs");
35083
+ var import_node_path41 = require("node:path");
34834
35084
 
34835
35085
  // src/lib/prove/safe-write.ts
34836
- var import_node_fs54 = require("node:fs");
35086
+ var import_node_fs55 = require("node:fs");
34837
35087
  var import_node_crypto14 = require("node:crypto");
34838
- var import_node_path39 = require("node:path");
35088
+ var import_node_path40 = require("node:path");
34839
35089
  var SafeWriteError = class extends Error {
34840
35090
  constructor(reason, path) {
34841
35091
  super(`refusing to write ${path}: ${reason}`);
@@ -34844,10 +35094,10 @@ var SafeWriteError = class extends Error {
34844
35094
  this.name = "SafeWriteError";
34845
35095
  }
34846
35096
  };
34847
- var FLAGS3 = import_node_fs54.constants;
35097
+ var FLAGS3 = import_node_fs55.constants;
34848
35098
  var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
34849
35099
  function assertPlainRelative(rel) {
34850
- if (!rel || (0, import_node_path39.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
35100
+ if (!rel || (0, import_node_path40.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
34851
35101
  for (const part of rel.split(/[\\/]/)) {
34852
35102
  if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
34853
35103
  }
@@ -34856,34 +35106,34 @@ function ensureDirsNoFollow(root, rel) {
34856
35106
  const parts2 = rel.split(/[\\/]/);
34857
35107
  let cur = root;
34858
35108
  for (const part of parts2.slice(0, -1)) {
34859
- cur = (0, import_node_path39.join)(cur, part);
35109
+ cur = (0, import_node_path40.join)(cur, part);
34860
35110
  let st;
34861
35111
  try {
34862
- st = (0, import_node_fs54.lstatSync)(cur);
35112
+ st = (0, import_node_fs55.lstatSync)(cur);
34863
35113
  } catch {
34864
- (0, import_node_fs54.mkdirSync)(cur);
35114
+ (0, import_node_fs55.mkdirSync)(cur);
34865
35115
  continue;
34866
35116
  }
34867
35117
  if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
34868
35118
  if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
34869
35119
  }
34870
- return (0, import_node_path39.join)(root, rel);
35120
+ return (0, import_node_path40.join)(root, rel);
34871
35121
  }
34872
35122
  function insideRoot(realRoot, realPath) {
34873
- return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path39.sep) ? realRoot : realRoot + import_node_path39.sep);
35123
+ return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path40.sep) ? realRoot : realRoot + import_node_path40.sep);
34874
35124
  }
34875
35125
  function removeQuietly(path) {
34876
35126
  try {
34877
- (0, import_node_fs54.unlinkSync)(path);
35127
+ (0, import_node_fs55.unlinkSync)(path);
34878
35128
  } catch {
34879
35129
  }
34880
35130
  }
34881
35131
  function writeFileInRootNoFollow(root, rel, content) {
34882
35132
  assertPlainRelative(rel);
34883
35133
  const dest = ensureDirsNoFollow(root, rel);
34884
- const dir = (0, import_node_path39.dirname)(dest);
35134
+ const dir = (0, import_node_path40.dirname)(dest);
34885
35135
  try {
34886
- const st = (0, import_node_fs54.lstatSync)(dest);
35136
+ const st = (0, import_node_fs55.lstatSync)(dest);
34887
35137
  if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
34888
35138
  if (!st.isFile()) throw new SafeWriteError("not-regular", dest);
34889
35139
  } catch (err2) {
@@ -34891,41 +35141,41 @@ function writeFileInRootNoFollow(root, rel, content) {
34891
35141
  }
34892
35142
  let realRoot;
34893
35143
  try {
34894
- realRoot = (0, import_node_fs54.realpathSync)(root);
35144
+ realRoot = (0, import_node_fs55.realpathSync)(root);
34895
35145
  } catch {
34896
35146
  throw new SafeWriteError("unwritable", root);
34897
35147
  }
34898
- const tmp = (0, import_node_path39.join)(dir, `.${(0, import_node_path39.basename)(dest)}.${(0, import_node_crypto14.randomBytes)(6).toString("hex")}.tmp`);
35148
+ const tmp = (0, import_node_path40.join)(dir, `.${(0, import_node_path40.basename)(dest)}.${(0, import_node_crypto14.randomBytes)(6).toString("hex")}.tmp`);
34899
35149
  let fd;
34900
35150
  try {
34901
- fd = (0, import_node_fs54.openSync)(tmp, import_node_fs54.constants.O_WRONLY | import_node_fs54.constants.O_CREAT | import_node_fs54.constants.O_EXCL | NOFOLLOW2, 420);
35151
+ fd = (0, import_node_fs55.openSync)(tmp, import_node_fs55.constants.O_WRONLY | import_node_fs55.constants.O_CREAT | import_node_fs55.constants.O_EXCL | NOFOLLOW2, 420);
34902
35152
  } catch {
34903
35153
  throw new SafeWriteError("unwritable", tmp);
34904
35154
  }
34905
35155
  try {
34906
- const opened = (0, import_node_fs54.fstatSync)(fd, { bigint: true });
35156
+ const opened = (0, import_node_fs55.fstatSync)(fd, { bigint: true });
34907
35157
  let realTmp;
34908
35158
  try {
34909
- realTmp = (0, import_node_fs54.realpathSync)(tmp);
35159
+ realTmp = (0, import_node_fs55.realpathSync)(tmp);
34910
35160
  } catch {
34911
35161
  throw new SafeWriteError("escaped", tmp);
34912
35162
  }
34913
- const there = (0, import_node_fs54.lstatSync)(realTmp, { bigint: true });
35163
+ const there = (0, import_node_fs55.lstatSync)(realTmp, { bigint: true });
34914
35164
  if (!opened.isFile() || there.ino !== opened.ino || there.dev !== opened.dev || !insideRoot(realRoot, realTmp)) {
34915
35165
  throw new SafeWriteError("escaped", tmp);
34916
35166
  }
34917
35167
  const buf = Buffer.from(content, "utf-8");
34918
35168
  let off = 0;
34919
- while (off < buf.length) off += (0, import_node_fs54.writeSync)(fd, buf, off, buf.length - off);
35169
+ while (off < buf.length) off += (0, import_node_fs55.writeSync)(fd, buf, off, buf.length - off);
34920
35170
  } catch (err2) {
34921
- (0, import_node_fs54.closeSync)(fd);
35171
+ (0, import_node_fs55.closeSync)(fd);
34922
35172
  removeQuietly(tmp);
34923
35173
  throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", tmp);
34924
35174
  }
34925
- (0, import_node_fs54.closeSync)(fd);
35175
+ (0, import_node_fs55.closeSync)(fd);
34926
35176
  try {
34927
- if (!insideRoot(realRoot, (0, import_node_fs54.realpathSync)(dir)) || (0, import_node_fs54.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
34928
- (0, import_node_fs54.renameSync)(tmp, dest);
35177
+ if (!insideRoot(realRoot, (0, import_node_fs55.realpathSync)(dir)) || (0, import_node_fs55.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
35178
+ (0, import_node_fs55.renameSync)(tmp, dest);
34929
35179
  } catch (err2) {
34930
35180
  removeQuietly(tmp);
34931
35181
  throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", dest);
@@ -34939,9 +35189,9 @@ function pathHasNoLink(root, rel) {
34939
35189
  }
34940
35190
  let cur = root;
34941
35191
  for (const part of rel.split(/[\\/]/)) {
34942
- cur = cur + import_node_path39.sep + part;
35192
+ cur = cur + import_node_path40.sep + part;
34943
35193
  try {
34944
- if ((0, import_node_fs54.lstatSync)(cur).isSymbolicLink()) return false;
35194
+ if ((0, import_node_fs55.lstatSync)(cur).isSymbolicLink()) return false;
34945
35195
  } catch {
34946
35196
  return true;
34947
35197
  }
@@ -35251,20 +35501,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
35251
35501
  never committed; what reaches the team is the bug report and the fix.
35252
35502
  `;
35253
35503
  function scaffoldProofs(root) {
35254
- const proofsDir = (0, import_node_path40.join)(root, PROOFS_DIR);
35504
+ const proofsDir = (0, import_node_path41.join)(root, PROOFS_DIR);
35255
35505
  const written = [];
35256
35506
  const kept = [];
35257
35507
  for (const stray of ["lakefile.lean"]) {
35258
35508
  const rel = `${PROOFS_DIR}/${stray}`;
35259
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path40.join)(root, rel));
35509
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path41.join)(root, rel));
35260
35510
  try {
35261
- (0, import_node_fs55.rmSync)((0, import_node_path40.join)(root, rel), { force: true });
35511
+ (0, import_node_fs56.rmSync)((0, import_node_path41.join)(root, rel), { force: true });
35262
35512
  } catch {
35263
35513
  }
35264
35514
  }
35265
35515
  for (const f of PROOFS_TEMPLATE_FILES) {
35266
35516
  const rel = `${PROOFS_DIR}/${f.path}`;
35267
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path40.join)(root, rel));
35517
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path41.join)(root, rel));
35268
35518
  const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
35269
35519
  if (current.ok && current.content === f.content) {
35270
35520
  kept.push(rel);
@@ -35277,8 +35527,8 @@ function scaffoldProofs(root) {
35277
35527
  [`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
35278
35528
  [`${MODELS_DIR}/README.md`, MODELS_README]
35279
35529
  ]) {
35280
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path40.join)(root, rel));
35281
- if (existsNoFollow((0, import_node_path40.join)(root, rel))) {
35530
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path41.join)(root, rel));
35531
+ if (existsNoFollow((0, import_node_path41.join)(root, rel))) {
35282
35532
  kept.push(rel);
35283
35533
  continue;
35284
35534
  }
@@ -35289,7 +35539,7 @@ function scaffoldProofs(root) {
35289
35539
  }
35290
35540
  function existsNoFollow(abs) {
35291
35541
  try {
35292
- (0, import_node_fs55.lstatSync)(abs);
35542
+ (0, import_node_fs56.lstatSync)(abs);
35293
35543
  return true;
35294
35544
  } catch {
35295
35545
  return false;
@@ -35547,16 +35797,16 @@ function renderReport(r) {
35547
35797
 
35548
35798
  // src/lib/prove/runner.ts
35549
35799
  function verityLeanHome(env = process.env) {
35550
- return env.VERITY_LEAN_HOME ?? (0, import_node_path41.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
35800
+ return env.VERITY_LEAN_HOME ?? (0, import_node_path42.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
35551
35801
  }
35552
35802
  function findToolchain(env = process.env) {
35553
- const managedBin = (0, import_node_path41.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
35554
- const elanBin = (0, import_node_path41.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
35555
- const path = [managedBin, elanBin, env.PATH ?? ""].filter(Boolean).join(import_node_path41.delimiter);
35803
+ const managedBin = (0, import_node_path42.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
35804
+ const elanBin = (0, import_node_path42.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
35805
+ const path = [managedBin, elanBin, env.PATH ?? ""].filter(Boolean).join(import_node_path42.delimiter);
35556
35806
  const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
35557
- const elanHas = (0, import_node_fs56.existsSync)((0, import_node_path41.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
35807
+ const elanHas = (0, import_node_fs57.existsSync)((0, import_node_path42.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
35558
35808
  const exe = process.platform === "win32" ? "lake.exe" : "lake";
35559
- const candidates2 = [(0, import_node_path41.join)(managedBin, exe), ...elanHas ? [(0, import_node_path41.join)(elanBin, exe)] : [], exe];
35809
+ const candidates2 = [(0, import_node_path42.join)(managedBin, exe), ...elanHas ? [(0, import_node_path42.join)(elanBin, exe)] : [], exe];
35560
35810
  for (const candidate of candidates2) {
35561
35811
  try {
35562
35812
  (0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
@@ -35632,41 +35882,41 @@ function runAsync(tc, cwd, args2, timeoutMs) {
35632
35882
  var DEFAULT_BUILD_TIMEOUT_MS = 10 * 6e4;
35633
35883
  var DEFAULT_CHECK_TIMEOUT_MS = 12e4;
35634
35884
  function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
35635
- return run2(tc, (0, import_node_path41.join)(root, PROOFS_DIR), ["build"], timeoutMs);
35885
+ return run2(tc, (0, import_node_path42.join)(root, PROOFS_DIR), ["build"], timeoutMs);
35636
35886
  }
35637
35887
  function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
35638
- return runAsync(tc, (0, import_node_path41.join)(root, PROOFS_DIR), ["build"], timeoutMs);
35888
+ return runAsync(tc, (0, import_node_path42.join)(root, PROOFS_DIR), ["build"], timeoutMs);
35639
35889
  }
35640
35890
  function isModelInRoot(modelsAbs, rel) {
35641
- if (!rel.endsWith(".lean") || (0, import_node_path41.isAbsolute)(rel) || rel.startsWith("..")) return false;
35891
+ if (!rel.endsWith(".lean") || (0, import_node_path42.isAbsolute)(rel) || rel.startsWith("..")) return false;
35642
35892
  return statRegularInRoot(modelsAbs, rel).ok;
35643
35893
  }
35644
35894
  function resolveModelFile(root, arg) {
35645
- const modelsAbs = (0, import_node_path41.join)(root, MODELS_DIR);
35646
- const asPath = (0, import_node_path41.relative)(modelsAbs, (0, import_node_path41.isAbsolute)(arg) ? arg : (0, import_node_path41.resolve)(root, arg));
35895
+ const modelsAbs = (0, import_node_path42.join)(root, MODELS_DIR);
35896
+ const asPath = (0, import_node_path42.relative)(modelsAbs, (0, import_node_path42.isAbsolute)(arg) ? arg : (0, import_node_path42.resolve)(root, arg));
35647
35897
  const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
35648
35898
  for (const rel of candidates2) {
35649
- if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path41.join)(modelsAbs, rel);
35899
+ if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path42.join)(modelsAbs, rel);
35650
35900
  }
35651
35901
  return null;
35652
35902
  }
35653
35903
  function listModelFiles(root) {
35654
- const modelsAbs = (0, import_node_path41.join)(root, MODELS_DIR);
35655
- if (!(0, import_node_fs56.existsSync)(modelsAbs)) return [];
35656
- return (0, import_node_fs56.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path41.join)(modelsAbs, f));
35904
+ const modelsAbs = (0, import_node_path42.join)(root, MODELS_DIR);
35905
+ if (!(0, import_node_fs57.existsSync)(modelsAbs)) return [];
35906
+ return (0, import_node_fs57.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path42.join)(modelsAbs, f));
35657
35907
  }
35658
35908
  function trimDiagnostics(text) {
35659
35909
  return text.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
35660
35910
  }
35661
35911
  function checkModel(tc, root, modelFile, opts = {}) {
35662
- const proofsAbs = (0, import_node_path41.join)(root, PROOFS_DIR);
35663
- const rel = (0, import_node_path41.relative)(proofsAbs, modelFile);
35912
+ const proofsAbs = (0, import_node_path42.join)(root, PROOFS_DIR);
35913
+ const rel = (0, import_node_path42.relative)(proofsAbs, modelFile);
35664
35914
  const res = run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
35665
35915
  return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
35666
35916
  }
35667
35917
  async function checkModelAsync(tc, root, modelFile, opts = {}) {
35668
- const proofsAbs = (0, import_node_path41.join)(root, PROOFS_DIR);
35669
- const rel = (0, import_node_path41.relative)(proofsAbs, modelFile);
35918
+ const proofsAbs = (0, import_node_path42.join)(root, PROOFS_DIR);
35919
+ const rel = (0, import_node_path42.relative)(proofsAbs, modelFile);
35670
35920
  const res = await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
35671
35921
  return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
35672
35922
  }
@@ -35674,10 +35924,10 @@ function toReport(res, root, modelFile, timeoutMs) {
35674
35924
  const parsed = parseVerityLines(res.stdout);
35675
35925
  const combined = `${res.stdout}
35676
35926
  ${res.stderr}`;
35677
- const name2 = parsed.header?.model ?? (0, import_node_path41.basename)(modelFile, ".lean");
35927
+ const name2 = parsed.header?.model ?? (0, import_node_path42.basename)(modelFile, ".lean");
35678
35928
  const report = {
35679
35929
  model: name2,
35680
- file: (0, import_node_path41.relative)(root, modelFile),
35930
+ file: (0, import_node_path42.relative)(root, modelFile),
35681
35931
  ok: res.ok,
35682
35932
  header: parsed.header,
35683
35933
  properties: parsed.properties,
@@ -36207,7 +36457,7 @@ async function runFormalPhase(input) {
36207
36457
  modelName = gen.name;
36208
36458
  const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
36209
36459
  writeFileInRootNoFollow(root, rel, gen.source);
36210
- const abs = resolveModelFile(root, rel) ?? (0, import_node_path42.join)(root, rel);
36460
+ const abs = resolveModelFile(root, rel) ?? (0, import_node_path43.join)(root, rel);
36211
36461
  progress.model = { name: gen.name, file: rel, rounds: round };
36212
36462
  progress.step = "check";
36213
36463
  report = await deps.check(root, abs);
@@ -36307,7 +36557,7 @@ async function runFormalPhase(input) {
36307
36557
  return done({
36308
36558
  status: "checked",
36309
36559
  target,
36310
- model: { name: modelName, file: (0, import_node_path42.relative)(root, (0, import_node_path42.join)(root, modelFile)), rounds },
36560
+ model: { name: modelName, file: (0, import_node_path43.relative)(root, (0, import_node_path43.join)(root, modelFile)), rounds },
36311
36561
  properties: report.properties,
36312
36562
  findings
36313
36563
  });
@@ -36370,7 +36620,7 @@ async function generateAndCheck(root, req, opts) {
36370
36620
  }
36371
36621
  const rel = `${dir}/${gen.name}.lean`;
36372
36622
  writeFileInRootNoFollow(root, rel, gen.source);
36373
- const abs = resolveModelFile(root, rel) ?? (0, import_node_path42.join)(root, rel);
36623
+ const abs = resolveModelFile(root, rel) ?? (0, import_node_path43.join)(root, rel);
36374
36624
  const report = await opts.deps.check(root, abs);
36375
36625
  const abstracts = report.header?.abstracts ?? [];
36376
36626
  const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
@@ -36480,7 +36730,7 @@ var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
36480
36730
  var WRITERS_BUDGET_MS = 1500;
36481
36731
  var EXCERPT_MAX_LINES2 = 30;
36482
36732
  var GUARD_BLOCK_CAP = 2;
36483
- var GUARD_ITER_FILE = (0, import_node_path43.join)(VERITY_DIR, ".guard-iteration");
36733
+ var GUARD_ITER_FILE = (0, import_node_path44.join)(VERITY_DIR, ".guard-iteration");
36484
36734
  function readPreToolUseStdin() {
36485
36735
  const empty = { command: "", cwd: null, sessionId: null };
36486
36736
  return new Promise((resolve8) => {
@@ -36525,7 +36775,7 @@ function readPreToolUseStdin() {
36525
36775
  }
36526
36776
  function readIterMap() {
36527
36777
  try {
36528
- const raw = JSON.parse((0, import_node_fs57.readFileSync)(GUARD_ITER_FILE, "utf-8"));
36778
+ const raw = JSON.parse((0, import_node_fs58.readFileSync)(GUARD_ITER_FILE, "utf-8"));
36529
36779
  if (raw && typeof raw === "object") {
36530
36780
  if (typeof raw.moment === "string" && typeof raw.count === "number") {
36531
36781
  return { [raw.moment]: raw.count };
@@ -36545,10 +36795,10 @@ function readIter(moment) {
36545
36795
  }
36546
36796
  function writeIter(moment, count) {
36547
36797
  try {
36548
- (0, import_node_fs57.mkdirSync)(VERITY_DIR, { recursive: true });
36798
+ (0, import_node_fs58.mkdirSync)(VERITY_DIR, { recursive: true });
36549
36799
  const map = readIterMap();
36550
36800
  map[moment] = count;
36551
- (0, import_node_fs57.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
36801
+ (0, import_node_fs58.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
36552
36802
  } catch {
36553
36803
  }
36554
36804
  }
@@ -36558,10 +36808,10 @@ function resetIter(moment) {
36558
36808
  if (!(moment in map)) return;
36559
36809
  delete map[moment];
36560
36810
  if (Object.keys(map).length === 0) {
36561
- if ((0, import_node_fs57.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs57.unlinkSync)(GUARD_ITER_FILE);
36811
+ if ((0, import_node_fs58.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs58.unlinkSync)(GUARD_ITER_FILE);
36562
36812
  } else {
36563
- (0, import_node_fs57.mkdirSync)(VERITY_DIR, { recursive: true });
36564
- (0, import_node_fs57.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
36813
+ (0, import_node_fs58.mkdirSync)(VERITY_DIR, { recursive: true });
36814
+ (0, import_node_fs58.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
36565
36815
  }
36566
36816
  } catch {
36567
36817
  }
@@ -36631,7 +36881,7 @@ function hasBlockingFinding(response, sentFiles) {
36631
36881
  function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
36632
36882
  const analyzable = filterAnalyzable(files);
36633
36883
  const securityFiles = filterSecurity(files);
36634
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs57.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
36884
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs58.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
36635
36885
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
36636
36886
  const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
36637
36887
  const requestBody = {
@@ -37239,7 +37489,7 @@ function registerIgnoreCommand(program2) {
37239
37489
 
37240
37490
  // src/commands/waive.ts
37241
37491
  var import_node_crypto19 = require("node:crypto");
37242
- var import_node_fs58 = require("node:fs");
37492
+ var import_node_fs59 = require("node:fs");
37243
37493
  function registerWaiveCommand(program2) {
37244
37494
  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) => {
37245
37495
  const globals = program2.opts();
@@ -37268,7 +37518,7 @@ function registerWaiveCommand(program2) {
37268
37518
  if (opts.file) {
37269
37519
  body2.file = opts.file;
37270
37520
  try {
37271
- body2.file_sha256 = (0, import_node_crypto19.createHash)("sha256").update((0, import_node_fs58.readFileSync)(opts.file)).digest("hex");
37521
+ body2.file_sha256 = (0, import_node_crypto19.createHash)("sha256").update((0, import_node_fs59.readFileSync)(opts.file)).digest("hex");
37272
37522
  } catch {
37273
37523
  printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
37274
37524
  process.exit(1);
@@ -37293,10 +37543,10 @@ function registerWaiveCommand(program2) {
37293
37543
  }
37294
37544
 
37295
37545
  // src/commands/init.ts
37296
- var import_node_fs63 = require("node:fs");
37546
+ var import_node_fs64 = require("node:fs");
37297
37547
  var import_promises20 = require("node:fs/promises");
37298
37548
  var import_yaml6 = __toESM2(require_dist());
37299
- var import_node_path47 = require("node:path");
37549
+ var import_node_path48 = require("node:path");
37300
37550
  var import_node_child_process19 = require("node:child_process");
37301
37551
 
37302
37552
  // src/lib/banner.ts
@@ -37375,7 +37625,7 @@ function printPhase(n, of, title, subtitle) {
37375
37625
  }
37376
37626
 
37377
37627
  // src/commands/doctor.ts
37378
- var import_node_fs59 = require("node:fs");
37628
+ var import_node_fs60 = require("node:fs");
37379
37629
 
37380
37630
  // src/lib/prereqs.ts
37381
37631
  var import_node_child_process16 = require("node:child_process");
@@ -37583,11 +37833,11 @@ async function buildReport() {
37583
37833
  const hooks = wiring.status;
37584
37834
  const provenance = cliProvenance();
37585
37835
  const telemetry = await checkTelemetry();
37586
- const hasConfig = (0, import_node_fs59.existsSync)(projectPath(CODACY_CONFIG_FILE));
37836
+ const hasConfig = (0, import_node_fs60.existsSync)(projectPath(CODACY_CONFIG_FILE));
37587
37837
  const artifacts = {
37588
- standard: (0, import_node_fs59.existsSync)(projectPath(STANDARD_FILE)),
37838
+ standard: (0, import_node_fs60.existsSync)(projectPath(STANDARD_FILE)),
37589
37839
  analysisConfig: hasConfig,
37590
- verityMd: (0, import_node_fs59.existsSync)(projectPath(VERITY_MD_FILE)),
37840
+ verityMd: (0, import_node_fs60.existsSync)(projectPath(VERITY_MD_FILE)),
37591
37841
  analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
37592
37842
  };
37593
37843
  const next = [];
@@ -37634,8 +37884,18 @@ async function buildReport() {
37634
37884
  if (state?.telemetry === "deferred") {
37635
37885
  next.push('Telemetry was requested but needs a token \u2014 run "verity login", then "verity telemetry install".');
37636
37886
  }
37637
- const memory2 = { posture: memoryPosture(), trackedFiles: committedMemoryFiles().length };
37638
- if (memory2.trackedFiles > 0 && !memoryOptOut()) {
37887
+ const memory2 = {
37888
+ posture: memoryPosture(),
37889
+ trackedFiles: committedMemoryFiles().length,
37890
+ optedOut: memoryOptOut()
37891
+ };
37892
+ const trackedState = { files: committedVerityState().length };
37893
+ if (trackedState.files > 0) {
37894
+ next.push(
37895
+ `${trackedState.files} machine-local Verity state file(s) under .verity/ are tracked in git (they can include copies of flagged secrets). Run "verity init --untrack-state" to untrack them (the files stay on disk).`
37896
+ );
37897
+ }
37898
+ if (memory2.trackedFiles > 0 && !memory2.optedOut) {
37639
37899
  next.push(
37640
37900
  `${memory2.trackedFiles} knowledge-graph file(s) under .verity/memory/ are tracked in git, so Verity's generated notes appear in every diff and pull request. Run "verity memory untrack" to stop that (the files stay on disk), or "verity memory track" if this project commits them on purpose.`
37641
37901
  );
@@ -37674,6 +37934,7 @@ async function buildReport() {
37674
37934
  telemetry: { enabled: telemetry.enabled, endpoint: telemetry.endpoint },
37675
37935
  artifacts,
37676
37936
  memory: memory2,
37937
+ trackedState,
37677
37938
  next
37678
37939
  };
37679
37940
  }
@@ -37733,8 +37994,8 @@ function registerDoctorCommand(program2) {
37733
37994
  }
37734
37995
 
37735
37996
  // src/commands/migrate.ts
37736
- var import_node_fs60 = require("node:fs");
37737
- var import_node_path44 = require("node:path");
37997
+ var import_node_fs61 = require("node:fs");
37998
+ var import_node_path45 = require("node:path");
37738
37999
  var import_node_child_process17 = require("node:child_process");
37739
38000
  var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
37740
38001
  function defaultNpmRemover(pkg) {
@@ -37771,12 +38032,12 @@ async function runMigration(opts = {}) {
37771
38032
  return { actions, migrated: actions.length > 0 };
37772
38033
  }
37773
38034
  function migrateProjectDir(root, actions) {
37774
- const gateDir = (0, import_node_path44.join)(root, ".gate");
37775
- const verityDir = (0, import_node_path44.join)(root, ".verity");
37776
- if ((0, import_node_fs60.existsSync)(gateDir) && !(0, import_node_fs60.existsSync)(verityDir)) {
38035
+ const gateDir = (0, import_node_path45.join)(root, ".gate");
38036
+ const verityDir = (0, import_node_path45.join)(root, ".verity");
38037
+ if ((0, import_node_fs61.existsSync)(gateDir) && !(0, import_node_fs61.existsSync)(verityDir)) {
37777
38038
  return migrateProjectDirRename(root, gateDir, verityDir, actions);
37778
38039
  }
37779
- if ((0, import_node_fs60.existsSync)(gateDir) && (0, import_node_fs60.existsSync)(verityDir)) {
38040
+ if ((0, import_node_fs61.existsSync)(gateDir) && (0, import_node_fs61.existsSync)(verityDir)) {
37780
38041
  return migrateProjectDirCarry(gateDir, verityDir, actions);
37781
38042
  }
37782
38043
  return false;
@@ -37797,13 +38058,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
37797
38058
  }
37798
38059
  }
37799
38060
  if (moved) {
37800
- if ((0, import_node_fs60.existsSync)(gateDir)) {
38061
+ if ((0, import_node_fs61.existsSync)(gateDir)) {
37801
38062
  const carried = carryLegacyContents(gateDir, verityDir);
37802
38063
  if (carried > 0) {
37803
38064
  actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
37804
38065
  }
37805
38066
  try {
37806
- (0, import_node_fs60.rmSync)(gateDir, { recursive: true, force: true });
38067
+ (0, import_node_fs61.rmSync)(gateDir, { recursive: true, force: true });
37807
38068
  } catch {
37808
38069
  }
37809
38070
  }
@@ -37819,18 +38080,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
37819
38080
  actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
37820
38081
  }
37821
38082
  try {
37822
- (0, import_node_fs60.rmSync)(gateDir, { recursive: true, force: true });
38083
+ (0, import_node_fs61.rmSync)(gateDir, { recursive: true, force: true });
37823
38084
  } catch {
37824
38085
  }
37825
38086
  return carried > 0;
37826
38087
  }
37827
38088
  function migrateGlobalCredentials(home, actions) {
37828
38089
  if (!home) return;
37829
- const gateCreds = (0, import_node_path44.join)(home, ".gate", "credentials");
37830
- const verityCreds = (0, import_node_path44.join)(home, ".verity", "credentials");
37831
- if (!(0, import_node_fs60.existsSync)(gateCreds)) return;
37832
- if (!(0, import_node_fs60.existsSync)(verityCreds)) {
37833
- (0, import_node_fs60.mkdirSync)((0, import_node_path44.join)(home, ".verity"), { recursive: true });
38090
+ const gateCreds = (0, import_node_path45.join)(home, ".gate", "credentials");
38091
+ const verityCreds = (0, import_node_path45.join)(home, ".verity", "credentials");
38092
+ if (!(0, import_node_fs61.existsSync)(gateCreds)) return;
38093
+ if (!(0, import_node_fs61.existsSync)(verityCreds)) {
38094
+ (0, import_node_fs61.mkdirSync)((0, import_node_path45.join)(home, ".verity"), { recursive: true });
37834
38095
  moveFile(gateCreds, verityCreds);
37835
38096
  actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
37836
38097
  return;
@@ -37852,8 +38113,8 @@ async function migrateLegacyHooks(root, actions) {
37852
38113
  }
37853
38114
  }
37854
38115
  async function migrateClaudeMd(root, actions) {
37855
- const claudeMd = (0, import_node_path44.join)(root, "CLAUDE.md");
37856
- const hadLegacyBlock = (0, import_node_fs60.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
38116
+ const claudeMd = (0, import_node_path45.join)(root, "CLAUDE.md");
38117
+ const hadLegacyBlock = (0, import_node_fs61.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
37857
38118
  if (!hadLegacyBlock) return;
37858
38119
  try {
37859
38120
  await ensureClaudeMdPointer(root);
@@ -37863,9 +38124,9 @@ async function migrateClaudeMd(root, actions) {
37863
38124
  }
37864
38125
  }
37865
38126
  function migrateStandardFile(root, actions) {
37866
- const gateMd = (0, import_node_path44.join)(root, "GATE.md");
37867
- const verityMd = (0, import_node_path44.join)(root, "VERITY.md");
37868
- if (!(0, import_node_fs60.existsSync)(gateMd) || (0, import_node_fs60.existsSync)(verityMd)) return;
38127
+ const gateMd = (0, import_node_path45.join)(root, "GATE.md");
38128
+ const verityMd = (0, import_node_path45.join)(root, "VERITY.md");
38129
+ if (!(0, import_node_fs61.existsSync)(gateMd) || (0, import_node_fs61.existsSync)(verityMd)) return;
37869
38130
  let moved = false;
37870
38131
  if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
37871
38132
  try {
@@ -37877,12 +38138,12 @@ function migrateStandardFile(root, actions) {
37877
38138
  if (!moved) moveFile(gateMd, verityMd);
37878
38139
  const content = readFileSyncSafe(verityMd);
37879
38140
  const refreshed = content.split("GATE.md").join("VERITY.md");
37880
- if (refreshed !== content) (0, import_node_fs60.writeFileSync)(verityMd, refreshed);
38141
+ if (refreshed !== content) (0, import_node_fs61.writeFileSync)(verityMd, refreshed);
37881
38142
  actions.push("Renamed GATE.md \u2192 VERITY.md");
37882
38143
  }
37883
38144
  async function migrateTelemetryHeaders(root, actions) {
37884
- const file = (0, import_node_path44.join)(root, ".claude", "settings.local.json");
37885
- if (!(0, import_node_fs60.existsSync)(file)) return;
38145
+ const file = (0, import_node_path45.join)(root, ".claude", "settings.local.json");
38146
+ if (!(0, import_node_fs61.existsSync)(file)) return;
37886
38147
  let settings;
37887
38148
  try {
37888
38149
  settings = JSON.parse(readFileSyncSafe(file) || "{}");
@@ -37930,14 +38191,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
37930
38191
  }
37931
38192
  if (toAppend.length > 0) {
37932
38193
  const sep5 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
37933
- (0, import_node_fs60.writeFileSync)(verityCreds, verityContent + sep5 + toAppend.join("\n") + "\n");
38194
+ (0, import_node_fs61.writeFileSync)(verityCreds, verityContent + sep5 + toAppend.join("\n") + "\n");
37934
38195
  }
37935
- (0, import_node_fs60.rmSync)(gateCreds, { force: true });
38196
+ (0, import_node_fs61.rmSync)(gateCreds, { force: true });
37936
38197
  return toAppend.length;
37937
38198
  }
37938
38199
  function readFileSyncSafe(path) {
37939
38200
  try {
37940
- return (0, import_node_fs60.readFileSync)(path, "utf-8");
38201
+ return (0, import_node_fs61.readFileSync)(path, "utf-8");
37941
38202
  } catch {
37942
38203
  return "";
37943
38204
  }
@@ -37952,35 +38213,35 @@ function hasStagedChanges(root) {
37952
38213
  }
37953
38214
  function moveDir(from, to) {
37954
38215
  try {
37955
- (0, import_node_fs60.renameSync)(from, to);
38216
+ (0, import_node_fs61.renameSync)(from, to);
37956
38217
  } catch (err2) {
37957
38218
  if (err2.code !== "EXDEV") throw err2;
37958
- (0, import_node_fs60.cpSync)(from, to, { recursive: true });
37959
- (0, import_node_fs60.rmSync)(from, { recursive: true, force: true });
38219
+ (0, import_node_fs61.cpSync)(from, to, { recursive: true });
38220
+ (0, import_node_fs61.rmSync)(from, { recursive: true, force: true });
37960
38221
  }
37961
38222
  }
37962
38223
  function moveFile(from, to) {
37963
38224
  try {
37964
- (0, import_node_fs60.renameSync)(from, to);
38225
+ (0, import_node_fs61.renameSync)(from, to);
37965
38226
  } catch (err2) {
37966
38227
  if (err2.code !== "EXDEV") throw err2;
37967
- (0, import_node_fs60.cpSync)(from, to);
37968
- (0, import_node_fs60.rmSync)(from, { force: true });
38228
+ (0, import_node_fs61.cpSync)(from, to);
38229
+ (0, import_node_fs61.rmSync)(from, { force: true });
37969
38230
  }
37970
38231
  }
37971
38232
  function carryLegacyContents(gateDir, verityDir) {
37972
38233
  let copied = 0;
37973
38234
  const walk2 = (relDir) => {
37974
- const srcDir = (0, import_node_path44.join)(gateDir, relDir);
37975
- for (const entry of (0, import_node_fs60.readdirSync)(srcDir)) {
37976
- const rel = relDir ? (0, import_node_path44.join)(relDir, entry) : entry;
37977
- const src = (0, import_node_path44.join)(gateDir, rel);
37978
- const dest = (0, import_node_path44.join)(verityDir, rel);
37979
- if ((0, import_node_fs60.statSync)(src).isDirectory()) {
38235
+ const srcDir = (0, import_node_path45.join)(gateDir, relDir);
38236
+ for (const entry of (0, import_node_fs61.readdirSync)(srcDir)) {
38237
+ const rel = relDir ? (0, import_node_path45.join)(relDir, entry) : entry;
38238
+ const src = (0, import_node_path45.join)(gateDir, rel);
38239
+ const dest = (0, import_node_path45.join)(verityDir, rel);
38240
+ if ((0, import_node_fs61.statSync)(src).isDirectory()) {
37980
38241
  walk2(rel);
37981
- } else if (!(0, import_node_fs60.existsSync)(dest)) {
37982
- (0, import_node_fs60.mkdirSync)((0, import_node_path44.dirname)(dest), { recursive: true });
37983
- (0, import_node_fs60.cpSync)(src, dest);
38242
+ } else if (!(0, import_node_fs61.existsSync)(dest)) {
38243
+ (0, import_node_fs61.mkdirSync)((0, import_node_path45.dirname)(dest), { recursive: true });
38244
+ (0, import_node_fs61.cpSync)(src, dest);
37984
38245
  copied++;
37985
38246
  }
37986
38247
  }
@@ -37989,22 +38250,22 @@ function carryLegacyContents(gateDir, verityDir) {
37989
38250
  return copied;
37990
38251
  }
37991
38252
  async function needsMigration(root = repoRoot()) {
37992
- const gateDir = (0, import_node_path44.join)(root, ".gate");
37993
- const verityDir = (0, import_node_path44.join)(root, ".verity");
37994
- if ((0, import_node_fs60.existsSync)(gateDir) && !(0, import_node_fs60.existsSync)(verityDir)) return true;
37995
- if ((0, import_node_fs60.existsSync)(gateDir) && (0, import_node_fs60.existsSync)(verityDir)) {
37996
- if ((0, import_node_fs60.existsSync)((0, import_node_path44.join)(gateDir, "credentials")) && !(0, import_node_fs60.existsSync)((0, import_node_path44.join)(verityDir, "credentials"))) {
38253
+ const gateDir = (0, import_node_path45.join)(root, ".gate");
38254
+ const verityDir = (0, import_node_path45.join)(root, ".verity");
38255
+ if ((0, import_node_fs61.existsSync)(gateDir) && !(0, import_node_fs61.existsSync)(verityDir)) return true;
38256
+ if ((0, import_node_fs61.existsSync)(gateDir) && (0, import_node_fs61.existsSync)(verityDir)) {
38257
+ if ((0, import_node_fs61.existsSync)((0, import_node_path45.join)(gateDir, "credentials")) && !(0, import_node_fs61.existsSync)((0, import_node_path45.join)(verityDir, "credentials"))) {
37997
38258
  return true;
37998
38259
  }
37999
- if ((0, import_node_fs60.existsSync)((0, import_node_path44.join)(gateDir, "memory")) && !(0, import_node_fs60.existsSync)((0, import_node_path44.join)(verityDir, "memory"))) {
38260
+ if ((0, import_node_fs61.existsSync)((0, import_node_path45.join)(gateDir, "memory")) && !(0, import_node_fs61.existsSync)((0, import_node_path45.join)(verityDir, "memory"))) {
38000
38261
  return true;
38001
38262
  }
38002
38263
  }
38003
- const claudeMd = (0, import_node_path44.join)(root, "CLAUDE.md");
38004
- if ((0, import_node_fs60.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
38264
+ const claudeMd = (0, import_node_path45.join)(root, "CLAUDE.md");
38265
+ if ((0, import_node_fs61.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
38005
38266
  return true;
38006
38267
  }
38007
- if ((0, import_node_fs60.existsSync)((0, import_node_path44.join)(root, "GATE.md")) && !(0, import_node_fs60.existsSync)((0, import_node_path44.join)(root, "VERITY.md"))) {
38268
+ if ((0, import_node_fs61.existsSync)((0, import_node_path45.join)(root, "GATE.md")) && !(0, import_node_fs61.existsSync)((0, import_node_path45.join)(root, "VERITY.md"))) {
38008
38269
  return true;
38009
38270
  }
38010
38271
  if (await hasLegacyHooksAt(root)) return true;
@@ -38285,11 +38546,11 @@ async function promptMultiSelect(question, choices, fallback) {
38285
38546
  }
38286
38547
 
38287
38548
  // src/lib/prove/lean-install.ts
38288
- var import_node_fs61 = require("node:fs");
38549
+ var import_node_fs62 = require("node:fs");
38289
38550
  var import_node_crypto20 = require("node:crypto");
38290
38551
  var import_node_child_process18 = require("node:child_process");
38291
38552
  var import_node_os10 = require("node:os");
38292
- var import_node_path45 = require("node:path");
38553
+ var import_node_path46 = require("node:path");
38293
38554
  var import_promises18 = require("node:stream/promises");
38294
38555
  var import_node_stream = require("node:stream");
38295
38556
  var RELEASES = "https://releases.lean-lang.org/lean4";
@@ -38309,7 +38570,7 @@ function expectedSha256(asset, version = pinnedVersion()) {
38309
38570
  function sha256File(path) {
38310
38571
  return new Promise((resolve8, reject) => {
38311
38572
  const hash = (0, import_node_crypto20.createHash)("sha256");
38312
- (0, import_node_fs61.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve8(hash.digest("hex"))).on("error", reject);
38573
+ (0, import_node_fs62.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve8(hash.digest("hex"))).on("error", reject);
38313
38574
  });
38314
38575
  }
38315
38576
  async function verifyDownload(zip, asset, version = pinnedVersion()) {
@@ -38329,7 +38590,7 @@ function leanAssetName(version = pinnedVersion()) {
38329
38590
  return suffix ? `lean-${v}-${suffix}.zip` : null;
38330
38591
  }
38331
38592
  function pinnedVersionDir(env = process.env) {
38332
- return (0, import_node_path45.join)(verityLeanHome(env), pinnedVersion());
38593
+ return (0, import_node_path46.join)(verityLeanHome(env), pinnedVersion());
38333
38594
  }
38334
38595
  function lakeBinary() {
38335
38596
  return (0, import_node_os10.platform)() === "win32" ? "lake.exe" : "lake";
@@ -38340,12 +38601,12 @@ function unzip(zip, dest) {
38340
38601
  for (const [cmd, args2] of attempts) {
38341
38602
  try {
38342
38603
  (0, import_node_child_process18.execFileSync)(cmd, args2, { stdio: ["ignore", "ignore", "pipe"], timeout: 15 * 6e4 });
38343
- if ((0, import_node_fs61.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
38604
+ if ((0, import_node_fs62.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
38344
38605
  errors.push(`${cmd}: produced nothing`);
38345
38606
  } catch (err2) {
38346
38607
  errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
38347
38608
  try {
38348
- for (const e of (0, import_node_fs61.readdirSync)(dest)) (0, import_node_fs61.rmSync)((0, import_node_path45.join)(dest, e), { recursive: true, force: true });
38609
+ for (const e of (0, import_node_fs62.readdirSync)(dest)) (0, import_node_fs62.rmSync)((0, import_node_path46.join)(dest, e), { recursive: true, force: true });
38349
38610
  } catch {
38350
38611
  }
38351
38612
  }
@@ -38362,7 +38623,7 @@ async function download(url, dest, onProgress) {
38362
38623
  seen += chunk.length;
38363
38624
  onProgress(seen, total);
38364
38625
  });
38365
- await (0, import_promises18.pipeline)(stream, (0, import_node_fs61.createWriteStream)(dest));
38626
+ await (0, import_promises18.pipeline)(stream, (0, import_node_fs62.createWriteStream)(dest));
38366
38627
  }
38367
38628
  function inPlaceProgress(label2, write = (s) => process.stderr.write(s)) {
38368
38629
  let active = false;
@@ -38400,10 +38661,10 @@ async function installLean(opts = {}) {
38400
38661
  const dir = pinnedVersionDir(env);
38401
38662
  const url = `${RELEASES}/${pinnedVersion()}/${asset}`;
38402
38663
  const home = verityLeanHome(env);
38403
- const tmp = (0, import_node_path45.join)(home, ".tmp");
38404
- (0, import_node_fs61.rmSync)(tmp, { recursive: true, force: true });
38405
- (0, import_node_fs61.mkdirSync)(tmp, { recursive: true });
38406
- const zip = (0, import_node_path45.join)(tmp, asset);
38664
+ const tmp = (0, import_node_path46.join)(home, ".tmp");
38665
+ (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38666
+ (0, import_node_fs62.mkdirSync)(tmp, { recursive: true });
38667
+ const zip = (0, import_node_path46.join)(tmp, asset);
38407
38668
  say(`downloading ${url}`);
38408
38669
  let lastPct = -1;
38409
38670
  try {
@@ -38416,40 +38677,40 @@ async function installLean(opts = {}) {
38416
38677
  }
38417
38678
  });
38418
38679
  } catch (err2) {
38419
- (0, import_node_fs61.rmSync)(tmp, { recursive: true, force: true });
38680
+ (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38420
38681
  return { ok: false, error: err2.message };
38421
38682
  }
38422
38683
  say("verifying checksum");
38423
38684
  const verified = await verifyDownload(zip, asset);
38424
38685
  if (!verified.ok) {
38425
- (0, import_node_fs61.rmSync)(tmp, { recursive: true, force: true });
38686
+ (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38426
38687
  return { ok: false, error: verified.error };
38427
38688
  }
38428
38689
  say("unpacking (this takes a minute)");
38429
- const unpack = (0, import_node_path45.join)(tmp, "unpack");
38430
- (0, import_node_fs61.mkdirSync)(unpack);
38690
+ const unpack = (0, import_node_path46.join)(tmp, "unpack");
38691
+ (0, import_node_fs62.mkdirSync)(unpack);
38431
38692
  const unpacked = unzip(zip, unpack);
38432
38693
  if (!unpacked.ok) {
38433
- (0, import_node_fs61.rmSync)(tmp, { recursive: true, force: true });
38694
+ (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38434
38695
  return { ok: false, error: `unpack failed: ${unpacked.error}` };
38435
38696
  }
38436
- const entries = (0, import_node_fs61.readdirSync)(unpack);
38437
- const top = entries.length === 1 && (0, import_node_fs61.statSync)((0, import_node_path45.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path45.join)(unpack, entries[0]) : unpack;
38438
- if (!(0, import_node_fs61.existsSync)((0, import_node_path45.join)(top, "bin", lakeBinary()))) {
38439
- (0, import_node_fs61.rmSync)(tmp, { recursive: true, force: true });
38697
+ const entries = (0, import_node_fs62.readdirSync)(unpack);
38698
+ const top = entries.length === 1 && (0, import_node_fs62.statSync)((0, import_node_path46.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path46.join)(unpack, entries[0]) : unpack;
38699
+ if (!(0, import_node_fs62.existsSync)((0, import_node_path46.join)(top, "bin", lakeBinary()))) {
38700
+ (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38440
38701
  return { ok: false, error: "the archive did not contain bin/lake" };
38441
38702
  }
38442
- (0, import_node_fs61.rmSync)(dir, { recursive: true, force: true });
38443
- (0, import_node_fs61.mkdirSync)(home, { recursive: true });
38444
- (0, import_node_fs61.renameSync)(top, dir);
38445
- (0, import_node_fs61.rmSync)(tmp, { recursive: true, force: true });
38703
+ (0, import_node_fs62.rmSync)(dir, { recursive: true, force: true });
38704
+ (0, import_node_fs62.mkdirSync)(home, { recursive: true });
38705
+ (0, import_node_fs62.renameSync)(top, dir);
38706
+ (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38446
38707
  return { ok: true, dir };
38447
38708
  }
38448
38709
 
38449
38710
  // src/lib/remote-config.ts
38450
- var import_node_fs62 = require("node:fs");
38711
+ var import_node_fs63 = require("node:fs");
38451
38712
  var import_promises19 = require("node:fs/promises");
38452
- var import_node_path46 = require("node:path");
38713
+ var import_node_path47 = require("node:path");
38453
38714
  var import_yaml5 = __toESM2(require_dist());
38454
38715
  var IGNORE_RIDER = "verityignore";
38455
38716
  async function fetchRemoteSetup(opts) {
@@ -38494,7 +38755,7 @@ async function adoptRemoteSetup(found, opts) {
38494
38755
  written.push(STANDARD_FILE);
38495
38756
  if (rider !== null) {
38496
38757
  const localIgnore = projectPath(VERITYIGNORE_FILE);
38497
- if (!(0, import_node_fs62.existsSync)(localIgnore)) {
38758
+ if (!(0, import_node_fs63.existsSync)(localIgnore)) {
38498
38759
  await writeOut(VERITYIGNORE_FILE, rider);
38499
38760
  written.push(VERITYIGNORE_FILE);
38500
38761
  } else {
@@ -38527,7 +38788,7 @@ async function adoptRemoteSetup(found, opts) {
38527
38788
  }
38528
38789
  async function writeOut(relative6, body2) {
38529
38790
  const target = projectPath(relative6);
38530
- await (0, import_promises19.mkdir)((0, import_node_path46.dirname)(target), { recursive: true });
38791
+ await (0, import_promises19.mkdir)((0, import_node_path47.dirname)(target), { recursive: true });
38531
38792
  await (0, import_promises19.writeFile)(target, body2);
38532
38793
  }
38533
38794
  function describeRemote(found) {
@@ -38644,15 +38905,15 @@ async function runOptionalAuth(resolution, opts = {}) {
38644
38905
  }
38645
38906
  function resolveDataDir2() {
38646
38907
  const candidates2 = [
38647
- (0, import_node_path47.join)(__dirname, "..", "data"),
38908
+ (0, import_node_path48.join)(__dirname, "..", "data"),
38648
38909
  // installed: node_modules/@codacy/verity-cli/data
38649
- (0, import_node_path47.join)(__dirname, "..", "..", "data"),
38910
+ (0, import_node_path48.join)(__dirname, "..", "..", "data"),
38650
38911
  // edge case: nested resolution
38651
- (0, import_node_path47.join)(process.cwd(), "cli", "data")
38912
+ (0, import_node_path48.join)(process.cwd(), "cli", "data")
38652
38913
  // local dev: running from repo root
38653
38914
  ];
38654
38915
  for (const candidate of candidates2) {
38655
- if ((0, import_node_fs63.existsSync)((0, import_node_path47.join)(candidate, "skills"))) {
38916
+ if ((0, import_node_fs64.existsSync)((0, import_node_path48.join)(candidate, "skills"))) {
38656
38917
  return candidate;
38657
38918
  }
38658
38919
  }
@@ -38668,9 +38929,9 @@ async function skillIsCurrent(src, dest) {
38668
38929
  const list2 = (dir) => {
38669
38930
  const out2 = [];
38670
38931
  const walk2 = (d, prefix) => {
38671
- for (const e of (0, import_node_fs63.readdirSync)(d, { withFileTypes: true })) {
38932
+ for (const e of (0, import_node_fs64.readdirSync)(d, { withFileTypes: true })) {
38672
38933
  const rel = prefix ? `${prefix}/${e.name}` : e.name;
38673
- if (e.isDirectory()) walk2((0, import_node_path47.join)(d, e.name), rel);
38934
+ if (e.isDirectory()) walk2((0, import_node_path48.join)(d, e.name), rel);
38674
38935
  else if (e.isFile()) out2.push(rel);
38675
38936
  }
38676
38937
  };
@@ -38681,8 +38942,8 @@ async function skillIsCurrent(src, dest) {
38681
38942
  const shipped = list2(src);
38682
38943
  if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
38683
38944
  for (const rel of shipped) {
38684
- const a = await (0, import_promises20.readFile)((0, import_node_path47.join)(src, rel), "utf-8");
38685
- const b = await (0, import_promises20.readFile)((0, import_node_path47.join)(dest, rel), "utf-8");
38945
+ const a = await (0, import_promises20.readFile)((0, import_node_path48.join)(src, rel), "utf-8");
38946
+ const b = await (0, import_promises20.readFile)((0, import_node_path48.join)(dest, rel), "utf-8");
38686
38947
  if (a !== b) return false;
38687
38948
  }
38688
38949
  return true;
@@ -38730,8 +38991,14 @@ async function askSetupQuestions(defaultsOnly, previous, given = {}) {
38730
38991
  const momentsDefault = given.moments ?? (previous?.moments?.length ? previous.moments : await momentsFromInstalledHooks());
38731
38992
  const askIntensity = !given.intensity;
38732
38993
  const askMoments = !given.moments;
38994
+ const givenTelemetry = async () => {
38995
+ if (given.telemetry === void 0) return "not-asked";
38996
+ const enabled = (await checkTelemetry()).enabled;
38997
+ if (given.telemetry) return enabled ? "already-on" : "yes";
38998
+ return enabled ? "turn-off" : "no";
38999
+ };
38733
39000
  if (defaultsOnly || !askIntensity && !askMoments) {
38734
- return { intensity: intensityDefault, moments: momentsDefault, telemetry: "not-asked" };
39001
+ return { intensity: intensityDefault, moments: momentsDefault, telemetry: await givenTelemetry() };
38735
39002
  }
38736
39003
  if (previous?.intensity || previous?.moments) {
38737
39004
  printInfo(`Current: ${intensityDefault} \xB7 ${momentsDefault.join(", ")} \u2014 press Enter to keep either.`);
@@ -38746,6 +39013,9 @@ async function askSetupQuestions(defaultsOnly, previous, given = {}) {
38746
39013
  MOMENT_CHOICES,
38747
39014
  momentsDefault
38748
39015
  );
39016
+ if (given.telemetry !== void 0) {
39017
+ return { intensity, moments, telemetry: await givenTelemetry() };
39018
+ }
38749
39019
  const current = await checkTelemetry();
38750
39020
  if (current.enabled) {
38751
39021
  printInfo(`Cost & usage telemetry: already enabled \u2192 ${current.endpoint}`);
@@ -38760,6 +39030,12 @@ async function askSetupQuestions(defaultsOnly, previous, given = {}) {
38760
39030
  const wants = await promptYes(" Enable cost & usage telemetry? [Y/n] ", { nonInteractive: false });
38761
39031
  return { intensity, moments, telemetry: wants ? "yes" : "no" };
38762
39032
  }
39033
+ function parseTelemetryAnswer(raw) {
39034
+ const v = raw.trim().toLowerCase();
39035
+ if (v === "on") return true;
39036
+ if (v === "off") return false;
39037
+ return null;
39038
+ }
38763
39039
  function insideClaudeCode() {
38764
39040
  return !!process.env.CLAUDECODE || !!process.env.CLAUDE_SESSION_ID;
38765
39041
  }
@@ -38868,7 +39144,7 @@ async function synthesizeLocally(opts) {
38868
39144
  async function healStaleAnalysisConfig(globals) {
38869
39145
  const configPath = projectPath(CODACY_CONFIG_FILE);
38870
39146
  const standardPath = projectPath(STANDARD_FILE);
38871
- if (!(0, import_node_fs63.existsSync)(configPath) || !(0, import_node_fs63.existsSync)(standardPath)) return;
39147
+ if (!(0, import_node_fs64.existsSync)(configPath) || !(0, import_node_fs64.existsSync)(standardPath)) return;
38872
39148
  const validation = validatePatternIds();
38873
39149
  if (validation.status !== "invalid") return;
38874
39150
  printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
@@ -38965,17 +39241,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
38965
39241
  async function installSkills(force, step) {
38966
39242
  step("Installing skills");
38967
39243
  const dataDir = resolveDataDir2();
38968
- const skillsSource = (0, import_node_path47.join)(dataDir, "skills");
39244
+ const skillsSource = (0, import_node_path48.join)(dataDir, "skills");
38969
39245
  const skillsDest = ".claude/skills";
38970
39246
  let skillsInstalled = 0;
38971
39247
  for (const skill of SKILLS) {
38972
- const src = (0, import_node_path47.join)(skillsSource, skill);
38973
- const dest = (0, import_node_path47.join)(skillsDest, skill);
38974
- if (!(0, import_node_fs63.existsSync)(src)) {
39248
+ const src = (0, import_node_path48.join)(skillsSource, skill);
39249
+ const dest = (0, import_node_path48.join)(skillsDest, skill);
39250
+ if (!(0, import_node_fs64.existsSync)(src)) {
38975
39251
  printWarn(` Skill data not found: ${skill}`);
38976
39252
  continue;
38977
39253
  }
38978
- if ((0, import_node_fs63.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
39254
+ if ((0, import_node_fs64.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
38979
39255
  skillsInstalled++;
38980
39256
  continue;
38981
39257
  }
@@ -39037,7 +39313,7 @@ async function checkPrerequisites(step) {
39037
39313
  }
39038
39314
  return prereqs.checks.some((c) => c.id === "claude" && c.status === "ok");
39039
39315
  }
39040
- async function scaffoldProject(step, defaultsOnly, pluginMode) {
39316
+ async function scaffoldProject(step, defaultsOnly, pluginMode, given = {}) {
39041
39317
  step("Knowledge base, .gitignore and CLAUDE.md");
39042
39318
  await (0, import_promises20.mkdir)(VERITY_DIR, { recursive: true });
39043
39319
  await ensureMemoryDir();
@@ -39062,7 +39338,7 @@ async function scaffoldProject(step, defaultsOnly, pluginMode) {
39062
39338
  const trackedMemory = memoryOptOut() ? [] : committedMemoryFiles();
39063
39339
  if (trackedMemory.length > 0) {
39064
39340
  printWarn(` ${trackedMemory.length} knowledge-graph file(s) are tracked, so they show up in every diff.`);
39065
- const fence = defaultsOnly ? false : await promptYes(" Stop tracking them (files stay on disk)? [Y/n] ", { nonInteractive: false });
39341
+ const fence = given.untrackMemory ? true : defaultsOnly ? false : await promptYes(" Stop tracking them (files stay on disk)? [Y/n] ", { nonInteractive: false });
39066
39342
  if (fence) {
39067
39343
  const result = fenceMemory();
39068
39344
  if (!result.ok) printWarn(' Could not untrack \u2014 run "verity memory untrack" when you can');
@@ -39077,7 +39353,7 @@ async function scaffoldProject(step, defaultsOnly, pluginMode) {
39077
39353
  const tracked = committedVerityState();
39078
39354
  if (tracked.length > 0) {
39079
39355
  printWarn(` ${tracked.length} Verity state file(s) are tracked in git (e.g. ${tracked[0]}).`);
39080
- const untrack = defaultsOnly ? false : await promptYes(" Untrack them now (files stay on disk)? [Y/n] ", { nonInteractive: false });
39356
+ const untrack = given.untrackState ? true : defaultsOnly ? false : await promptYes(" Untrack them now (files stay on disk)? [Y/n] ", { nonInteractive: false });
39081
39357
  if (untrack) {
39082
39358
  const result = untrackVerityState();
39083
39359
  if (result === "untracked") printInfo(" Untracked (staged) \u2014 commit to finish \u2713");
@@ -39155,7 +39431,10 @@ function registerInitCommand(program2) {
39155
39431
  ).option(
39156
39432
  "--intensity <level>",
39157
39433
  "Answer the analysis-intensity question without asking: lightweight | balanced | thorough"
39158
- ).action(async (opts) => {
39434
+ ).option(
39435
+ "--telemetry <on|off>",
39436
+ "Answer the cost & usage telemetry question without asking: on | off"
39437
+ ).option("--untrack-memory", 'Answer yes to "stop tracking the knowledge graph in git?" without asking').option("--untrack-state", 'Answer yes to "untrack committed Verity state?" without asking').action(async (opts) => {
39159
39438
  const force = opts.force ?? false;
39160
39439
  const wantsHandoff = opts.setup !== false;
39161
39440
  const wantsAdopt = opts.adopt !== false;
@@ -39163,7 +39442,7 @@ function registerInitCommand(program2) {
39163
39442
  const staleMarker = clearStalePluginMarker();
39164
39443
  const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
39165
39444
  const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
39166
- const isProject = projectMarkers.some((m) => (0, import_node_fs63.existsSync)(m));
39445
+ const isProject = projectMarkers.some((m) => (0, import_node_fs64.existsSync)(m));
39167
39446
  if (!isProject) {
39168
39447
  printError("No project detected in the current directory.");
39169
39448
  printInfo('Run "verity init" from your project root.');
@@ -39244,16 +39523,29 @@ function registerInitCommand(program2) {
39244
39523
  }
39245
39524
  givenIntensity = match.id;
39246
39525
  }
39526
+ let givenTelemetry;
39527
+ if (opts.telemetry != null) {
39528
+ const parsed = parseTelemetryAnswer(String(opts.telemetry));
39529
+ if (parsed === null) {
39530
+ printError(`--telemetry: unrecognised "${opts.telemetry}". Valid: on, off.`);
39531
+ process.exit(1);
39532
+ }
39533
+ givenTelemetry = parsed;
39534
+ }
39247
39535
  const answers = await askSetupQuestions(defaultsOnly, previous, {
39248
39536
  intensity: givenIntensity,
39249
- moments: givenMoments
39537
+ moments: givenMoments,
39538
+ telemetry: givenTelemetry
39250
39539
  });
39251
39540
  const { intensity, moments } = answers;
39252
39541
  if (defaultsOnly) {
39253
39542
  printInfo(` intensity: ${intensity} \xB7 moments: ${moments.join(", ") || "none"} (no questions asked)`);
39254
39543
  }
39255
- await scaffoldProject(step, defaultsOnly, pluginMode);
39256
- const globalVerityDir = (0, import_node_path47.join)(process.env.HOME ?? "", ".verity");
39544
+ await scaffoldProject(step, defaultsOnly, pluginMode, {
39545
+ untrackMemory: opts.untrackMemory === true,
39546
+ untrackState: opts.untrackState === true
39547
+ });
39548
+ const globalVerityDir = (0, import_node_path48.join)(process.env.HOME ?? "", ".verity");
39257
39549
  await (0, import_promises20.mkdir)(globalVerityDir, { recursive: true });
39258
39550
  console.log("");
39259
39551
  step("Wiring Claude Code hooks");
@@ -39301,8 +39593,14 @@ function registerInitCommand(program2) {
39301
39593
  printInfo(' not asked (unattended run) \u2014 enable later with "verity telemetry install"');
39302
39594
  } else if (answers.telemetry === "no") {
39303
39595
  printInfo(' declined \u2014 enable later with "verity telemetry install"');
39304
- }
39305
- let telemetryChoice = answers.telemetry === "already-on" ? "enabled" : answers.telemetry === "no" ? "declined" : wantsTelemetry ? "deferred" : void 0;
39596
+ } else if (answers.telemetry === "already-on") {
39597
+ printInfo(" already enabled \u2713");
39598
+ } else if (answers.telemetry === "turn-off") {
39599
+ const removed = await uninstallTelemetry();
39600
+ if (removed.ok) printInfo(' turned off (--telemetry off) \u2014 re-enable with "verity telemetry install"');
39601
+ else printWarn(` Could not turn telemetry off: ${removed.error}`);
39602
+ }
39603
+ let telemetryChoice = answers.telemetry === "already-on" ? "enabled" : answers.telemetry === "no" || answers.telemetry === "turn-off" ? "declined" : wantsTelemetry ? "deferred" : void 0;
39306
39604
  if (wantsTelemetry) {
39307
39605
  const globals = program2.opts();
39308
39606
  const token = await resolveToken(globals.token);
@@ -39322,7 +39620,7 @@ function registerInitCommand(program2) {
39322
39620
  }
39323
39621
  step("Your project's Standard");
39324
39622
  let haveStandard = false;
39325
- if ((0, import_node_fs63.existsSync)(projectPath(STANDARD_FILE))) {
39623
+ if ((0, import_node_fs64.existsSync)(projectPath(STANDARD_FILE))) {
39326
39624
  printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
39327
39625
  haveStandard = true;
39328
39626
  } else {
@@ -39352,7 +39650,7 @@ function registerInitCommand(program2) {
39352
39650
  ...telemetryChoice ? { telemetry: telemetryChoice } : {},
39353
39651
  init: {
39354
39652
  completed_at: (/* @__PURE__ */ new Date()).toISOString(),
39355
- cli_version: true ? "0.33.3-experimental.53cd005" : "dev"
39653
+ cli_version: true ? "0.33.3-experimental.5a3f573" : "dev"
39356
39654
  }
39357
39655
  });
39358
39656
  } catch (err2) {
@@ -39402,8 +39700,8 @@ function registerInitCommand(program2) {
39402
39700
  }
39403
39701
 
39404
39702
  // src/commands/uninstall.ts
39405
- var import_node_fs64 = require("node:fs");
39406
- var import_node_path48 = require("node:path");
39703
+ var import_node_fs65 = require("node:fs");
39704
+ var import_node_path49 = require("node:path");
39407
39705
  function registerUninstallCommand(program2) {
39408
39706
  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) => {
39409
39707
  const dryRun = opts.dryRun ?? false;
@@ -39412,11 +39710,11 @@ function registerUninstallCommand(program2) {
39412
39710
  const actions = [];
39413
39711
  const skillsRoot = projectPath(".claude/skills");
39414
39712
  for (const name2 of PROJECT_SKILL_NAMES) {
39415
- const dir = (0, import_node_path48.join)(skillsRoot, name2);
39416
- if ((0, import_node_fs64.existsSync)(dir)) {
39713
+ const dir = (0, import_node_path49.join)(skillsRoot, name2);
39714
+ if ((0, import_node_fs65.existsSync)(dir)) {
39417
39715
  actions.push({
39418
39716
  label: `Remove .claude/skills/${name2}/`,
39419
- apply: () => (0, import_node_fs64.rmSync)(dir, { recursive: true, force: true })
39717
+ apply: () => (0, import_node_fs65.rmSync)(dir, { recursive: true, force: true })
39420
39718
  });
39421
39719
  }
39422
39720
  }
@@ -39430,24 +39728,24 @@ function registerUninstallCommand(program2) {
39430
39728
  });
39431
39729
  }
39432
39730
  const verityDir = projectPath(VERITY_DIR);
39433
- if ((0, import_node_fs64.existsSync)(verityDir)) {
39731
+ if ((0, import_node_fs65.existsSync)(verityDir)) {
39434
39732
  actions.push({
39435
39733
  label: `Remove ${VERITY_DIR}/`,
39436
- apply: () => (0, import_node_fs64.rmSync)(verityDir, { recursive: true, force: true })
39734
+ apply: () => (0, import_node_fs65.rmSync)(verityDir, { recursive: true, force: true })
39437
39735
  });
39438
39736
  }
39439
39737
  if (!keepVerityMd) {
39440
39738
  const verityMd = projectPath(VERITY_MD_FILE);
39441
- if ((0, import_node_fs64.existsSync)(verityMd)) {
39739
+ if ((0, import_node_fs65.existsSync)(verityMd)) {
39442
39740
  actions.push({
39443
39741
  label: `Remove ${VERITY_MD_FILE}`,
39444
- apply: () => (0, import_node_fs64.rmSync)(verityMd, { force: true })
39742
+ apply: () => (0, import_node_fs65.rmSync)(verityMd, { force: true })
39445
39743
  });
39446
39744
  }
39447
39745
  }
39448
39746
  const cleanupEmptyDir = (path) => {
39449
- if ((0, import_node_fs64.existsSync)(path) && (0, import_node_fs64.statSync)(path).isDirectory() && (0, import_node_fs64.readdirSync)(path).length === 0) {
39450
- (0, import_node_fs64.rmdirSync)(path);
39747
+ if ((0, import_node_fs65.existsSync)(path) && (0, import_node_fs65.statSync)(path).isDirectory() && (0, import_node_fs65.readdirSync)(path).length === 0) {
39748
+ (0, import_node_fs65.rmdirSync)(path);
39451
39749
  }
39452
39750
  };
39453
39751
  actions.push({
@@ -39458,11 +39756,11 @@ function registerUninstallCommand(program2) {
39458
39756
  }
39459
39757
  });
39460
39758
  const home = process.env.HOME ?? "";
39461
- const globalVerityDir = (0, import_node_path48.join)(home, ".verity");
39462
- if (purgeGlobal && (0, import_node_fs64.existsSync)(globalVerityDir)) {
39759
+ const globalVerityDir = (0, import_node_path49.join)(home, ".verity");
39760
+ if (purgeGlobal && (0, import_node_fs65.existsSync)(globalVerityDir)) {
39463
39761
  actions.push({
39464
39762
  label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
39465
- apply: () => (0, import_node_fs64.rmSync)(globalVerityDir, { recursive: true, force: true })
39763
+ apply: () => (0, import_node_fs65.rmSync)(globalVerityDir, { recursive: true, force: true })
39466
39764
  });
39467
39765
  }
39468
39766
  if (actions.length === 0) {
@@ -39656,8 +39954,8 @@ function registerTaskCommands(program2) {
39656
39954
  }
39657
39955
 
39658
39956
  // src/commands/reset.ts
39659
- var import_node_fs65 = require("node:fs");
39660
- var import_node_path49 = require("node:path");
39957
+ var import_node_fs66 = require("node:fs");
39958
+ var import_node_path50 = require("node:path");
39661
39959
  function registerResetCommand(program2) {
39662
39960
  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) => {
39663
39961
  const globals = program2.opts();
@@ -39694,11 +39992,11 @@ function registerResetCommand(program2) {
39694
39992
  }
39695
39993
  const cacheDir = projectPath(CACHE_DIR);
39696
39994
  let purged = 0;
39697
- if ((0, import_node_fs65.existsSync)(cacheDir)) {
39698
- for (const entry of (0, import_node_fs65.readdirSync)(cacheDir)) {
39995
+ if ((0, import_node_fs66.existsSync)(cacheDir)) {
39996
+ for (const entry of (0, import_node_fs66.readdirSync)(cacheDir)) {
39699
39997
  if (entry.startsWith("pending-")) {
39700
39998
  try {
39701
- (0, import_node_fs65.unlinkSync)((0, import_node_path49.join)(cacheDir, entry));
39999
+ (0, import_node_fs66.unlinkSync)((0, import_node_path50.join)(cacheDir, entry));
39702
40000
  purged++;
39703
40001
  } catch {
39704
40002
  }
@@ -39713,19 +40011,19 @@ function registerResetCommand(program2) {
39713
40011
  projectPath(`${VERITY_DIR}/.last-analysis`)
39714
40012
  ];
39715
40013
  for (const file of filesToClear) {
39716
- if ((0, import_node_fs65.existsSync)(file)) {
40014
+ if ((0, import_node_fs66.existsSync)(file)) {
39717
40015
  try {
39718
- (0, import_node_fs65.writeFileSync)(file, "");
40016
+ (0, import_node_fs66.writeFileSync)(file, "");
39719
40017
  } catch {
39720
40018
  }
39721
40019
  }
39722
40020
  }
39723
40021
  if (opts.all) {
39724
40022
  const logsDir = projectPath(`${VERITY_DIR}/.logs`);
39725
- if ((0, import_node_fs65.existsSync)(logsDir)) {
39726
- for (const entry of (0, import_node_fs65.readdirSync)(logsDir)) {
40023
+ if ((0, import_node_fs66.existsSync)(logsDir)) {
40024
+ for (const entry of (0, import_node_fs66.readdirSync)(logsDir)) {
39727
40025
  try {
39728
- (0, import_node_fs65.unlinkSync)((0, import_node_path49.join)(logsDir, entry));
40026
+ (0, import_node_fs66.unlinkSync)((0, import_node_path50.join)(logsDir, entry));
39729
40027
  } catch {
39730
40028
  }
39731
40029
  }
@@ -39737,7 +40035,7 @@ function registerResetCommand(program2) {
39737
40035
  }
39738
40036
 
39739
40037
  // src/commands/reflect.ts
39740
- var import_node_fs66 = require("node:fs");
40038
+ var import_node_fs67 = require("node:fs");
39741
40039
 
39742
40040
  // src/lib/reflection-globs.ts
39743
40041
  var MAX_GLOBS = 6;
@@ -39775,7 +40073,7 @@ async function writeNodeToDisk(args2) {
39775
40073
  { treePaths: listTrackedFiles(), recordBaseline: false }
39776
40074
  );
39777
40075
  if (written === 0) return false;
39778
- return (0, import_node_fs66.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
40076
+ return (0, import_node_fs67.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
39779
40077
  } catch {
39780
40078
  return false;
39781
40079
  }
@@ -40207,6 +40505,15 @@ function registerRunCommand(program2) {
40207
40505
  }
40208
40506
 
40209
40507
  // src/commands/telemetry.ts
40508
+ var import_node_fs68 = require("node:fs");
40509
+ async function recordTelemetryChoice(choice) {
40510
+ if (!(0, import_node_fs68.existsSync)(projectPath(SETUP_STATE_FILE))) return;
40511
+ try {
40512
+ if ((await readSetupState())?.telemetry === choice) return;
40513
+ await writeSetupState({ telemetry: choice });
40514
+ } catch {
40515
+ }
40516
+ }
40210
40517
  function registerTelemetryCommands(program2) {
40211
40518
  const telemetry = program2.command("telemetry").description("Manage Claude Code OpenTelemetry export to Verity (cost & usage)");
40212
40519
  telemetry.command("install").description("Enable Claude Code telemetry export to Verity (writes .claude/settings.local.json)").action(async () => {
@@ -40232,6 +40539,7 @@ function registerTelemetryCommands(program2) {
40232
40539
  printError(result.error);
40233
40540
  process.exit(1);
40234
40541
  }
40542
+ await recordTelemetryChoice("enabled");
40235
40543
  printInfo(`Telemetry enabled \u2192 ${result.data.endpoint}`);
40236
40544
  printInfo(` wrote ${SETTINGS_LOCAL_FILE2} (no token stored \u2014 resolved at runtime via otelHeadersHelper)`);
40237
40545
  printInfo(" takes effect on your NEXT Claude Code session; first metrics appear within ~60s of activity");
@@ -40268,6 +40576,7 @@ function registerTelemetryCommands(program2) {
40268
40576
  printError(result.error);
40269
40577
  process.exit(1);
40270
40578
  }
40579
+ await recordTelemetryChoice("declined");
40271
40580
  printInfo(
40272
40581
  result.data.removed > 0 ? `Telemetry disabled (${result.data.removed} keys removed from ${SETTINGS_LOCAL_FILE2})` : "Telemetry was not enabled \u2014 nothing to remove."
40273
40582
  );
@@ -40275,8 +40584,8 @@ function registerTelemetryCommands(program2) {
40275
40584
  }
40276
40585
 
40277
40586
  // src/commands/prove.ts
40278
- var import_node_fs67 = require("node:fs");
40279
- var import_node_path50 = require("node:path");
40587
+ var import_node_fs69 = require("node:fs");
40588
+ var import_node_path51 = require("node:path");
40280
40589
 
40281
40590
  // src/lib/prove/hint-pool.ts
40282
40591
  var STOP2 = /* @__PURE__ */ new Set([
@@ -40412,7 +40721,7 @@ function registerProveCommand(program2) {
40412
40721
  process.exit(2);
40413
40722
  }
40414
40723
  const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
40415
- let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path50.relative)(root, (0, import_node_path50.resolve)(p)) || ".") });
40724
+ let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path51.relative)(root, (0, import_node_path51.resolve)(p)) || ".") });
40416
40725
  if (opts.hint && paths.length === 0) {
40417
40726
  const hit = hintMatches(root, opts.hint);
40418
40727
  if (hit.files.length > 0) {
@@ -40466,7 +40775,7 @@ function registerProveCommand(program2) {
40466
40775
  });
40467
40776
  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) => {
40468
40777
  const root = repoRoot();
40469
- if (!(0, import_node_fs67.existsSync)((0, import_node_path50.join)(root, PROOFS_DIR, "lakefile.toml"))) {
40778
+ if (!(0, import_node_fs69.existsSync)((0, import_node_path51.join)(root, PROOFS_DIR, "lakefile.toml"))) {
40470
40779
  printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
40471
40780
  process.exit(2);
40472
40781
  }
@@ -40490,7 +40799,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
40490
40799
  const reports = [];
40491
40800
  for (const f of files) {
40492
40801
  const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
40493
- report.file = (0, import_node_path50.relative)(root, f);
40802
+ report.file = (0, import_node_path51.relative)(root, f);
40494
40803
  reports.push(report);
40495
40804
  try {
40496
40805
  writeResult(root, report);
@@ -40528,7 +40837,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
40528
40837
  printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
40529
40838
  process.exit(2);
40530
40839
  }
40531
- if (!(0, import_node_fs67.existsSync)((0, import_node_path50.join)(root, PROOFS_DIR, "lakefile.toml"))) {
40840
+ if (!(0, import_node_fs69.existsSync)((0, import_node_path51.join)(root, PROOFS_DIR, "lakefile.toml"))) {
40532
40841
  printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
40533
40842
  process.exit(2);
40534
40843
  }
@@ -40559,7 +40868,7 @@ ${report.error ?? ""}`);
40559
40868
  printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
40560
40869
  return;
40561
40870
  }
40562
- const modelSource = readRegularFileInRoot(root, (0, import_node_path50.relative)(root, file), 512 * 1024);
40871
+ const modelSource = readRegularFileInRoot(root, (0, import_node_path51.relative)(root, file), 512 * 1024);
40563
40872
  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`);
40564
40873
  const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
40565
40874
  const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
@@ -40579,7 +40888,7 @@ ${report.error ?? ""}`);
40579
40888
  });
40580
40889
  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) => {
40581
40890
  const root = repoRoot();
40582
- let files = paths.map((p) => (0, import_node_path50.relative)(root, (0, import_node_path50.resolve)(p)));
40891
+ let files = paths.map((p) => (0, import_node_path51.relative)(root, (0, import_node_path51.resolve)(p)));
40583
40892
  if (files.length === 0) {
40584
40893
  const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
40585
40894
  const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
@@ -40639,7 +40948,7 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
40639
40948
  let revise;
40640
40949
  if (opts.revise) {
40641
40950
  const existing = resolveModelFile(root, opts.revise);
40642
- const src = existing ? readRegularFileInRoot(root, (0, import_node_path50.relative)(root, existing), 64 * 1024) : null;
40951
+ const src = existing ? readRegularFileInRoot(root, (0, import_node_path51.relative)(root, existing), 64 * 1024) : null;
40643
40952
  if (!src || !src.ok || !opts.note) {
40644
40953
  printError('--revise needs an existing model under Models/ and --note "<what the replay showed>"');
40645
40954
  process.exit(2);
@@ -40678,8 +40987,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
40678
40987
  });
40679
40988
  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) => {
40680
40989
  const root = repoRoot();
40681
- const rel0 = (0, import_node_path50.relative)(root, (0, import_node_path50.isAbsolute)(file) ? file : (0, import_node_path50.join)(root, file)).replace(/\\/g, "/");
40682
- const rel = rel0.startsWith("..") || (0, import_node_path50.isAbsolute)(rel0) ? null : rel0;
40990
+ const rel0 = (0, import_node_path51.relative)(root, (0, import_node_path51.isAbsolute)(file) ? file : (0, import_node_path51.join)(root, file)).replace(/\\/g, "/");
40991
+ const rel = rel0.startsWith("..") || (0, import_node_path51.isAbsolute)(rel0) ? null : rel0;
40683
40992
  if (!rel) {
40684
40993
  printError(`${file} is not inside this repository`);
40685
40994
  process.exit(2);
@@ -40695,8 +41004,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
40695
41004
  });
40696
41005
  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) => {
40697
41006
  const root = repoRoot();
40698
- const rel = (0, import_node_path50.relative)(root, (0, import_node_path50.isAbsolute)(file) ? file : (0, import_node_path50.join)(root, file));
40699
- const digest = rel.startsWith("..") || (0, import_node_path50.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
41007
+ const rel = (0, import_node_path51.relative)(root, (0, import_node_path51.isAbsolute)(file) ? file : (0, import_node_path51.join)(root, file));
41008
+ const digest = rel.startsWith("..") || (0, import_node_path51.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
40700
41009
  if (!digest) {
40701
41010
  printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
40702
41011
  process.exit(2);
@@ -40730,10 +41039,10 @@ function refreshScaffold(root) {
40730
41039
  }
40731
41040
 
40732
41041
  // src/commands/lean.ts
40733
- var import_node_fs68 = require("node:fs");
41042
+ var import_node_fs70 = require("node:fs");
40734
41043
  var import_node_child_process20 = require("node:child_process");
40735
41044
  var import_node_os11 = require("node:os");
40736
- var import_node_path51 = require("node:path");
41045
+ var import_node_path52 = require("node:path");
40737
41046
  function registerLeanCommand(program2) {
40738
41047
  const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
40739
41048
  lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
@@ -40750,7 +41059,7 @@ function registerLeanCommand(program2) {
40750
41059
  const managed = pinnedVersionDir();
40751
41060
  const matches = version ? version.includes(pin) : false;
40752
41061
  if (opts.json) {
40753
- printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs68.existsSync)((0, import_node_path51.join)(managed, "bin")), asset: leanAssetName() });
41062
+ printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs70.existsSync)((0, import_node_path52.join)(managed, "bin")), asset: leanAssetName() });
40754
41063
  return;
40755
41064
  }
40756
41065
  printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
@@ -40768,7 +41077,7 @@ function registerLeanCommand(program2) {
40768
41077
  process.exit(2);
40769
41078
  }
40770
41079
  const dir = pinnedVersionDir();
40771
- if ((0, import_node_fs68.existsSync)((0, import_node_path51.join)(dir, "bin", "lake")) && !opts.force) {
41080
+ if ((0, import_node_fs70.existsSync)((0, import_node_path52.join)(dir, "bin", "lake")) && !opts.force) {
40772
41081
  printInfo(`already installed at ${dir}`);
40773
41082
  return;
40774
41083
  }
@@ -40804,18 +41113,18 @@ function registerLeanCommand(program2) {
40804
41113
  });
40805
41114
  lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
40806
41115
  const dir = pinnedVersionDir();
40807
- if (!(0, import_node_fs68.existsSync)(dir)) {
41116
+ if (!(0, import_node_fs70.existsSync)(dir)) {
40808
41117
  printInfo("nothing to remove");
40809
41118
  return;
40810
41119
  }
40811
- (0, import_node_fs68.rmSync)(dir, { recursive: true, force: true });
41120
+ (0, import_node_fs70.rmSync)(dir, { recursive: true, force: true });
40812
41121
  printInfo(`removed ${dir}`);
40813
41122
  });
40814
41123
  }
40815
41124
 
40816
41125
  // src/cli.ts
40817
- program.name("verity").description("CLI for Verity quality gate service").version("0.33.3-experimental.53cd005").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) => {
40818
- installStderrLog(actionCommand.name(), process.argv.slice(2), "0.33.3-experimental.53cd005");
41126
+ program.name("verity").description("CLI for Verity quality gate service").version("0.33.3-experimental.5a3f573").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) => {
41127
+ installStderrLog(actionCommand.name(), process.argv.slice(2), "0.33.3-experimental.5a3f573");
40819
41128
  setUserNamedServiceUrl(program.opts().serviceUrl);
40820
41129
  try {
40821
41130
  await foldLegacyLocalCredential();