@codacy/verity-cli 0.33.1-experimental.4a41d04 → 0.33.2-experimental.0c53bed

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/bin/verity.js +701 -556
  3. package/package.json +1 -1
package/bin/verity.js CHANGED
@@ -12911,10 +12911,11 @@ function readMarker() {
12911
12911
  const raw = JSON.parse((0, import_node_fs7.readFileSync)(markerPath(), "utf-8"));
12912
12912
  const pluginRoot = typeof raw.plugin_root === "string" ? raw.plugin_root : "";
12913
12913
  if (!pluginRoot || CONTROL_CHARS.test(pluginRoot)) return null;
12914
+ const version = typeof raw.version === "string" && !CONTROL_CHARS.test(raw.version) ? raw.version : null;
12914
12915
  return {
12915
12916
  session_id: typeof raw.session_id === "string" ? raw.session_id : null,
12916
12917
  plugin_root: pluginRoot,
12917
- version: typeof raw.version === "string" ? raw.version : null,
12918
+ version,
12918
12919
  ts: typeof raw.ts === "number" ? raw.ts : 0
12919
12920
  };
12920
12921
  } catch {
@@ -12988,20 +12989,6 @@ function globalVerityVersion() {
12988
12989
  return null;
12989
12990
  }
12990
12991
  }
12991
- function pluginCliInvocation() {
12992
- const root = process.env.VERITY_PLUGIN_ROOT;
12993
- if (!root) return null;
12994
- const onPath = globalVerityVersion();
12995
- if (onPath !== null && onPath === activePluginVersion()) return null;
12996
- return `node ${JSON.stringify((0, import_node_path8.join)(root, "scripts", "verity.mjs"))}`;
12997
- }
12998
- function cliVersionSkew() {
12999
- if (!process.env.VERITY_PLUGIN_ROOT) return null;
13000
- const onPath = globalVerityVersion();
13001
- const plugin = activePluginVersion();
13002
- if (!onPath || !plugin || onPath === plugin) return null;
13003
- return { global: onPath, plugin };
13004
- }
13005
12992
  function activePluginVersion() {
13006
12993
  const fromEnv = process.env.VERITY_PLUGIN_VERSION;
13007
12994
  if (fromEnv) return fromEnv;
@@ -13193,6 +13180,150 @@ async function resolveHookWiring() {
13193
13180
  };
13194
13181
  }
13195
13182
 
13183
+ // src/lib/cli-provenance.ts
13184
+ var import_node_fs8 = require("node:fs");
13185
+ var import_node_os3 = require("node:os");
13186
+ var import_node_path9 = require("node:path");
13187
+ var CLI_PACKAGE = "@codacy/verity-cli";
13188
+ var CLI_ENTRY = (0, import_node_path9.join)("node_modules", CLI_PACKAGE, "bin", "verity.js");
13189
+ function readJson(path) {
13190
+ try {
13191
+ const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path, "utf-8"));
13192
+ return parsed && typeof parsed === "object" ? parsed : null;
13193
+ } catch {
13194
+ return null;
13195
+ }
13196
+ }
13197
+ function versionUnder(base) {
13198
+ const entry = (0, import_node_path9.join)(base, CLI_ENTRY);
13199
+ if (!(0, import_node_fs8.existsSync)(entry)) return null;
13200
+ const pkg = readJson((0, import_node_path9.join)(base, "node_modules", CLI_PACKAGE, "package.json"));
13201
+ return typeof pkg?.version === "string" ? pkg.version : null;
13202
+ }
13203
+ function versionForEntry(entry) {
13204
+ try {
13205
+ const pkg = readJson((0, import_node_path9.join)((0, import_node_path9.dirname)((0, import_node_fs8.realpathSync)(entry)), "..", "package.json"));
13206
+ return typeof pkg?.version === "string" ? pkg.version : null;
13207
+ } catch {
13208
+ return null;
13209
+ }
13210
+ }
13211
+ function resolveHooksCli(pluginRoot) {
13212
+ const override = process.env.VERITY_CLI_PATH;
13213
+ if (override && (0, import_node_fs8.existsSync)(override)) {
13214
+ return { version: versionForEntry(override), rung: "override" };
13215
+ }
13216
+ const fromPlugin = versionUnder(pluginRoot);
13217
+ if (fromPlugin !== null) return { version: fromPlugin, rung: "plugin" };
13218
+ if ((0, import_node_fs8.existsSync)((0, import_node_path9.join)(pluginRoot, CLI_ENTRY))) return { version: null, rung: "plugin" };
13219
+ const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".verity", "plugin-cli");
13220
+ const fromData = versionUnder(dataDir);
13221
+ if (fromData !== null) return { version: fromData, rung: "plugin-data" };
13222
+ if ((0, import_node_fs8.existsSync)((0, import_node_path9.join)(dataDir, CLI_ENTRY))) return { version: null, rung: "plugin-data" };
13223
+ const global = globalVerityVersion();
13224
+ if (global !== null) return { version: global, rung: "global" };
13225
+ return null;
13226
+ }
13227
+ function compareVersions(a, b) {
13228
+ const parse = (v) => {
13229
+ const [core, ...rest] = v.split("-");
13230
+ const parts = core.split(".");
13231
+ if (parts.length !== 3) return null;
13232
+ const nums = parts.map((p) => /^\d+$/.test(p) ? Number(p) : NaN);
13233
+ if (nums.some(Number.isNaN)) return null;
13234
+ return { nums, pre: rest.join("-") };
13235
+ };
13236
+ const x = parse(a);
13237
+ const y = parse(b);
13238
+ if (!x || !y) return null;
13239
+ for (let i = 0; i < 3; i++) {
13240
+ if (x.nums[i] !== y.nums[i]) return x.nums[i] < y.nums[i] ? -1 : 1;
13241
+ }
13242
+ if (x.pre === y.pre) return 0;
13243
+ if (!x.pre) return 1;
13244
+ if (!y.pre) return -1;
13245
+ return null;
13246
+ }
13247
+ var PLUGIN_UPDATE_REMEDY = "claude plugin update verity@verity, then /reload-plugins (or restart Claude Code)";
13248
+ function globalUpdateRemedy(version) {
13249
+ return `npm install -g ${CLI_PACKAGE}@${version}`;
13250
+ }
13251
+ function remedyFor(global, hooks) {
13252
+ const order = compareVersions(global, hooks);
13253
+ if (order === -1) return { behind: "global", remedy: globalUpdateRemedy(hooks) };
13254
+ if (order === 1) return { behind: "plugin", remedy: PLUGIN_UPDATE_REMEDY };
13255
+ return {
13256
+ behind: "unknown",
13257
+ remedy: `${globalUpdateRemedy(hooks)} \u2014 or, if the plugin is the older one, ${PLUGIN_UPDATE_REMEDY}`
13258
+ };
13259
+ }
13260
+ function cliProvenance() {
13261
+ const envRoot = process.env.VERITY_PLUGIN_ROOT;
13262
+ const install = envRoot ? { pluginRoot: envRoot, version: process.env.VERITY_PLUGIN_VERSION || activePluginInstall()?.version || null } : activePluginInstall();
13263
+ const global = globalVerityVersion();
13264
+ if (!install) return { plugin: null, hooksCli: null, global, skew: null };
13265
+ const hooksCli = resolveHooksCli(install.pluginRoot);
13266
+ return {
13267
+ plugin: { root: install.pluginRoot, version: install.version },
13268
+ hooksCli,
13269
+ global,
13270
+ skew: computeSkew(global, hooksCli)
13271
+ };
13272
+ }
13273
+ function computeSkew(global, hooksCli) {
13274
+ if (!global || !hooksCli?.version) return null;
13275
+ if (global === hooksCli.version) return null;
13276
+ return { global, hooks: hooksCli.version, ...remedyFor(global, hooksCli.version) };
13277
+ }
13278
+ function cliVersionSkew() {
13279
+ return cliProvenance().skew;
13280
+ }
13281
+ function versionReport(p = cliProvenance()) {
13282
+ if (!p.plugin) return null;
13283
+ return {
13284
+ plugin: p.plugin.version,
13285
+ hooksCli: p.hooksCli?.version ?? null,
13286
+ hooksCliRung: p.hooksCli?.rung ?? null,
13287
+ global: p.global,
13288
+ skew: p.skew
13289
+ };
13290
+ }
13291
+ function versionLines(v) {
13292
+ if (!v) return { info: [], warn: [] };
13293
+ const plugin = v.plugin ? `plugin ${v.plugin}` : "plugin (version unreadable)";
13294
+ const rung = v.hooksCliRung && v.hooksCliRung !== "plugin" ? ` via ${RUNG_LABELS[v.hooksCliRung]}` : "";
13295
+ const hooks = v.hooksCli ? `hooks run ${CLI_PACKAGE} ${v.hooksCli}${rung}` : "hooks run a CLI whose version could not be read";
13296
+ if (!v.skew) {
13297
+ const agrees = v.global && v.hooksCli && v.global === v.hooksCli ? " \xB7 `verity` on PATH matches \u2713" : "";
13298
+ return { info: [` Versions: ${plugin} \xB7 ${hooks}${agrees}`], warn: [] };
13299
+ }
13300
+ return {
13301
+ info: [` Versions: ${plugin} \xB7 ${hooks}`],
13302
+ warn: [
13303
+ ` \u26A0 \`verity\` on PATH is ${v.skew.global}, which is NOT the CLI the hooks run (${v.skew.hooks}).`,
13304
+ ` The gate and your terminal are different builds. Fix: ${v.skew.remedy}`
13305
+ ]
13306
+ };
13307
+ }
13308
+ var RUNG_LABELS = {
13309
+ override: "VERITY_CLI_PATH",
13310
+ plugin: "the plugin's node_modules",
13311
+ "plugin-data": "the plugin's data directory",
13312
+ global: "the global install on PATH"
13313
+ };
13314
+ function pluginCliInvocation() {
13315
+ const root = process.env.VERITY_PLUGIN_ROOT;
13316
+ if (!root) return null;
13317
+ const onPath = globalVerityVersion();
13318
+ if (onPath === null) return resolverCommand(root);
13319
+ const hooksCli = resolveHooksCli(root);
13320
+ if (hooksCli?.version && hooksCli.version === onPath) return null;
13321
+ return resolverCommand(root);
13322
+ }
13323
+ function resolverCommand(root) {
13324
+ return `node ${JSON.stringify((0, import_node_path9.join)(root, "scripts", "verity.mjs"))}`;
13325
+ }
13326
+
13196
13327
  // src/commands/hooks.ts
13197
13328
  var ALL_MOMENTS = ["stop", "pre-commit", "pre-push"];
13198
13329
  function parseMomentSelection(raw) {
@@ -13287,6 +13418,9 @@ function registerHooksCommands(program2) {
13287
13418
  const moments = status.guardOn;
13288
13419
  const inherited = wiring.gitMoments.source === "main-worktree" && wiring.gitMoments.path ? ` (inherited from the main worktree: ${wiring.gitMoments.path})` : "";
13289
13420
  printInfo("Wired by the Verity Claude Code plugin (not .claude/settings.json):");
13421
+ const versionOut = versionLines(versionReport());
13422
+ for (const line of versionOut.info) printInfo(line);
13423
+ for (const line of versionOut.warn) printWarn(line);
13290
13424
  printInfo(" Stop hook (verity analyze): installed");
13291
13425
  printInfo(" Intent hook (verity intent capture): installed");
13292
13426
  printInfo(" Baseline hook (verity baseline capture): installed");
@@ -13327,7 +13461,7 @@ var import_node_crypto8 = require("node:crypto");
13327
13461
 
13328
13462
  // src/lib/conversation-buffer.ts
13329
13463
  var import_promises5 = require("node:fs/promises");
13330
- var import_node_fs8 = require("node:fs");
13464
+ var import_node_fs9 = require("node:fs");
13331
13465
  var import_node_child_process5 = require("node:child_process");
13332
13466
  var import_node_crypto = require("node:crypto");
13333
13467
  function stripImageReferences(text) {
@@ -13363,7 +13497,7 @@ async function appendToConversationBuffer(prompt, sessionId) {
13363
13497
  }
13364
13498
  async function readAndClearConversationBuffer(currentSessionId) {
13365
13499
  try {
13366
- if ((0, import_node_fs8.existsSync)(CONVERSATION_BUFFER_FILE)) {
13500
+ if ((0, import_node_fs9.existsSync)(CONVERSATION_BUFFER_FILE)) {
13367
13501
  const entries = await readBufferEntries();
13368
13502
  let mine = entries;
13369
13503
  let others = [];
@@ -13387,7 +13521,7 @@ async function readAndClearConversationBuffer(currentSessionId) {
13387
13521
  };
13388
13522
  }
13389
13523
  }
13390
- if ((0, import_node_fs8.existsSync)(INTENT_FILE)) {
13524
+ if ((0, import_node_fs9.existsSync)(INTENT_FILE)) {
13391
13525
  try {
13392
13526
  const content = await (0, import_promises5.readFile)(INTENT_FILE, "utf-8");
13393
13527
  await (0, import_promises5.unlink)(INTENT_FILE).catch(() => {
@@ -13680,9 +13814,9 @@ function isCommandOnlyTurn(input) {
13680
13814
 
13681
13815
  // src/lib/context-identity.ts
13682
13816
  var import_node_crypto2 = require("node:crypto");
13683
- var import_node_fs9 = require("node:fs");
13684
- var import_node_os3 = require("node:os");
13685
- var import_node_path9 = require("node:path");
13817
+ var import_node_fs10 = require("node:fs");
13818
+ var import_node_os4 = require("node:os");
13819
+ var import_node_path10 = require("node:path");
13686
13820
  var SHARED_SENTINELS = /* @__PURE__ */ new Set([
13687
13821
  "",
13688
13822
  "-",
@@ -13720,7 +13854,7 @@ function contextIdentity(input) {
13720
13854
  if (rawTree && !isSharedSentinel(rawTree)) {
13721
13855
  let resolved = rawTree;
13722
13856
  try {
13723
- resolved = import_node_fs9.realpathSync.native(rawTree);
13857
+ resolved = import_node_fs10.realpathSync.native(rawTree);
13724
13858
  } catch {
13725
13859
  }
13726
13860
  treeKey = (0, import_node_crypto2.createHash)("sha256").update(resolved).digest("hex").slice(0, 12);
@@ -13736,13 +13870,13 @@ function contextIdentity(input) {
13736
13870
  }
13737
13871
  function verityHome() {
13738
13872
  const override = process.env.VERITY_HOME;
13739
- return override && override.trim() ? (0, import_node_path9.resolve)(override) : (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".verity");
13873
+ return override && override.trim() ? (0, import_node_path10.resolve)(override) : (0, import_node_path10.join)((0, import_node_os4.homedir)(), ".verity");
13740
13874
  }
13741
13875
  function dossierDir(identity) {
13742
- return (0, import_node_path9.join)(verityHome(), "sessions", identity.userKey, identity.treeKey, identity.sessionKey);
13876
+ return (0, import_node_path10.join)(verityHome(), "sessions", identity.userKey, identity.treeKey, identity.sessionKey);
13743
13877
  }
13744
13878
  function treeDir(identity) {
13745
- return (0, import_node_path9.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
13879
+ return (0, import_node_path10.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
13746
13880
  }
13747
13881
  function scopeIdentity(token, sessionId) {
13748
13882
  const t = (token ?? "").trim();
@@ -13757,8 +13891,8 @@ function sessionScopeKey(token, sessionId) {
13757
13891
 
13758
13892
  // src/lib/task-context-buffer.ts
13759
13893
  var import_promises6 = require("node:fs/promises");
13760
- var import_node_fs10 = require("node:fs");
13761
- var import_node_path10 = require("node:path");
13894
+ var import_node_fs11 = require("node:fs");
13895
+ var import_node_path11 = require("node:path");
13762
13896
  var TASK_CONTEXT_DIR = `${VERITY_DIR}/.task-context`;
13763
13897
  var MAX_BUFFER_BYTES = 500 * 1024;
13764
13898
  var MAX_PROMPT_CHARS = 2e3;
@@ -13797,7 +13931,7 @@ async function appendResponseToTaskBuffer(taskId, assistantResponse, actionSumma
13797
13931
  }
13798
13932
  async function readTaskContextBuffer(taskId) {
13799
13933
  const filePath = bufferPath(taskId);
13800
- if (!(0, import_node_fs10.existsSync)(filePath)) return null;
13934
+ if (!(0, import_node_fs11.existsSync)(filePath)) return null;
13801
13935
  try {
13802
13936
  const content = await (0, import_promises6.readFile)(filePath, "utf-8");
13803
13937
  if (!content.trim()) return null;
@@ -13831,12 +13965,12 @@ async function readTaskContextBuffer(taskId) {
13831
13965
  }
13832
13966
  async function cleanupTaskContextBuffers() {
13833
13967
  try {
13834
- if (!(0, import_node_fs10.existsSync)(TASK_CONTEXT_DIR)) return;
13968
+ if (!(0, import_node_fs11.existsSync)(TASK_CONTEXT_DIR)) return;
13835
13969
  const files = await (0, import_promises6.readdir)(TASK_CONTEXT_DIR);
13836
13970
  const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1e3;
13837
13971
  for (const file of files) {
13838
13972
  if (!file.endsWith(".jsonl")) continue;
13839
- const filePath = (0, import_node_path10.join)(TASK_CONTEXT_DIR, file);
13973
+ const filePath = (0, import_node_path11.join)(TASK_CONTEXT_DIR, file);
13840
13974
  try {
13841
13975
  const stats = await (0, import_promises6.stat)(filePath);
13842
13976
  if (stats.mtimeMs < cutoffMs) {
@@ -13850,13 +13984,13 @@ async function cleanupTaskContextBuffers() {
13850
13984
  }
13851
13985
  function bufferPath(taskId) {
13852
13986
  const safe = taskId.replace(/[^a-zA-Z0-9_-]/g, "");
13853
- return (0, import_node_path10.join)(TASK_CONTEXT_DIR, `${safe}.jsonl`);
13987
+ return (0, import_node_path11.join)(TASK_CONTEXT_DIR, `${safe}.jsonl`);
13854
13988
  }
13855
13989
  async function appendEntry(taskId, entry) {
13856
13990
  try {
13857
13991
  await (0, import_promises6.mkdir)(TASK_CONTEXT_DIR, { recursive: true });
13858
13992
  const filePath = bufferPath(taskId);
13859
- if ((0, import_node_fs10.existsSync)(filePath)) {
13993
+ if ((0, import_node_fs11.existsSync)(filePath)) {
13860
13994
  const stats = await (0, import_promises6.stat)(filePath);
13861
13995
  if (stats.size >= MAX_BUFFER_BYTES) {
13862
13996
  const content = await (0, import_promises6.readFile)(filePath, "utf-8");
@@ -13867,7 +14001,7 @@ async function appendEntry(taskId, entry) {
13867
14001
  }
13868
14002
  }
13869
14003
  const line = JSON.stringify(entry) + "\n";
13870
- const existing = (0, import_node_fs10.existsSync)(filePath) ? await (0, import_promises6.readFile)(filePath, "utf-8") : "";
14004
+ const existing = (0, import_node_fs11.existsSync)(filePath) ? await (0, import_promises6.readFile)(filePath, "utf-8") : "";
13871
14005
  await (0, import_promises6.writeFile)(filePath, existing + line);
13872
14006
  } catch {
13873
14007
  }
@@ -13875,20 +14009,20 @@ async function appendEntry(taskId, entry) {
13875
14009
 
13876
14010
  // src/lib/memory-retrieval.ts
13877
14011
  var import_promises8 = require("node:fs/promises");
13878
- var import_node_fs12 = require("node:fs");
13879
- var import_node_path12 = require("node:path");
14012
+ var import_node_fs13 = require("node:fs");
14013
+ var import_node_path13 = require("node:path");
13880
14014
 
13881
14015
  // src/lib/org-mirror.ts
13882
- var import_node_fs11 = require("node:fs");
14016
+ var import_node_fs12 = require("node:fs");
13883
14017
  var import_promises7 = require("node:fs/promises");
13884
- var import_node_path11 = require("node:path");
14018
+ var import_node_path12 = require("node:path");
13885
14019
  var ORG_KINDS = ["decision", "security", "gotcha", "pattern", "domain", "integration"];
13886
14020
  var STATE_FILE = ".org-pull-state.json";
13887
14021
  var BODY_MAX = 8192;
13888
14022
  function orgMirrorDir(remote = requestRemote()) {
13889
14023
  const parsed = parseRemote(remote);
13890
14024
  if (!parsed) return null;
13891
- return (0, import_node_path11.join)(verityHome(), "orgs", parsed.host, parsed.owner.toLowerCase(), "memory");
14025
+ return (0, import_node_path12.join)(verityHome(), "orgs", parsed.host, parsed.owner.toLowerCase(), "memory");
13892
14026
  }
13893
14027
  function slugify(s) {
13894
14028
  return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
@@ -13954,7 +14088,7 @@ function parseOrgNode(content) {
13954
14088
  }
13955
14089
  async function readState(dir) {
13956
14090
  try {
13957
- const parsed = JSON.parse(await (0, import_promises7.readFile)((0, import_node_path11.join)(dir, STATE_FILE), "utf-8"));
14091
+ const parsed = JSON.parse(await (0, import_promises7.readFile)((0, import_node_path12.join)(dir, STATE_FILE), "utf-8"));
13958
14092
  return {
13959
14093
  version: typeof parsed?.version === "string" ? parsed.version : null,
13960
14094
  organization: parsed?.organization && typeof parsed.organization.id === "string" ? parsed.organization : null,
@@ -13966,7 +14100,7 @@ async function readState(dir) {
13966
14100
  }
13967
14101
  async function writeState(dir, state) {
13968
14102
  await (0, import_promises7.mkdir)(dir, { recursive: true });
13969
- await (0, import_promises7.writeFile)((0, import_node_path11.join)(dir, STATE_FILE), JSON.stringify({
14103
+ await (0, import_promises7.writeFile)((0, import_node_path12.join)(dir, STATE_FILE), JSON.stringify({
13970
14104
  ...state.version ? { version: state.version } : {},
13971
14105
  organization: state.organization,
13972
14106
  pulled_at: (/* @__PURE__ */ new Date()).toISOString(),
@@ -14031,24 +14165,24 @@ async function pullOrgKnowledge(opts) {
14031
14165
  for (const n of nodes) {
14032
14166
  const rel = orgNodePath(n);
14033
14167
  if (written.has(rel)) continue;
14034
- await (0, import_promises7.mkdir)((0, import_node_path11.join)(dir, rel.split("/")[0]), { recursive: true });
14035
- await (0, import_promises7.writeFile)((0, import_node_path11.join)(dir, rel), renderOrgNode(n, org?.name ?? ""));
14168
+ await (0, import_promises7.mkdir)((0, import_node_path12.join)(dir, rel.split("/")[0]), { recursive: true });
14169
+ await (0, import_promises7.writeFile)((0, import_node_path12.join)(dir, rel), renderOrgNode(n, org?.name ?? ""));
14036
14170
  written.add(rel);
14037
14171
  }
14038
14172
  for (const rel of state.files) {
14039
- if (!written.has(rel)) await (0, import_promises7.rm)((0, import_node_path11.join)(dir, rel), { force: true });
14173
+ if (!written.has(rel)) await (0, import_promises7.rm)((0, import_node_path12.join)(dir, rel), { force: true });
14040
14174
  }
14041
- await (0, import_promises7.writeFile)((0, import_node_path11.join)(dir, "index.md"), renderIndex(org?.name ?? "no organization", nodes));
14175
+ await (0, import_promises7.writeFile)((0, import_node_path12.join)(dir, "index.md"), renderIndex(org?.name ?? "no organization", nodes));
14042
14176
  await writeState(dir, { version: org ? page.version : null, organization: org, files: [...written].sort() });
14043
14177
  return { ok: true, status: org ? "pulled" : "none", received: nodes.length, dir };
14044
14178
  }
14045
14179
  async function readOrgMirror(remote = requestRemote()) {
14046
14180
  const dir = orgMirrorDir(remote);
14047
- if (!dir || !(0, import_node_fs11.existsSync)(dir)) return [];
14181
+ if (!dir || !(0, import_node_fs12.existsSync)(dir)) return [];
14048
14182
  const out = [];
14049
14183
  for (const kind of ORG_KINDS) {
14050
- const kindDir = (0, import_node_path11.join)(dir, kind);
14051
- if (!(0, import_node_fs11.existsSync)(kindDir)) continue;
14184
+ const kindDir = (0, import_node_path12.join)(dir, kind);
14185
+ if (!(0, import_node_fs12.existsSync)(kindDir)) continue;
14052
14186
  let files;
14053
14187
  try {
14054
14188
  files = await (0, import_promises7.readdir)(kindDir);
@@ -14058,7 +14192,7 @@ async function readOrgMirror(remote = requestRemote()) {
14058
14192
  for (const file of files) {
14059
14193
  if (!file.endsWith(".md")) continue;
14060
14194
  try {
14061
- const node = parseOrgNode(await (0, import_promises7.readFile)((0, import_node_path11.join)(kindDir, file), "utf-8"));
14195
+ const node = parseOrgNode(await (0, import_promises7.readFile)((0, import_node_path12.join)(kindDir, file), "utf-8"));
14062
14196
  if (node) out.push(node);
14063
14197
  } catch {
14064
14198
  }
@@ -14181,19 +14315,19 @@ function parseFrontmatter(content) {
14181
14315
  return { fm, body: match[2].trim() };
14182
14316
  }
14183
14317
  async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = DEFAULT_BUDGET_TOKENS) {
14184
- const hasRepoGraph = (0, import_node_fs12.existsSync)(memoryDir());
14318
+ const hasRepoGraph = (0, import_node_fs13.existsSync)(memoryDir());
14185
14319
  const budget = Math.min(budgetTokens, MAX_BUDGET_TOKENS);
14186
14320
  const promptTokens = tokenize(promptText);
14187
14321
  const nodes = [];
14188
14322
  for (const domain of hasRepoGraph ? DOMAINS : []) {
14189
- const domainDir = (0, import_node_path12.join)(memoryDir(), domain);
14190
- if (!(0, import_node_fs12.existsSync)(domainDir)) continue;
14323
+ const domainDir = (0, import_node_path13.join)(memoryDir(), domain);
14324
+ if (!(0, import_node_fs13.existsSync)(domainDir)) continue;
14191
14325
  try {
14192
14326
  const files = await (0, import_promises8.readdir)(domainDir);
14193
14327
  for (const file of files) {
14194
14328
  if (!file.endsWith(".md")) continue;
14195
14329
  try {
14196
- const content = await (0, import_promises8.readFile)((0, import_node_path12.join)(domainDir, file), "utf-8");
14330
+ const content = await (0, import_promises8.readFile)((0, import_node_path13.join)(domainDir, file), "utf-8");
14197
14331
  const { fm, body } = parseFrontmatter(content);
14198
14332
  if (fm.status && fm.status !== "active") continue;
14199
14333
  nodes.push({
@@ -14260,13 +14394,13 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
14260
14394
 
14261
14395
  // src/lib/memory-sync.ts
14262
14396
  var import_promises9 = require("node:fs/promises");
14263
- var import_node_fs15 = require("node:fs");
14264
- var import_node_path14 = require("node:path");
14397
+ var import_node_fs16 = require("node:fs");
14398
+ var import_node_path15 = require("node:path");
14265
14399
  var import_node_crypto3 = require("node:crypto");
14266
14400
 
14267
14401
  // src/lib/gitignore.ts
14268
14402
  var import_node_child_process6 = require("node:child_process");
14269
- var import_node_fs13 = require("node:fs");
14403
+ var import_node_fs14 = require("node:fs");
14270
14404
  var VERITY_GITIGNORE_MARKER = "# Verity \u2014 machine-local state.";
14271
14405
  var SETTINGS_LOCAL_IGNORE_ENTRY = ".claude/settings.local.json";
14272
14406
  var VERITY_GITIGNORE_BLOCK = [
@@ -14350,7 +14484,7 @@ function fenceMemoryLines(lines) {
14350
14484
  function ensureVerityGitignore() {
14351
14485
  let content = "";
14352
14486
  try {
14353
- content = (0, import_node_fs13.readFileSync)(".gitignore", "utf-8");
14487
+ content = (0, import_node_fs14.readFileSync)(".gitignore", "utf-8");
14354
14488
  } catch {
14355
14489
  }
14356
14490
  const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
@@ -14377,7 +14511,7 @@ function ensureVerityGitignore() {
14377
14511
  const sep4 = text === "" ? "" : text.endsWith("\n") ? "\n" : "\n\n";
14378
14512
  text = text + sep4 + VERITY_GITIGNORE_BLOCK;
14379
14513
  }
14380
- if (text !== content) (0, import_node_fs13.writeFileSync)(".gitignore", text);
14514
+ if (text !== content) (0, import_node_fs14.writeFileSync)(".gitignore", text);
14381
14515
  return verified(
14382
14516
  memoryIsCommitted ? "memory-tracked" : hasSupersededMemory ? "memory-fenced" : needsRepair ? "repaired" : "added"
14383
14517
  );
@@ -14397,7 +14531,7 @@ function untrackMemory() {
14397
14531
  function writeFencedBlock() {
14398
14532
  let content = "";
14399
14533
  try {
14400
- content = (0, import_node_fs13.readFileSync)(".gitignore", "utf-8");
14534
+ content = (0, import_node_fs14.readFileSync)(".gitignore", "utf-8");
14401
14535
  } catch {
14402
14536
  }
14403
14537
  const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
@@ -14409,7 +14543,7 @@ function writeFencedBlock() {
14409
14543
  text = text + sep4 + VERITY_GITIGNORE_BLOCK;
14410
14544
  }
14411
14545
  try {
14412
- (0, import_node_fs13.writeFileSync)(".gitignore", text);
14546
+ (0, import_node_fs14.writeFileSync)(".gitignore", text);
14413
14547
  return true;
14414
14548
  } catch {
14415
14549
  return false;
@@ -14418,14 +14552,14 @@ function writeFencedBlock() {
14418
14552
  function fenceMemory() {
14419
14553
  let original = null;
14420
14554
  try {
14421
- original = (0, import_node_fs13.readFileSync)(".gitignore", "utf-8");
14555
+ original = (0, import_node_fs14.readFileSync)(".gitignore", "utf-8");
14422
14556
  } catch {
14423
14557
  original = null;
14424
14558
  }
14425
14559
  const restore = () => {
14426
14560
  try {
14427
- if (original === null) (0, import_node_fs13.rmSync)(".gitignore", { force: true });
14428
- else (0, import_node_fs13.writeFileSync)(".gitignore", original);
14561
+ if (original === null) (0, import_node_fs14.rmSync)(".gitignore", { force: true });
14562
+ else (0, import_node_fs14.writeFileSync)(".gitignore", original);
14429
14563
  } catch {
14430
14564
  }
14431
14565
  };
@@ -14443,7 +14577,7 @@ function fenceMemory() {
14443
14577
  }
14444
14578
  function memoryOptOut() {
14445
14579
  try {
14446
- return (0, import_node_fs13.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
14580
+ return (0, import_node_fs14.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
14447
14581
  } catch {
14448
14582
  return false;
14449
14583
  }
@@ -14451,13 +14585,13 @@ function memoryOptOut() {
14451
14585
  function keepMemoryTracked() {
14452
14586
  let content = "";
14453
14587
  try {
14454
- content = (0, import_node_fs13.readFileSync)(".gitignore", "utf-8");
14588
+ content = (0, import_node_fs14.readFileSync)(".gitignore", "utf-8");
14455
14589
  } catch {
14456
14590
  }
14457
14591
  if (content.includes(MEMORY_OPT_OUT_MARKER)) return "already";
14458
14592
  try {
14459
14593
  const sep4 = content === "" ? "" : content.endsWith("\n") ? "\n" : "\n\n";
14460
- (0, import_node_fs13.writeFileSync)(".gitignore", content + sep4 + MEMORY_OPT_OUT_STANZA);
14594
+ (0, import_node_fs14.writeFileSync)(".gitignore", content + sep4 + MEMORY_OPT_OUT_STANZA);
14461
14595
  } catch {
14462
14596
  return "failed";
14463
14597
  }
@@ -14492,26 +14626,26 @@ function untrackVerityState() {
14492
14626
  }
14493
14627
 
14494
14628
  // src/lib/safe-path.ts
14495
- var import_node_fs14 = require("node:fs");
14496
- var import_node_path13 = require("node:path");
14629
+ var import_node_fs15 = require("node:fs");
14630
+ var import_node_path14 = require("node:path");
14497
14631
  function resolveInside(baseDir, candidate) {
14498
14632
  if (typeof candidate !== "string" || candidate.length === 0) return null;
14499
- if ((0, import_node_path13.isAbsolute)(candidate)) return null;
14500
- const baseAbs = (0, import_node_path13.resolve)(baseDir);
14501
- const full = (0, import_node_path13.resolve)(baseAbs, candidate);
14502
- const baseSep = baseAbs.endsWith(import_node_path13.sep) ? baseAbs : baseAbs + import_node_path13.sep;
14633
+ if ((0, import_node_path14.isAbsolute)(candidate)) return null;
14634
+ const baseAbs = (0, import_node_path14.resolve)(baseDir);
14635
+ const full = (0, import_node_path14.resolve)(baseAbs, candidate);
14636
+ const baseSep = baseAbs.endsWith(import_node_path14.sep) ? baseAbs : baseAbs + import_node_path14.sep;
14503
14637
  if (full !== baseAbs && !full.startsWith(baseSep)) return null;
14504
14638
  try {
14505
- if ((0, import_node_fs14.existsSync)(baseAbs)) {
14506
- const realBase = (0, import_node_fs14.realpathSync)(baseAbs);
14507
- const realBaseSep = realBase.endsWith(import_node_path13.sep) ? realBase : realBase + import_node_path13.sep;
14639
+ if ((0, import_node_fs15.existsSync)(baseAbs)) {
14640
+ const realBase = (0, import_node_fs15.realpathSync)(baseAbs);
14641
+ const realBaseSep = realBase.endsWith(import_node_path14.sep) ? realBase : realBase + import_node_path14.sep;
14508
14642
  let probe = full;
14509
- while (!(0, import_node_fs14.existsSync)(probe)) {
14510
- const parent = (0, import_node_path13.dirname)(probe);
14643
+ while (!(0, import_node_fs15.existsSync)(probe)) {
14644
+ const parent = (0, import_node_path14.dirname)(probe);
14511
14645
  if (parent === probe) break;
14512
14646
  probe = parent;
14513
14647
  }
14514
- const realProbe = (0, import_node_fs14.realpathSync)(probe);
14648
+ const realProbe = (0, import_node_fs15.realpathSync)(probe);
14515
14649
  if (realProbe !== realBase && !realProbe.startsWith(realBaseSep)) return null;
14516
14650
  }
14517
14651
  } catch {
@@ -14519,37 +14653,37 @@ function resolveInside(baseDir, candidate) {
14519
14653
  }
14520
14654
  return full;
14521
14655
  }
14522
- var O_NOFOLLOW = typeof import_node_fs14.constants.O_NOFOLLOW === "number" ? import_node_fs14.constants.O_NOFOLLOW : 0;
14656
+ var O_NOFOLLOW = typeof import_node_fs15.constants.O_NOFOLLOW === "number" ? import_node_fs15.constants.O_NOFOLLOW : 0;
14523
14657
  function readFileInside(baseDir, candidate, maxBytes) {
14524
14658
  const full = resolveInside(baseDir, candidate);
14525
14659
  if (!full) return null;
14526
14660
  let realParent;
14527
14661
  let realBase;
14528
14662
  try {
14529
- realParent = (0, import_node_fs14.realpathSync)((0, import_node_path13.dirname)(full));
14530
- realBase = (0, import_node_fs14.realpathSync)((0, import_node_path13.resolve)(baseDir));
14663
+ realParent = (0, import_node_fs15.realpathSync)((0, import_node_path14.dirname)(full));
14664
+ realBase = (0, import_node_fs15.realpathSync)((0, import_node_path14.resolve)(baseDir));
14531
14665
  } catch {
14532
14666
  return null;
14533
14667
  }
14534
- const realBaseSep = realBase.endsWith(import_node_path13.sep) ? realBase : realBase + import_node_path13.sep;
14668
+ const realBaseSep = realBase.endsWith(import_node_path14.sep) ? realBase : realBase + import_node_path14.sep;
14535
14669
  if (realParent !== realBase && !realParent.startsWith(realBaseSep)) return null;
14536
- const target = (0, import_node_path13.join)(realParent, (0, import_node_path13.basename)(full));
14670
+ const target = (0, import_node_path14.join)(realParent, (0, import_node_path14.basename)(full));
14537
14671
  let fd = null;
14538
14672
  try {
14539
- fd = (0, import_node_fs14.openSync)(target, import_node_fs14.constants.O_RDONLY | O_NOFOLLOW);
14540
- const st = (0, import_node_fs14.fstatSync)(fd);
14673
+ fd = (0, import_node_fs15.openSync)(target, import_node_fs15.constants.O_RDONLY | O_NOFOLLOW);
14674
+ const st = (0, import_node_fs15.fstatSync)(fd);
14541
14675
  if (!st.isFile()) return null;
14542
14676
  const cap = Math.min(maxBytes, st.size);
14543
14677
  if (cap <= 0) return "";
14544
14678
  const buf = Buffer.alloc(cap);
14545
- const bytesRead = (0, import_node_fs14.readSync)(fd, buf, 0, cap, 0);
14679
+ const bytesRead = (0, import_node_fs15.readSync)(fd, buf, 0, cap, 0);
14546
14680
  return buf.subarray(0, bytesRead).toString("utf-8");
14547
14681
  } catch {
14548
14682
  return null;
14549
14683
  } finally {
14550
14684
  if (fd !== null) {
14551
14685
  try {
14552
- (0, import_node_fs14.closeSync)(fd);
14686
+ (0, import_node_fs15.closeSync)(fd);
14553
14687
  } catch {
14554
14688
  }
14555
14689
  }
@@ -14632,32 +14766,32 @@ var syncStateFile = () => projectPath(`${VERITY_DIR}/.memory-sync-state.json`);
14632
14766
  async function ensureMemoryDir() {
14633
14767
  await (0, import_promises9.mkdir)(memoryDir2(), { recursive: true });
14634
14768
  for (const domain of DOMAINS2) {
14635
- await (0, import_promises9.mkdir)((0, import_node_path14.join)(memoryDir2(), domain), { recursive: true });
14769
+ await (0, import_promises9.mkdir)((0, import_node_path15.join)(memoryDir2(), domain), { recursive: true });
14636
14770
  }
14637
- if (!(0, import_node_fs15.existsSync)((0, import_node_path14.join)(memoryDir2(), "SCHEMA.md"))) {
14638
- await (0, import_promises9.writeFile)((0, import_node_path14.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
14771
+ if (!(0, import_node_fs16.existsSync)((0, import_node_path15.join)(memoryDir2(), "SCHEMA.md"))) {
14772
+ await (0, import_promises9.writeFile)((0, import_node_path15.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
14639
14773
  }
14640
- if (!(0, import_node_fs15.existsSync)((0, import_node_path14.join)(memoryDir2(), "index.md"))) {
14641
- await (0, import_promises9.writeFile)((0, import_node_path14.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
14774
+ if (!(0, import_node_fs16.existsSync)((0, import_node_path15.join)(memoryDir2(), "index.md"))) {
14775
+ await (0, import_promises9.writeFile)((0, import_node_path15.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
14642
14776
  }
14643
- if (!(0, import_node_fs15.existsSync)((0, import_node_path14.join)(memoryDir2(), "log.md"))) {
14644
- await (0, import_promises9.writeFile)((0, import_node_path14.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
14777
+ if (!(0, import_node_fs16.existsSync)((0, import_node_path15.join)(memoryDir2(), "log.md"))) {
14778
+ await (0, import_promises9.writeFile)((0, import_node_path15.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
14645
14779
  }
14646
14780
  }
14647
14781
  async function buildManifest() {
14648
- if (!(0, import_node_fs15.existsSync)(memoryDir2())) {
14782
+ if (!(0, import_node_fs16.existsSync)(memoryDir2())) {
14649
14783
  return { schema_version: 1, nodes: [], index_hash: null, log_length: 0 };
14650
14784
  }
14651
14785
  const nodes = [];
14652
14786
  for (const domain of DOMAINS2) {
14653
- const domainDir = (0, import_node_path14.join)(memoryDir2(), domain);
14654
- if (!(0, import_node_fs15.existsSync)(domainDir)) continue;
14787
+ const domainDir = (0, import_node_path15.join)(memoryDir2(), domain);
14788
+ if (!(0, import_node_fs16.existsSync)(domainDir)) continue;
14655
14789
  try {
14656
14790
  const files = await (0, import_promises9.readdir)(domainDir);
14657
14791
  for (const file of files) {
14658
14792
  if (!file.endsWith(".md")) continue;
14659
14793
  const filePath = `${domain}/${file}`;
14660
- const fullPath = (0, import_node_path14.join)(memoryDir2(), filePath);
14794
+ const fullPath = (0, import_node_path15.join)(memoryDir2(), filePath);
14661
14795
  try {
14662
14796
  const content = await (0, import_promises9.readFile)(fullPath, "utf-8");
14663
14797
  const hash = (0, import_node_crypto3.createHash)("sha256").update(content).digest("hex").slice(0, 16);
@@ -14670,13 +14804,13 @@ async function buildManifest() {
14670
14804
  }
14671
14805
  let indexHash = null;
14672
14806
  try {
14673
- const indexContent = await (0, import_promises9.readFile)((0, import_node_path14.join)(memoryDir2(), "index.md"), "utf-8");
14807
+ const indexContent = await (0, import_promises9.readFile)((0, import_node_path15.join)(memoryDir2(), "index.md"), "utf-8");
14674
14808
  indexHash = `sha256:${(0, import_node_crypto3.createHash)("sha256").update(indexContent).digest("hex").slice(0, 16)}`;
14675
14809
  } catch {
14676
14810
  }
14677
14811
  let logLength = 0;
14678
14812
  try {
14679
- const logContent = await (0, import_promises9.readFile)((0, import_node_path14.join)(memoryDir2(), "log.md"), "utf-8");
14813
+ const logContent = await (0, import_promises9.readFile)((0, import_node_path15.join)(memoryDir2(), "log.md"), "utf-8");
14680
14814
  logLength = logContent.split("\n").length;
14681
14815
  } catch {
14682
14816
  }
@@ -14687,15 +14821,15 @@ function hashContent(content) {
14687
14821
  }
14688
14822
  async function readOnDiskNodes() {
14689
14823
  const out = /* @__PURE__ */ new Map();
14690
- if (!(0, import_node_fs15.existsSync)(memoryDir2())) return out;
14824
+ if (!(0, import_node_fs16.existsSync)(memoryDir2())) return out;
14691
14825
  for (const domain of DOMAINS2) {
14692
- const domainDir = (0, import_node_path14.join)(memoryDir2(), domain);
14693
- if (!(0, import_node_fs15.existsSync)(domainDir)) continue;
14826
+ const domainDir = (0, import_node_path15.join)(memoryDir2(), domain);
14827
+ if (!(0, import_node_fs16.existsSync)(domainDir)) continue;
14694
14828
  try {
14695
14829
  for (const file of await (0, import_promises9.readdir)(domainDir)) {
14696
14830
  if (!file.endsWith(".md")) continue;
14697
14831
  try {
14698
- out.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0, import_node_path14.join)(domainDir, file), "utf-8")));
14832
+ out.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0, import_node_path15.join)(domainDir, file), "utf-8")));
14699
14833
  } catch {
14700
14834
  }
14701
14835
  }
@@ -14732,7 +14866,7 @@ async function recordSyncedNodePaths() {
14732
14866
  }
14733
14867
  }
14734
14868
  async function writeFileAtomic(path, content) {
14735
- await (0, import_promises9.mkdir)((0, import_node_path14.dirname)(path), { recursive: true });
14869
+ await (0, import_promises9.mkdir)((0, import_node_path15.dirname)(path), { recursive: true });
14736
14870
  const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
14737
14871
  await (0, import_promises9.writeFile)(tmp, content);
14738
14872
  await (0, import_promises9.rename)(tmp, path);
@@ -14746,8 +14880,8 @@ async function computeEditedNodeUploads() {
14746
14880
  const uploads = [];
14747
14881
  for (const [path, prevHash] of prev) {
14748
14882
  if (prevHash == null) continue;
14749
- const full = (0, import_node_path14.join)(memoryDir2(), path);
14750
- if (!(0, import_node_fs15.existsSync)(full)) continue;
14883
+ const full = (0, import_node_path15.join)(memoryDir2(), path);
14884
+ if (!(0, import_node_fs16.existsSync)(full)) continue;
14751
14885
  let content;
14752
14886
  try {
14753
14887
  content = await (0, import_promises9.readFile)(full, "utf-8");
@@ -14791,8 +14925,8 @@ async function applyMemoryWrites(writes, opts = {}) {
14791
14925
  const logLines = [`- ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 16)} \u2014 Applied ${count} write(s) from server`];
14792
14926
  for (const n of notes) logLines.push(` - ${n}`);
14793
14927
  try {
14794
- const existing = (0, import_node_fs15.existsSync)((0, import_node_path14.join)(memoryDir2(), "log.md")) ? await (0, import_promises9.readFile)((0, import_node_path14.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
14795
- await (0, import_promises9.writeFile)((0, import_node_path14.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
14928
+ const existing = (0, import_node_fs16.existsSync)((0, import_node_path15.join)(memoryDir2(), "log.md")) ? await (0, import_promises9.readFile)((0, import_node_path15.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
14929
+ await (0, import_promises9.writeFile)((0, import_node_path15.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
14796
14930
  } catch {
14797
14931
  }
14798
14932
  if (opts.baseline === "written") await mergeSyncBaseline(synced);
@@ -14802,7 +14936,7 @@ async function applyMemoryWrites(writes, opts = {}) {
14802
14936
  async function mergeSyncBaseline(entries) {
14803
14937
  if (entries.size === 0) return;
14804
14938
  try {
14805
- if ((0, import_node_fs15.existsSync)(syncStateFile())) {
14939
+ if ((0, import_node_fs16.existsSync)(syncStateFile())) {
14806
14940
  try {
14807
14941
  JSON.parse(await (0, import_promises9.readFile)(syncStateFile(), "utf-8"));
14808
14942
  } catch {
@@ -14830,7 +14964,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
14830
14964
  notes.push(`${write.path}: dropped unmatched file_globs [${grounded.dropped.join(", ")}]`);
14831
14965
  }
14832
14966
  }
14833
- if ((0, import_node_fs15.existsSync)(fullPath)) {
14967
+ if ((0, import_node_fs16.existsSync)(fullPath)) {
14834
14968
  let existing = "";
14835
14969
  try {
14836
14970
  existing = await (0, import_promises9.readFile)(fullPath, "utf-8");
@@ -14846,7 +14980,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
14846
14980
  notes.push(`${write.path}: updated from server (untouched here since the server delivered it)`);
14847
14981
  }
14848
14982
  }
14849
- await (0, import_promises9.mkdir)((0, import_node_path14.dirname)(fullPath), { recursive: true });
14983
+ await (0, import_promises9.mkdir)((0, import_node_path15.dirname)(fullPath), { recursive: true });
14850
14984
  await (0, import_promises9.writeFile)(fullPath, content);
14851
14985
  return { written: true, syncedHash: hashContent(content), notes };
14852
14986
  }
@@ -14887,8 +15021,8 @@ async function regenerateIndex() {
14887
15021
  ];
14888
15022
  let totalNodes = 0;
14889
15023
  for (const domain of DOMAINS2.filter((d) => d !== "_archive")) {
14890
- const domainDir = (0, import_node_path14.join)(memoryDir2(), domain);
14891
- if (!(0, import_node_fs15.existsSync)(domainDir)) continue;
15024
+ const domainDir = (0, import_node_path15.join)(memoryDir2(), domain);
15025
+ if (!(0, import_node_fs16.existsSync)(domainDir)) continue;
14892
15026
  try {
14893
15027
  const files = await (0, import_promises9.readdir)(domainDir);
14894
15028
  const mdFiles = files.filter((f) => f.endsWith(".md"));
@@ -14898,7 +15032,7 @@ async function regenerateIndex() {
14898
15032
  for (const file of mdFiles.sort()) {
14899
15033
  const slug = file.replace(/\.md$/, "");
14900
15034
  try {
14901
- const content = await (0, import_promises9.readFile)((0, import_node_path14.join)(domainDir, file), "utf-8");
15035
+ const content = await (0, import_promises9.readFile)((0, import_node_path15.join)(domainDir, file), "utf-8");
14902
15036
  const title = pickFrontmatter(content, "title") ?? slug;
14903
15037
  const kind = pickFrontmatter(content, "kind") ?? "-";
14904
15038
  const confidence = pickFrontmatter(content, "confidence");
@@ -14922,7 +15056,7 @@ async function regenerateIndex() {
14922
15056
  lines.push("No nodes yet. Run an analysis to start building the knowledge graph.");
14923
15057
  }
14924
15058
  const next = lines.join("\n") + "\n";
14925
- const indexPath = (0, import_node_path14.join)(memoryDir2(), "index.md");
15059
+ const indexPath = (0, import_node_path15.join)(memoryDir2(), "index.md");
14926
15060
  let existing = null;
14927
15061
  try {
14928
15062
  existing = await (0, import_promises9.readFile)(indexPath, "utf-8");
@@ -15319,9 +15453,9 @@ function hasLegacyMemoryBlock(text) {
15319
15453
  return findMarker(text, LEGACY_MD_START) !== -1;
15320
15454
  }
15321
15455
  async function ensureClaudeMdPointer(cwd = repoRoot()) {
15322
- const claudeMdPath = (0, import_node_path14.join)(cwd, "CLAUDE.md");
15456
+ const claudeMdPath = (0, import_node_path15.join)(cwd, "CLAUDE.md");
15323
15457
  let existing = "";
15324
- if ((0, import_node_fs15.existsSync)(claudeMdPath)) {
15458
+ if ((0, import_node_fs16.existsSync)(claudeMdPath)) {
15325
15459
  existing = await (0, import_promises9.readFile)(claudeMdPath, "utf-8");
15326
15460
  }
15327
15461
  let startTag = CLAUDE_MD_START;
@@ -15462,9 +15596,9 @@ Body content (\u22648KB). Use [[node-id]] wikilinks for cross-references.
15462
15596
  `;
15463
15597
 
15464
15598
  // src/lib/dossier-session.ts
15465
- var import_node_fs20 = require("node:fs");
15599
+ var import_node_fs21 = require("node:fs");
15466
15600
  var import_node_crypto7 = require("node:crypto");
15467
- var import_node_path17 = require("node:path");
15601
+ var import_node_path18 = require("node:path");
15468
15602
 
15469
15603
  // src/lib/pending-repeat.ts
15470
15604
  var STOP = /* @__PURE__ */ new Set([
@@ -15569,8 +15703,8 @@ function statementAnchorKey(file, patternId) {
15569
15703
 
15570
15704
  // src/lib/dossier/log.ts
15571
15705
  var import_node_crypto4 = require("node:crypto");
15572
- var import_node_fs16 = require("node:fs");
15573
- var import_node_path15 = require("node:path");
15706
+ var import_node_fs17 = require("node:fs");
15707
+ var import_node_path16 = require("node:path");
15574
15708
  var CRC_TABLE = (() => {
15575
15709
  const t = new Int32Array(256);
15576
15710
  for (let i = 0; i < 256; i++) {
@@ -15589,13 +15723,13 @@ function crc32(s) {
15589
15723
  function openDossier(identity) {
15590
15724
  try {
15591
15725
  const dir = dossierDir(identity);
15592
- (0, import_node_fs16.mkdirSync)(dir, { recursive: true, mode: 448 });
15726
+ (0, import_node_fs17.mkdirSync)(dir, { recursive: true, mode: 448 });
15593
15727
  return {
15594
15728
  dir,
15595
15729
  identity,
15596
- eventsPath: (0, import_node_path15.join)(dir, "events.jsonl"),
15597
- foldPath: (0, import_node_path15.join)(dir, "fold.json"),
15598
- rotatedDir: (0, import_node_path15.join)(dir, "rotated")
15730
+ eventsPath: (0, import_node_path16.join)(dir, "events.jsonl"),
15731
+ foldPath: (0, import_node_path16.join)(dir, "fold.json"),
15732
+ rotatedDir: (0, import_node_path16.join)(dir, "rotated")
15599
15733
  };
15600
15734
  } catch {
15601
15735
  return null;
@@ -15657,7 +15791,7 @@ function appendEvent(d, ev) {
15657
15791
  at: ev.at ?? (/* @__PURE__ */ new Date()).toISOString(),
15658
15792
  ...ev
15659
15793
  });
15660
- (0, import_node_fs16.appendFileSync)(d.eventsPath, line, { mode: 384 });
15794
+ (0, import_node_fs17.appendFileSync)(d.eventsPath, line, { mode: 384 });
15661
15795
  return true;
15662
15796
  } catch {
15663
15797
  return false;
@@ -15665,14 +15799,14 @@ function appendEvent(d, ev) {
15665
15799
  }
15666
15800
  function rotateIfNeeded2(d) {
15667
15801
  try {
15668
- if (!(0, import_node_fs16.existsSync)(d.eventsPath)) return;
15669
- if ((0, import_node_fs16.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
15670
- (0, import_node_fs16.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
15671
- (0, import_node_fs16.renameSync)(d.eventsPath, (0, import_node_path15.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
15672
- const kept = (0, import_node_fs16.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
15802
+ if (!(0, import_node_fs17.existsSync)(d.eventsPath)) return;
15803
+ if ((0, import_node_fs17.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
15804
+ (0, import_node_fs17.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
15805
+ (0, import_node_fs17.renameSync)(d.eventsPath, (0, import_node_path16.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
15806
+ const kept = (0, import_node_fs17.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
15673
15807
  for (const stale of kept.slice(0, Math.max(0, kept.length - ROTATE_KEEP))) {
15674
15808
  try {
15675
- (0, import_node_fs16.renameSync)((0, import_node_path15.join)(d.rotatedDir, stale), (0, import_node_path15.join)(d.rotatedDir, `${stale}.pruned`));
15809
+ (0, import_node_fs17.renameSync)((0, import_node_path16.join)(d.rotatedDir, stale), (0, import_node_path16.join)(d.rotatedDir, `${stale}.pruned`));
15676
15810
  } catch {
15677
15811
  }
15678
15812
  }
@@ -15682,8 +15816,8 @@ function rotateIfNeeded2(d) {
15682
15816
 
15683
15817
  // src/lib/dossier/fold-dossier.ts
15684
15818
  var import_node_crypto5 = require("node:crypto");
15685
- var import_node_fs17 = require("node:fs");
15686
- var import_node_path16 = require("node:path");
15819
+ var import_node_fs18 = require("node:fs");
15820
+ var import_node_path17 = require("node:path");
15687
15821
  var EMPTY_CAPABILITIES = () => ({
15688
15822
  human_reachable: { value: "unknown", tier: "unknown" },
15689
15823
  authorship_observability: { value: "unknown", tier: "unknown" },
@@ -15734,12 +15868,12 @@ function foldDossier(d, opts = {}) {
15734
15868
  }
15735
15869
  };
15736
15870
  try {
15737
- if ((0, import_node_fs17.existsSync)(d.rotatedDir)) {
15738
- const files = (0, import_node_fs17.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
15871
+ if ((0, import_node_fs18.existsSync)(d.rotatedDir)) {
15872
+ const files = (0, import_node_fs18.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
15739
15873
  state.meta.rotations = files.length;
15740
15874
  for (const f of files) {
15741
15875
  try {
15742
- ingest((0, import_node_fs17.readFileSync)((0, import_node_path16.join)(d.rotatedDir, f), "utf8"));
15876
+ ingest((0, import_node_fs18.readFileSync)((0, import_node_path17.join)(d.rotatedDir, f), "utf8"));
15743
15877
  } catch {
15744
15878
  state.meta.dropped_lines++;
15745
15879
  }
@@ -15748,9 +15882,9 @@ function foldDossier(d, opts = {}) {
15748
15882
  } catch {
15749
15883
  }
15750
15884
  try {
15751
- if ((0, import_node_fs17.existsSync)(d.eventsPath)) {
15752
- state.meta.upto_offset = (0, import_node_fs17.statSync)(d.eventsPath).size;
15753
- ingest((0, import_node_fs17.readFileSync)(d.eventsPath, "utf8"));
15885
+ if ((0, import_node_fs18.existsSync)(d.eventsPath)) {
15886
+ state.meta.upto_offset = (0, import_node_fs18.statSync)(d.eventsPath).size;
15887
+ ingest((0, import_node_fs18.readFileSync)(d.eventsPath, "utf8"));
15754
15888
  }
15755
15889
  } catch {
15756
15890
  }
@@ -16021,7 +16155,7 @@ function applyBounds(state, input) {
16021
16155
  }
16022
16156
 
16023
16157
  // src/lib/dossier/cache.ts
16024
- var import_node_fs18 = require("node:fs");
16158
+ var import_node_fs19 = require("node:fs");
16025
16159
  function compactState(s) {
16026
16160
  const ms = (iso) => Date.parse(iso) || 0;
16027
16161
  return {
@@ -16150,20 +16284,20 @@ function encodeState(s) {
16150
16284
  function writeFoldCache(d, state) {
16151
16285
  try {
16152
16286
  const tmp = `${d.foldPath}.${process.pid}.tmp`;
16153
- (0, import_node_fs18.writeFileSync)(tmp, encodeState(state), { mode: 384 });
16154
- (0, import_node_fs18.renameSync)(tmp, d.foldPath);
16287
+ (0, import_node_fs19.writeFileSync)(tmp, encodeState(state), { mode: 384 });
16288
+ (0, import_node_fs19.renameSync)(tmp, d.foldPath);
16155
16289
  } catch {
16156
16290
  }
16157
16291
  }
16158
16292
  function readFoldCache(d) {
16159
16293
  try {
16160
- if (!(0, import_node_fs18.existsSync)(d.foldPath)) return null;
16161
- const raw = JSON.parse((0, import_node_fs18.readFileSync)(d.foldPath, "utf8"));
16294
+ if (!(0, import_node_fs19.existsSync)(d.foldPath)) return null;
16295
+ const raw = JSON.parse((0, import_node_fs19.readFileSync)(d.foldPath, "utf8"));
16162
16296
  if (raw?.v !== 1) return null;
16163
16297
  const cached2 = expandState(raw);
16164
16298
  if (!cached2?.meta) return null;
16165
- const size = (0, import_node_fs18.existsSync)(d.eventsPath) ? (0, import_node_fs18.statSync)(d.eventsPath).size : 0;
16166
- const rotations = (0, import_node_fs18.existsSync)(d.rotatedDir) ? (0, import_node_fs18.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
16299
+ const size = (0, import_node_fs19.existsSync)(d.eventsPath) ? (0, import_node_fs19.statSync)(d.eventsPath).size : 0;
16300
+ const rotations = (0, import_node_fs19.existsSync)(d.rotatedDir) ? (0, import_node_fs19.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
16167
16301
  if (cached2.meta.upto_offset !== size || cached2.meta.rotations !== rotations) return null;
16168
16302
  return cached2;
16169
16303
  } catch {
@@ -16214,13 +16348,13 @@ function assessContinuity(i) {
16214
16348
 
16215
16349
  // src/lib/dossier/reanchor.ts
16216
16350
  var import_node_crypto6 = require("node:crypto");
16217
- var import_node_fs19 = require("node:fs");
16351
+ var import_node_fs20 = require("node:fs");
16218
16352
  function lineSha(text) {
16219
16353
  return (0, import_node_crypto6.createHash)("sha256").update(text.trim()).digest("hex").slice(0, HASH_WIDTH);
16220
16354
  }
16221
16355
  function fileHash(path) {
16222
16356
  try {
16223
- return (0, import_node_crypto6.createHash)("sha256").update((0, import_node_fs19.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
16357
+ return (0, import_node_crypto6.createHash)("sha256").update((0, import_node_fs20.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
16224
16358
  } catch {
16225
16359
  return null;
16226
16360
  }
@@ -16592,20 +16726,20 @@ function foreignAuthoredPaths(identity, opts = {}) {
16592
16726
  let sessions = 0;
16593
16727
  try {
16594
16728
  const dir = treeDir(identity);
16595
- if (!(0, import_node_fs20.existsSync)(dir)) return { paths: [], sessions: 0 };
16596
- for (const entry of (0, import_node_fs20.readdirSync)(dir, { withFileTypes: true })) {
16729
+ if (!(0, import_node_fs21.existsSync)(dir)) return { paths: [], sessions: 0 };
16730
+ for (const entry of (0, import_node_fs21.readdirSync)(dir, { withFileTypes: true })) {
16597
16731
  if (!entry.isDirectory()) continue;
16598
16732
  if (entry.name === identity.sessionKey) continue;
16599
- const log = (0, import_node_path17.join)(dir, entry.name, "events.jsonl");
16733
+ const log = (0, import_node_path18.join)(dir, entry.name, "events.jsonl");
16600
16734
  try {
16601
- if (!(0, import_node_fs20.existsSync)(log)) continue;
16602
- if (now - (0, import_node_fs20.statSync)(log).mtimeMs > windowMs) continue;
16735
+ if (!(0, import_node_fs21.existsSync)(log)) continue;
16736
+ if (now - (0, import_node_fs21.statSync)(log).mtimeMs > windowMs) continue;
16603
16737
  const sib = {
16604
- dir: (0, import_node_path17.join)(dir, entry.name),
16738
+ dir: (0, import_node_path18.join)(dir, entry.name),
16605
16739
  identity,
16606
16740
  eventsPath: log,
16607
- foldPath: (0, import_node_path17.join)(dir, entry.name, "fold.json"),
16608
- rotatedDir: (0, import_node_path17.join)(dir, entry.name, "rotated")
16741
+ foldPath: (0, import_node_path18.join)(dir, entry.name, "fold.json"),
16742
+ rotatedDir: (0, import_node_path18.join)(dir, entry.name, "rotated")
16609
16743
  };
16610
16744
  const state = readFoldCache(sib) ?? foldDossier(sib);
16611
16745
  sessions++;
@@ -16633,25 +16767,25 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
16633
16767
  let removed = 0;
16634
16768
  try {
16635
16769
  const mine = dossierDir(identity);
16636
- const userDir = (0, import_node_path17.dirname)((0, import_node_path17.dirname)(mine));
16637
- if (!(0, import_node_fs20.existsSync)(userDir)) return 0;
16770
+ const userDir = (0, import_node_path18.dirname)((0, import_node_path18.dirname)(mine));
16771
+ if (!(0, import_node_fs21.existsSync)(userDir)) return 0;
16638
16772
  const cutoff = Date.now() - maxAgeMs;
16639
- for (const tree of (0, import_node_fs20.readdirSync)(userDir, { withFileTypes: true })) {
16773
+ for (const tree of (0, import_node_fs21.readdirSync)(userDir, { withFileTypes: true })) {
16640
16774
  if (!tree.isDirectory()) continue;
16641
- const treePath = (0, import_node_path17.join)(userDir, tree.name);
16775
+ const treePath = (0, import_node_path18.join)(userDir, tree.name);
16642
16776
  let live = 0;
16643
- for (const entry of (0, import_node_fs20.readdirSync)(treePath, { withFileTypes: true })) {
16777
+ for (const entry of (0, import_node_fs21.readdirSync)(treePath, { withFileTypes: true })) {
16644
16778
  if (!entry.isDirectory()) continue;
16645
- const dir = (0, import_node_path17.join)(treePath, entry.name);
16779
+ const dir = (0, import_node_path18.join)(treePath, entry.name);
16646
16780
  if (dir === mine) {
16647
16781
  live++;
16648
16782
  continue;
16649
16783
  }
16650
16784
  try {
16651
- const log = (0, import_node_path17.join)(dir, "events.jsonl");
16652
- const at = (0, import_node_fs20.existsSync)(log) ? (0, import_node_fs20.statSync)(log).mtimeMs : (0, import_node_fs20.statSync)(dir).mtimeMs;
16785
+ const log = (0, import_node_path18.join)(dir, "events.jsonl");
16786
+ const at = (0, import_node_fs21.existsSync)(log) ? (0, import_node_fs21.statSync)(log).mtimeMs : (0, import_node_fs21.statSync)(dir).mtimeMs;
16653
16787
  if (at < cutoff) {
16654
- (0, import_node_fs20.rmSync)(dir, { recursive: true, force: true });
16788
+ (0, import_node_fs21.rmSync)(dir, { recursive: true, force: true });
16655
16789
  removed++;
16656
16790
  } else {
16657
16791
  live++;
@@ -16661,7 +16795,7 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
16661
16795
  }
16662
16796
  if (live === 0) {
16663
16797
  try {
16664
- (0, import_node_fs20.rmSync)(treePath, { recursive: false, force: false });
16798
+ (0, import_node_fs21.rmSync)(treePath, { recursive: false, force: false });
16665
16799
  } catch {
16666
16800
  }
16667
16801
  }
@@ -16678,8 +16812,8 @@ function sessionDossier(token, sessionId) {
16678
16812
  }
16679
16813
  function hasActiveGoal(d) {
16680
16814
  try {
16681
- if (!(0, import_node_fs20.existsSync)(d.eventsPath)) return false;
16682
- return (0, import_node_fs20.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
16815
+ if (!(0, import_node_fs21.existsSync)(d.eventsPath)) return false;
16816
+ return (0, import_node_fs21.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
16683
16817
  } catch {
16684
16818
  return false;
16685
16819
  }
@@ -16703,7 +16837,7 @@ function recordTurn(d, t) {
16703
16837
  for (const a of t.authored) {
16704
16838
  const origin = a.owner === "subagent" ? "subagent" : "edit_tool";
16705
16839
  const prior = t.known?.authored?.get(a.p);
16706
- const hash = fileHash((0, import_node_path17.join)(root, a.p));
16840
+ const hash = fileHash((0, import_node_path18.join)(root, a.p));
16707
16841
  const hunks = Math.max(0, a.h - (prior?.hunks ?? 0));
16708
16842
  const adds = Math.max(0, a.a - (prior?.adds ?? 0));
16709
16843
  const dels = Math.max(0, a.d - (prior?.dels ?? 0));
@@ -16736,7 +16870,7 @@ function recordTurn(d, t) {
16736
16870
  }
16737
16871
  const seenDivergence = t.known?.divergence ?? /* @__PURE__ */ new Set();
16738
16872
  for (const u of t.unobserved) {
16739
- const hash = fileHash((0, import_node_path17.join)(root, u.p));
16873
+ const hash = fileHash((0, import_node_path18.join)(root, u.p));
16740
16874
  if (seenDivergence.has(divergenceKey(u.p, hash))) continue;
16741
16875
  appendEvent(d, { k: "divergence", kind: "external_mutation", path: u.p, hash });
16742
16876
  }
@@ -16771,8 +16905,8 @@ function recordVerdict(d, v) {
16771
16905
  if (!sent.has(f.file)) continue;
16772
16906
  if (!lines.has(f.file)) {
16773
16907
  try {
16774
- const abs = (0, import_node_path17.join)(root, f.file);
16775
- lines.set(f.file, (0, import_node_fs20.existsSync)(abs) ? (0, import_node_fs20.readFileSync)(abs, "utf8").split("\n") : null);
16908
+ const abs = (0, import_node_path18.join)(root, f.file);
16909
+ lines.set(f.file, (0, import_node_fs21.existsSync)(abs) ? (0, import_node_fs21.readFileSync)(abs, "utf8").split("\n") : null);
16776
16910
  } catch {
16777
16911
  lines.set(f.file, null);
16778
16912
  }
@@ -16872,8 +17006,8 @@ function recallMemory(d, identity, opts) {
16872
17006
  budgetBytes: opts.budgetBytes,
16873
17007
  readFileLines: (file) => {
16874
17008
  try {
16875
- const abs = (0, import_node_path17.join)(root, file);
16876
- return (0, import_node_fs20.existsSync)(abs) ? (0, import_node_fs20.readFileSync)(abs, "utf8").split("\n") : null;
17009
+ const abs = (0, import_node_path18.join)(root, file);
17010
+ return (0, import_node_fs21.existsSync)(abs) ? (0, import_node_fs21.readFileSync)(abs, "utf8").split("\n") : null;
16877
17011
  } catch {
16878
17012
  return null;
16879
17013
  }
@@ -17017,46 +17151,46 @@ async function fireClassify(prompt, sessionId, globals) {
17017
17151
  }
17018
17152
 
17019
17153
  // src/commands/lifecycle.ts
17020
- var import_node_fs24 = require("node:fs");
17021
- var import_node_path22 = require("node:path");
17154
+ var import_node_fs25 = require("node:fs");
17155
+ var import_node_path23 = require("node:path");
17022
17156
 
17023
17157
  // src/lib/baseline.ts
17024
- var import_node_fs23 = require("node:fs");
17025
- var import_node_path21 = require("node:path");
17158
+ var import_node_fs24 = require("node:fs");
17159
+ var import_node_path22 = require("node:path");
17026
17160
  var import_node_crypto9 = require("node:crypto");
17027
17161
 
17028
17162
  // src/lib/snapshot.ts
17029
- var import_node_fs22 = require("node:fs");
17030
- var import_node_path20 = require("node:path");
17163
+ var import_node_fs23 = require("node:fs");
17164
+ var import_node_path21 = require("node:path");
17031
17165
  var import_node_child_process7 = require("node:child_process");
17032
17166
 
17033
17167
  // src/lib/files.ts
17034
- var import_node_path19 = require("node:path");
17168
+ var import_node_path20 = require("node:path");
17035
17169
 
17036
17170
  // src/lib/safe-read.ts
17037
- var import_node_fs21 = require("node:fs");
17038
- var import_node_path18 = require("node:path");
17039
- var FLAGS = import_node_fs21.constants;
17171
+ var import_node_fs22 = require("node:fs");
17172
+ var import_node_path19 = require("node:path");
17173
+ var FLAGS = import_node_fs22.constants;
17040
17174
  var NOFOLLOW = FLAGS.O_NOFOLLOW;
17041
17175
  var NONBLOCK = FLAGS.O_NONBLOCK;
17042
17176
  function closeOpened(fd) {
17043
17177
  try {
17044
- (0, import_node_fs21.closeSync)(fd);
17178
+ (0, import_node_fs22.closeSync)(fd);
17045
17179
  } catch {
17046
17180
  }
17047
17181
  }
17048
17182
  function isInsideRoot(realRoot, realPath) {
17049
- return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path18.sep) ? realRoot : realRoot + import_node_path18.sep);
17183
+ return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path19.sep) ? realRoot : realRoot + import_node_path19.sep);
17050
17184
  }
17051
17185
  function sameOpenedFile(opened, current, nofollowAvailable) {
17052
17186
  if (!nofollowAvailable && (opened.ino === 0n || current.ino === 0n)) return false;
17053
17187
  return opened.ino === current.ino && opened.dev === current.dev;
17054
17188
  }
17055
17189
  function openRegularInRoot(root, path) {
17056
- const full = (0, import_node_path18.isAbsolute)(path) ? path : (0, import_node_path18.join)(root, path);
17190
+ const full = (0, import_node_path19.isAbsolute)(path) ? path : (0, import_node_path19.join)(root, path);
17057
17191
  let fd;
17058
17192
  try {
17059
- fd = (0, import_node_fs21.openSync)(full, import_node_fs21.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
17193
+ fd = (0, import_node_fs22.openSync)(full, import_node_fs22.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
17060
17194
  } catch (err) {
17061
17195
  const code = err.code;
17062
17196
  if (code === "ELOOP" || code === "EMLINK" || code === "EFTYPE") return { ok: false, reason: "symlink" };
@@ -17064,18 +17198,18 @@ function openRegularInRoot(root, path) {
17064
17198
  return { ok: false, reason: "unreadable" };
17065
17199
  }
17066
17200
  try {
17067
- const opened = (0, import_node_fs21.fstatSync)(fd, { bigint: true });
17201
+ const opened = (0, import_node_fs22.fstatSync)(fd, { bigint: true });
17068
17202
  if (!opened.isFile()) {
17069
17203
  closeOpened(fd);
17070
17204
  return { ok: false, reason: "not-regular" };
17071
17205
  }
17072
- const realRoot = import_node_fs21.realpathSync.native(root);
17073
- const realPath = import_node_fs21.realpathSync.native(full);
17206
+ const realRoot = import_node_fs22.realpathSync.native(root);
17207
+ const realPath = import_node_fs22.realpathSync.native(full);
17074
17208
  if (!isInsideRoot(realRoot, realPath)) {
17075
17209
  closeOpened(fd);
17076
17210
  return { ok: false, reason: "outside-root" };
17077
17211
  }
17078
- const current = (0, import_node_fs21.statSync)(realPath, { bigint: true });
17212
+ const current = (0, import_node_fs22.statSync)(realPath, { bigint: true });
17079
17213
  if (!sameOpenedFile(opened, current, NOFOLLOW !== void 0)) {
17080
17214
  closeOpened(fd);
17081
17215
  return { ok: false, reason: NOFOLLOW === void 0 ? "unreadable" : "outside-root" };
@@ -17097,7 +17231,7 @@ function readOpened(fd, size) {
17097
17231
  const buffer = Buffer.alloc(size);
17098
17232
  let offset = 0;
17099
17233
  while (offset < size) {
17100
- const n = (0, import_node_fs21.readSync)(fd, buffer, offset, size - offset, offset);
17234
+ const n = (0, import_node_fs22.readSync)(fd, buffer, offset, size - offset, offset);
17101
17235
  if (n === 0) break;
17102
17236
  offset += n;
17103
17237
  }
@@ -17191,7 +17325,7 @@ var LANG_MAP = {
17191
17325
  mk: "make"
17192
17326
  };
17193
17327
  function detectLanguage(filepath) {
17194
- const ext = (0, import_node_path19.extname)(filepath).slice(1);
17328
+ const ext = (0, import_node_path20.extname)(filepath).slice(1);
17195
17329
  return LANG_MAP[ext] ?? ext;
17196
17330
  }
17197
17331
  function sortByMtime(files) {
@@ -17282,16 +17416,16 @@ function collectCodeDelta(files, opts) {
17282
17416
 
17283
17417
  // src/lib/snapshot.ts
17284
17418
  function generateSnapshotDiffs(files) {
17285
- if (!(0, import_node_fs22.existsSync)(SNAPSHOT_DIR)) {
17419
+ if (!(0, import_node_fs23.existsSync)(SNAPSHOT_DIR)) {
17286
17420
  return { diffs: [], has_snapshots: false };
17287
17421
  }
17288
17422
  const diffs = [];
17289
17423
  for (const file of files) {
17290
17424
  if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
17291
- const snapshotPath = (0, import_node_path20.join)(SNAPSHOT_DIR, file.path);
17425
+ const snapshotPath = (0, import_node_path21.join)(SNAPSHOT_DIR, file.path);
17292
17426
  const language = file.language ?? detectLanguage(file.path);
17293
- if ((0, import_node_fs22.existsSync)(snapshotPath)) {
17294
- const oldContent = (0, import_node_fs22.readFileSync)(snapshotPath, "utf-8");
17427
+ if ((0, import_node_fs23.existsSync)(snapshotPath)) {
17428
+ const oldContent = (0, import_node_fs23.readFileSync)(snapshotPath, "utf-8");
17295
17429
  if (oldContent === file.content) continue;
17296
17430
  const diff = computeDiff(oldContent, file.content, file.path);
17297
17431
  if (diff) {
@@ -17316,20 +17450,20 @@ function saveSnapshots(files) {
17316
17450
  const snapshotPaths = /* @__PURE__ */ new Set();
17317
17451
  for (const file of files) {
17318
17452
  if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
17319
- const snapshotPath = (0, import_node_path20.join)(SNAPSHOT_DIR, file.path);
17453
+ const snapshotPath = (0, import_node_path21.join)(SNAPSHOT_DIR, file.path);
17320
17454
  snapshotPaths.add(snapshotPath);
17321
- (0, import_node_fs22.mkdirSync)((0, import_node_path20.dirname)(snapshotPath), { recursive: true });
17322
- (0, import_node_fs22.writeFileSync)(snapshotPath, file.content);
17455
+ (0, import_node_fs23.mkdirSync)((0, import_node_path21.dirname)(snapshotPath), { recursive: true });
17456
+ (0, import_node_fs23.writeFileSync)(snapshotPath, file.content);
17323
17457
  }
17324
17458
  cleanStaleSnapshots(SNAPSHOT_DIR, snapshotPaths);
17325
17459
  }
17326
17460
  function computeDiff(oldContent, newContent, filePath) {
17327
- const tmpOld = (0, import_node_path20.join)(SNAPSHOT_DIR, ".diff-old.tmp");
17328
- const tmpNew = (0, import_node_path20.join)(SNAPSHOT_DIR, ".diff-new.tmp");
17461
+ const tmpOld = (0, import_node_path21.join)(SNAPSHOT_DIR, ".diff-old.tmp");
17462
+ const tmpNew = (0, import_node_path21.join)(SNAPSHOT_DIR, ".diff-new.tmp");
17329
17463
  try {
17330
- (0, import_node_fs22.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
17331
- (0, import_node_fs22.writeFileSync)(tmpOld, oldContent);
17332
- (0, import_node_fs22.writeFileSync)(tmpNew, newContent);
17464
+ (0, import_node_fs23.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
17465
+ (0, import_node_fs23.writeFileSync)(tmpOld, oldContent);
17466
+ (0, import_node_fs23.writeFileSync)(tmpNew, newContent);
17333
17467
  const result = (0, import_node_child_process7.execSync)(
17334
17468
  `git diff --no-index --unified=10 -- "${tmpOld}" "${tmpNew}"`,
17335
17469
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
@@ -17343,32 +17477,32 @@ function computeDiff(oldContent, newContent, filePath) {
17343
17477
  return null;
17344
17478
  } finally {
17345
17479
  try {
17346
- (0, import_node_fs22.unlinkSync)(tmpOld);
17480
+ (0, import_node_fs23.unlinkSync)(tmpOld);
17347
17481
  } catch {
17348
17482
  }
17349
17483
  try {
17350
- (0, import_node_fs22.unlinkSync)(tmpNew);
17484
+ (0, import_node_fs23.unlinkSync)(tmpNew);
17351
17485
  } catch {
17352
17486
  }
17353
17487
  }
17354
17488
  }
17355
17489
  function cleanStaleSnapshots(dir, keepSet) {
17356
- if (!(0, import_node_fs22.existsSync)(dir)) return;
17490
+ if (!(0, import_node_fs23.existsSync)(dir)) return;
17357
17491
  try {
17358
- const entries = (0, import_node_fs22.readdirSync)(dir, { withFileTypes: true });
17492
+ const entries = (0, import_node_fs23.readdirSync)(dir, { withFileTypes: true });
17359
17493
  for (const entry of entries) {
17360
17494
  if (dir === SNAPSHOT_DIR && (entry.name === ".diff-old.tmp" || entry.name === ".diff-new.tmp")) continue;
17361
- const fullPath = (0, import_node_path20.join)(dir, entry.name);
17495
+ const fullPath = (0, import_node_path21.join)(dir, entry.name);
17362
17496
  if (entry.isDirectory()) {
17363
17497
  cleanStaleSnapshots(fullPath, keepSet);
17364
17498
  try {
17365
- const remaining = (0, import_node_fs22.readdirSync)(fullPath);
17366
- if (remaining.length === 0) (0, import_node_fs22.rmdirSync)(fullPath);
17499
+ const remaining = (0, import_node_fs23.readdirSync)(fullPath);
17500
+ if (remaining.length === 0) (0, import_node_fs23.rmdirSync)(fullPath);
17367
17501
  } catch {
17368
17502
  }
17369
17503
  } else if (!keepSet.has(fullPath)) {
17370
17504
  try {
17371
- (0, import_node_fs22.unlinkSync)(fullPath);
17505
+ (0, import_node_fs23.unlinkSync)(fullPath);
17372
17506
  } catch {
17373
17507
  }
17374
17508
  }
@@ -17387,20 +17521,20 @@ function sessionKey(sessionId) {
17387
17521
  return (0, import_node_crypto9.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
17388
17522
  }
17389
17523
  function sessionDir(key) {
17390
- return (0, import_node_path21.join)(projectPath(BASELINE_DIR), key);
17524
+ return (0, import_node_path22.join)(projectPath(BASELINE_DIR), key);
17391
17525
  }
17392
17526
  function manifestPath(dir) {
17393
- return (0, import_node_path21.join)(dir, "manifest.json");
17527
+ return (0, import_node_path22.join)(dir, "manifest.json");
17394
17528
  }
17395
17529
  function mirrorPath(dir, repoRelPath) {
17396
- return (0, import_node_path21.join)(dir, "files", repoRelPath);
17530
+ return (0, import_node_path22.join)(dir, "files", repoRelPath);
17397
17531
  }
17398
17532
  var CARRY_FILE = `${BASELINE_DIR}/.carry`;
17399
17533
  var CARRY_WINDOW_MS = 12e4;
17400
17534
  function writeCarry(sessionId, headSha) {
17401
17535
  try {
17402
- (0, import_node_fs23.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
17403
- (0, import_node_fs23.writeFileSync)(
17536
+ (0, import_node_fs24.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
17537
+ (0, import_node_fs24.writeFileSync)(
17404
17538
  projectPath(CARRY_FILE),
17405
17539
  JSON.stringify({ from_key: sessionKey(sessionId), head_sha: headSha, ts: Date.now() })
17406
17540
  );
@@ -17410,10 +17544,10 @@ function writeCarry(sessionId, headSha) {
17410
17544
  function claimCarry(newKey) {
17411
17545
  const carryPath = projectPath(CARRY_FILE);
17412
17546
  try {
17413
- if (!(0, import_node_fs23.existsSync)(carryPath)) return null;
17414
- const carry = JSON.parse((0, import_node_fs23.readFileSync)(carryPath, "utf-8"));
17547
+ if (!(0, import_node_fs24.existsSync)(carryPath)) return null;
17548
+ const carry = JSON.parse((0, import_node_fs24.readFileSync)(carryPath, "utf-8"));
17415
17549
  try {
17416
- (0, import_node_fs23.rmSync)(carryPath, { force: true });
17550
+ (0, import_node_fs24.rmSync)(carryPath, { force: true });
17417
17551
  } catch {
17418
17552
  }
17419
17553
  if (!carry?.from_key || typeof carry.ts !== "number") return null;
@@ -17424,11 +17558,11 @@ function claimCarry(newKey) {
17424
17558
  if (!prior) return null;
17425
17559
  const toDir = sessionDir(newKey);
17426
17560
  try {
17427
- (0, import_node_fs23.rmSync)(toDir, { recursive: true, force: true });
17561
+ (0, import_node_fs24.rmSync)(toDir, { recursive: true, force: true });
17428
17562
  } catch {
17429
17563
  }
17430
- (0, import_node_fs23.renameSync)(fromDir, toDir);
17431
- (0, import_node_fs23.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
17564
+ (0, import_node_fs24.renameSync)(fromDir, toDir);
17565
+ (0, import_node_fs24.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
17432
17566
  return readManifest(toDir);
17433
17567
  } catch {
17434
17568
  return null;
@@ -17452,21 +17586,21 @@ function captureBaseline(opts = {}) {
17452
17586
  const head_sha = getCurrentCommit();
17453
17587
  const dirty = getDirtyFiles();
17454
17588
  try {
17455
- (0, import_node_fs23.rmSync)(dir, { recursive: true, force: true });
17589
+ (0, import_node_fs24.rmSync)(dir, { recursive: true, force: true });
17456
17590
  } catch {
17457
17591
  }
17458
- const filesDir = (0, import_node_path21.join)(dir, "files");
17592
+ const filesDir = (0, import_node_path22.join)(dir, "files");
17459
17593
  const mirrored = [];
17460
17594
  try {
17461
- (0, import_node_fs23.mkdirSync)(filesDir, { recursive: true });
17595
+ (0, import_node_fs24.mkdirSync)(filesDir, { recursive: true });
17462
17596
  for (const p of dirty) {
17463
17597
  if (p.includes("..")) continue;
17464
17598
  const content = safeReadForMirror(projectPath(p));
17465
17599
  if (content === null) continue;
17466
17600
  const dest = mirrorPath(dir, p);
17467
17601
  try {
17468
- (0, import_node_fs23.mkdirSync)((0, import_node_path21.dirname)(dest), { recursive: true });
17469
- (0, import_node_fs23.writeFileSync)(dest, content);
17602
+ (0, import_node_fs24.mkdirSync)((0, import_node_path22.dirname)(dest), { recursive: true });
17603
+ (0, import_node_fs24.writeFileSync)(dest, content);
17470
17604
  mirrored.push(p);
17471
17605
  } catch {
17472
17606
  }
@@ -17481,8 +17615,8 @@ function captureBaseline(opts = {}) {
17481
17615
  version: BASELINE_VERSION
17482
17616
  };
17483
17617
  try {
17484
- (0, import_node_fs23.mkdirSync)(dir, { recursive: true });
17485
- (0, import_node_fs23.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
17618
+ (0, import_node_fs24.mkdirSync)(dir, { recursive: true });
17619
+ (0, import_node_fs24.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
17486
17620
  } catch {
17487
17621
  }
17488
17622
  pruneOldBaselines();
@@ -17493,9 +17627,9 @@ function readBaseline(sessionId) {
17493
17627
  }
17494
17628
  function readManifest(dir) {
17495
17629
  const mp = manifestPath(dir);
17496
- if (!(0, import_node_fs23.existsSync)(mp)) return null;
17630
+ if (!(0, import_node_fs24.existsSync)(mp)) return null;
17497
17631
  try {
17498
- const parsed = JSON.parse((0, import_node_fs23.readFileSync)(mp, "utf-8"));
17632
+ const parsed = JSON.parse((0, import_node_fs24.readFileSync)(mp, "utf-8"));
17499
17633
  if (typeof parsed.head_sha !== "string" || typeof parsed.captured_at !== "number" || !Array.isArray(parsed.dirty_paths) || parsed.version !== BASELINE_VERSION) {
17500
17634
  return null;
17501
17635
  }
@@ -17526,9 +17660,9 @@ function preImage(repoRelPath, baseline) {
17526
17660
  function resolvePreImage(repoRelPath, baseline) {
17527
17661
  if (baseline.dirty_paths.includes(repoRelPath)) {
17528
17662
  const mp = mirrorPath(sessionDir(sessionKey(baseline.session_id)), repoRelPath);
17529
- if ((0, import_node_fs23.existsSync)(mp)) {
17663
+ if ((0, import_node_fs24.existsSync)(mp)) {
17530
17664
  try {
17531
- return { content: (0, import_node_fs23.readFileSync)(mp, "utf-8"), existed: true };
17665
+ return { content: (0, import_node_fs24.readFileSync)(mp, "utf-8"), existed: true };
17532
17666
  } catch {
17533
17667
  }
17534
17668
  }
@@ -17573,8 +17707,8 @@ function absorbIntoBaseline(paths, sessionId) {
17573
17707
  const content = safeReadForMirror(projectPath(p));
17574
17708
  if (content === null) continue;
17575
17709
  const dest = mirrorPath(dir, p);
17576
- (0, import_node_fs23.mkdirSync)((0, import_node_path21.dirname)(dest), { recursive: true });
17577
- (0, import_node_fs23.writeFileSync)(dest, content);
17710
+ (0, import_node_fs24.mkdirSync)((0, import_node_path22.dirname)(dest), { recursive: true });
17711
+ (0, import_node_fs24.writeFileSync)(dest, content);
17578
17712
  dirty.add(p);
17579
17713
  adopted++;
17580
17714
  } catch {
@@ -17583,7 +17717,7 @@ function absorbIntoBaseline(paths, sessionId) {
17583
17717
  if (adopted === 0) return 0;
17584
17718
  try {
17585
17719
  const updated = { ...baseline, dirty_paths: [...dirty] };
17586
- (0, import_node_fs23.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
17720
+ (0, import_node_fs24.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
17587
17721
  preImageCache.delete(baseline);
17588
17722
  } catch {
17589
17723
  return 0;
@@ -17594,7 +17728,7 @@ function changedSinceBaseline(repoRelPath, baseline) {
17594
17728
  const pre = preImage(repoRelPath, baseline);
17595
17729
  let current;
17596
17730
  try {
17597
- current = (0, import_node_fs23.readFileSync)(projectPath(repoRelPath), "utf-8");
17731
+ current = (0, import_node_fs24.readFileSync)(projectPath(repoRelPath), "utf-8");
17598
17732
  } catch {
17599
17733
  return pre.existed;
17600
17734
  }
@@ -17603,8 +17737,8 @@ function changedSinceBaseline(repoRelPath, baseline) {
17603
17737
  }
17604
17738
  function safeReadForMirror(absPath) {
17605
17739
  try {
17606
- if ((0, import_node_fs23.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
17607
- const buf = (0, import_node_fs23.readFileSync)(absPath);
17740
+ if ((0, import_node_fs24.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
17741
+ const buf = (0, import_node_fs24.readFileSync)(absPath);
17608
17742
  if (buf.includes(0)) return null;
17609
17743
  return buf.toString("utf-8");
17610
17744
  } catch {
@@ -17615,18 +17749,18 @@ function pruneOldBaselines() {
17615
17749
  const root = projectPath(BASELINE_DIR);
17616
17750
  let entries;
17617
17751
  try {
17618
- entries = (0, import_node_fs23.readdirSync)(root);
17752
+ entries = (0, import_node_fs24.readdirSync)(root);
17619
17753
  } catch {
17620
17754
  return;
17621
17755
  }
17622
17756
  const now = Date.now();
17623
17757
  for (const name of entries) {
17624
- const dir = (0, import_node_path21.join)(root, name);
17758
+ const dir = (0, import_node_path22.join)(root, name);
17625
17759
  const manifest = readManifest(dir);
17626
17760
  if (!manifest) {
17627
17761
  try {
17628
- if (now - (0, import_node_fs23.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
17629
- (0, import_node_fs23.rmSync)(dir, { recursive: true, force: true });
17762
+ if (now - (0, import_node_fs24.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
17763
+ (0, import_node_fs24.rmSync)(dir, { recursive: true, force: true });
17630
17764
  }
17631
17765
  } catch {
17632
17766
  }
@@ -17634,7 +17768,7 @@ function pruneOldBaselines() {
17634
17768
  }
17635
17769
  if (now - manifest.captured_at <= BASELINE_TTL_MS) continue;
17636
17770
  try {
17637
- (0, import_node_fs23.rmSync)(dir, { recursive: true, force: true });
17771
+ (0, import_node_fs24.rmSync)(dir, { recursive: true, force: true });
17638
17772
  } catch {
17639
17773
  }
17640
17774
  }
@@ -17809,8 +17943,8 @@ function buildCompactionContext(session) {
17809
17943
  commitsSince: commitsSincePaths(watermark, (state.authored ?? []).map((a) => a.path)),
17810
17944
  readFileLines: (file) => {
17811
17945
  try {
17812
- const abs = (0, import_node_path22.join)(root, file);
17813
- return (0, import_node_fs24.existsSync)(abs) ? (0, import_node_fs24.readFileSync)(abs, "utf8").split("\n") : null;
17946
+ const abs = (0, import_node_path23.join)(root, file);
17947
+ return (0, import_node_fs25.existsSync)(abs) ? (0, import_node_fs25.readFileSync)(abs, "utf8").split("\n") : null;
17814
17948
  } catch {
17815
17949
  return null;
17816
17950
  }
@@ -17867,24 +18001,24 @@ async function readHookStdin() {
17867
18001
 
17868
18002
  // src/commands/standard.ts
17869
18003
  var import_promises13 = require("node:fs/promises");
17870
- var import_node_fs31 = require("node:fs");
18004
+ var import_node_fs32 = require("node:fs");
17871
18005
  var import_yaml3 = __toESM(require_dist());
17872
18006
 
17873
18007
  // src/lib/synthesize.ts
17874
18008
  var import_node_child_process9 = require("node:child_process");
17875
- var import_node_fs27 = require("node:fs");
18009
+ var import_node_fs28 = require("node:fs");
17876
18010
  var import_promises10 = require("node:fs/promises");
17877
- var import_node_path25 = require("node:path");
18011
+ var import_node_path26 = require("node:path");
17878
18012
  var import_yaml = __toESM(require_dist());
17879
18013
 
17880
18014
  // src/lib/data-dir.ts
17881
- var import_node_fs25 = require("node:fs");
17882
- var import_node_path23 = require("node:path");
18015
+ var import_node_fs26 = require("node:fs");
18016
+ var import_node_path24 = require("node:path");
17883
18017
  function resolveDataDir() {
17884
18018
  const candidates2 = [
17885
- (0, import_node_path23.join)(__dirname, "..", "data"),
18019
+ (0, import_node_path24.join)(__dirname, "..", "data"),
17886
18020
  // installed: node_modules/@codacy/verity-cli/data
17887
- (0, import_node_path23.join)(__dirname, "..", "..", "data"),
18021
+ (0, import_node_path24.join)(__dirname, "..", "..", "data"),
17888
18022
  // edge case: nested resolution
17889
18023
  // THE COMMITTED SOURCE, for a source checkout that has not been built.
17890
18024
  // cli/data/skills/ is a BUILD ARTIFACT (scripts/build.js copies client/skills
@@ -17893,14 +18027,14 @@ function resolveDataDir() {
17893
18027
  // without this the synthesizer throws "Could not find Verity skill data"
17894
18028
  // for every test and every `verity` run from source. Resolved from this
17895
18029
  // module's own location, never the cwd: see the warning below.
17896
- (0, import_node_path23.join)(__dirname, "..", "..", "client"),
18030
+ (0, import_node_path24.join)(__dirname, "..", "..", "client"),
17897
18031
  // bundled: cli/bin/ → ../../client
17898
- (0, import_node_path23.join)(__dirname, "..", "..", "..", "client"),
18032
+ (0, import_node_path24.join)(__dirname, "..", "..", "..", "client"),
17899
18033
  // tsx: cli/src/lib/ → ../../../client
17900
18034
  ...process.env.VERITY_DEV_DATA_DIR ? [process.env.VERITY_DEV_DATA_DIR] : []
17901
18035
  ];
17902
18036
  for (const candidate of candidates2) {
17903
- if ((0, import_node_fs25.existsSync)((0, import_node_path23.join)(candidate, "skills"))) {
18037
+ if ((0, import_node_fs26.existsSync)((0, import_node_path24.join)(candidate, "skills"))) {
17904
18038
  return candidate;
17905
18039
  }
17906
18040
  }
@@ -17909,13 +18043,13 @@ function resolveDataDir() {
17909
18043
  );
17910
18044
  }
17911
18045
  function setupDataPath(file) {
17912
- return (0, import_node_path23.join)(resolveDataDir(), "skills", "verity-setup", file);
18046
+ return (0, import_node_path24.join)(resolveDataDir(), "skills", "verity-setup", file);
17913
18047
  }
17914
18048
 
17915
18049
  // src/lib/detect.ts
17916
18050
  var import_node_child_process8 = require("node:child_process");
17917
- var import_node_fs26 = require("node:fs");
17918
- var import_node_path24 = require("node:path");
18051
+ var import_node_fs27 = require("node:fs");
18052
+ var import_node_path25 = require("node:path");
17919
18053
  var TOOLED_LANGUAGES = /* @__PURE__ */ new Set([
17920
18054
  "typescript",
17921
18055
  "javascript",
@@ -17972,25 +18106,25 @@ function walk(root) {
17972
18106
  if (depth > WALK_MAX_DEPTH || found.length >= WALK_MAX_FILES) return;
17973
18107
  let entries;
17974
18108
  try {
17975
- entries = (0, import_node_fs26.readdirSync)(dir, { withFileTypes: true });
18109
+ entries = (0, import_node_fs27.readdirSync)(dir, { withFileTypes: true });
17976
18110
  } catch {
17977
18111
  return;
17978
18112
  }
17979
18113
  for (const entry of entries) {
17980
18114
  if (found.length >= WALK_MAX_FILES) return;
17981
18115
  if (IGNORED_SEGMENTS.includes(entry.name)) continue;
17982
- const full = (0, import_node_path24.join)(dir, entry.name);
18116
+ const full = (0, import_node_path25.join)(dir, entry.name);
17983
18117
  if (entry.isDirectory()) visit(full, depth + 1);
17984
- else if (entry.isFile()) found.push((0, import_node_path24.relative)(root, full));
18118
+ else if (entry.isFile()) found.push((0, import_node_path25.relative)(root, full));
17985
18119
  }
17986
18120
  };
17987
18121
  visit(root, 0);
17988
18122
  return found;
17989
18123
  }
17990
18124
  function languageOf(path) {
17991
- const name = (0, import_node_path24.basename)(path);
18125
+ const name = (0, import_node_path25.basename)(path);
17992
18126
  if (/^Dockerfile(\..+)?$/i.test(name)) return "dockerfile";
17993
- if (!(0, import_node_path24.extname)(name)) return null;
18127
+ if (!(0, import_node_path25.extname)(name)) return null;
17994
18128
  const lang = detectLanguage(path);
17995
18129
  return lang || null;
17996
18130
  }
@@ -18045,9 +18179,9 @@ var TOOL_CONFIG_MARKERS = [
18045
18179
  ["detekt", ["detekt.yml", "detekt.yaml"]],
18046
18180
  ["Hadolint", [".hadolint.yaml", ".hadolint.yml"]]
18047
18181
  ];
18048
- function readJson(path) {
18182
+ function readJson2(path) {
18049
18183
  try {
18050
- return JSON.parse((0, import_node_fs26.readFileSync)(path, "utf-8"));
18184
+ return JSON.parse((0, import_node_fs27.readFileSync)(path, "utf-8"));
18051
18185
  } catch {
18052
18186
  return null;
18053
18187
  }
@@ -18065,24 +18199,24 @@ var NESTED_MANIFEST_LIMIT = 25;
18065
18199
  function declaredDependencies(root, files) {
18066
18200
  const names2 = [];
18067
18201
  const readPackageJson = (path) => {
18068
- const pkg = readJson(path);
18202
+ const pkg = readJson2(path);
18069
18203
  if (!pkg) return;
18070
18204
  for (const field of ["dependencies", "devDependencies", "peerDependencies"]) {
18071
18205
  const deps = pkg[field];
18072
18206
  if (deps && typeof deps === "object") names2.push(...Object.keys(deps));
18073
18207
  }
18074
18208
  };
18075
- readPackageJson((0, import_node_path24.join)(root, "package.json"));
18076
- const nested = files.filter((f) => f.includes("/") && (0, import_node_path24.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
18077
- for (const rel of nested) readPackageJson((0, import_node_path24.join)(root, rel));
18209
+ readPackageJson((0, import_node_path25.join)(root, "package.json"));
18210
+ const nested = files.filter((f) => f.includes("/") && (0, import_node_path25.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
18211
+ for (const rel of nested) readPackageJson((0, import_node_path25.join)(root, rel));
18078
18212
  const pythonManifests = [
18079
- ...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path24.join)(root, f)),
18080
- ...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path24.join)(root, f))
18213
+ ...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path25.join)(root, f)),
18214
+ ...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path25.join)(root, f))
18081
18215
  ];
18082
18216
  for (const path of pythonManifests) {
18083
- if (!(0, import_node_fs26.existsSync)(path)) continue;
18217
+ if (!(0, import_node_fs27.existsSync)(path)) continue;
18084
18218
  try {
18085
- const text = (0, import_node_fs26.readFileSync)(path, "utf-8");
18219
+ const text = (0, import_node_fs27.readFileSync)(path, "utf-8");
18086
18220
  for (const m of text.matchAll(/^\s*["']?([A-Za-z][A-Za-z0-9._-]+)/gm)) names2.push(m[1]);
18087
18221
  for (const line of text.split("\n")) {
18088
18222
  if (!/dependencies\s*=/.test(line)) continue;
@@ -18092,13 +18226,13 @@ function declaredDependencies(root, files) {
18092
18226
  }
18093
18227
  }
18094
18228
  const goMods = [
18095
- (0, import_node_path24.join)(root, "go.mod"),
18096
- ...files.filter((f) => f.includes("/") && (0, import_node_path24.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path24.join)(root, f))
18229
+ (0, import_node_path25.join)(root, "go.mod"),
18230
+ ...files.filter((f) => f.includes("/") && (0, import_node_path25.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path25.join)(root, f))
18097
18231
  ];
18098
18232
  for (const path of goMods) {
18099
- if (!(0, import_node_fs26.existsSync)(path)) continue;
18233
+ if (!(0, import_node_fs27.existsSync)(path)) continue;
18100
18234
  try {
18101
- const text = (0, import_node_fs26.readFileSync)(path, "utf-8");
18235
+ const text = (0, import_node_fs27.readFileSync)(path, "utf-8");
18102
18236
  for (const m of text.matchAll(/^\s+([\w.-]+\/[\w./-]+)\s+v/gm)) {
18103
18237
  names2.push(m[1].replace(/^github\.com\//, ""));
18104
18238
  }
@@ -18106,10 +18240,10 @@ function declaredDependencies(root, files) {
18106
18240
  }
18107
18241
  }
18108
18242
  for (const file of ["pom.xml", "build.gradle", "build.gradle.kts", "Gemfile", "Cargo.toml"]) {
18109
- const path = (0, import_node_path24.join)(root, file);
18110
- if (!(0, import_node_fs26.existsSync)(path)) continue;
18243
+ const path = (0, import_node_path25.join)(root, file);
18244
+ if (!(0, import_node_fs27.existsSync)(path)) continue;
18111
18245
  try {
18112
- const text = (0, import_node_fs26.readFileSync)(path, "utf-8");
18246
+ const text = (0, import_node_fs27.readFileSync)(path, "utf-8");
18113
18247
  for (const m of text.matchAll(/["'<]([A-Za-z][A-Za-z0-9._-]{2,})["'>]/g)) names2.push(m[1]);
18114
18248
  } catch {
18115
18249
  }
@@ -18117,7 +18251,7 @@ function declaredDependencies(root, files) {
18117
18251
  return names2;
18118
18252
  }
18119
18253
  function detectBuildSystem(root, files) {
18120
- const has = (f) => (0, import_node_fs26.existsSync)((0, import_node_path24.join)(root, f)) || files.some((p) => (0, import_node_path24.basename)(p) === f);
18254
+ const has = (f) => (0, import_node_fs27.existsSync)((0, import_node_path25.join)(root, f)) || files.some((p) => (0, import_node_path25.basename)(p) === f);
18121
18255
  if (has("pnpm-lock.yaml")) return "pnpm";
18122
18256
  if (has("yarn.lock")) return "yarn";
18123
18257
  if (has("bun.lock") || has("bun.lockb")) return "bun";
@@ -18134,8 +18268,8 @@ function detectBuildSystem(root, files) {
18134
18268
  }
18135
18269
  function detectArchitecture(root, files) {
18136
18270
  const workspaceMarkers = ["lerna.json", "pnpm-workspace.yaml", "nx.json", "turbo.json", "rush.json"];
18137
- if (workspaceMarkers.some((m) => (0, import_node_fs26.existsSync)((0, import_node_path24.join)(root, m)))) return "monorepo";
18138
- const pkg = readJson((0, import_node_path24.join)(root, "package.json"));
18271
+ if (workspaceMarkers.some((m) => (0, import_node_fs27.existsSync)((0, import_node_path25.join)(root, m)))) return "monorepo";
18272
+ const pkg = readJson2((0, import_node_path25.join)(root, "package.json"));
18139
18273
  if (pkg && "workspaces" in pkg) return "monorepo";
18140
18274
  const manifests = files.filter((f) => /(^|\/)(package\.json|go\.mod|pyproject\.toml|Cargo\.toml|pom\.xml)$/.test(f));
18141
18275
  const nested = manifests.filter((f) => f.includes("/"));
@@ -18157,10 +18291,10 @@ function measureAvgFileLength(root, files, languages) {
18157
18291
  let total = 0;
18158
18292
  let counted = 0;
18159
18293
  for (let i = 0; i < candidates2.length; i += stride) {
18160
- const path = (0, import_node_path24.join)(root, candidates2[i]);
18294
+ const path = (0, import_node_path25.join)(root, candidates2[i]);
18161
18295
  try {
18162
- if ((0, import_node_fs26.statSync)(path).size > 2 * 1024 * 1024) continue;
18163
- total += (0, import_node_fs26.readFileSync)(path, "utf-8").split("\n").length;
18296
+ if ((0, import_node_fs27.statSync)(path).size > 2 * 1024 * 1024) continue;
18297
+ total += (0, import_node_fs27.readFileSync)(path, "utf-8").split("\n").length;
18164
18298
  counted++;
18165
18299
  } catch {
18166
18300
  }
@@ -18190,14 +18324,14 @@ function detectProject(root = repoRoot()) {
18190
18324
  const existingToolConfigs = [];
18191
18325
  for (const [tool, markers] of TOOL_CONFIG_MARKERS) {
18192
18326
  for (const marker of markers) {
18193
- if ((0, import_node_fs26.existsSync)((0, import_node_path24.join)(root, marker))) {
18327
+ if ((0, import_node_fs27.existsSync)((0, import_node_path25.join)(root, marker))) {
18194
18328
  existingToolConfigs.push({ tool, path: `./${marker}` });
18195
18329
  break;
18196
18330
  }
18197
18331
  }
18198
18332
  }
18199
18333
  return {
18200
- projectName: (0, import_node_path24.basename)(root),
18334
+ projectName: (0, import_node_path25.basename)(root),
18201
18335
  languages,
18202
18336
  languageCounts,
18203
18337
  frameworks: matchAll(dependencies, FRAMEWORK_BY_DEPENDENCY),
@@ -18295,8 +18429,8 @@ ${closingNote(input.origin)}
18295
18429
 
18296
18430
  // src/lib/synthesize.ts
18297
18431
  function loadCatalog() {
18298
- const catalog = (0, import_yaml.parse)((0, import_node_fs27.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
18299
- const template = (0, import_yaml.parse)((0, import_node_fs27.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
18432
+ const catalog = (0, import_yaml.parse)((0, import_node_fs28.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
18433
+ const template = (0, import_yaml.parse)((0, import_node_fs28.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
18300
18434
  return { catalog, template };
18301
18435
  }
18302
18436
  function selectTools(languages, intensity, catalog) {
@@ -18574,7 +18708,7 @@ function validatePatternIds() {
18574
18708
  }
18575
18709
  async function runSynthesis(opts) {
18576
18710
  const standardPath = projectPath(STANDARD_FILE);
18577
- if ((0, import_node_fs27.existsSync)(standardPath) && !opts.force) {
18711
+ if ((0, import_node_fs28.existsSync)(standardPath) && !opts.force) {
18578
18712
  return { refused: `${STANDARD_FILE} already exists \u2014 pass --force to replace it.` };
18579
18713
  }
18580
18714
  const detected = opts.detected ?? detectProject();
@@ -18643,7 +18777,7 @@ async function correctVerityMdVersion(opts) {
18643
18777
  }
18644
18778
  async function writeFileTo(relative3, body) {
18645
18779
  const target = projectPath(relative3);
18646
- await (0, import_promises10.mkdir)((0, import_node_path25.dirname)(target), { recursive: true });
18780
+ await (0, import_promises10.mkdir)((0, import_node_path26.dirname)(target), { recursive: true });
18647
18781
  await (0, import_promises10.writeFile)(target, body);
18648
18782
  }
18649
18783
  async function deriveConfigForStandard(standard) {
@@ -18702,11 +18836,11 @@ ${validation.detail}`);
18702
18836
 
18703
18837
  // src/lib/setup-state.ts
18704
18838
  var import_promises11 = require("node:fs/promises");
18705
- var import_node_fs28 = require("node:fs");
18839
+ var import_node_fs29 = require("node:fs");
18706
18840
  var SETUP_STATE_FILE = `${VERITY_DIR}/setup.json`;
18707
18841
  async function readSetupState() {
18708
18842
  const path = projectPath(SETUP_STATE_FILE);
18709
- if (!(0, import_node_fs28.existsSync)(path)) return null;
18843
+ if (!(0, import_node_fs29.existsSync)(path)) return null;
18710
18844
  try {
18711
18845
  const parsed = JSON.parse(await (0, import_promises11.readFile)(path, "utf-8"));
18712
18846
  return parsed && typeof parsed === "object" ? parsed : null;
@@ -18722,12 +18856,12 @@ async function writeSetupState(patch) {
18722
18856
  }
18723
18857
 
18724
18858
  // src/lib/push-setup.ts
18725
- var import_node_fs30 = require("node:fs");
18859
+ var import_node_fs31 = require("node:fs");
18726
18860
  var import_promises12 = require("node:fs/promises");
18727
18861
  var import_yaml2 = __toESM(require_dist());
18728
18862
 
18729
18863
  // src/lib/verityignore.ts
18730
- var import_node_fs29 = require("node:fs");
18864
+ var import_node_fs30 = require("node:fs");
18731
18865
  var EMPTY = { rules: [], securityOverlap: [], problems: [] };
18732
18866
  var SECURITY_PROBES = [
18733
18867
  ".env",
@@ -18820,9 +18954,9 @@ function isIgnored3(ig, path) {
18820
18954
  }
18821
18955
  function loadVerityIgnore() {
18822
18956
  const file = projectPath(VERITYIGNORE_FILE);
18823
- if (!(0, import_node_fs29.existsSync)(file)) return EMPTY;
18957
+ if (!(0, import_node_fs30.existsSync)(file)) return EMPTY;
18824
18958
  try {
18825
- return parseVerityIgnore((0, import_node_fs29.readFileSync)(file, "utf-8"));
18959
+ return parseVerityIgnore((0, import_node_fs30.readFileSync)(file, "utf-8"));
18826
18960
  } catch {
18827
18961
  return EMPTY;
18828
18962
  }
@@ -18860,9 +18994,9 @@ function buildStandardUpload(standard, ignoreRaw) {
18860
18994
  }
18861
18995
  function readVerityIgnoreRaw() {
18862
18996
  const file = projectPath(VERITYIGNORE_FILE);
18863
- if (!(0, import_node_fs29.existsSync)(file)) return null;
18997
+ if (!(0, import_node_fs30.existsSync)(file)) return null;
18864
18998
  try {
18865
- return (0, import_node_fs29.readFileSync)(file, "utf-8");
18999
+ return (0, import_node_fs30.readFileSync)(file, "utf-8");
18866
19000
  } catch {
18867
19001
  return null;
18868
19002
  }
@@ -18890,7 +19024,7 @@ async function pushStandardAndConfig(globals, what = {}) {
18890
19024
  }
18891
19025
  let standardVersion = null;
18892
19026
  const standardPath = projectPath(STANDARD_FILE);
18893
- if (pushStandard && (0, import_node_fs30.existsSync)(standardPath)) {
19027
+ if (pushStandard && (0, import_node_fs31.existsSync)(standardPath)) {
18894
19028
  try {
18895
19029
  const content = (0, import_yaml2.parse)(await (0, import_promises12.readFile)(standardPath, "utf-8"));
18896
19030
  const upload = buildStandardUpload(content, readVerityIgnoreRaw());
@@ -18915,7 +19049,7 @@ async function pushStandardAndConfig(globals, what = {}) {
18915
19049
  }
18916
19050
  let configPushed = false;
18917
19051
  const configPath = projectPath(CODACY_CONFIG_FILE);
18918
- if (pushConfig && (0, import_node_fs30.existsSync)(configPath)) {
19052
+ if (pushConfig && (0, import_node_fs31.existsSync)(configPath)) {
18919
19053
  try {
18920
19054
  const content = JSON.parse(await (0, import_promises12.readFile)(configPath, "utf-8"));
18921
19055
  const result = await apiRequest({
@@ -18947,7 +19081,7 @@ function registerStandardCommands(program2) {
18947
19081
  const state = await readSetupState();
18948
19082
  if (opts.configOnly) {
18949
19083
  const standardPath = projectPath(STANDARD_FILE);
18950
- if (!(0, import_node_fs31.existsSync)(standardPath)) {
19084
+ if (!(0, import_node_fs32.existsSync)(standardPath)) {
18951
19085
  printError(`No ${STANDARD_FILE} here \u2014 run "verity standard synthesize" to create one.`);
18952
19086
  process.exit(1);
18953
19087
  }
@@ -19280,10 +19414,10 @@ function formatRunDetail(run2) {
19280
19414
  }
19281
19415
 
19282
19416
  // src/lib/ignore-declaration.ts
19283
- var import_node_fs33 = require("node:fs");
19417
+ var import_node_fs34 = require("node:fs");
19284
19418
 
19285
19419
  // src/lib/debounce.ts
19286
- var import_node_fs32 = require("node:fs");
19420
+ var import_node_fs33 = require("node:fs");
19287
19421
  var import_node_crypto10 = require("node:crypto");
19288
19422
  function scopedFile(base, sessionId) {
19289
19423
  if (!sessionId) return base;
@@ -19291,9 +19425,9 @@ function scopedFile(base, sessionId) {
19291
19425
  }
19292
19426
  function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
19293
19427
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
19294
- if (!(0, import_node_fs32.existsSync)(file)) return null;
19428
+ if (!(0, import_node_fs33.existsSync)(file)) return null;
19295
19429
  try {
19296
- const lastTs = parseInt((0, import_node_fs32.readFileSync)(file, "utf-8").trim(), 10);
19430
+ const lastTs = parseInt((0, import_node_fs33.readFileSync)(file, "utf-8").trim(), 10);
19297
19431
  const nowTs = Math.floor(Date.now() / 1e3);
19298
19432
  const elapsed = nowTs - lastTs;
19299
19433
  if (elapsed < debounceSeconds) {
@@ -19306,10 +19440,10 @@ function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
19306
19440
  function checkMtime(files, bypassForRecentCommits, sessionId) {
19307
19441
  if (bypassForRecentCommits) return null;
19308
19442
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
19309
- if (!(0, import_node_fs32.existsSync)(file)) return null;
19443
+ if (!(0, import_node_fs33.existsSync)(file)) return null;
19310
19444
  let debounceTime;
19311
19445
  try {
19312
- debounceTime = (0, import_node_fs32.statSync)(file).mtimeMs;
19446
+ debounceTime = (0, import_node_fs33.statSync)(file).mtimeMs;
19313
19447
  } catch {
19314
19448
  return null;
19315
19449
  }
@@ -19317,7 +19451,7 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
19317
19451
  const resolved = resolveFile(f);
19318
19452
  if (!resolved) continue;
19319
19453
  try {
19320
- const stat3 = (0, import_node_fs32.statSync)(resolved);
19454
+ const stat3 = (0, import_node_fs33.statSync)(resolved);
19321
19455
  if (stat3.mtimeMs > debounceTime) {
19322
19456
  return null;
19323
19457
  }
@@ -19333,8 +19467,8 @@ function computeContentHash(files) {
19333
19467
  for (const f of sorted) {
19334
19468
  const resolved = resolveFile(f) ?? f;
19335
19469
  try {
19336
- if ((0, import_node_fs32.existsSync)(resolved)) {
19337
- hash.update((0, import_node_fs32.readFileSync)(resolved));
19470
+ if ((0, import_node_fs33.existsSync)(resolved)) {
19471
+ hash.update((0, import_node_fs33.readFileSync)(resolved));
19338
19472
  }
19339
19473
  } catch {
19340
19474
  }
@@ -19344,9 +19478,9 @@ function computeContentHash(files) {
19344
19478
  function checkContentHash(files, sessionId) {
19345
19479
  const hash = computeContentHash(files);
19346
19480
  const file = scopedFile(HASH_FILE, sessionId);
19347
- if ((0, import_node_fs32.existsSync)(file)) {
19481
+ if ((0, import_node_fs33.existsSync)(file)) {
19348
19482
  try {
19349
- const storedHash = (0, import_node_fs32.readFileSync)(file, "utf-8").trim();
19483
+ const storedHash = (0, import_node_fs33.readFileSync)(file, "utf-8").trim();
19350
19484
  if (hash === storedHash) {
19351
19485
  return { skip: "No source changes since last analysis", hash };
19352
19486
  }
@@ -19356,24 +19490,24 @@ function checkContentHash(files, sessionId) {
19356
19490
  return { skip: null, hash };
19357
19491
  }
19358
19492
  function recordAnalysisStart(sessionId) {
19359
- (0, import_node_fs32.mkdirSync)(VERITY_DIR, { recursive: true });
19360
- (0, import_node_fs32.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
19493
+ (0, import_node_fs33.mkdirSync)(VERITY_DIR, { recursive: true });
19494
+ (0, import_node_fs33.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
19361
19495
  }
19362
19496
  function recordPassHash(hash, sessionId) {
19363
- (0, import_node_fs32.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
19497
+ (0, import_node_fs33.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
19364
19498
  }
19365
19499
  function narrowToRecent(files, sessionId) {
19366
19500
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
19367
- if (!(0, import_node_fs32.existsSync)(file)) return files;
19501
+ if (!(0, import_node_fs33.existsSync)(file)) return files;
19368
19502
  let debounceTime;
19369
19503
  try {
19370
- debounceTime = (0, import_node_fs32.statSync)(file).mtimeMs;
19504
+ debounceTime = (0, import_node_fs33.statSync)(file).mtimeMs;
19371
19505
  } catch {
19372
19506
  return files;
19373
19507
  }
19374
19508
  const recent = files.filter((f) => {
19375
19509
  try {
19376
- return (0, import_node_fs32.existsSync)(f) && (0, import_node_fs32.statSync)(f).mtimeMs > debounceTime;
19510
+ return (0, import_node_fs33.existsSync)(f) && (0, import_node_fs33.statSync)(f).mtimeMs > debounceTime;
19377
19511
  } catch {
19378
19512
  return false;
19379
19513
  }
@@ -19386,9 +19520,9 @@ function readIteration(currentCommit, _contentHash) {
19386
19520
  var NO_BLOCKS = { attempts: 0, blocks: 0, fingerprint: null };
19387
19521
  function readBlockState(currentCommit, opts) {
19388
19522
  if (opts?.newUserPrompt) return NO_BLOCKS;
19389
- if (!(0, import_node_fs32.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
19523
+ if (!(0, import_node_fs33.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
19390
19524
  try {
19391
- const stored = (0, import_node_fs32.readFileSync)(ITERATION_FILE, "utf-8").trim();
19525
+ const stored = (0, import_node_fs33.readFileSync)(ITERATION_FILE, "utf-8").trim();
19392
19526
  const parsed = stored.startsWith("{") ? parseJsonState(stored) : parseLegacyState(stored);
19393
19527
  if (!parsed) return NO_BLOCKS;
19394
19528
  if (parsed.commit !== currentCommit) return NO_BLOCKS;
@@ -19434,8 +19568,8 @@ function isSameProblem(previous, current) {
19434
19568
  return current.split(",").some((k) => prev.has(k));
19435
19569
  }
19436
19570
  function writeBlockState(commit, state) {
19437
- (0, import_node_fs32.mkdirSync)(VERITY_DIR, { recursive: true });
19438
- (0, import_node_fs32.writeFileSync)(
19571
+ (0, import_node_fs33.mkdirSync)(VERITY_DIR, { recursive: true });
19572
+ (0, import_node_fs33.writeFileSync)(
19439
19573
  ITERATION_FILE,
19440
19574
  JSON.stringify({
19441
19575
  v: 2,
@@ -19540,9 +19674,9 @@ function resolveIgnoreState(keys) {
19540
19674
  }
19541
19675
  function readIgnoreState(sessionId) {
19542
19676
  const file = stateFile(sessionId);
19543
- if (!(0, import_node_fs33.existsSync)(file)) return null;
19677
+ if (!(0, import_node_fs34.existsSync)(file)) return null;
19544
19678
  try {
19545
- const o = JSON.parse((0, import_node_fs33.readFileSync)(file, "utf-8")) ?? {};
19679
+ const o = JSON.parse((0, import_node_fs34.readFileSync)(file, "utf-8")) ?? {};
19546
19680
  const spent = typeof o.spent === "number" ? o.spent : 0;
19547
19681
  const raw = o.active;
19548
19682
  let active = null;
@@ -19566,8 +19700,8 @@ function readIgnoreState(sessionId) {
19566
19700
  }
19567
19701
  function writeIgnoreState(state, sessionId) {
19568
19702
  try {
19569
- (0, import_node_fs33.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
19570
- (0, import_node_fs33.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
19703
+ (0, import_node_fs34.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
19704
+ (0, import_node_fs34.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
19571
19705
  } catch {
19572
19706
  }
19573
19707
  }
@@ -19950,15 +20084,15 @@ function createRun(opts, globals) {
19950
20084
  }
19951
20085
 
19952
20086
  // src/commands/analyze/index.ts
19953
- var import_node_fs46 = require("node:fs");
20087
+ var import_node_fs47 = require("node:fs");
19954
20088
 
19955
20089
  // src/lib/repo-context.ts
19956
20090
  var import_node_child_process10 = require("node:child_process");
19957
- var import_node_os4 = require("node:os");
20091
+ var import_node_os5 = require("node:os");
19958
20092
  function rgInvocations(env = process.env) {
19959
20093
  const out = [{ cmd: "rg" }];
19960
20094
  if (env.CLAUDE_CODE_EXECPATH) out.push({ cmd: env.CLAUDE_CODE_EXECPATH, argv0: "rg" });
19961
- out.push({ cmd: `${(0, import_node_os4.homedir)()}/.local/bin/claude`, argv0: "rg" });
20095
+ out.push({ cmd: `${(0, import_node_os5.homedir)()}/.local/bin/claude`, argv0: "rg" });
19962
20096
  return out;
19963
20097
  }
19964
20098
  function ripgrepEnv(base = process.env) {
@@ -20886,10 +21020,10 @@ function installRunEvidence(run2) {
20886
21020
  }
20887
21021
 
20888
21022
  // src/lib/git-frame.ts
20889
- var import_node_fs34 = require("node:fs");
20890
- var import_node_os5 = require("node:os");
20891
- var import_node_path26 = require("node:path");
21023
+ var import_node_fs35 = require("node:fs");
21024
+ var import_node_os6 = require("node:os");
20892
21025
  var import_node_path27 = require("node:path");
21026
+ var import_node_path28 = require("node:path");
20893
21027
 
20894
21028
  // src/lib/hardened-git.ts
20895
21029
  var import_node_child_process11 = require("node:child_process");
@@ -21044,15 +21178,15 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
21044
21178
  if (!m) continue;
21045
21179
  named = true;
21046
21180
  if (m[1] === void 0) {
21047
- dir = (0, import_node_os5.homedir)();
21181
+ dir = (0, import_node_os6.homedir)();
21048
21182
  continue;
21049
21183
  }
21050
21184
  const raw = unquote(m[1]);
21051
21185
  if (SHELL_DYNAMIC.test(raw) || raw === "-") {
21052
21186
  return { dir: null, named: true, unresolvable: `cd target not statically resolvable: ${raw}` };
21053
21187
  }
21054
- const expanded = raw === "~" ? (0, import_node_os5.homedir)() : raw.startsWith("~/") ? (0, import_node_path27.join)((0, import_node_os5.homedir)(), raw.slice(2)) : raw;
21055
- dir = (0, import_node_path26.isAbsolute)(expanded) ? expanded : (0, import_node_path26.resolve)(dir, expanded);
21188
+ const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path28.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
21189
+ dir = (0, import_node_path27.isAbsolute)(expanded) ? expanded : (0, import_node_path27.resolve)(dir, expanded);
21056
21190
  }
21057
21191
  const seg = segments[segmentIndex];
21058
21192
  const overrideMatch = /--(?:git-dir|work-tree)(?:=|\s)|\bGIT_(?:DIR|WORK_TREE|INDEX_FILE)=/.exec(seg);
@@ -21070,8 +21204,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
21070
21204
  if (SHELL_DYNAMIC.test(raw)) {
21071
21205
  return { dir: null, named: true, unresolvable: `-C target not statically resolvable: ${raw}` };
21072
21206
  }
21073
- const expanded = raw === "~" ? (0, import_node_os5.homedir)() : raw.startsWith("~/") ? (0, import_node_path27.join)((0, import_node_os5.homedir)(), raw.slice(2)) : raw;
21074
- dir = (0, import_node_path26.isAbsolute)(expanded) ? expanded : (0, import_node_path26.resolve)(dir, expanded);
21207
+ const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path28.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
21208
+ dir = (0, import_node_path27.isAbsolute)(expanded) ? expanded : (0, import_node_path27.resolve)(dir, expanded);
21075
21209
  }
21076
21210
  }
21077
21211
  return { dir, named, unresolvable: null };
@@ -21131,14 +21265,14 @@ function gitAt(dir, args) {
21131
21265
  }
21132
21266
  function realpathOr2(p) {
21133
21267
  try {
21134
- return import_node_fs34.realpathSync.native(p);
21268
+ return import_node_fs35.realpathSync.native(p);
21135
21269
  } catch {
21136
- return (0, import_node_path26.resolve)(p);
21270
+ return (0, import_node_path27.resolve)(p);
21137
21271
  }
21138
21272
  }
21139
21273
  function resolveFrame(input) {
21140
21274
  const found = findMomentSegment(input.command, input.on);
21141
- const hookDirUsable = !!input.hookCwd && (0, import_node_fs34.existsSync)(input.hookCwd);
21275
+ const hookDirUsable = !!input.hookCwd && (0, import_node_fs35.existsSync)(input.hookCwd);
21142
21276
  const baseDir = hookDirUsable ? input.hookCwd : process.cwd();
21143
21277
  let anchor = hookDirUsable ? "hook-cwd" : "process-cwd";
21144
21278
  const refuse = (refusal) => ({
@@ -21161,7 +21295,7 @@ function resolveFrame(input) {
21161
21295
  if (dirs.size > 1) return refuse(`target:multiple ${found.moment} targets in one command`);
21162
21296
  const targetDir = dirs.size === 1 ? [...dirs][0] : baseDir;
21163
21297
  if (targetDir !== baseDir) {
21164
- if (!(0, import_node_fs34.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
21298
+ if (!(0, import_node_fs35.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
21165
21299
  dir = targetDir;
21166
21300
  }
21167
21301
  }
@@ -21172,7 +21306,7 @@ function resolveFrame(input) {
21172
21306
  const gitDirRaw = gitAt(dir, ["rev-parse", "--absolute-git-dir"]);
21173
21307
  const commonRaw = gitAt(dir, ["rev-parse", "--git-common-dir"]);
21174
21308
  const gitDir = gitDirRaw ? realpathOr2(gitDirRaw) : null;
21175
- const commonDir = commonRaw ? realpathOr2((0, import_node_path26.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path26.resolve)(dir, commonRaw)) : null;
21309
+ const commonDir = commonRaw ? realpathOr2((0, import_node_path27.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path27.resolve)(dir, commonRaw)) : null;
21176
21310
  const branchRaw = gitAt(dir, ["rev-parse", "--abbrev-ref", "HEAD"]);
21177
21311
  return {
21178
21312
  moment: found?.moment ?? null,
@@ -21347,8 +21481,8 @@ function stagedRange(frame, command) {
21347
21481
  if (plan.kind === "unpredictable") {
21348
21482
  return { kind: "staged", base: "HEAD", head: "INDEX", via: "staged-in-command", refusal: plan.reason };
21349
21483
  }
21350
- const mergeHead = frame.gitDir ? (0, import_node_path27.join)(frame.gitDir, "MERGE_HEAD") : null;
21351
- if (mergeHead && (0, import_node_fs34.existsSync)(mergeHead)) {
21484
+ const mergeHead = frame.gitDir ? (0, import_node_path28.join)(frame.gitDir, "MERGE_HEAD") : null;
21485
+ if (mergeHead && (0, import_node_fs35.existsSync)(mergeHead)) {
21352
21486
  const vsHead = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "HEAD"]).split("\n").filter(Boolean));
21353
21487
  const vsMerge = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "MERGE_HEAD"]).split("\n").filter(Boolean));
21354
21488
  const resolutions = new Set([...vsHead].filter((f) => vsMerge.has(f) && !isVerityOwnedPath(f)));
@@ -21482,7 +21616,7 @@ function truthy(v) {
21482
21616
  }
21483
21617
 
21484
21618
  // src/lib/transcript.ts
21485
- var import_node_fs35 = require("node:fs");
21619
+ var import_node_fs36 = require("node:fs");
21486
21620
  var MAX_READ_BYTES = 256 * 1024;
21487
21621
  var SMALL_FILE_BYTES = 64 * 1024;
21488
21622
  var MAX_FILES_LIST = 20;
@@ -21509,7 +21643,7 @@ async function extractActionSummary(transcriptPath) {
21509
21643
  function readTurnLines(transcriptPath) {
21510
21644
  let size;
21511
21645
  try {
21512
- size = (0, import_node_fs35.statSync)(transcriptPath).size;
21646
+ size = (0, import_node_fs36.statSync)(transcriptPath).size;
21513
21647
  } catch {
21514
21648
  return null;
21515
21649
  }
@@ -21517,7 +21651,7 @@ function readTurnLines(transcriptPath) {
21517
21651
  let raw;
21518
21652
  let windowed = false;
21519
21653
  if (size <= SMALL_FILE_BYTES) {
21520
- raw = (0, import_node_fs35.readFileSync)(transcriptPath, "utf-8");
21654
+ raw = (0, import_node_fs36.readFileSync)(transcriptPath, "utf-8");
21521
21655
  } else {
21522
21656
  windowed = true;
21523
21657
  const buf = Buffer.alloc(Math.min(MAX_READ_BYTES, size));
@@ -22025,7 +22159,7 @@ function channelSilence(input) {
22025
22159
  // src/lib/cli-version.ts
22026
22160
  function cliVersion() {
22027
22161
  try {
22028
- return true ? "0.33.1-experimental.4a41d04" : "dev";
22162
+ return true ? "0.33.2-experimental.0c53bed" : "dev";
22029
22163
  } catch {
22030
22164
  return "dev";
22031
22165
  }
@@ -22066,7 +22200,7 @@ async function sendSkipBeacon(ctx, reason) {
22066
22200
 
22067
22201
  // src/lib/static-analysis.ts
22068
22202
  var import_node_child_process12 = require("node:child_process");
22069
- var import_node_fs36 = require("node:fs");
22203
+ var import_node_fs37 = require("node:fs");
22070
22204
  var SEVERITY_ORDER = {
22071
22205
  Error: 0,
22072
22206
  Critical: 0,
@@ -22122,7 +22256,7 @@ function runCodacyAnalysis(files) {
22122
22256
  if (files.length === 0) return empty;
22123
22257
  const existingFiles = files.filter((f) => {
22124
22258
  try {
22125
- return (0, import_node_fs36.existsSync)(f);
22259
+ return (0, import_node_fs37.existsSync)(f);
22126
22260
  } catch {
22127
22261
  return false;
22128
22262
  }
@@ -22391,8 +22525,8 @@ async function scope(run2) {
22391
22525
  }
22392
22526
 
22393
22527
  // src/lib/specs.ts
22394
- var import_node_fs37 = require("node:fs");
22395
- var import_node_path28 = require("node:path");
22528
+ var import_node_fs38 = require("node:fs");
22529
+ var import_node_path29 = require("node:path");
22396
22530
  var SPEC_CANDIDATES = [
22397
22531
  "CLAUDE.md",
22398
22532
  "AGENTS.md",
@@ -22414,7 +22548,7 @@ var UNCONSULTED_TOTAL_BYTES = 30720;
22414
22548
  function readSpecFiles(specsOpt, root) {
22415
22549
  const out = [];
22416
22550
  for (const raw of specsOpt.split(",").map((f) => f.trim()).filter(Boolean)) {
22417
- const candidate = (0, import_node_path28.isAbsolute)(raw) ? (0, import_node_path28.relative)(root, raw) : raw;
22551
+ const candidate = (0, import_node_path29.isAbsolute)(raw) ? (0, import_node_path29.relative)(root, raw) : raw;
22418
22552
  const content = readFileInside(root, candidate, MAX_EXPLICIT_SPEC_FILE_BYTES);
22419
22553
  if (content === null) continue;
22420
22554
  out.push({ path: raw, content });
@@ -22433,7 +22567,7 @@ function discoverSpecs(consulted = []) {
22433
22567
  const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
22434
22568
  if (totalBytes >= totalCap) return false;
22435
22569
  if (seen.has(specPath)) return true;
22436
- if (!(0, import_node_fs37.existsSync)(specPath)) return true;
22570
+ if (!(0, import_node_fs38.existsSync)(specPath)) return true;
22437
22571
  seen.add(specPath);
22438
22572
  const remaining = totalCap - totalBytes;
22439
22573
  const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
@@ -22456,7 +22590,7 @@ function discoverSpecs(consulted = []) {
22456
22590
  if (!addSpec(candidate)) break;
22457
22591
  }
22458
22592
  for (const dir of ["spec", "docs"]) {
22459
- if (!(0, import_node_fs37.existsSync)(dir)) continue;
22593
+ if (!(0, import_node_fs38.existsSync)(dir)) continue;
22460
22594
  try {
22461
22595
  const mdFiles = findMdFiles(dir, 2).sort();
22462
22596
  for (const mdFile of mdFiles) {
@@ -22471,9 +22605,9 @@ function findMdFiles(dir, maxDepth, depth = 0) {
22471
22605
  if (depth >= maxDepth) return [];
22472
22606
  const result = [];
22473
22607
  try {
22474
- const entries = (0, import_node_fs37.readdirSync)(dir, { withFileTypes: true });
22608
+ const entries = (0, import_node_fs38.readdirSync)(dir, { withFileTypes: true });
22475
22609
  for (const entry of entries) {
22476
- const fullPath = (0, import_node_path28.join)(dir, entry.name);
22610
+ const fullPath = (0, import_node_path29.join)(dir, entry.name);
22477
22611
  if (entry.isFile() && entry.name.endsWith(".md")) {
22478
22612
  result.push(fullPath);
22479
22613
  } else if (entry.isDirectory() && depth < maxDepth - 1) {
@@ -22486,25 +22620,25 @@ function findMdFiles(dir, maxDepth, depth = 0) {
22486
22620
  }
22487
22621
  function discoverPlans() {
22488
22622
  const home = process.env.HOME ?? "";
22489
- const homePlansDir = (0, import_node_path28.join)(home, ".claude", "plans");
22623
+ const homePlansDir = (0, import_node_path29.join)(home, ".claude", "plans");
22490
22624
  const sources = [];
22491
22625
  if (isRealDirectoryChain(process.cwd(), [".claude", "plans"])) {
22492
- sources.push({ root: process.cwd(), prefix: (0, import_node_path28.join)(".claude", "plans") });
22626
+ sources.push({ root: process.cwd(), prefix: (0, import_node_path29.join)(".claude", "plans") });
22493
22627
  }
22494
- if (home && (0, import_node_fs37.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
22628
+ if (home && (0, import_node_fs38.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
22495
22629
  const candidates2 = [];
22496
22630
  const seen = /* @__PURE__ */ new Set();
22497
22631
  for (const source of sources) {
22498
22632
  let names2;
22499
22633
  try {
22500
- names2 = (0, import_node_fs37.readdirSync)(source.prefix ? (0, import_node_path28.join)(source.root, source.prefix) : source.root);
22634
+ names2 = (0, import_node_fs38.readdirSync)(source.prefix ? (0, import_node_path29.join)(source.root, source.prefix) : source.root);
22501
22635
  } catch {
22502
22636
  continue;
22503
22637
  }
22504
22638
  for (const f of names2) {
22505
22639
  if (!f.endsWith(".md") || seen.has(f)) continue;
22506
22640
  seen.add(f);
22507
- const relPath = source.prefix ? (0, import_node_path28.join)(source.prefix, f) : f;
22641
+ const relPath = source.prefix ? (0, import_node_path29.join)(source.prefix, f) : f;
22508
22642
  const stat3 = statRegularInRoot(source.root, relPath);
22509
22643
  if (!stat3.ok) continue;
22510
22644
  candidates2.push({ name: f, root: source.root, relPath, mtime: stat3.mtimeMs, size: stat3.size });
@@ -22522,9 +22656,9 @@ function discoverPlans() {
22522
22656
  function isRealDirectoryChain(root, parts) {
22523
22657
  let current = root;
22524
22658
  for (const part of parts) {
22525
- current = (0, import_node_path28.join)(current, part);
22659
+ current = (0, import_node_path29.join)(current, part);
22526
22660
  try {
22527
- if (!(0, import_node_fs37.lstatSync)(current).isDirectory()) return false;
22661
+ if (!(0, import_node_fs38.lstatSync)(current).isDirectory()) return false;
22528
22662
  } catch {
22529
22663
  return false;
22530
22664
  }
@@ -22539,7 +22673,7 @@ function discoverGuardDocs(rangeFiles2) {
22539
22673
  if (result.length >= MAX_SPEC_FILES) break;
22540
22674
  if (!GUARD_DOC_EXT.test(path)) continue;
22541
22675
  if (path.startsWith("/") || path.includes("..")) continue;
22542
- if (!(0, import_node_fs37.existsSync)(path)) continue;
22676
+ if (!(0, import_node_fs38.existsSync)(path)) continue;
22543
22677
  const opened = openRegularInRoot(process.cwd(), path);
22544
22678
  if (!opened.ok) continue;
22545
22679
  if (opened.size > MAX_PLAN_FILE_BYTES || totalBytes + opened.size > MAX_TOTAL_SPEC_BYTES) {
@@ -22725,8 +22859,8 @@ async function mode(run2) {
22725
22859
  }
22726
22860
 
22727
22861
  // src/lib/fold.ts
22728
- var import_node_fs38 = require("node:fs");
22729
- var import_node_path29 = require("node:path");
22862
+ var import_node_fs39 = require("node:fs");
22863
+ var import_node_path30 = require("node:path");
22730
22864
  var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
22731
22865
  "user",
22732
22866
  "assistant",
@@ -22863,7 +22997,7 @@ function candidateRoots(repoRoot2) {
22863
22997
  const norm = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
22864
22998
  const out = [norm];
22865
22999
  try {
22866
- const real = import_node_fs38.realpathSync.native(norm).replace(/\\/g, "/").replace(/\/+$/, "");
23000
+ const real = import_node_fs39.realpathSync.native(norm).replace(/\\/g, "/").replace(/\/+$/, "");
22867
23001
  if (real !== norm) out.push(real);
22868
23002
  } catch {
22869
23003
  }
@@ -22951,31 +23085,31 @@ function fold(transcriptPath, opts = {}) {
22951
23085
  }
22952
23086
  };
22953
23087
  try {
22954
- if (!(0, import_node_fs38.existsSync)(transcriptPath)) return result;
22955
- ingest((0, import_node_fs38.readFileSync)(transcriptPath, "utf8"), "agent");
23088
+ if (!(0, import_node_fs39.existsSync)(transcriptPath)) return result;
23089
+ ingest((0, import_node_fs39.readFileSync)(transcriptPath, "utf8"), "agent");
22956
23090
  result.coverage.complete = true;
22957
23091
  } catch {
22958
23092
  return result;
22959
23093
  }
22960
23094
  try {
22961
- const sidecarDir = (0, import_node_path29.join)(
22962
- (0, import_node_path29.dirname)(transcriptPath),
22963
- (0, import_node_path29.basename)(transcriptPath).replace(/\.jsonl$/, ""),
23095
+ const sidecarDir = (0, import_node_path30.join)(
23096
+ (0, import_node_path30.dirname)(transcriptPath),
23097
+ (0, import_node_path30.basename)(transcriptPath).replace(/\.jsonl$/, ""),
22964
23098
  "subagents"
22965
23099
  );
22966
- if ((0, import_node_fs38.existsSync)(sidecarDir)) {
23100
+ if ((0, import_node_fs39.existsSync)(sidecarDir)) {
22967
23101
  const maxFiles = opts.maxSidecars ?? 200;
22968
23102
  const maxBytes = opts.maxSidecarBytes ?? 16 * 1024 * 1024;
22969
23103
  const found = [];
22970
23104
  const walk2 = (d, depth) => {
22971
23105
  if (depth > 4) return;
22972
- for (const e of (0, import_node_fs38.readdirSync)(d, { withFileTypes: true })) {
22973
- const p = (0, import_node_path29.join)(d, e.name);
23106
+ for (const e of (0, import_node_fs39.readdirSync)(d, { withFileTypes: true })) {
23107
+ const p = (0, import_node_path30.join)(d, e.name);
22974
23108
  if (e.isDirectory()) {
22975
23109
  walk2(p, depth + 1);
22976
23110
  } else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
22977
23111
  try {
22978
- const st = (0, import_node_fs38.statSync)(p);
23112
+ const st = (0, import_node_fs39.statSync)(p);
22979
23113
  found.push({ path: p, size: st.size, mtimeMs: st.mtimeMs });
22980
23114
  } catch {
22981
23115
  result.coverage.malformed++;
@@ -22992,7 +23126,7 @@ function fold(transcriptPath, opts = {}) {
22992
23126
  continue;
22993
23127
  }
22994
23128
  try {
22995
- ingest((0, import_node_fs38.readFileSync)(f.path, "utf8"), "subagent");
23129
+ ingest((0, import_node_fs39.readFileSync)(f.path, "utf8"), "subagent");
22996
23130
  bytes += f.size;
22997
23131
  result.coverage.subagentFiles++;
22998
23132
  } catch {
@@ -23027,7 +23161,7 @@ function fold(transcriptPath, opts = {}) {
23027
23161
  }
23028
23162
  function classifyUnobserved(path) {
23029
23163
  try {
23030
- const st = (0, import_node_fs38.statSync)(path);
23164
+ const st = (0, import_node_fs39.statSync)(path);
23031
23165
  if (!st.isFile()) return "unreadable";
23032
23166
  } catch {
23033
23167
  return "unreadable";
@@ -23342,20 +23476,20 @@ async function evidence(run2) {
23342
23476
  }
23343
23477
 
23344
23478
  // src/lib/cache-cleanup.ts
23345
- var import_node_fs39 = require("node:fs");
23346
- var import_node_path30 = require("node:path");
23479
+ var import_node_fs40 = require("node:fs");
23480
+ var import_node_path31 = require("node:path");
23347
23481
  var CACHE_TTL_DAYS = 7;
23348
23482
  function pruneStaleCache() {
23349
23483
  try {
23350
23484
  const dir = projectPath(CACHE_DIR);
23351
23485
  const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
23352
- for (const entry of (0, import_node_fs39.readdirSync)(dir)) {
23486
+ for (const entry of (0, import_node_fs40.readdirSync)(dir)) {
23353
23487
  if (!entry.startsWith("pending-")) continue;
23354
- const path = (0, import_node_path30.join)(dir, entry);
23488
+ const path = (0, import_node_path31.join)(dir, entry);
23355
23489
  try {
23356
- const stat3 = (0, import_node_fs39.statSync)(path);
23490
+ const stat3 = (0, import_node_fs40.statSync)(path);
23357
23491
  if (stat3.mtimeMs < cutoff) {
23358
- (0, import_node_fs39.unlinkSync)(path);
23492
+ (0, import_node_fs40.unlinkSync)(path);
23359
23493
  logEvent("cache_entry_pruned", {
23360
23494
  path: entry,
23361
23495
  age_days: Math.round((Date.now() - stat3.mtimeMs) / 864e5)
@@ -23369,8 +23503,8 @@ function pruneStaleCache() {
23369
23503
  }
23370
23504
 
23371
23505
  // src/lib/context-files.ts
23372
- var import_node_fs40 = require("node:fs");
23373
- var import_node_os6 = require("node:os");
23506
+ var import_node_fs41 = require("node:fs");
23507
+ var import_node_os7 = require("node:os");
23374
23508
  var MAX_CONTEXT_FILES = 10;
23375
23509
  var MAX_CONTEXT_FILE_BYTES = 10240;
23376
23510
  var MAX_CONTEXT_TOTAL_BYTES = 24576;
@@ -23378,7 +23512,7 @@ function readSetContextPaths(summary, deltaFiles) {
23378
23512
  const reads = summary?.files_read ?? [];
23379
23513
  if (reads.length === 0) return [];
23380
23514
  const root = process.cwd().replace(/\/+$/, "");
23381
- const home = (0, import_node_os6.homedir)();
23515
+ const home = (0, import_node_os7.homedir)();
23382
23516
  const toRepoRelative2 = (p) => {
23383
23517
  if (!p) return null;
23384
23518
  let abs;
@@ -23427,7 +23561,7 @@ function gatherContextFiles(contextPaths, deltaFiles, opts) {
23427
23561
  continue;
23428
23562
  }
23429
23563
  try {
23430
- const content = (0, import_node_fs40.readFileSync)(safePath, "utf8");
23564
+ const content = (0, import_node_fs41.readFileSync)(safePath, "utf8");
23431
23565
  const bytes = Buffer.byteLength(content);
23432
23566
  if (bytes > MAX_CONTEXT_FILE_BYTES) {
23433
23567
  logEvent("context_file_skipped", { path: filePath, reason: "too_large", bytes });
@@ -23519,8 +23653,8 @@ async function repoContext(run2) {
23519
23653
 
23520
23654
  // src/lib/seed-runner.ts
23521
23655
  var import_promises15 = require("node:fs/promises");
23522
- var import_node_fs41 = require("node:fs");
23523
- var import_node_path31 = require("node:path");
23656
+ var import_node_fs42 = require("node:fs");
23657
+ var import_node_path32 = require("node:path");
23524
23658
  var import_yaml4 = __toESM(require_dist());
23525
23659
 
23526
23660
  // src/lib/seed.ts
@@ -23759,7 +23893,7 @@ function renderNodeMarkdown(candidate, nodeId, createdAt) {
23759
23893
  return fm;
23760
23894
  }
23761
23895
  async function runSeed(opts) {
23762
- if (!(0, import_node_fs41.existsSync)(STANDARD_FILE)) {
23896
+ if (!(0, import_node_fs42.existsSync)(STANDARD_FILE)) {
23763
23897
  return { created: 0, failed: 0, skipped: "no_standard", candidates: [] };
23764
23898
  }
23765
23899
  let standardDoc;
@@ -23771,7 +23905,7 @@ async function runSeed(opts) {
23771
23905
  }
23772
23906
  const knowledgeSpec = standardDoc.knowledge_spec ?? {};
23773
23907
  let readmeContent;
23774
- if ((0, import_node_fs41.existsSync)("README.md")) {
23908
+ if ((0, import_node_fs42.existsSync)("README.md")) {
23775
23909
  try {
23776
23910
  readmeContent = await (0, import_promises15.readFile)("README.md", "utf-8");
23777
23911
  } catch {
@@ -23779,7 +23913,7 @@ async function runSeed(opts) {
23779
23913
  }
23780
23914
  let claudeMdContent;
23781
23915
  for (const p of ["CLAUDE.md", ".claude/CLAUDE.md"]) {
23782
- if ((0, import_node_fs41.existsSync)(p)) {
23916
+ if ((0, import_node_fs42.existsSync)(p)) {
23783
23917
  try {
23784
23918
  claudeMdContent = await (0, import_promises15.readFile)(p, "utf-8");
23785
23919
  break;
@@ -23802,8 +23936,8 @@ async function runSeed(opts) {
23802
23936
  if (candidates2.length === 0) {
23803
23937
  return { created: 0, failed: 0, skipped: "no_candidates", candidates: [] };
23804
23938
  }
23805
- const overviewPath = (0, import_node_path31.join)(MEMORY_DIR, "domain", "project-overview.md");
23806
- if ((0, import_node_fs41.existsSync)(overviewPath) && !opts.force) {
23939
+ const overviewPath = (0, import_node_path32.join)(MEMORY_DIR, "domain", "project-overview.md");
23940
+ if ((0, import_node_fs42.existsSync)(overviewPath) && !opts.force) {
23807
23941
  return { created: 0, failed: 0, skipped: "already_seeded", candidates: candidates2 };
23808
23942
  }
23809
23943
  if (opts.dryRun) {
@@ -23845,7 +23979,7 @@ async function runSeed(opts) {
23845
23979
  continue;
23846
23980
  }
23847
23981
  try {
23848
- await (0, import_promises15.mkdir)((0, import_node_path31.dirname)(targetPath), { recursive: true });
23982
+ await (0, import_promises15.mkdir)((0, import_node_path32.dirname)(targetPath), { recursive: true });
23849
23983
  await (0, import_promises15.writeFile)(targetPath, renderNodeMarkdown(c, nodeId, createdAt));
23850
23984
  created++;
23851
23985
  opts.onCreated?.(nodeId, filePathRel, c);
@@ -23858,8 +23992,8 @@ async function runSeed(opts) {
23858
23992
  }
23859
23993
 
23860
23994
  // src/commands/analyze/phases/08-memory-manifest.ts
23861
- var import_node_fs42 = require("node:fs");
23862
- var import_node_path32 = require("node:path");
23995
+ var import_node_fs43 = require("node:fs");
23996
+ var import_node_path33 = require("node:path");
23863
23997
  async function memoryManifest(run2) {
23864
23998
  const { globals } = run2;
23865
23999
  const { serviceUrl, token } = run2;
@@ -23869,9 +24003,9 @@ async function memoryManifest(run2) {
23869
24003
  let autoSeedNotice = null;
23870
24004
  try {
23871
24005
  await ensureMemoryDir();
23872
- const seedMarker = (0, import_node_path32.join)(VERITY_DIR, ".seeded");
23873
- const hasStandard = (0, import_node_fs42.existsSync)(STANDARD_FILE);
23874
- const alreadyTried = (0, import_node_fs42.existsSync)(seedMarker);
24006
+ const seedMarker = (0, import_node_path33.join)(VERITY_DIR, ".seeded");
24007
+ const hasStandard = (0, import_node_fs43.existsSync)(STANDARD_FILE);
24008
+ const alreadyTried = (0, import_node_fs43.existsSync)(seedMarker);
23875
24009
  if (hasStandard && !alreadyTried) {
23876
24010
  const preManifest = await buildManifest();
23877
24011
  if (preManifest.nodes.length === 0) {
@@ -23884,7 +24018,7 @@ async function memoryManifest(run2) {
23884
24018
  dryRun: false
23885
24019
  });
23886
24020
  if (seedResult.created > 0) {
23887
- (0, import_node_fs42.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created}
24021
+ (0, import_node_fs43.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created}
23888
24022
  `);
23889
24023
  autoSeedNotice = `Seeded ${seedResult.created} knowledge node(s) from your existing Standard (one-time).`;
23890
24024
  logEvent("auto_seed_ran", {
@@ -23892,7 +24026,7 @@ async function memoryManifest(run2) {
23892
24026
  failed: seedResult.failed
23893
24027
  });
23894
24028
  } else if (seedResult.skipped === "already_seeded") {
23895
- (0, import_node_fs42.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
24029
+ (0, import_node_fs43.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
23896
24030
  `);
23897
24031
  } else {
23898
24032
  logEvent("auto_seed_noop", {
@@ -23987,7 +24121,7 @@ function computeIncrement(reviewedPaths, hashOf, priorAuthored) {
23987
24121
  }
23988
24122
 
23989
24123
  // src/commands/analyze/phases/10-working-memory.ts
23990
- var import_node_path33 = require("node:path");
24124
+ var import_node_path34 = require("node:path");
23991
24125
  async function workingMemory(run2) {
23992
24126
  const { opts } = run2;
23993
24127
  const { allForReview, baseline, conversation, foldResult, sessionId, token, transcriptPath } = run2;
@@ -23999,7 +24133,7 @@ async function workingMemory(run2) {
23999
24133
  const priorState = foldForMarks(memorySession.d);
24000
24134
  incrementReport = computeIncrement(
24001
24135
  allForReview,
24002
- (p) => fileHash((0, import_node_path33.join)(repoRoot(), p)),
24136
+ (p) => fileHash((0, import_node_path34.join)(repoRoot(), p)),
24003
24137
  priorState.authored_all.map((a) => ({
24004
24138
  path: a.path,
24005
24139
  hash_at_last_verdict: a.hash_at_last_verdict
@@ -24081,7 +24215,7 @@ async function workingMemory(run2) {
24081
24215
  }
24082
24216
 
24083
24217
  // src/lib/note-budget.ts
24084
- var import_node_fs43 = require("node:fs");
24218
+ var import_node_fs44 = require("node:fs");
24085
24219
  var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
24086
24220
  var EPISODE_STALE_SECONDS = 30 * 60;
24087
24221
  var FRESH = { delivered: 0, tasksCompleted: 0, ts: 0 };
@@ -24103,9 +24237,9 @@ function advisoryBudgetSpent(episode, rawDecision) {
24103
24237
  }
24104
24238
  function readAdvisoryEpisode(sessionId) {
24105
24239
  const file = scopedFile(ADVISORY_EPISODE_FILE, sessionId);
24106
- if (!(0, import_node_fs43.existsSync)(file)) return null;
24240
+ if (!(0, import_node_fs44.existsSync)(file)) return null;
24107
24241
  try {
24108
- const o = JSON.parse((0, import_node_fs43.readFileSync)(file, "utf-8")) ?? {};
24242
+ const o = JSON.parse((0, import_node_fs44.readFileSync)(file, "utf-8")) ?? {};
24109
24243
  const delivered = typeof o.delivered === "number" ? o.delivered : NaN;
24110
24244
  if (isNaN(delivered)) return null;
24111
24245
  return {
@@ -24119,8 +24253,8 @@ function readAdvisoryEpisode(sessionId) {
24119
24253
  }
24120
24254
  function writeAdvisoryEpisode(episode, sessionId) {
24121
24255
  try {
24122
- (0, import_node_fs43.mkdirSync)(VERITY_DIR, { recursive: true });
24123
- (0, import_node_fs43.writeFileSync)(
24256
+ (0, import_node_fs44.mkdirSync)(VERITY_DIR, { recursive: true });
24257
+ (0, import_node_fs44.writeFileSync)(
24124
24258
  scopedFile(ADVISORY_EPISODE_FILE, sessionId),
24125
24259
  JSON.stringify({ v: 1, ...episode })
24126
24260
  );
@@ -24428,14 +24562,14 @@ async function buildRequest(run2) {
24428
24562
  }
24429
24563
 
24430
24564
  // src/lib/offline.ts
24431
- var import_node_fs44 = require("node:fs");
24565
+ var import_node_fs45 = require("node:fs");
24432
24566
  var import_node_crypto11 = require("node:crypto");
24433
24567
  function cacheRequest(body) {
24434
24568
  try {
24435
- (0, import_node_fs44.mkdirSync)(CACHE_DIR, { recursive: true });
24569
+ (0, import_node_fs45.mkdirSync)(CACHE_DIR, { recursive: true });
24436
24570
  const suffix = (0, import_node_crypto11.randomBytes)(4).toString("hex");
24437
24571
  const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
24438
- (0, import_node_fs44.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body)));
24572
+ (0, import_node_fs45.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body)));
24439
24573
  } catch {
24440
24574
  }
24441
24575
  }
@@ -24554,8 +24688,8 @@ async function transmit(run2) {
24554
24688
  }
24555
24689
 
24556
24690
  // src/commands/analyze/phases/13-reconcile.ts
24557
- var import_node_fs45 = require("node:fs");
24558
- var import_node_path34 = require("node:path");
24691
+ var import_node_fs46 = require("node:fs");
24692
+ var import_node_path35 = require("node:path");
24559
24693
  async function reconcile(run2) {
24560
24694
  const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory, memorySession, response, reviewable, securityFiles, turnId } = run2;
24561
24695
  const sentPaths = codeDelta.files.map((f) => f.path);
@@ -24584,7 +24718,7 @@ async function reconcile(run2) {
24584
24718
  const st = foldDossier(memorySession.d);
24585
24719
  openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line) => {
24586
24720
  try {
24587
- const src = (0, import_node_fs45.readFileSync)((0, import_node_path34.join)(repoRoot(), file), "utf8").split("\n");
24721
+ const src = (0, import_node_fs46.readFileSync)((0, import_node_path35.join)(repoRoot(), file), "utf8").split("\n");
24588
24722
  const at = src[line - 1];
24589
24723
  return at === void 0 ? null : lineSha(at);
24590
24724
  } catch {
@@ -25399,7 +25533,7 @@ function registerAnalyzeCommand(program2) {
25399
25533
  var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
25400
25534
  async function runAnalyze(opts, globals) {
25401
25535
  if (!verityConfigured()) {
25402
- (0, import_node_fs46.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
25536
+ (0, import_node_fs47.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
25403
25537
  process.exit(0);
25404
25538
  }
25405
25539
  const run2 = createRun(opts, globals);
@@ -25420,11 +25554,11 @@ async function runAnalyze(opts, globals) {
25420
25554
  }
25421
25555
 
25422
25556
  // src/commands/baseline.ts
25423
- var import_node_fs48 = require("node:fs");
25557
+ var import_node_fs49 = require("node:fs");
25424
25558
 
25425
25559
  // src/lib/project-skills.ts
25426
- var import_node_fs47 = require("node:fs");
25427
- var import_node_path35 = require("node:path");
25560
+ var import_node_fs48 = require("node:fs");
25561
+ var import_node_path36 = require("node:path");
25428
25562
  var PROJECT_SKILL_NAMES = [
25429
25563
  "verity-setup",
25430
25564
  "verity-analyze",
@@ -25449,14 +25583,14 @@ var LEGACY_SKILL_NAMES = [
25449
25583
  var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
25450
25584
  function staleProjectSkills() {
25451
25585
  const root = projectPath(".claude/skills");
25452
- if (!(0, import_node_fs47.existsSync)(root)) return [];
25453
- return ALL.filter((name) => (0, import_node_fs47.existsSync)((0, import_node_path35.join)(root, name)));
25586
+ if (!(0, import_node_fs48.existsSync)(root)) return [];
25587
+ return ALL.filter((name) => (0, import_node_fs48.existsSync)((0, import_node_path36.join)(root, name)));
25454
25588
  }
25455
25589
  function removeProjectSkills() {
25456
25590
  const root = projectPath(".claude/skills");
25457
25591
  const removed = [];
25458
25592
  for (const name of staleProjectSkills()) {
25459
- (0, import_node_fs47.rmSync)((0, import_node_path35.join)(root, name), { recursive: true, force: true });
25593
+ (0, import_node_fs48.rmSync)((0, import_node_path36.join)(root, name), { recursive: true, force: true });
25460
25594
  removed.push(name);
25461
25595
  }
25462
25596
  return removed;
@@ -25484,10 +25618,10 @@ function registerBaselineCommands(program2) {
25484
25618
  const session = sessionId ?? validSessionId(process.env.CLAUDE_SESSION_ID);
25485
25619
  const cli = pluginCliInvocation();
25486
25620
  const skew = cliVersionSkew();
25487
- const why = skew ? `the \`verity\` on PATH is ${skew.global} but this plugin runs ${skew.plugin}, so it is not the CLI the hooks use` : verityOnPath() ? "the `verity` on PATH is a separate install whose version could not be read" : "this machine has no `verity` on PATH \u2014 the plugin carries its own copy";
25621
+ const why = skew ? `the \`verity\` on PATH is ${skew.global} but the hooks run ${skew.hooks}, so it is not the CLI they use` : verityOnPath() ? "the `verity` on PATH is a separate install whose version could not be read" : "this machine has no `verity` on PATH \u2014 the plugin carries its own copy";
25488
25622
  const cliLine = cli ? `Verity CLI: ${why}. When a Verity skill tells you to run \`verity <args>\`, run \`${cli} <args>\` instead. Everything else about the command is identical.` : null;
25489
- const skewMsg = skew ? `Verity: your global \`verity\` CLI is ${skew.global} but the plugin runs ${skew.plugin}. Update it before using \`verity\` in a terminal: npm install -g @codacy/verity-cli@${skew.plugin}` : null;
25490
- const skewNote = skew ? `Before anything else, including /verity:init's questions, tell the user their global \`verity\` is ${skew.global}, the plugin runs ${skew.plugin}, and \`npm install -g @codacy/verity-cli@${skew.plugin}\` fixes it. Until they have, do not send them to run \`verity login\` in a terminal: that runs the global one, which can sign this machine in to a different server.` : null;
25623
+ const skewMsg = skew ? `Verity: your global \`verity\` CLI is ${skew.global} but the hooks run ${skew.hooks}. Fix it before using \`verity\` in a terminal: ${skew.remedy}` : null;
25624
+ const skewNote = skew ? `Before anything else, including /verity:init's questions, tell the user their global \`verity\` is ${skew.global}, the hooks run ${skew.hooks}, and \`${skew.remedy}\` fixes it. Until they have, do not send them to run \`verity login\` in a terminal: that runs the global one, which can sign this machine in to a different server.` : null;
25491
25625
  if (!verityConfigured()) {
25492
25626
  const how = isPluginInvocation() ? "Tell the user to run /verity:init \u2014 they type it; you cannot invoke it." : "Tell the user to run `verity init` in their terminal.";
25493
25627
  const lines = [
@@ -25521,13 +25655,13 @@ function registerBaselineCommands(program2) {
25521
25655
  let memoryMsg = null;
25522
25656
  let memoryAgentLine = null;
25523
25657
  const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
25524
- if (realStart && !(0, import_node_fs48.existsSync)(memoryNotice)) {
25658
+ if (realStart && !(0, import_node_fs49.existsSync)(memoryNotice)) {
25525
25659
  const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
25526
25660
  if (trackedGraph > 0) {
25527
25661
  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.`;
25528
25662
  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.`;
25529
25663
  try {
25530
- (0, import_node_fs48.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
25664
+ (0, import_node_fs49.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
25531
25665
  } catch {
25532
25666
  }
25533
25667
  }
@@ -25628,7 +25762,7 @@ function hookSource(value) {
25628
25762
  }
25629
25763
 
25630
25764
  // src/commands/review.ts
25631
- var import_node_fs49 = require("node:fs");
25765
+ var import_node_fs50 = require("node:fs");
25632
25766
  function registerReviewCommand(program2) {
25633
25767
  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) => {
25634
25768
  const globals = program2.opts();
@@ -25645,7 +25779,7 @@ async function runReview(opts, globals) {
25645
25779
  const changedFiles = opts.changed ? opts.changed.split(",").map((f) => f.trim()).filter(Boolean) : allFiles;
25646
25780
  const analyzable = filterAnalyzable(allFiles);
25647
25781
  const securityFiles = filterSecurity(allFiles);
25648
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs49.existsSync)(f) || resolveFile(f) !== null);
25782
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs50.existsSync)(f) || resolveFile(f) !== null);
25649
25783
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
25650
25784
  const codeDelta = collectCodeDelta(allFiles);
25651
25785
  const tokenResult = await resolveToken(globals.token);
@@ -25711,8 +25845,8 @@ async function runReview(opts, globals) {
25711
25845
  }
25712
25846
 
25713
25847
  // src/commands/guard.ts
25714
- var import_node_fs50 = require("node:fs");
25715
- var import_node_path36 = require("node:path");
25848
+ var import_node_fs51 = require("node:fs");
25849
+ var import_node_path37 = require("node:path");
25716
25850
 
25717
25851
  // src/lib/terminal-text.ts
25718
25852
  var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/g;
@@ -26087,7 +26221,7 @@ async function buildAgentDiffs(ctx, paths, limits = { perFileChars: 24e3, totalC
26087
26221
  // src/commands/guard.ts
26088
26222
  var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
26089
26223
  var GUARD_BLOCK_CAP = 2;
26090
- var GUARD_ITER_FILE = (0, import_node_path36.join)(VERITY_DIR, ".guard-iteration");
26224
+ var GUARD_ITER_FILE = (0, import_node_path37.join)(VERITY_DIR, ".guard-iteration");
26091
26225
  function readPreToolUseStdin() {
26092
26226
  const empty = { command: "", cwd: null, sessionId: null };
26093
26227
  return new Promise((resolve6) => {
@@ -26132,7 +26266,7 @@ function readPreToolUseStdin() {
26132
26266
  }
26133
26267
  function readIterMap() {
26134
26268
  try {
26135
- const raw = JSON.parse((0, import_node_fs50.readFileSync)(GUARD_ITER_FILE, "utf-8"));
26269
+ const raw = JSON.parse((0, import_node_fs51.readFileSync)(GUARD_ITER_FILE, "utf-8"));
26136
26270
  if (raw && typeof raw === "object") {
26137
26271
  if (typeof raw.moment === "string" && typeof raw.count === "number") {
26138
26272
  return { [raw.moment]: raw.count };
@@ -26152,10 +26286,10 @@ function readIter(moment) {
26152
26286
  }
26153
26287
  function writeIter(moment, count) {
26154
26288
  try {
26155
- (0, import_node_fs50.mkdirSync)(VERITY_DIR, { recursive: true });
26289
+ (0, import_node_fs51.mkdirSync)(VERITY_DIR, { recursive: true });
26156
26290
  const map = readIterMap();
26157
26291
  map[moment] = count;
26158
- (0, import_node_fs50.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
26292
+ (0, import_node_fs51.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
26159
26293
  } catch {
26160
26294
  }
26161
26295
  }
@@ -26165,10 +26299,10 @@ function resetIter(moment) {
26165
26299
  if (!(moment in map)) return;
26166
26300
  delete map[moment];
26167
26301
  if (Object.keys(map).length === 0) {
26168
- if ((0, import_node_fs50.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs50.unlinkSync)(GUARD_ITER_FILE);
26302
+ if ((0, import_node_fs51.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs51.unlinkSync)(GUARD_ITER_FILE);
26169
26303
  } else {
26170
- (0, import_node_fs50.mkdirSync)(VERITY_DIR, { recursive: true });
26171
- (0, import_node_fs50.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
26304
+ (0, import_node_fs51.mkdirSync)(VERITY_DIR, { recursive: true });
26305
+ (0, import_node_fs51.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
26172
26306
  }
26173
26307
  } catch {
26174
26308
  }
@@ -26238,7 +26372,7 @@ function hasBlockingFinding(response, sentFiles) {
26238
26372
  function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
26239
26373
  const analyzable = filterAnalyzable(files);
26240
26374
  const securityFiles = filterSecurity(files);
26241
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs50.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
26375
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs51.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
26242
26376
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
26243
26377
  const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
26244
26378
  const requestBody = {
@@ -26748,7 +26882,7 @@ function registerIgnoreCommand(program2) {
26748
26882
 
26749
26883
  // src/commands/waive.ts
26750
26884
  var import_node_crypto12 = require("node:crypto");
26751
- var import_node_fs51 = require("node:fs");
26885
+ var import_node_fs52 = require("node:fs");
26752
26886
  function registerWaiveCommand(program2) {
26753
26887
  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) => {
26754
26888
  const globals = program2.opts();
@@ -26777,7 +26911,7 @@ function registerWaiveCommand(program2) {
26777
26911
  if (opts.file) {
26778
26912
  body.file = opts.file;
26779
26913
  try {
26780
- body.file_sha256 = (0, import_node_crypto12.createHash)("sha256").update((0, import_node_fs51.readFileSync)(opts.file)).digest("hex");
26914
+ body.file_sha256 = (0, import_node_crypto12.createHash)("sha256").update((0, import_node_fs52.readFileSync)(opts.file)).digest("hex");
26781
26915
  } catch {
26782
26916
  printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
26783
26917
  process.exit(1);
@@ -26802,10 +26936,10 @@ function registerWaiveCommand(program2) {
26802
26936
  }
26803
26937
 
26804
26938
  // src/commands/init.ts
26805
- var import_node_fs55 = require("node:fs");
26939
+ var import_node_fs56 = require("node:fs");
26806
26940
  var import_promises19 = require("node:fs/promises");
26807
26941
  var import_yaml6 = __toESM(require_dist());
26808
- var import_node_path39 = require("node:path");
26942
+ var import_node_path40 = require("node:path");
26809
26943
  var import_node_child_process17 = require("node:child_process");
26810
26944
 
26811
26945
  // src/lib/banner.ts
@@ -26884,7 +27018,7 @@ function printPhase(n, of, title, subtitle) {
26884
27018
  }
26885
27019
 
26886
27020
  // src/commands/doctor.ts
26887
- var import_node_fs52 = require("node:fs");
27021
+ var import_node_fs53 = require("node:fs");
26888
27022
 
26889
27023
  // src/lib/prereqs.ts
26890
27024
  var import_node_child_process15 = require("node:child_process");
@@ -27090,12 +27224,13 @@ async function buildReport() {
27090
27224
  const state = await readSetupState();
27091
27225
  const wiring = await resolveHookWiring();
27092
27226
  const hooks = wiring.status;
27227
+ const provenance = cliProvenance();
27093
27228
  const telemetry = await checkTelemetry();
27094
- const hasConfig = (0, import_node_fs52.existsSync)(projectPath(CODACY_CONFIG_FILE));
27229
+ const hasConfig = (0, import_node_fs53.existsSync)(projectPath(CODACY_CONFIG_FILE));
27095
27230
  const artifacts = {
27096
- standard: (0, import_node_fs52.existsSync)(projectPath(STANDARD_FILE)),
27231
+ standard: (0, import_node_fs53.existsSync)(projectPath(STANDARD_FILE)),
27097
27232
  analysisConfig: hasConfig,
27098
- verityMd: (0, import_node_fs52.existsSync)(projectPath(VERITY_MD_FILE)),
27233
+ verityMd: (0, import_node_fs53.existsSync)(projectPath(VERITY_MD_FILE)),
27099
27234
  analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
27100
27235
  };
27101
27236
  const next = [];
@@ -27133,6 +27268,12 @@ async function buildReport() {
27133
27268
  'Duplicate Verity hooks also exist in .claude/settings.json. They stand down at run time under the plugin, but remove them with "verity init --plugin-mode" so the wiring says what it does.'
27134
27269
  );
27135
27270
  }
27271
+ const versions = versionReport(provenance);
27272
+ if (provenance.skew) {
27273
+ next.push(
27274
+ `The \`verity\` on PATH is ${provenance.skew.global}, but the plugin's hooks run ${provenance.skew.hooks} \u2014 so the gate and your terminal are different builds. Fix: ${provenance.skew.remedy}.`
27275
+ );
27276
+ }
27136
27277
  if (state?.telemetry === "deferred") {
27137
27278
  next.push('Telemetry was requested but needs a token \u2014 run "verity login", then "verity telemetry install".');
27138
27279
  }
@@ -27170,7 +27311,8 @@ async function buildReport() {
27170
27311
  source: wiring.source,
27171
27312
  ...hooks,
27172
27313
  duplicateSettingsHooks: wiring.duplicateSettingsHooks,
27173
- noAnalysisMoment
27314
+ noAnalysisMoment,
27315
+ versions
27174
27316
  },
27175
27317
  telemetry: { enabled: telemetry.enabled, endpoint: telemetry.endpoint },
27176
27318
  artifacts,
@@ -27201,6 +27343,9 @@ function registerDoctorCommand(program2) {
27201
27343
  printInfo(` intensity: ${report.answers.intensity ?? "\u2014"} moments: ${report.answers.moments?.join(", ") ?? "\u2014"}`);
27202
27344
  const plugin = report.hooks.source === "plugin";
27203
27345
  printInfo(plugin ? "Hooks: wired by the Verity Claude Code plugin (not .claude/settings.json)" : "Hooks:");
27346
+ const versionOut = versionLines(report.hooks.versions);
27347
+ for (const line of versionOut.info) printInfo(line);
27348
+ for (const line of versionOut.warn) printWarn(line);
27204
27349
  printInfo(` Stop (verity analyze): ${report.hooks.stop ? plugin ? "on (plugin)" : "on" : "off"}`);
27205
27350
  printInfo(` Git-moment gate: ${report.hooks.guardOn.length ? report.hooks.guardOn.join(", ") : "off"}`);
27206
27351
  printInfo(` Infra (intent/baseline/compact/session-end): ${[report.hooks.intent, report.hooks.baseline, report.hooks.compact, report.hooks.sessionEnd].filter(Boolean).length}/4`);
@@ -27226,8 +27371,8 @@ function registerDoctorCommand(program2) {
27226
27371
  }
27227
27372
 
27228
27373
  // src/commands/migrate.ts
27229
- var import_node_fs53 = require("node:fs");
27230
- var import_node_path37 = require("node:path");
27374
+ var import_node_fs54 = require("node:fs");
27375
+ var import_node_path38 = require("node:path");
27231
27376
  var import_node_child_process16 = require("node:child_process");
27232
27377
  var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
27233
27378
  function defaultNpmRemover(pkg) {
@@ -27264,12 +27409,12 @@ async function runMigration(opts = {}) {
27264
27409
  return { actions, migrated: actions.length > 0 };
27265
27410
  }
27266
27411
  function migrateProjectDir(root, actions) {
27267
- const gateDir = (0, import_node_path37.join)(root, ".gate");
27268
- const verityDir = (0, import_node_path37.join)(root, ".verity");
27269
- if ((0, import_node_fs53.existsSync)(gateDir) && !(0, import_node_fs53.existsSync)(verityDir)) {
27412
+ const gateDir = (0, import_node_path38.join)(root, ".gate");
27413
+ const verityDir = (0, import_node_path38.join)(root, ".verity");
27414
+ if ((0, import_node_fs54.existsSync)(gateDir) && !(0, import_node_fs54.existsSync)(verityDir)) {
27270
27415
  return migrateProjectDirRename(root, gateDir, verityDir, actions);
27271
27416
  }
27272
- if ((0, import_node_fs53.existsSync)(gateDir) && (0, import_node_fs53.existsSync)(verityDir)) {
27417
+ if ((0, import_node_fs54.existsSync)(gateDir) && (0, import_node_fs54.existsSync)(verityDir)) {
27273
27418
  return migrateProjectDirCarry(gateDir, verityDir, actions);
27274
27419
  }
27275
27420
  return false;
@@ -27290,13 +27435,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
27290
27435
  }
27291
27436
  }
27292
27437
  if (moved) {
27293
- if ((0, import_node_fs53.existsSync)(gateDir)) {
27438
+ if ((0, import_node_fs54.existsSync)(gateDir)) {
27294
27439
  const carried = carryLegacyContents(gateDir, verityDir);
27295
27440
  if (carried > 0) {
27296
27441
  actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
27297
27442
  }
27298
27443
  try {
27299
- (0, import_node_fs53.rmSync)(gateDir, { recursive: true, force: true });
27444
+ (0, import_node_fs54.rmSync)(gateDir, { recursive: true, force: true });
27300
27445
  } catch {
27301
27446
  }
27302
27447
  }
@@ -27312,18 +27457,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
27312
27457
  actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
27313
27458
  }
27314
27459
  try {
27315
- (0, import_node_fs53.rmSync)(gateDir, { recursive: true, force: true });
27460
+ (0, import_node_fs54.rmSync)(gateDir, { recursive: true, force: true });
27316
27461
  } catch {
27317
27462
  }
27318
27463
  return carried > 0;
27319
27464
  }
27320
27465
  function migrateGlobalCredentials(home, actions) {
27321
27466
  if (!home) return;
27322
- const gateCreds = (0, import_node_path37.join)(home, ".gate", "credentials");
27323
- const verityCreds = (0, import_node_path37.join)(home, ".verity", "credentials");
27324
- if (!(0, import_node_fs53.existsSync)(gateCreds)) return;
27325
- if (!(0, import_node_fs53.existsSync)(verityCreds)) {
27326
- (0, import_node_fs53.mkdirSync)((0, import_node_path37.join)(home, ".verity"), { recursive: true });
27467
+ const gateCreds = (0, import_node_path38.join)(home, ".gate", "credentials");
27468
+ const verityCreds = (0, import_node_path38.join)(home, ".verity", "credentials");
27469
+ if (!(0, import_node_fs54.existsSync)(gateCreds)) return;
27470
+ if (!(0, import_node_fs54.existsSync)(verityCreds)) {
27471
+ (0, import_node_fs54.mkdirSync)((0, import_node_path38.join)(home, ".verity"), { recursive: true });
27327
27472
  moveFile(gateCreds, verityCreds);
27328
27473
  actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
27329
27474
  return;
@@ -27345,8 +27490,8 @@ async function migrateLegacyHooks(root, actions) {
27345
27490
  }
27346
27491
  }
27347
27492
  async function migrateClaudeMd(root, actions) {
27348
- const claudeMd = (0, import_node_path37.join)(root, "CLAUDE.md");
27349
- const hadLegacyBlock = (0, import_node_fs53.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
27493
+ const claudeMd = (0, import_node_path38.join)(root, "CLAUDE.md");
27494
+ const hadLegacyBlock = (0, import_node_fs54.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
27350
27495
  if (!hadLegacyBlock) return;
27351
27496
  try {
27352
27497
  await ensureClaudeMdPointer(root);
@@ -27356,9 +27501,9 @@ async function migrateClaudeMd(root, actions) {
27356
27501
  }
27357
27502
  }
27358
27503
  function migrateStandardFile(root, actions) {
27359
- const gateMd = (0, import_node_path37.join)(root, "GATE.md");
27360
- const verityMd = (0, import_node_path37.join)(root, "VERITY.md");
27361
- if (!(0, import_node_fs53.existsSync)(gateMd) || (0, import_node_fs53.existsSync)(verityMd)) return;
27504
+ const gateMd = (0, import_node_path38.join)(root, "GATE.md");
27505
+ const verityMd = (0, import_node_path38.join)(root, "VERITY.md");
27506
+ if (!(0, import_node_fs54.existsSync)(gateMd) || (0, import_node_fs54.existsSync)(verityMd)) return;
27362
27507
  let moved = false;
27363
27508
  if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
27364
27509
  try {
@@ -27370,12 +27515,12 @@ function migrateStandardFile(root, actions) {
27370
27515
  if (!moved) moveFile(gateMd, verityMd);
27371
27516
  const content = readFileSyncSafe(verityMd);
27372
27517
  const refreshed = content.split("GATE.md").join("VERITY.md");
27373
- if (refreshed !== content) (0, import_node_fs53.writeFileSync)(verityMd, refreshed);
27518
+ if (refreshed !== content) (0, import_node_fs54.writeFileSync)(verityMd, refreshed);
27374
27519
  actions.push("Renamed GATE.md \u2192 VERITY.md");
27375
27520
  }
27376
27521
  async function migrateTelemetryHeaders(root, actions) {
27377
- const file = (0, import_node_path37.join)(root, ".claude", "settings.local.json");
27378
- if (!(0, import_node_fs53.existsSync)(file)) return;
27522
+ const file = (0, import_node_path38.join)(root, ".claude", "settings.local.json");
27523
+ if (!(0, import_node_fs54.existsSync)(file)) return;
27379
27524
  let settings;
27380
27525
  try {
27381
27526
  settings = JSON.parse(readFileSyncSafe(file) || "{}");
@@ -27423,14 +27568,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
27423
27568
  }
27424
27569
  if (toAppend.length > 0) {
27425
27570
  const sep4 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
27426
- (0, import_node_fs53.writeFileSync)(verityCreds, verityContent + sep4 + toAppend.join("\n") + "\n");
27571
+ (0, import_node_fs54.writeFileSync)(verityCreds, verityContent + sep4 + toAppend.join("\n") + "\n");
27427
27572
  }
27428
- (0, import_node_fs53.rmSync)(gateCreds, { force: true });
27573
+ (0, import_node_fs54.rmSync)(gateCreds, { force: true });
27429
27574
  return toAppend.length;
27430
27575
  }
27431
27576
  function readFileSyncSafe(path) {
27432
27577
  try {
27433
- return (0, import_node_fs53.readFileSync)(path, "utf-8");
27578
+ return (0, import_node_fs54.readFileSync)(path, "utf-8");
27434
27579
  } catch {
27435
27580
  return "";
27436
27581
  }
@@ -27445,35 +27590,35 @@ function hasStagedChanges(root) {
27445
27590
  }
27446
27591
  function moveDir(from, to) {
27447
27592
  try {
27448
- (0, import_node_fs53.renameSync)(from, to);
27593
+ (0, import_node_fs54.renameSync)(from, to);
27449
27594
  } catch (err) {
27450
27595
  if (err.code !== "EXDEV") throw err;
27451
- (0, import_node_fs53.cpSync)(from, to, { recursive: true });
27452
- (0, import_node_fs53.rmSync)(from, { recursive: true, force: true });
27596
+ (0, import_node_fs54.cpSync)(from, to, { recursive: true });
27597
+ (0, import_node_fs54.rmSync)(from, { recursive: true, force: true });
27453
27598
  }
27454
27599
  }
27455
27600
  function moveFile(from, to) {
27456
27601
  try {
27457
- (0, import_node_fs53.renameSync)(from, to);
27602
+ (0, import_node_fs54.renameSync)(from, to);
27458
27603
  } catch (err) {
27459
27604
  if (err.code !== "EXDEV") throw err;
27460
- (0, import_node_fs53.cpSync)(from, to);
27461
- (0, import_node_fs53.rmSync)(from, { force: true });
27605
+ (0, import_node_fs54.cpSync)(from, to);
27606
+ (0, import_node_fs54.rmSync)(from, { force: true });
27462
27607
  }
27463
27608
  }
27464
27609
  function carryLegacyContents(gateDir, verityDir) {
27465
27610
  let copied = 0;
27466
27611
  const walk2 = (relDir) => {
27467
- const srcDir = (0, import_node_path37.join)(gateDir, relDir);
27468
- for (const entry of (0, import_node_fs53.readdirSync)(srcDir)) {
27469
- const rel = relDir ? (0, import_node_path37.join)(relDir, entry) : entry;
27470
- const src = (0, import_node_path37.join)(gateDir, rel);
27471
- const dest = (0, import_node_path37.join)(verityDir, rel);
27472
- if ((0, import_node_fs53.statSync)(src).isDirectory()) {
27612
+ const srcDir = (0, import_node_path38.join)(gateDir, relDir);
27613
+ for (const entry of (0, import_node_fs54.readdirSync)(srcDir)) {
27614
+ const rel = relDir ? (0, import_node_path38.join)(relDir, entry) : entry;
27615
+ const src = (0, import_node_path38.join)(gateDir, rel);
27616
+ const dest = (0, import_node_path38.join)(verityDir, rel);
27617
+ if ((0, import_node_fs54.statSync)(src).isDirectory()) {
27473
27618
  walk2(rel);
27474
- } else if (!(0, import_node_fs53.existsSync)(dest)) {
27475
- (0, import_node_fs53.mkdirSync)((0, import_node_path37.dirname)(dest), { recursive: true });
27476
- (0, import_node_fs53.cpSync)(src, dest);
27619
+ } else if (!(0, import_node_fs54.existsSync)(dest)) {
27620
+ (0, import_node_fs54.mkdirSync)((0, import_node_path38.dirname)(dest), { recursive: true });
27621
+ (0, import_node_fs54.cpSync)(src, dest);
27477
27622
  copied++;
27478
27623
  }
27479
27624
  }
@@ -27482,22 +27627,22 @@ function carryLegacyContents(gateDir, verityDir) {
27482
27627
  return copied;
27483
27628
  }
27484
27629
  async function needsMigration(root = repoRoot()) {
27485
- const gateDir = (0, import_node_path37.join)(root, ".gate");
27486
- const verityDir = (0, import_node_path37.join)(root, ".verity");
27487
- if ((0, import_node_fs53.existsSync)(gateDir) && !(0, import_node_fs53.existsSync)(verityDir)) return true;
27488
- if ((0, import_node_fs53.existsSync)(gateDir) && (0, import_node_fs53.existsSync)(verityDir)) {
27489
- if ((0, import_node_fs53.existsSync)((0, import_node_path37.join)(gateDir, "credentials")) && !(0, import_node_fs53.existsSync)((0, import_node_path37.join)(verityDir, "credentials"))) {
27630
+ const gateDir = (0, import_node_path38.join)(root, ".gate");
27631
+ const verityDir = (0, import_node_path38.join)(root, ".verity");
27632
+ if ((0, import_node_fs54.existsSync)(gateDir) && !(0, import_node_fs54.existsSync)(verityDir)) return true;
27633
+ if ((0, import_node_fs54.existsSync)(gateDir) && (0, import_node_fs54.existsSync)(verityDir)) {
27634
+ if ((0, import_node_fs54.existsSync)((0, import_node_path38.join)(gateDir, "credentials")) && !(0, import_node_fs54.existsSync)((0, import_node_path38.join)(verityDir, "credentials"))) {
27490
27635
  return true;
27491
27636
  }
27492
- if ((0, import_node_fs53.existsSync)((0, import_node_path37.join)(gateDir, "memory")) && !(0, import_node_fs53.existsSync)((0, import_node_path37.join)(verityDir, "memory"))) {
27637
+ if ((0, import_node_fs54.existsSync)((0, import_node_path38.join)(gateDir, "memory")) && !(0, import_node_fs54.existsSync)((0, import_node_path38.join)(verityDir, "memory"))) {
27493
27638
  return true;
27494
27639
  }
27495
27640
  }
27496
- const claudeMd = (0, import_node_path37.join)(root, "CLAUDE.md");
27497
- if ((0, import_node_fs53.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
27641
+ const claudeMd = (0, import_node_path38.join)(root, "CLAUDE.md");
27642
+ if ((0, import_node_fs54.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
27498
27643
  return true;
27499
27644
  }
27500
- if ((0, import_node_fs53.existsSync)((0, import_node_path37.join)(root, "GATE.md")) && !(0, import_node_fs53.existsSync)((0, import_node_path37.join)(root, "VERITY.md"))) {
27645
+ if ((0, import_node_fs54.existsSync)((0, import_node_path38.join)(root, "GATE.md")) && !(0, import_node_fs54.existsSync)((0, import_node_path38.join)(root, "VERITY.md"))) {
27501
27646
  return true;
27502
27647
  }
27503
27648
  if (await hasLegacyHooksAt(root)) return true;
@@ -27778,9 +27923,9 @@ async function promptMultiSelect(question, choices, fallback) {
27778
27923
  }
27779
27924
 
27780
27925
  // src/lib/remote-config.ts
27781
- var import_node_fs54 = require("node:fs");
27926
+ var import_node_fs55 = require("node:fs");
27782
27927
  var import_promises18 = require("node:fs/promises");
27783
- var import_node_path38 = require("node:path");
27928
+ var import_node_path39 = require("node:path");
27784
27929
  var import_yaml5 = __toESM(require_dist());
27785
27930
  var IGNORE_RIDER = "verityignore";
27786
27931
  async function fetchRemoteSetup(opts) {
@@ -27825,7 +27970,7 @@ async function adoptRemoteSetup(found, opts) {
27825
27970
  written.push(STANDARD_FILE);
27826
27971
  if (rider !== null) {
27827
27972
  const localIgnore = projectPath(VERITYIGNORE_FILE);
27828
- if (!(0, import_node_fs54.existsSync)(localIgnore)) {
27973
+ if (!(0, import_node_fs55.existsSync)(localIgnore)) {
27829
27974
  await writeOut(VERITYIGNORE_FILE, rider);
27830
27975
  written.push(VERITYIGNORE_FILE);
27831
27976
  } else {
@@ -27858,7 +28003,7 @@ async function adoptRemoteSetup(found, opts) {
27858
28003
  }
27859
28004
  async function writeOut(relative3, body) {
27860
28005
  const target = projectPath(relative3);
27861
- await (0, import_promises18.mkdir)((0, import_node_path38.dirname)(target), { recursive: true });
28006
+ await (0, import_promises18.mkdir)((0, import_node_path39.dirname)(target), { recursive: true });
27862
28007
  await (0, import_promises18.writeFile)(target, body);
27863
28008
  }
27864
28009
  function describeRemote(found) {
@@ -27975,15 +28120,15 @@ async function runOptionalAuth(resolution, opts = {}) {
27975
28120
  }
27976
28121
  function resolveDataDir2() {
27977
28122
  const candidates2 = [
27978
- (0, import_node_path39.join)(__dirname, "..", "data"),
28123
+ (0, import_node_path40.join)(__dirname, "..", "data"),
27979
28124
  // installed: node_modules/@codacy/verity-cli/data
27980
- (0, import_node_path39.join)(__dirname, "..", "..", "data"),
28125
+ (0, import_node_path40.join)(__dirname, "..", "..", "data"),
27981
28126
  // edge case: nested resolution
27982
- (0, import_node_path39.join)(process.cwd(), "cli", "data")
28127
+ (0, import_node_path40.join)(process.cwd(), "cli", "data")
27983
28128
  // local dev: running from repo root
27984
28129
  ];
27985
28130
  for (const candidate of candidates2) {
27986
- if ((0, import_node_fs55.existsSync)((0, import_node_path39.join)(candidate, "skills"))) {
28131
+ if ((0, import_node_fs56.existsSync)((0, import_node_path40.join)(candidate, "skills"))) {
27987
28132
  return candidate;
27988
28133
  }
27989
28134
  }
@@ -27999,9 +28144,9 @@ async function skillIsCurrent(src, dest) {
27999
28144
  const list2 = (dir) => {
28000
28145
  const out = [];
28001
28146
  const walk2 = (d, prefix) => {
28002
- for (const e of (0, import_node_fs55.readdirSync)(d, { withFileTypes: true })) {
28147
+ for (const e of (0, import_node_fs56.readdirSync)(d, { withFileTypes: true })) {
28003
28148
  const rel = prefix ? `${prefix}/${e.name}` : e.name;
28004
- if (e.isDirectory()) walk2((0, import_node_path39.join)(d, e.name), rel);
28149
+ if (e.isDirectory()) walk2((0, import_node_path40.join)(d, e.name), rel);
28005
28150
  else if (e.isFile()) out.push(rel);
28006
28151
  }
28007
28152
  };
@@ -28012,8 +28157,8 @@ async function skillIsCurrent(src, dest) {
28012
28157
  const shipped = list2(src);
28013
28158
  if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
28014
28159
  for (const rel of shipped) {
28015
- const a = await (0, import_promises19.readFile)((0, import_node_path39.join)(src, rel), "utf-8");
28016
- const b = await (0, import_promises19.readFile)((0, import_node_path39.join)(dest, rel), "utf-8");
28160
+ const a = await (0, import_promises19.readFile)((0, import_node_path40.join)(src, rel), "utf-8");
28161
+ const b = await (0, import_promises19.readFile)((0, import_node_path40.join)(dest, rel), "utf-8");
28017
28162
  if (a !== b) return false;
28018
28163
  }
28019
28164
  return true;
@@ -28194,7 +28339,7 @@ async function synthesizeLocally(opts) {
28194
28339
  async function healStaleAnalysisConfig(globals) {
28195
28340
  const configPath = projectPath(CODACY_CONFIG_FILE);
28196
28341
  const standardPath = projectPath(STANDARD_FILE);
28197
- if (!(0, import_node_fs55.existsSync)(configPath) || !(0, import_node_fs55.existsSync)(standardPath)) return;
28342
+ if (!(0, import_node_fs56.existsSync)(configPath) || !(0, import_node_fs56.existsSync)(standardPath)) return;
28198
28343
  const validation = validatePatternIds();
28199
28344
  if (validation.status !== "invalid") return;
28200
28345
  printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
@@ -28291,17 +28436,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
28291
28436
  async function installSkills(force, step) {
28292
28437
  step("Installing skills");
28293
28438
  const dataDir = resolveDataDir2();
28294
- const skillsSource = (0, import_node_path39.join)(dataDir, "skills");
28439
+ const skillsSource = (0, import_node_path40.join)(dataDir, "skills");
28295
28440
  const skillsDest = ".claude/skills";
28296
28441
  let skillsInstalled = 0;
28297
28442
  for (const skill of SKILLS) {
28298
- const src = (0, import_node_path39.join)(skillsSource, skill);
28299
- const dest = (0, import_node_path39.join)(skillsDest, skill);
28300
- if (!(0, import_node_fs55.existsSync)(src)) {
28443
+ const src = (0, import_node_path40.join)(skillsSource, skill);
28444
+ const dest = (0, import_node_path40.join)(skillsDest, skill);
28445
+ if (!(0, import_node_fs56.existsSync)(src)) {
28301
28446
  printWarn(` Skill data not found: ${skill}`);
28302
28447
  continue;
28303
28448
  }
28304
- if ((0, import_node_fs55.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
28449
+ if ((0, import_node_fs56.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
28305
28450
  skillsInstalled++;
28306
28451
  continue;
28307
28452
  }
@@ -28440,7 +28585,7 @@ function registerInitCommand(program2) {
28440
28585
  const staleMarker = clearStalePluginMarker();
28441
28586
  const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
28442
28587
  const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
28443
- const isProject = projectMarkers.some((m) => (0, import_node_fs55.existsSync)(m));
28588
+ const isProject = projectMarkers.some((m) => (0, import_node_fs56.existsSync)(m));
28444
28589
  if (!isProject) {
28445
28590
  printError("No project detected in the current directory.");
28446
28591
  printInfo('Run "verity init" from your project root.');
@@ -28530,7 +28675,7 @@ function registerInitCommand(program2) {
28530
28675
  printInfo(` intensity: ${intensity} \xB7 moments: ${moments.join(", ") || "none"} (no questions asked)`);
28531
28676
  }
28532
28677
  await scaffoldProject(step, defaultsOnly);
28533
- const globalVerityDir = (0, import_node_path39.join)(process.env.HOME ?? "", ".verity");
28678
+ const globalVerityDir = (0, import_node_path40.join)(process.env.HOME ?? "", ".verity");
28534
28679
  await (0, import_promises19.mkdir)(globalVerityDir, { recursive: true });
28535
28680
  console.log("");
28536
28681
  step("Wiring Claude Code hooks");
@@ -28599,7 +28744,7 @@ function registerInitCommand(program2) {
28599
28744
  }
28600
28745
  step("Your project's Standard");
28601
28746
  let haveStandard = false;
28602
- if ((0, import_node_fs55.existsSync)(projectPath(STANDARD_FILE))) {
28747
+ if ((0, import_node_fs56.existsSync)(projectPath(STANDARD_FILE))) {
28603
28748
  printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
28604
28749
  haveStandard = true;
28605
28750
  } else {
@@ -28629,7 +28774,7 @@ function registerInitCommand(program2) {
28629
28774
  ...telemetryChoice ? { telemetry: telemetryChoice } : {},
28630
28775
  init: {
28631
28776
  completed_at: (/* @__PURE__ */ new Date()).toISOString(),
28632
- cli_version: true ? "0.33.1-experimental.4a41d04" : "dev"
28777
+ cli_version: true ? "0.33.2-experimental.0c53bed" : "dev"
28633
28778
  }
28634
28779
  });
28635
28780
  } catch (err) {
@@ -28679,8 +28824,8 @@ function registerInitCommand(program2) {
28679
28824
  }
28680
28825
 
28681
28826
  // src/commands/uninstall.ts
28682
- var import_node_fs56 = require("node:fs");
28683
- var import_node_path40 = require("node:path");
28827
+ var import_node_fs57 = require("node:fs");
28828
+ var import_node_path41 = require("node:path");
28684
28829
  function registerUninstallCommand(program2) {
28685
28830
  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) => {
28686
28831
  const dryRun = opts.dryRun ?? false;
@@ -28689,11 +28834,11 @@ function registerUninstallCommand(program2) {
28689
28834
  const actions = [];
28690
28835
  const skillsRoot = projectPath(".claude/skills");
28691
28836
  for (const name of PROJECT_SKILL_NAMES) {
28692
- const dir = (0, import_node_path40.join)(skillsRoot, name);
28693
- if ((0, import_node_fs56.existsSync)(dir)) {
28837
+ const dir = (0, import_node_path41.join)(skillsRoot, name);
28838
+ if ((0, import_node_fs57.existsSync)(dir)) {
28694
28839
  actions.push({
28695
28840
  label: `Remove .claude/skills/${name}/`,
28696
- apply: () => (0, import_node_fs56.rmSync)(dir, { recursive: true, force: true })
28841
+ apply: () => (0, import_node_fs57.rmSync)(dir, { recursive: true, force: true })
28697
28842
  });
28698
28843
  }
28699
28844
  }
@@ -28707,24 +28852,24 @@ function registerUninstallCommand(program2) {
28707
28852
  });
28708
28853
  }
28709
28854
  const verityDir = projectPath(VERITY_DIR);
28710
- if ((0, import_node_fs56.existsSync)(verityDir)) {
28855
+ if ((0, import_node_fs57.existsSync)(verityDir)) {
28711
28856
  actions.push({
28712
28857
  label: `Remove ${VERITY_DIR}/`,
28713
- apply: () => (0, import_node_fs56.rmSync)(verityDir, { recursive: true, force: true })
28858
+ apply: () => (0, import_node_fs57.rmSync)(verityDir, { recursive: true, force: true })
28714
28859
  });
28715
28860
  }
28716
28861
  if (!keepVerityMd) {
28717
28862
  const verityMd = projectPath(VERITY_MD_FILE);
28718
- if ((0, import_node_fs56.existsSync)(verityMd)) {
28863
+ if ((0, import_node_fs57.existsSync)(verityMd)) {
28719
28864
  actions.push({
28720
28865
  label: `Remove ${VERITY_MD_FILE}`,
28721
- apply: () => (0, import_node_fs56.rmSync)(verityMd, { force: true })
28866
+ apply: () => (0, import_node_fs57.rmSync)(verityMd, { force: true })
28722
28867
  });
28723
28868
  }
28724
28869
  }
28725
28870
  const cleanupEmptyDir = (path) => {
28726
- if ((0, import_node_fs56.existsSync)(path) && (0, import_node_fs56.statSync)(path).isDirectory() && (0, import_node_fs56.readdirSync)(path).length === 0) {
28727
- (0, import_node_fs56.rmdirSync)(path);
28871
+ if ((0, import_node_fs57.existsSync)(path) && (0, import_node_fs57.statSync)(path).isDirectory() && (0, import_node_fs57.readdirSync)(path).length === 0) {
28872
+ (0, import_node_fs57.rmdirSync)(path);
28728
28873
  }
28729
28874
  };
28730
28875
  actions.push({
@@ -28735,11 +28880,11 @@ function registerUninstallCommand(program2) {
28735
28880
  }
28736
28881
  });
28737
28882
  const home = process.env.HOME ?? "";
28738
- const globalVerityDir = (0, import_node_path40.join)(home, ".verity");
28739
- if (purgeGlobal && (0, import_node_fs56.existsSync)(globalVerityDir)) {
28883
+ const globalVerityDir = (0, import_node_path41.join)(home, ".verity");
28884
+ if (purgeGlobal && (0, import_node_fs57.existsSync)(globalVerityDir)) {
28740
28885
  actions.push({
28741
28886
  label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
28742
- apply: () => (0, import_node_fs56.rmSync)(globalVerityDir, { recursive: true, force: true })
28887
+ apply: () => (0, import_node_fs57.rmSync)(globalVerityDir, { recursive: true, force: true })
28743
28888
  });
28744
28889
  }
28745
28890
  if (actions.length === 0) {
@@ -28933,8 +29078,8 @@ function registerTaskCommands(program2) {
28933
29078
  }
28934
29079
 
28935
29080
  // src/commands/reset.ts
28936
- var import_node_fs57 = require("node:fs");
28937
- var import_node_path41 = require("node:path");
29081
+ var import_node_fs58 = require("node:fs");
29082
+ var import_node_path42 = require("node:path");
28938
29083
  function registerResetCommand(program2) {
28939
29084
  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) => {
28940
29085
  const globals = program2.opts();
@@ -28971,11 +29116,11 @@ function registerResetCommand(program2) {
28971
29116
  }
28972
29117
  const cacheDir = projectPath(CACHE_DIR);
28973
29118
  let purged = 0;
28974
- if ((0, import_node_fs57.existsSync)(cacheDir)) {
28975
- for (const entry of (0, import_node_fs57.readdirSync)(cacheDir)) {
29119
+ if ((0, import_node_fs58.existsSync)(cacheDir)) {
29120
+ for (const entry of (0, import_node_fs58.readdirSync)(cacheDir)) {
28976
29121
  if (entry.startsWith("pending-")) {
28977
29122
  try {
28978
- (0, import_node_fs57.unlinkSync)((0, import_node_path41.join)(cacheDir, entry));
29123
+ (0, import_node_fs58.unlinkSync)((0, import_node_path42.join)(cacheDir, entry));
28979
29124
  purged++;
28980
29125
  } catch {
28981
29126
  }
@@ -28990,19 +29135,19 @@ function registerResetCommand(program2) {
28990
29135
  projectPath(`${VERITY_DIR}/.last-analysis`)
28991
29136
  ];
28992
29137
  for (const file of filesToClear) {
28993
- if ((0, import_node_fs57.existsSync)(file)) {
29138
+ if ((0, import_node_fs58.existsSync)(file)) {
28994
29139
  try {
28995
- (0, import_node_fs57.writeFileSync)(file, "");
29140
+ (0, import_node_fs58.writeFileSync)(file, "");
28996
29141
  } catch {
28997
29142
  }
28998
29143
  }
28999
29144
  }
29000
29145
  if (opts.all) {
29001
29146
  const logsDir = projectPath(`${VERITY_DIR}/.logs`);
29002
- if ((0, import_node_fs57.existsSync)(logsDir)) {
29003
- for (const entry of (0, import_node_fs57.readdirSync)(logsDir)) {
29147
+ if ((0, import_node_fs58.existsSync)(logsDir)) {
29148
+ for (const entry of (0, import_node_fs58.readdirSync)(logsDir)) {
29004
29149
  try {
29005
- (0, import_node_fs57.unlinkSync)((0, import_node_path41.join)(logsDir, entry));
29150
+ (0, import_node_fs58.unlinkSync)((0, import_node_path42.join)(logsDir, entry));
29006
29151
  } catch {
29007
29152
  }
29008
29153
  }
@@ -29014,7 +29159,7 @@ function registerResetCommand(program2) {
29014
29159
  }
29015
29160
 
29016
29161
  // src/commands/reflect.ts
29017
- var import_node_fs58 = require("node:fs");
29162
+ var import_node_fs59 = require("node:fs");
29018
29163
 
29019
29164
  // src/lib/reflection-globs.ts
29020
29165
  var MAX_GLOBS = 6;
@@ -29052,7 +29197,7 @@ async function writeNodeToDisk(args) {
29052
29197
  { treePaths: listTrackedFiles(), recordBaseline: false }
29053
29198
  );
29054
29199
  if (written === 0) return false;
29055
- return (0, import_node_fs58.existsSync)(projectPath(`${VERITY_DIR}/memory/${args.filePath}`));
29200
+ return (0, import_node_fs59.existsSync)(projectPath(`${VERITY_DIR}/memory/${args.filePath}`));
29056
29201
  } catch {
29057
29202
  return false;
29058
29203
  }
@@ -29551,8 +29696,8 @@ function registerTelemetryCommands(program2) {
29551
29696
  }
29552
29697
 
29553
29698
  // src/cli.ts
29554
- program.name("verity").description("CLI for Verity quality gate service").version("0.33.1-experimental.4a41d04").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) => {
29555
- installStderrLog(actionCommand.name(), process.argv.slice(2), "0.33.1-experimental.4a41d04");
29699
+ program.name("verity").description("CLI for Verity quality gate service").version("0.33.2-experimental.0c53bed").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) => {
29700
+ installStderrLog(actionCommand.name(), process.argv.slice(2), "0.33.2-experimental.0c53bed");
29556
29701
  setUserNamedServiceUrl(program.opts().serviceUrl);
29557
29702
  try {
29558
29703
  await foldLegacyLocalCredential();