@codacy/verity-cli 0.32.6-experimental.8f2b5f7 → 0.32.6-experimental.df0a578

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 (2) hide show
  1. package/bin/verity.js +933 -546
  2. package/package.json +1 -1
package/bin/verity.js CHANGED
@@ -13846,14 +13846,206 @@ async function appendEntry(taskId, entry) {
13846
13846
  }
13847
13847
 
13848
13848
  // src/lib/memory-retrieval.ts
13849
- var import_promises7 = require("node:fs/promises");
13849
+ var import_promises8 = require("node:fs/promises");
13850
+ var import_node_fs11 = require("node:fs");
13851
+ var import_node_path11 = require("node:path");
13852
+
13853
+ // src/lib/org-mirror.ts
13850
13854
  var import_node_fs10 = require("node:fs");
13855
+ var import_promises7 = require("node:fs/promises");
13851
13856
  var import_node_path10 = require("node:path");
13857
+ var ORG_KINDS = ["decision", "security", "gotcha", "pattern", "domain", "integration"];
13858
+ var STATE_FILE = ".org-pull-state.json";
13859
+ var BODY_MAX = 8192;
13860
+ function orgMirrorDir(remote = requestRemote()) {
13861
+ const parsed = parseRemote(remote);
13862
+ if (!parsed) return null;
13863
+ return (0, import_node_path10.join)(verityHome(), "orgs", parsed.host, parsed.owner.toLowerCase(), "memory");
13864
+ }
13865
+ function slugify(s) {
13866
+ return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
13867
+ }
13868
+ function orgNodePath(node) {
13869
+ const kind = ORG_KINDS.includes(node.kind) ? node.kind : "domain";
13870
+ return `${kind}/${slugify(node.title) || "claim"}-${node.tag_id.replace(/-/g, "").slice(0, 8)}.md`;
13871
+ }
13872
+ function renderOrgNode(node, orgName) {
13873
+ const fm = [
13874
+ "---",
13875
+ `id: ${JSON.stringify(node.tag_id)}`,
13876
+ `node_id: ${JSON.stringify(node.node_id)}`,
13877
+ 'scope: "org"',
13878
+ `org: ${JSON.stringify(orgName)}`,
13879
+ `kind: ${JSON.stringify(node.kind)}`,
13880
+ `title: ${JSON.stringify(node.title)}`,
13881
+ `origin: ${JSON.stringify(node.origin)}`,
13882
+ `signal: ${JSON.stringify(node.signal)}`,
13883
+ `tier: ${node.tier === null ? "null" : JSON.stringify(node.tier)}`,
13884
+ `applies_to: ${JSON.stringify(node.applies_to)}`,
13885
+ `source_repo_count: ${JSON.stringify(node.source_repo_count)}`,
13886
+ `promoted_at: ${JSON.stringify(node.promoted_at)}`,
13887
+ 'status: "active"',
13888
+ "---"
13889
+ ];
13890
+ return `${fm.join("\n")}
13891
+
13892
+ # ${node.title}
13893
+
13894
+ ${node.body.trim()}
13895
+ `;
13896
+ }
13897
+ function parseOrgNode(content) {
13898
+ const m = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
13899
+ if (!m) return null;
13900
+ const fm = {};
13901
+ for (const line of m[1].split("\n")) {
13902
+ const kv = line.match(/^([a-z_]+):\s*(.*)$/);
13903
+ if (!kv) continue;
13904
+ try {
13905
+ fm[kv[1]] = JSON.parse(kv[2]);
13906
+ } catch {
13907
+ fm[kv[1]] = kv[2];
13908
+ }
13909
+ }
13910
+ if (fm.scope !== "org" || typeof fm.id !== "string" || typeof fm.title !== "string") return null;
13911
+ if (fm.status && fm.status !== "active") return null;
13912
+ const body = m[2].replace(/^\s*#[^\n]*\n/, "").trim();
13913
+ return {
13914
+ tag_id: fm.id,
13915
+ node_id: typeof fm.node_id === "string" ? fm.node_id : "",
13916
+ kind: typeof fm.kind === "string" ? fm.kind : "domain",
13917
+ title: fm.title,
13918
+ body,
13919
+ origin: typeof fm.origin === "string" ? fm.origin : "",
13920
+ signal: typeof fm.signal === "string" ? fm.signal : "",
13921
+ tier: typeof fm.tier === "number" ? fm.tier : null,
13922
+ applies_to: Array.isArray(fm.applies_to) ? fm.applies_to.filter((v) => typeof v === "string") : [],
13923
+ source_repo_count: typeof fm.source_repo_count === "number" ? fm.source_repo_count : 1,
13924
+ promoted_at: typeof fm.promoted_at === "string" ? fm.promoted_at : ""
13925
+ };
13926
+ }
13927
+ async function readState(dir) {
13928
+ try {
13929
+ const parsed = JSON.parse(await (0, import_promises7.readFile)((0, import_node_path10.join)(dir, STATE_FILE), "utf-8"));
13930
+ return {
13931
+ version: typeof parsed?.version === "string" ? parsed.version : null,
13932
+ organization: parsed?.organization && typeof parsed.organization.id === "string" ? parsed.organization : null,
13933
+ files: Array.isArray(parsed?.files) ? parsed.files.filter((f) => typeof f === "string") : []
13934
+ };
13935
+ } catch {
13936
+ return { version: null, organization: null, files: [] };
13937
+ }
13938
+ }
13939
+ async function writeState(dir, state) {
13940
+ await (0, import_promises7.mkdir)(dir, { recursive: true });
13941
+ await (0, import_promises7.writeFile)((0, import_node_path10.join)(dir, STATE_FILE), JSON.stringify({
13942
+ ...state.version ? { version: state.version } : {},
13943
+ organization: state.organization,
13944
+ pulled_at: (/* @__PURE__ */ new Date()).toISOString(),
13945
+ files: state.files
13946
+ }, null, 2) + "\n");
13947
+ }
13948
+ function renderIndex(orgName, nodes) {
13949
+ const lines = [
13950
+ `# Org Knowledge \u2014 ${orgName}`,
13951
+ "",
13952
+ "*Auto-generated by verity CLI from what this organization's repositories learned. Do not hand-edit; `verity memory pull` overwrites it.*",
13953
+ "",
13954
+ '> These claims hold across the organization\'s repositories, not only this one. Each names where it came from. A claim that is wrong for this repository is demoted with `verity memory demote <id> --reason "\u2026"`, for everyone.',
13955
+ ""
13956
+ ];
13957
+ const byKind = /* @__PURE__ */ new Map();
13958
+ for (const n of nodes) byKind.set(n.kind, [...byKind.get(n.kind) ?? [], n]);
13959
+ for (const kind of ORG_KINDS) {
13960
+ const list2 = byKind.get(kind);
13961
+ if (!list2?.length) continue;
13962
+ lines.push(`## ${kind}/ (${list2.length})`);
13963
+ for (const n of list2) lines.push(`- [[${orgNodePath(n).split("/")[1].replace(/\.md$/, "")}]] \u2014 ${n.title} \xB7 ${n.origin}`);
13964
+ lines.push("");
13965
+ }
13966
+ if (nodes.length === 0) lines.push("No org knowledge yet.", "");
13967
+ return lines.join("\n");
13968
+ }
13969
+ async function pullOrgKnowledge(opts) {
13970
+ const dir = orgMirrorDir(opts.remote ?? requestRemote());
13971
+ if (!dir) return { ok: true, status: "no_remote", received: 0, dir: null };
13972
+ const state = await readState(dir);
13973
+ const params = new URLSearchParams({ for: "agent" });
13974
+ if (!opts.force && state.version) params.set("if_version", state.version);
13975
+ const res = await apiRequest({
13976
+ method: "GET",
13977
+ path: `/memory/org?${params.toString()}`,
13978
+ serviceUrl: opts.serviceUrl,
13979
+ token: opts.token,
13980
+ verbose: opts.verbose,
13981
+ timeout: opts.timeoutMs ?? 3e4,
13982
+ cmd: "memory-org-pull"
13983
+ });
13984
+ if (!res.ok) return { ok: false, error: res.error, category: res.category };
13985
+ const page = res.data;
13986
+ if (page.unchanged) return { ok: true, status: "unchanged", received: 0, dir };
13987
+ const org = page.organization;
13988
+ const nodes = org ? (page.nodes ?? []).flatMap((n) => typeof n.tag_id === "string" && typeof n.title === "string" && typeof n.body === "string" ? [{
13989
+ tag_id: n.tag_id,
13990
+ node_id: typeof n.node_id === "string" ? n.node_id : "",
13991
+ kind: typeof n.kind === "string" ? n.kind : "domain",
13992
+ title: n.title,
13993
+ body: n.body.slice(0, BODY_MAX),
13994
+ origin: typeof n.origin === "string" ? n.origin : "",
13995
+ signal: typeof n.signal === "string" ? n.signal : "",
13996
+ tier: typeof n.tier === "number" ? n.tier : null,
13997
+ applies_to: Array.isArray(n.applies_to) ? n.applies_to.filter((v) => typeof v === "string") : [],
13998
+ source_repo_count: typeof n.source_repo_count === "number" ? n.source_repo_count : 1,
13999
+ promoted_at: typeof n.promoted_at === "string" ? n.promoted_at : ""
14000
+ }] : []) : [];
14001
+ const written = /* @__PURE__ */ new Set();
14002
+ await (0, import_promises7.mkdir)(dir, { recursive: true });
14003
+ for (const n of nodes) {
14004
+ const rel = orgNodePath(n);
14005
+ if (written.has(rel)) continue;
14006
+ await (0, import_promises7.mkdir)((0, import_node_path10.join)(dir, rel.split("/")[0]), { recursive: true });
14007
+ await (0, import_promises7.writeFile)((0, import_node_path10.join)(dir, rel), renderOrgNode(n, org?.name ?? ""));
14008
+ written.add(rel);
14009
+ }
14010
+ for (const rel of state.files) {
14011
+ if (!written.has(rel)) await (0, import_promises7.rm)((0, import_node_path10.join)(dir, rel), { force: true });
14012
+ }
14013
+ await (0, import_promises7.writeFile)((0, import_node_path10.join)(dir, "index.md"), renderIndex(org?.name ?? "no organization", nodes));
14014
+ await writeState(dir, { version: org ? page.version : null, organization: org, files: [...written].sort() });
14015
+ return { ok: true, status: org ? "pulled" : "none", received: nodes.length, dir };
14016
+ }
14017
+ async function readOrgMirror(remote = requestRemote()) {
14018
+ const dir = orgMirrorDir(remote);
14019
+ if (!dir || !(0, import_node_fs10.existsSync)(dir)) return [];
14020
+ const out = [];
14021
+ for (const kind of ORG_KINDS) {
14022
+ const kindDir = (0, import_node_path10.join)(dir, kind);
14023
+ if (!(0, import_node_fs10.existsSync)(kindDir)) continue;
14024
+ let files;
14025
+ try {
14026
+ files = await (0, import_promises7.readdir)(kindDir);
14027
+ } catch {
14028
+ continue;
14029
+ }
14030
+ for (const file of files) {
14031
+ if (!file.endsWith(".md")) continue;
14032
+ try {
14033
+ const node = parseOrgNode(await (0, import_promises7.readFile)((0, import_node_path10.join)(kindDir, file), "utf-8"));
14034
+ if (node) out.push(node);
14035
+ } catch {
14036
+ }
14037
+ }
14038
+ }
14039
+ return out;
14040
+ }
14041
+
14042
+ // src/lib/memory-retrieval.ts
13852
14043
  var memoryDir = () => projectPath(`${VERITY_DIR}/memory`);
13853
14044
  var DOMAINS = ["decisions", "quality", "security", "intent", "gotchas", "patterns", "domain", "integrations"];
13854
14045
  var DEFAULT_BUDGET_TOKENS = 2e3;
13855
14046
  var MAX_BUDGET_TOKENS = 4e3;
13856
14047
  var MIN_SCORE = 0.5;
14048
+ var ORG_MIN_SHARED_TERMS = 2;
13857
14049
  function tokenize(text) {
13858
14050
  return new Set(
13859
14051
  text.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((w) => w.length > 2)
@@ -13866,6 +14058,26 @@ function jaccardKeywords(a, b) {
13866
14058
  const union = a.size + b.size - inter;
13867
14059
  return union === 0 ? 0 : inter / union;
13868
14060
  }
14061
+ function sharedTerms(a, b) {
14062
+ let n = 0;
14063
+ for (const w of a) if (b.has(w)) n++;
14064
+ return n;
14065
+ }
14066
+ function orgNodeToLocal(n) {
14067
+ return {
14068
+ path: `org:${n.tag_id}`,
14069
+ nodeId: n.tag_id,
14070
+ kind: n.kind,
14071
+ title: n.title,
14072
+ body: n.body.slice(0, 2e3),
14073
+ fileGlobs: [],
14074
+ confidence: 0.5,
14075
+ citedCount: 0,
14076
+ tokenEstimate: Math.ceil((n.title.length + n.body.length) / 4) + 20,
14077
+ scope: "org",
14078
+ origin: n.origin
14079
+ };
14080
+ }
13869
14081
  function globMatch(glob, filePath) {
13870
14082
  if (glob === filePath) return true;
13871
14083
  const suffixMatch = glob.match(/^\*\*\/\*(.+)$/);
@@ -13941,19 +14153,19 @@ function parseFrontmatter(content) {
13941
14153
  return { fm, body: match[2].trim() };
13942
14154
  }
13943
14155
  async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = DEFAULT_BUDGET_TOKENS) {
13944
- if (!(0, import_node_fs10.existsSync)(memoryDir())) return null;
14156
+ const hasRepoGraph = (0, import_node_fs11.existsSync)(memoryDir());
13945
14157
  const budget = Math.min(budgetTokens, MAX_BUDGET_TOKENS);
13946
14158
  const promptTokens = tokenize(promptText);
13947
14159
  const nodes = [];
13948
- for (const domain of DOMAINS) {
13949
- const domainDir = (0, import_node_path10.join)(memoryDir(), domain);
13950
- if (!(0, import_node_fs10.existsSync)(domainDir)) continue;
14160
+ for (const domain of hasRepoGraph ? DOMAINS : []) {
14161
+ const domainDir = (0, import_node_path11.join)(memoryDir(), domain);
14162
+ if (!(0, import_node_fs11.existsSync)(domainDir)) continue;
13951
14163
  try {
13952
- const files = await (0, import_promises7.readdir)(domainDir);
14164
+ const files = await (0, import_promises8.readdir)(domainDir);
13953
14165
  for (const file of files) {
13954
14166
  if (!file.endsWith(".md")) continue;
13955
14167
  try {
13956
- const content = await (0, import_promises7.readFile)((0, import_node_path10.join)(domainDir, file), "utf-8");
14168
+ const content = await (0, import_promises8.readFile)((0, import_node_path11.join)(domainDir, file), "utf-8");
13957
14169
  const { fm, body } = parseFrontmatter(content);
13958
14170
  if (fm.status && fm.status !== "active") continue;
13959
14171
  nodes.push({
@@ -13973,6 +14185,13 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
13973
14185
  } catch {
13974
14186
  }
13975
14187
  }
14188
+ try {
14189
+ for (const claim of await readOrgMirror()) {
14190
+ const local = orgNodeToLocal(claim);
14191
+ if (sharedTerms(tokenize(`${local.title} ${local.body}`), promptTokens) >= ORG_MIN_SHARED_TERMS) nodes.push(local);
14192
+ }
14193
+ } catch {
14194
+ }
13976
14195
  if (nodes.length === 0) return null;
13977
14196
  const scored = nodes.map((n) => ({
13978
14197
  ...n,
@@ -13991,12 +14210,13 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
13991
14210
  const lines = [
13992
14211
  "## Project Knowledge (auto-injected)",
13993
14212
  "",
13994
- `*${selected.length} node(s) relevant to your current task. See \`.verity/memory/index.md\` for the full knowledge base.*`,
14213
+ `*${selected.length} node(s) relevant to your current task. See \`.verity/memory/index.md\` for the full knowledge base${selected.some((n) => n.scope === "org") ? ", and `~/.verity/orgs/` for what the organization's other repositories learned" : ""}.*`,
13995
14214
  ""
13996
14215
  ];
13997
14216
  for (const node of selected) {
13998
14217
  lines.push(`### ${node.title}`);
13999
- lines.push(`*${node.kind}* \xB7 confidence ${Math.round(node.confidence * 100)}%`);
14218
+ if (node.scope === "org") lines.push(`*org \xB7 ${node.origin}* \xB7 ${node.kind}`);
14219
+ else lines.push(`*${node.kind}* \xB7 confidence ${Math.round(node.confidence * 100)}%`);
14000
14220
  lines.push("");
14001
14221
  lines.push(node.body.slice(0, 800));
14002
14222
  lines.push("");
@@ -14011,14 +14231,14 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
14011
14231
  }
14012
14232
 
14013
14233
  // src/lib/memory-sync.ts
14014
- var import_promises8 = require("node:fs/promises");
14015
- var import_node_fs13 = require("node:fs");
14016
- var import_node_path12 = require("node:path");
14234
+ var import_promises9 = require("node:fs/promises");
14235
+ var import_node_fs14 = require("node:fs");
14236
+ var import_node_path13 = require("node:path");
14017
14237
  var import_node_crypto3 = require("node:crypto");
14018
14238
 
14019
14239
  // src/lib/gitignore.ts
14020
14240
  var import_node_child_process6 = require("node:child_process");
14021
- var import_node_fs11 = require("node:fs");
14241
+ var import_node_fs12 = require("node:fs");
14022
14242
  var VERITY_GITIGNORE_MARKER = "# Verity \u2014 machine-local state.";
14023
14243
  var SETTINGS_LOCAL_IGNORE_ENTRY = ".claude/settings.local.json";
14024
14244
  var VERITY_GITIGNORE_BLOCK = [
@@ -14102,7 +14322,7 @@ function fenceMemoryLines(lines) {
14102
14322
  function ensureVerityGitignore() {
14103
14323
  let content = "";
14104
14324
  try {
14105
- content = (0, import_node_fs11.readFileSync)(".gitignore", "utf-8");
14325
+ content = (0, import_node_fs12.readFileSync)(".gitignore", "utf-8");
14106
14326
  } catch {
14107
14327
  }
14108
14328
  const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
@@ -14129,7 +14349,7 @@ function ensureVerityGitignore() {
14129
14349
  const sep4 = text === "" ? "" : text.endsWith("\n") ? "\n" : "\n\n";
14130
14350
  text = text + sep4 + VERITY_GITIGNORE_BLOCK;
14131
14351
  }
14132
- if (text !== content) (0, import_node_fs11.writeFileSync)(".gitignore", text);
14352
+ if (text !== content) (0, import_node_fs12.writeFileSync)(".gitignore", text);
14133
14353
  return verified(
14134
14354
  memoryIsCommitted ? "memory-tracked" : hasSupersededMemory ? "memory-fenced" : needsRepair ? "repaired" : "added"
14135
14355
  );
@@ -14149,7 +14369,7 @@ function untrackMemory() {
14149
14369
  function writeFencedBlock() {
14150
14370
  let content = "";
14151
14371
  try {
14152
- content = (0, import_node_fs11.readFileSync)(".gitignore", "utf-8");
14372
+ content = (0, import_node_fs12.readFileSync)(".gitignore", "utf-8");
14153
14373
  } catch {
14154
14374
  }
14155
14375
  const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
@@ -14161,7 +14381,7 @@ function writeFencedBlock() {
14161
14381
  text = text + sep4 + VERITY_GITIGNORE_BLOCK;
14162
14382
  }
14163
14383
  try {
14164
- (0, import_node_fs11.writeFileSync)(".gitignore", text);
14384
+ (0, import_node_fs12.writeFileSync)(".gitignore", text);
14165
14385
  return true;
14166
14386
  } catch {
14167
14387
  return false;
@@ -14170,14 +14390,14 @@ function writeFencedBlock() {
14170
14390
  function fenceMemory() {
14171
14391
  let original = null;
14172
14392
  try {
14173
- original = (0, import_node_fs11.readFileSync)(".gitignore", "utf-8");
14393
+ original = (0, import_node_fs12.readFileSync)(".gitignore", "utf-8");
14174
14394
  } catch {
14175
14395
  original = null;
14176
14396
  }
14177
14397
  const restore = () => {
14178
14398
  try {
14179
- if (original === null) (0, import_node_fs11.rmSync)(".gitignore", { force: true });
14180
- else (0, import_node_fs11.writeFileSync)(".gitignore", original);
14399
+ if (original === null) (0, import_node_fs12.rmSync)(".gitignore", { force: true });
14400
+ else (0, import_node_fs12.writeFileSync)(".gitignore", original);
14181
14401
  } catch {
14182
14402
  }
14183
14403
  };
@@ -14195,7 +14415,7 @@ function fenceMemory() {
14195
14415
  }
14196
14416
  function memoryOptOut() {
14197
14417
  try {
14198
- return (0, import_node_fs11.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
14418
+ return (0, import_node_fs12.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
14199
14419
  } catch {
14200
14420
  return false;
14201
14421
  }
@@ -14203,13 +14423,13 @@ function memoryOptOut() {
14203
14423
  function keepMemoryTracked() {
14204
14424
  let content = "";
14205
14425
  try {
14206
- content = (0, import_node_fs11.readFileSync)(".gitignore", "utf-8");
14426
+ content = (0, import_node_fs12.readFileSync)(".gitignore", "utf-8");
14207
14427
  } catch {
14208
14428
  }
14209
14429
  if (content.includes(MEMORY_OPT_OUT_MARKER)) return "already";
14210
14430
  try {
14211
14431
  const sep4 = content === "" ? "" : content.endsWith("\n") ? "\n" : "\n\n";
14212
- (0, import_node_fs11.writeFileSync)(".gitignore", content + sep4 + MEMORY_OPT_OUT_STANZA);
14432
+ (0, import_node_fs12.writeFileSync)(".gitignore", content + sep4 + MEMORY_OPT_OUT_STANZA);
14213
14433
  } catch {
14214
14434
  return "failed";
14215
14435
  }
@@ -14244,26 +14464,26 @@ function untrackVerityState() {
14244
14464
  }
14245
14465
 
14246
14466
  // src/lib/safe-path.ts
14247
- var import_node_fs12 = require("node:fs");
14248
- var import_node_path11 = require("node:path");
14467
+ var import_node_fs13 = require("node:fs");
14468
+ var import_node_path12 = require("node:path");
14249
14469
  function resolveInside(baseDir, candidate) {
14250
14470
  if (typeof candidate !== "string" || candidate.length === 0) return null;
14251
- if ((0, import_node_path11.isAbsolute)(candidate)) return null;
14252
- const baseAbs = (0, import_node_path11.resolve)(baseDir);
14253
- const full = (0, import_node_path11.resolve)(baseAbs, candidate);
14254
- const baseSep = baseAbs.endsWith(import_node_path11.sep) ? baseAbs : baseAbs + import_node_path11.sep;
14471
+ if ((0, import_node_path12.isAbsolute)(candidate)) return null;
14472
+ const baseAbs = (0, import_node_path12.resolve)(baseDir);
14473
+ const full = (0, import_node_path12.resolve)(baseAbs, candidate);
14474
+ const baseSep = baseAbs.endsWith(import_node_path12.sep) ? baseAbs : baseAbs + import_node_path12.sep;
14255
14475
  if (full !== baseAbs && !full.startsWith(baseSep)) return null;
14256
14476
  try {
14257
- if ((0, import_node_fs12.existsSync)(baseAbs)) {
14258
- const realBase = (0, import_node_fs12.realpathSync)(baseAbs);
14259
- const realBaseSep = realBase.endsWith(import_node_path11.sep) ? realBase : realBase + import_node_path11.sep;
14477
+ if ((0, import_node_fs13.existsSync)(baseAbs)) {
14478
+ const realBase = (0, import_node_fs13.realpathSync)(baseAbs);
14479
+ const realBaseSep = realBase.endsWith(import_node_path12.sep) ? realBase : realBase + import_node_path12.sep;
14260
14480
  let probe = full;
14261
- while (!(0, import_node_fs12.existsSync)(probe)) {
14262
- const parent = (0, import_node_path11.dirname)(probe);
14481
+ while (!(0, import_node_fs13.existsSync)(probe)) {
14482
+ const parent = (0, import_node_path12.dirname)(probe);
14263
14483
  if (parent === probe) break;
14264
14484
  probe = parent;
14265
14485
  }
14266
- const realProbe = (0, import_node_fs12.realpathSync)(probe);
14486
+ const realProbe = (0, import_node_fs13.realpathSync)(probe);
14267
14487
  if (realProbe !== realBase && !realProbe.startsWith(realBaseSep)) return null;
14268
14488
  }
14269
14489
  } catch {
@@ -14346,36 +14566,36 @@ var memoryDir2 = () => projectPath(`${VERITY_DIR}/memory`);
14346
14566
  var DOMAINS2 = ["decisions", "quality", "security", "intent", "gotchas", "patterns", "domain", "integrations", "_archive"];
14347
14567
  var syncStateFile = () => projectPath(`${VERITY_DIR}/.memory-sync-state.json`);
14348
14568
  async function ensureMemoryDir() {
14349
- await (0, import_promises8.mkdir)(memoryDir2(), { recursive: true });
14569
+ await (0, import_promises9.mkdir)(memoryDir2(), { recursive: true });
14350
14570
  for (const domain of DOMAINS2) {
14351
- await (0, import_promises8.mkdir)((0, import_node_path12.join)(memoryDir2(), domain), { recursive: true });
14571
+ await (0, import_promises9.mkdir)((0, import_node_path13.join)(memoryDir2(), domain), { recursive: true });
14352
14572
  }
14353
- if (!(0, import_node_fs13.existsSync)((0, import_node_path12.join)(memoryDir2(), "SCHEMA.md"))) {
14354
- await (0, import_promises8.writeFile)((0, import_node_path12.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
14573
+ if (!(0, import_node_fs14.existsSync)((0, import_node_path13.join)(memoryDir2(), "SCHEMA.md"))) {
14574
+ await (0, import_promises9.writeFile)((0, import_node_path13.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
14355
14575
  }
14356
- if (!(0, import_node_fs13.existsSync)((0, import_node_path12.join)(memoryDir2(), "index.md"))) {
14357
- await (0, import_promises8.writeFile)((0, import_node_path12.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
14576
+ if (!(0, import_node_fs14.existsSync)((0, import_node_path13.join)(memoryDir2(), "index.md"))) {
14577
+ await (0, import_promises9.writeFile)((0, import_node_path13.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
14358
14578
  }
14359
- if (!(0, import_node_fs13.existsSync)((0, import_node_path12.join)(memoryDir2(), "log.md"))) {
14360
- await (0, import_promises8.writeFile)((0, import_node_path12.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
14579
+ if (!(0, import_node_fs14.existsSync)((0, import_node_path13.join)(memoryDir2(), "log.md"))) {
14580
+ await (0, import_promises9.writeFile)((0, import_node_path13.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
14361
14581
  }
14362
14582
  }
14363
14583
  async function buildManifest() {
14364
- if (!(0, import_node_fs13.existsSync)(memoryDir2())) {
14584
+ if (!(0, import_node_fs14.existsSync)(memoryDir2())) {
14365
14585
  return { schema_version: 1, nodes: [], index_hash: null, log_length: 0 };
14366
14586
  }
14367
14587
  const nodes = [];
14368
14588
  for (const domain of DOMAINS2) {
14369
- const domainDir = (0, import_node_path12.join)(memoryDir2(), domain);
14370
- if (!(0, import_node_fs13.existsSync)(domainDir)) continue;
14589
+ const domainDir = (0, import_node_path13.join)(memoryDir2(), domain);
14590
+ if (!(0, import_node_fs14.existsSync)(domainDir)) continue;
14371
14591
  try {
14372
- const files = await (0, import_promises8.readdir)(domainDir);
14592
+ const files = await (0, import_promises9.readdir)(domainDir);
14373
14593
  for (const file of files) {
14374
14594
  if (!file.endsWith(".md")) continue;
14375
14595
  const filePath = `${domain}/${file}`;
14376
- const fullPath = (0, import_node_path12.join)(memoryDir2(), filePath);
14596
+ const fullPath = (0, import_node_path13.join)(memoryDir2(), filePath);
14377
14597
  try {
14378
- const content = await (0, import_promises8.readFile)(fullPath, "utf-8");
14598
+ const content = await (0, import_promises9.readFile)(fullPath, "utf-8");
14379
14599
  const hash = (0, import_node_crypto3.createHash)("sha256").update(content).digest("hex").slice(0, 16);
14380
14600
  nodes.push({ path: filePath, content_hash: `sha256:${hash}` });
14381
14601
  } catch {
@@ -14386,13 +14606,13 @@ async function buildManifest() {
14386
14606
  }
14387
14607
  let indexHash = null;
14388
14608
  try {
14389
- const indexContent = await (0, import_promises8.readFile)((0, import_node_path12.join)(memoryDir2(), "index.md"), "utf-8");
14609
+ const indexContent = await (0, import_promises9.readFile)((0, import_node_path13.join)(memoryDir2(), "index.md"), "utf-8");
14390
14610
  indexHash = `sha256:${(0, import_node_crypto3.createHash)("sha256").update(indexContent).digest("hex").slice(0, 16)}`;
14391
14611
  } catch {
14392
14612
  }
14393
14613
  let logLength = 0;
14394
14614
  try {
14395
- const logContent = await (0, import_promises8.readFile)((0, import_node_path12.join)(memoryDir2(), "log.md"), "utf-8");
14615
+ const logContent = await (0, import_promises9.readFile)((0, import_node_path13.join)(memoryDir2(), "log.md"), "utf-8");
14396
14616
  logLength = logContent.split("\n").length;
14397
14617
  } catch {
14398
14618
  }
@@ -14403,15 +14623,15 @@ function hashContent(content) {
14403
14623
  }
14404
14624
  async function readOnDiskNodes() {
14405
14625
  const out = /* @__PURE__ */ new Map();
14406
- if (!(0, import_node_fs13.existsSync)(memoryDir2())) return out;
14626
+ if (!(0, import_node_fs14.existsSync)(memoryDir2())) return out;
14407
14627
  for (const domain of DOMAINS2) {
14408
- const domainDir = (0, import_node_path12.join)(memoryDir2(), domain);
14409
- if (!(0, import_node_fs13.existsSync)(domainDir)) continue;
14628
+ const domainDir = (0, import_node_path13.join)(memoryDir2(), domain);
14629
+ if (!(0, import_node_fs14.existsSync)(domainDir)) continue;
14410
14630
  try {
14411
- for (const file of await (0, import_promises8.readdir)(domainDir)) {
14631
+ for (const file of await (0, import_promises9.readdir)(domainDir)) {
14412
14632
  if (!file.endsWith(".md")) continue;
14413
14633
  try {
14414
- out.set(`${domain}/${file}`, hashContent(await (0, import_promises8.readFile)((0, import_node_path12.join)(domainDir, file), "utf-8")));
14634
+ out.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0, import_node_path13.join)(domainDir, file), "utf-8")));
14415
14635
  } catch {
14416
14636
  }
14417
14637
  }
@@ -14423,7 +14643,7 @@ async function readOnDiskNodes() {
14423
14643
  async function readSyncBaseline() {
14424
14644
  const out = /* @__PURE__ */ new Map();
14425
14645
  try {
14426
- const parsed = JSON.parse(await (0, import_promises8.readFile)(syncStateFile(), "utf-8"));
14646
+ const parsed = JSON.parse(await (0, import_promises9.readFile)(syncStateFile(), "utf-8"));
14427
14647
  if (Array.isArray(parsed?.nodes)) {
14428
14648
  for (const n of parsed.nodes) if (n?.path) out.set(n.path, n.hash ?? null);
14429
14649
  } else if (Array.isArray(parsed?.paths)) {
@@ -14439,7 +14659,7 @@ async function recordSyncedNodePaths() {
14439
14659
  const next = JSON.stringify({ schema: 2, nodes }) + "\n";
14440
14660
  let existing = "";
14441
14661
  try {
14442
- existing = await (0, import_promises8.readFile)(syncStateFile(), "utf-8");
14662
+ existing = await (0, import_promises9.readFile)(syncStateFile(), "utf-8");
14443
14663
  } catch {
14444
14664
  }
14445
14665
  if (existing === next) return;
@@ -14448,10 +14668,10 @@ async function recordSyncedNodePaths() {
14448
14668
  }
14449
14669
  }
14450
14670
  async function writeFileAtomic(path, content) {
14451
- await (0, import_promises8.mkdir)((0, import_node_path12.dirname)(path), { recursive: true });
14671
+ await (0, import_promises9.mkdir)((0, import_node_path13.dirname)(path), { recursive: true });
14452
14672
  const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
14453
- await (0, import_promises8.writeFile)(tmp, content);
14454
- await (0, import_promises8.rename)(tmp, path);
14673
+ await (0, import_promises9.writeFile)(tmp, content);
14674
+ await (0, import_promises9.rename)(tmp, path);
14455
14675
  }
14456
14676
  async function recordSyncBaseline() {
14457
14677
  await recordSyncedNodePaths();
@@ -14462,11 +14682,11 @@ async function computeEditedNodeUploads() {
14462
14682
  const uploads = [];
14463
14683
  for (const [path, prevHash] of prev) {
14464
14684
  if (prevHash == null) continue;
14465
- const full = (0, import_node_path12.join)(memoryDir2(), path);
14466
- if (!(0, import_node_fs13.existsSync)(full)) continue;
14685
+ const full = (0, import_node_path13.join)(memoryDir2(), path);
14686
+ if (!(0, import_node_fs14.existsSync)(full)) continue;
14467
14687
  let content;
14468
14688
  try {
14469
- content = await (0, import_promises8.readFile)(full, "utf-8");
14689
+ content = await (0, import_promises9.readFile)(full, "utf-8");
14470
14690
  } catch {
14471
14691
  continue;
14472
14692
  }
@@ -14507,8 +14727,8 @@ async function applyMemoryWrites(writes, opts = {}) {
14507
14727
  const logLines = [`- ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 16)} \u2014 Applied ${count} write(s) from server`];
14508
14728
  for (const n of notes) logLines.push(` - ${n}`);
14509
14729
  try {
14510
- const existing = (0, import_node_fs13.existsSync)((0, import_node_path12.join)(memoryDir2(), "log.md")) ? await (0, import_promises8.readFile)((0, import_node_path12.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
14511
- await (0, import_promises8.writeFile)((0, import_node_path12.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
14730
+ const existing = (0, import_node_fs14.existsSync)((0, import_node_path13.join)(memoryDir2(), "log.md")) ? await (0, import_promises9.readFile)((0, import_node_path13.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
14731
+ await (0, import_promises9.writeFile)((0, import_node_path13.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
14512
14732
  } catch {
14513
14733
  }
14514
14734
  if (opts.baseline === "written") await mergeSyncBaseline(synced);
@@ -14518,9 +14738,9 @@ async function applyMemoryWrites(writes, opts = {}) {
14518
14738
  async function mergeSyncBaseline(entries) {
14519
14739
  if (entries.size === 0) return;
14520
14740
  try {
14521
- if ((0, import_node_fs13.existsSync)(syncStateFile())) {
14741
+ if ((0, import_node_fs14.existsSync)(syncStateFile())) {
14522
14742
  try {
14523
- JSON.parse(await (0, import_promises8.readFile)(syncStateFile(), "utf-8"));
14743
+ JSON.parse(await (0, import_promises9.readFile)(syncStateFile(), "utf-8"));
14524
14744
  } catch {
14525
14745
  return;
14526
14746
  }
@@ -14546,10 +14766,10 @@ async function applyOneWrite(write, treePaths, lastServed) {
14546
14766
  notes.push(`${write.path}: dropped unmatched file_globs [${grounded.dropped.join(", ")}]`);
14547
14767
  }
14548
14768
  }
14549
- if ((0, import_node_fs13.existsSync)(fullPath)) {
14769
+ if ((0, import_node_fs14.existsSync)(fullPath)) {
14550
14770
  let existing = "";
14551
14771
  try {
14552
- existing = await (0, import_promises8.readFile)(fullPath, "utf-8");
14772
+ existing = await (0, import_promises9.readFile)(fullPath, "utf-8");
14553
14773
  } catch {
14554
14774
  }
14555
14775
  if (existing === content) return { written: false, syncedHash: hashContent(content), notes };
@@ -14562,8 +14782,8 @@ async function applyOneWrite(write, treePaths, lastServed) {
14562
14782
  notes.push(`${write.path}: updated from server (untouched here since the server delivered it)`);
14563
14783
  }
14564
14784
  }
14565
- await (0, import_promises8.mkdir)((0, import_node_path12.dirname)(fullPath), { recursive: true });
14566
- await (0, import_promises8.writeFile)(fullPath, content);
14785
+ await (0, import_promises9.mkdir)((0, import_node_path13.dirname)(fullPath), { recursive: true });
14786
+ await (0, import_promises9.writeFile)(fullPath, content);
14567
14787
  return { written: true, syncedHash: hashContent(content), notes };
14568
14788
  }
14569
14789
  function groundFileGlobs(content, treePaths) {
@@ -14603,10 +14823,10 @@ async function regenerateIndex() {
14603
14823
  ];
14604
14824
  let totalNodes = 0;
14605
14825
  for (const domain of DOMAINS2.filter((d) => d !== "_archive")) {
14606
- const domainDir = (0, import_node_path12.join)(memoryDir2(), domain);
14607
- if (!(0, import_node_fs13.existsSync)(domainDir)) continue;
14826
+ const domainDir = (0, import_node_path13.join)(memoryDir2(), domain);
14827
+ if (!(0, import_node_fs14.existsSync)(domainDir)) continue;
14608
14828
  try {
14609
- const files = await (0, import_promises8.readdir)(domainDir);
14829
+ const files = await (0, import_promises9.readdir)(domainDir);
14610
14830
  const mdFiles = files.filter((f) => f.endsWith(".md"));
14611
14831
  if (mdFiles.length === 0) continue;
14612
14832
  lines.push(`## ${domain}/ (${mdFiles.length})`);
@@ -14614,7 +14834,7 @@ async function regenerateIndex() {
14614
14834
  for (const file of mdFiles.sort()) {
14615
14835
  const slug = file.replace(/\.md$/, "");
14616
14836
  try {
14617
- const content = await (0, import_promises8.readFile)((0, import_node_path12.join)(domainDir, file), "utf-8");
14837
+ const content = await (0, import_promises9.readFile)((0, import_node_path13.join)(domainDir, file), "utf-8");
14618
14838
  const title = pickFrontmatter(content, "title") ?? slug;
14619
14839
  const kind = pickFrontmatter(content, "kind") ?? "-";
14620
14840
  const confidence = pickFrontmatter(content, "confidence");
@@ -14638,14 +14858,14 @@ async function regenerateIndex() {
14638
14858
  lines.push("No nodes yet. Run an analysis to start building the knowledge graph.");
14639
14859
  }
14640
14860
  const next = lines.join("\n") + "\n";
14641
- const indexPath = (0, import_node_path12.join)(memoryDir2(), "index.md");
14861
+ const indexPath = (0, import_node_path13.join)(memoryDir2(), "index.md");
14642
14862
  let existing = null;
14643
14863
  try {
14644
- existing = await (0, import_promises8.readFile)(indexPath, "utf-8");
14864
+ existing = await (0, import_promises9.readFile)(indexPath, "utf-8");
14645
14865
  } catch {
14646
14866
  }
14647
14867
  if (existing === next) return;
14648
- await (0, import_promises8.writeFile)(indexPath, next);
14868
+ await (0, import_promises9.writeFile)(indexPath, next);
14649
14869
  }
14650
14870
  function pickFrontmatter(content, key) {
14651
14871
  const re = new RegExp(`^${key}:\\s*"?([^"\\n]+?)"?\\s*$`, "m");
@@ -14672,6 +14892,90 @@ var LEGACY_MD_END = "<!-- gate-memory:end -->";
14672
14892
  var LEGACY_PRESERVE_START = "<!-- gate-memory:preserve -->";
14673
14893
  var LEGACY_PRESERVE_END = "<!-- /gate-memory:preserve -->";
14674
14894
  var CLAUDE_MD_PROSE = [
14895
+ "## Project Memory",
14896
+ "",
14897
+ "This project has a knowledge graph maintained at `.verity/memory/`. Before starting",
14898
+ "non-trivial work, scan `.verity/memory/index.md` for decisions, gotchas, and patterns",
14899
+ "that may apply to the change you are about to make. Open specific node files via",
14900
+ "the Read tool when the title or scope suggests relevance.",
14901
+ "",
14902
+ "The graph is auto-maintained by Verity. Files at `.verity/memory/_archive/` are",
14903
+ "superseded \u2014 ignore them unless investigating history.",
14904
+ "",
14905
+ "Knowledge the organization's other repositories learned is mirrored outside the",
14906
+ "repo at `~/.verity/orgs/<host>/<owner>/memory/` (`verity memory org` lists it).",
14907
+ "Each claim says where it came from; one that is wrong here is demoted for",
14908
+ 'everyone with `verity memory demote <id> --reason "\u2026"`.',
14909
+ "",
14910
+ "## Quality gate: accepted risks",
14911
+ "",
14912
+ "When the Verity pre-commit/pre-push gate FAILs, fix the findings \u2014 that is the",
14913
+ 'default. Use `verity waive <pattern-id> --file <path> --reason "\u2026"` ONLY to relay',
14914
+ "a risk a human has explicitly accepted: a named code-review finding, an ADR, or",
14915
+ "the user saying so in this conversation. The --reason must cite that source.",
14916
+ "",
14917
+ "Never waive on your own judgment, to get past a block, or pre-emptively. A waive",
14918
+ "binds to the file's current bytes and voids automatically when the file changes,",
14919
+ "and every waive is recorded in the run ledger. For a pattern-level false positive",
14920
+ "use `verity feedback finding <run-id> <pattern-id> false_positive` instead.",
14921
+ "",
14922
+ "## Post-task reflection",
14923
+ "",
14924
+ `When a task is complete (you've created a PR, the user says "done" or "ship it",`,
14925
+ "or the work is clearly finished), **draft the reflection yourself** \u2014 1\u20133",
14926
+ "concrete things worth remembering (a decision, a gotcha, or a pattern), each",
14927
+ "cited with the files / PR / commands / error-signatures it came from. Skip",
14928
+ "entirely if nothing non-obvious happened \u2014 that judgement is the ONLY filter,",
14929
+ "because nothing reviews the reflection before it lands.",
14930
+ "",
14931
+ "Then record it straight away. There is no confirm step, in any environment:",
14932
+ "",
14933
+ "```bash",
14934
+ 'verity reflect --user-input "<your draft>" --kind <kind>',
14935
+ "```",
14936
+ "",
14937
+ "Add `--confirmed` ONLY when the user authored or dictated the words. Without",
14938
+ "it the node is stored as `source: agent` \u2014 Verity thought this, nobody checked",
14939
+ "it. With it, `source: user` at full confidence \u2014 a person stands behind this.",
14940
+ "Never claim the second for your own draft, however good it is.",
14941
+ "",
14942
+ "**Name the files in the text.** Verity scopes the reflection to the paths it",
14943
+ "cites, and a reflection that names no file in this repo is never retrieved for",
14944
+ "a later review \u2014 it is recorded and then invisible. The command says so when it",
14945
+ 'happens; `--file-globs "<path or glob>"` is the fix when the prose cannot carry',
14946
+ "the paths.",
14947
+ "",
14948
+ "Then tell the user, in one line, what you recorded and where: the command",
14949
+ "prints the node id, the path under `.verity/memory/`, and a dashboard link.",
14950
+ "They did not agree to it in advance, so say it happened \u2014 editing or deleting",
14951
+ "that file is how they correct it.",
14952
+ "",
14953
+ "> Durable, hand-curated guidance goes in the preserve region below (it survives",
14954
+ "> regeneration) or anywhere OUTSIDE these markers. Everything else between the",
14955
+ "> markers is tool-owned and overwritten on each run.",
14956
+ "",
14957
+ "## Housekeeping Turns",
14958
+ "",
14959
+ "When a turn will be pure housekeeping \u2014 pulling, installing dependencies,",
14960
+ "rebasing, a formatting sweep you are not authoring \u2014 declare it BEFORE doing it:",
14961
+ "",
14962
+ "```bash",
14963
+ 'verity ignore --turn --agent --reason "pulling latest before starting"',
14964
+ "```",
14965
+ "",
14966
+ "This skips the review for that turn, which saves the turn Verity would",
14967
+ "otherwise spend saying it had nothing to say. Use `--for 30m` instead of",
14968
+ "`--turn` when a single piece of housekeeping spans several turns.",
14969
+ "",
14970
+ "**It is a claim about the turn, not a way to silence review.** The declaration",
14971
+ "is checked against what the turn actually did: if anything is authored \u2014 by you,",
14972
+ "by a subagent, or by a shell command that can write files \u2014 it voids, the review",
14973
+ "runs anyway, and the broken declaration is reported. So declare housekeeping you",
14974
+ "are about to do, never work you have already done, and never as a way to get past",
14975
+ "a finding. Declarations are budgeted per session and every one is recorded with",
14976
+ "its reason."
14977
+ ].join("\n");
14978
+ var CLAUDE_MD_PROSE_PRE_ORG = [
14675
14979
  "## Project Memory",
14676
14980
  "",
14677
14981
  "This project has a knowledge graph maintained at `.verity/memory/`. Before starting",
@@ -14951,10 +15255,10 @@ function hasLegacyMemoryBlock(text) {
14951
15255
  return findMarker(text, LEGACY_MD_START) !== -1;
14952
15256
  }
14953
15257
  async function ensureClaudeMdPointer(cwd = repoRoot()) {
14954
- const claudeMdPath = (0, import_node_path12.join)(cwd, "CLAUDE.md");
15258
+ const claudeMdPath = (0, import_node_path13.join)(cwd, "CLAUDE.md");
14955
15259
  let existing = "";
14956
- if ((0, import_node_fs13.existsSync)(claudeMdPath)) {
14957
- existing = await (0, import_promises8.readFile)(claudeMdPath, "utf-8");
15260
+ if ((0, import_node_fs14.existsSync)(claudeMdPath)) {
15261
+ existing = await (0, import_promises9.readFile)(claudeMdPath, "utf-8");
14958
15262
  }
14959
15263
  let startTag = CLAUDE_MD_START;
14960
15264
  let endTag = CLAUDE_MD_END;
@@ -15010,7 +15314,7 @@ async function ensureClaudeMdPointer(cwd = repoRoot()) {
15010
15314
  next = existing.replace(/\n*$/, "") + "\n\n" + block + "\n";
15011
15315
  }
15012
15316
  if (next === existing) return;
15013
- await (0, import_promises8.writeFile)(claudeMdPath, next);
15317
+ await (0, import_promises9.writeFile)(claudeMdPath, next);
15014
15318
  }
15015
15319
  function extractPreserveContent(interior) {
15016
15320
  for (const [start, end] of [
@@ -15029,6 +15333,7 @@ function stripKnownProse(interior) {
15029
15333
  const trimmed = interior.replace(/^\n+/, "");
15030
15334
  for (const prose of [
15031
15335
  CLAUDE_MD_PROSE,
15336
+ CLAUDE_MD_PROSE_PRE_ORG,
15032
15337
  CLAUDE_MD_PROSE_PRE_AUTORECORD,
15033
15338
  CLAUDE_MD_PROSE_PRE_REFLECT,
15034
15339
  CLAUDE_MD_PROSE_PRE_WAIVE,
@@ -15093,9 +15398,9 @@ Body content (\u22648KB). Use [[node-id]] wikilinks for cross-references.
15093
15398
  `;
15094
15399
 
15095
15400
  // src/lib/dossier-session.ts
15096
- var import_node_fs18 = require("node:fs");
15401
+ var import_node_fs19 = require("node:fs");
15097
15402
  var import_node_crypto7 = require("node:crypto");
15098
- var import_node_path15 = require("node:path");
15403
+ var import_node_path16 = require("node:path");
15099
15404
 
15100
15405
  // src/lib/pending-repeat.ts
15101
15406
  var STOP = /* @__PURE__ */ new Set([
@@ -15200,8 +15505,8 @@ function statementAnchorKey(file, patternId) {
15200
15505
 
15201
15506
  // src/lib/dossier/log.ts
15202
15507
  var import_node_crypto4 = require("node:crypto");
15203
- var import_node_fs14 = require("node:fs");
15204
- var import_node_path13 = require("node:path");
15508
+ var import_node_fs15 = require("node:fs");
15509
+ var import_node_path14 = require("node:path");
15205
15510
  var CRC_TABLE = (() => {
15206
15511
  const t = new Int32Array(256);
15207
15512
  for (let i = 0; i < 256; i++) {
@@ -15220,13 +15525,13 @@ function crc32(s) {
15220
15525
  function openDossier(identity) {
15221
15526
  try {
15222
15527
  const dir = dossierDir(identity);
15223
- (0, import_node_fs14.mkdirSync)(dir, { recursive: true, mode: 448 });
15528
+ (0, import_node_fs15.mkdirSync)(dir, { recursive: true, mode: 448 });
15224
15529
  return {
15225
15530
  dir,
15226
15531
  identity,
15227
- eventsPath: (0, import_node_path13.join)(dir, "events.jsonl"),
15228
- foldPath: (0, import_node_path13.join)(dir, "fold.json"),
15229
- rotatedDir: (0, import_node_path13.join)(dir, "rotated")
15532
+ eventsPath: (0, import_node_path14.join)(dir, "events.jsonl"),
15533
+ foldPath: (0, import_node_path14.join)(dir, "fold.json"),
15534
+ rotatedDir: (0, import_node_path14.join)(dir, "rotated")
15230
15535
  };
15231
15536
  } catch {
15232
15537
  return null;
@@ -15288,7 +15593,7 @@ function appendEvent(d, ev) {
15288
15593
  at: ev.at ?? (/* @__PURE__ */ new Date()).toISOString(),
15289
15594
  ...ev
15290
15595
  });
15291
- (0, import_node_fs14.appendFileSync)(d.eventsPath, line, { mode: 384 });
15596
+ (0, import_node_fs15.appendFileSync)(d.eventsPath, line, { mode: 384 });
15292
15597
  return true;
15293
15598
  } catch {
15294
15599
  return false;
@@ -15296,14 +15601,14 @@ function appendEvent(d, ev) {
15296
15601
  }
15297
15602
  function rotateIfNeeded2(d) {
15298
15603
  try {
15299
- if (!(0, import_node_fs14.existsSync)(d.eventsPath)) return;
15300
- if ((0, import_node_fs14.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
15301
- (0, import_node_fs14.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
15302
- (0, import_node_fs14.renameSync)(d.eventsPath, (0, import_node_path13.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
15303
- const kept = (0, import_node_fs14.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
15604
+ if (!(0, import_node_fs15.existsSync)(d.eventsPath)) return;
15605
+ if ((0, import_node_fs15.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
15606
+ (0, import_node_fs15.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
15607
+ (0, import_node_fs15.renameSync)(d.eventsPath, (0, import_node_path14.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
15608
+ const kept = (0, import_node_fs15.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
15304
15609
  for (const stale of kept.slice(0, Math.max(0, kept.length - ROTATE_KEEP))) {
15305
15610
  try {
15306
- (0, import_node_fs14.renameSync)((0, import_node_path13.join)(d.rotatedDir, stale), (0, import_node_path13.join)(d.rotatedDir, `${stale}.pruned`));
15611
+ (0, import_node_fs15.renameSync)((0, import_node_path14.join)(d.rotatedDir, stale), (0, import_node_path14.join)(d.rotatedDir, `${stale}.pruned`));
15307
15612
  } catch {
15308
15613
  }
15309
15614
  }
@@ -15313,8 +15618,8 @@ function rotateIfNeeded2(d) {
15313
15618
 
15314
15619
  // src/lib/dossier/fold-dossier.ts
15315
15620
  var import_node_crypto5 = require("node:crypto");
15316
- var import_node_fs15 = require("node:fs");
15317
- var import_node_path14 = require("node:path");
15621
+ var import_node_fs16 = require("node:fs");
15622
+ var import_node_path15 = require("node:path");
15318
15623
  var EMPTY_CAPABILITIES = () => ({
15319
15624
  human_reachable: { value: "unknown", tier: "unknown" },
15320
15625
  authorship_observability: { value: "unknown", tier: "unknown" },
@@ -15365,12 +15670,12 @@ function foldDossier(d, opts = {}) {
15365
15670
  }
15366
15671
  };
15367
15672
  try {
15368
- if ((0, import_node_fs15.existsSync)(d.rotatedDir)) {
15369
- const files = (0, import_node_fs15.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
15673
+ if ((0, import_node_fs16.existsSync)(d.rotatedDir)) {
15674
+ const files = (0, import_node_fs16.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
15370
15675
  state.meta.rotations = files.length;
15371
15676
  for (const f of files) {
15372
15677
  try {
15373
- ingest((0, import_node_fs15.readFileSync)((0, import_node_path14.join)(d.rotatedDir, f), "utf8"));
15678
+ ingest((0, import_node_fs16.readFileSync)((0, import_node_path15.join)(d.rotatedDir, f), "utf8"));
15374
15679
  } catch {
15375
15680
  state.meta.dropped_lines++;
15376
15681
  }
@@ -15379,9 +15684,9 @@ function foldDossier(d, opts = {}) {
15379
15684
  } catch {
15380
15685
  }
15381
15686
  try {
15382
- if ((0, import_node_fs15.existsSync)(d.eventsPath)) {
15383
- state.meta.upto_offset = (0, import_node_fs15.statSync)(d.eventsPath).size;
15384
- ingest((0, import_node_fs15.readFileSync)(d.eventsPath, "utf8"));
15687
+ if ((0, import_node_fs16.existsSync)(d.eventsPath)) {
15688
+ state.meta.upto_offset = (0, import_node_fs16.statSync)(d.eventsPath).size;
15689
+ ingest((0, import_node_fs16.readFileSync)(d.eventsPath, "utf8"));
15385
15690
  }
15386
15691
  } catch {
15387
15692
  }
@@ -15652,7 +15957,7 @@ function applyBounds(state, input) {
15652
15957
  }
15653
15958
 
15654
15959
  // src/lib/dossier/cache.ts
15655
- var import_node_fs16 = require("node:fs");
15960
+ var import_node_fs17 = require("node:fs");
15656
15961
  function compactState(s) {
15657
15962
  const ms = (iso) => Date.parse(iso) || 0;
15658
15963
  return {
@@ -15781,20 +16086,20 @@ function encodeState(s) {
15781
16086
  function writeFoldCache(d, state) {
15782
16087
  try {
15783
16088
  const tmp = `${d.foldPath}.${process.pid}.tmp`;
15784
- (0, import_node_fs16.writeFileSync)(tmp, encodeState(state), { mode: 384 });
15785
- (0, import_node_fs16.renameSync)(tmp, d.foldPath);
16089
+ (0, import_node_fs17.writeFileSync)(tmp, encodeState(state), { mode: 384 });
16090
+ (0, import_node_fs17.renameSync)(tmp, d.foldPath);
15786
16091
  } catch {
15787
16092
  }
15788
16093
  }
15789
16094
  function readFoldCache(d) {
15790
16095
  try {
15791
- if (!(0, import_node_fs16.existsSync)(d.foldPath)) return null;
15792
- const raw = JSON.parse((0, import_node_fs16.readFileSync)(d.foldPath, "utf8"));
16096
+ if (!(0, import_node_fs17.existsSync)(d.foldPath)) return null;
16097
+ const raw = JSON.parse((0, import_node_fs17.readFileSync)(d.foldPath, "utf8"));
15793
16098
  if (raw?.v !== 1) return null;
15794
16099
  const cached2 = expandState(raw);
15795
16100
  if (!cached2?.meta) return null;
15796
- const size = (0, import_node_fs16.existsSync)(d.eventsPath) ? (0, import_node_fs16.statSync)(d.eventsPath).size : 0;
15797
- const rotations = (0, import_node_fs16.existsSync)(d.rotatedDir) ? (0, import_node_fs16.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
16101
+ const size = (0, import_node_fs17.existsSync)(d.eventsPath) ? (0, import_node_fs17.statSync)(d.eventsPath).size : 0;
16102
+ const rotations = (0, import_node_fs17.existsSync)(d.rotatedDir) ? (0, import_node_fs17.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
15798
16103
  if (cached2.meta.upto_offset !== size || cached2.meta.rotations !== rotations) return null;
15799
16104
  return cached2;
15800
16105
  } catch {
@@ -15845,13 +16150,13 @@ function assessContinuity(i) {
15845
16150
 
15846
16151
  // src/lib/dossier/reanchor.ts
15847
16152
  var import_node_crypto6 = require("node:crypto");
15848
- var import_node_fs17 = require("node:fs");
16153
+ var import_node_fs18 = require("node:fs");
15849
16154
  function lineSha(text) {
15850
16155
  return (0, import_node_crypto6.createHash)("sha256").update(text.trim()).digest("hex").slice(0, HASH_WIDTH);
15851
16156
  }
15852
16157
  function fileHash(path) {
15853
16158
  try {
15854
- return (0, import_node_crypto6.createHash)("sha256").update((0, import_node_fs17.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
16159
+ return (0, import_node_crypto6.createHash)("sha256").update((0, import_node_fs18.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
15855
16160
  } catch {
15856
16161
  return null;
15857
16162
  }
@@ -16223,20 +16528,20 @@ function foreignAuthoredPaths(identity, opts = {}) {
16223
16528
  let sessions = 0;
16224
16529
  try {
16225
16530
  const dir = treeDir(identity);
16226
- if (!(0, import_node_fs18.existsSync)(dir)) return { paths: [], sessions: 0 };
16227
- for (const entry of (0, import_node_fs18.readdirSync)(dir, { withFileTypes: true })) {
16531
+ if (!(0, import_node_fs19.existsSync)(dir)) return { paths: [], sessions: 0 };
16532
+ for (const entry of (0, import_node_fs19.readdirSync)(dir, { withFileTypes: true })) {
16228
16533
  if (!entry.isDirectory()) continue;
16229
16534
  if (entry.name === identity.sessionKey) continue;
16230
- const log = (0, import_node_path15.join)(dir, entry.name, "events.jsonl");
16535
+ const log = (0, import_node_path16.join)(dir, entry.name, "events.jsonl");
16231
16536
  try {
16232
- if (!(0, import_node_fs18.existsSync)(log)) continue;
16233
- if (now - (0, import_node_fs18.statSync)(log).mtimeMs > windowMs) continue;
16537
+ if (!(0, import_node_fs19.existsSync)(log)) continue;
16538
+ if (now - (0, import_node_fs19.statSync)(log).mtimeMs > windowMs) continue;
16234
16539
  const sib = {
16235
- dir: (0, import_node_path15.join)(dir, entry.name),
16540
+ dir: (0, import_node_path16.join)(dir, entry.name),
16236
16541
  identity,
16237
16542
  eventsPath: log,
16238
- foldPath: (0, import_node_path15.join)(dir, entry.name, "fold.json"),
16239
- rotatedDir: (0, import_node_path15.join)(dir, entry.name, "rotated")
16543
+ foldPath: (0, import_node_path16.join)(dir, entry.name, "fold.json"),
16544
+ rotatedDir: (0, import_node_path16.join)(dir, entry.name, "rotated")
16240
16545
  };
16241
16546
  const state = readFoldCache(sib) ?? foldDossier(sib);
16242
16547
  sessions++;
@@ -16264,25 +16569,25 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
16264
16569
  let removed = 0;
16265
16570
  try {
16266
16571
  const mine = dossierDir(identity);
16267
- const userDir = (0, import_node_path15.dirname)((0, import_node_path15.dirname)(mine));
16268
- if (!(0, import_node_fs18.existsSync)(userDir)) return 0;
16572
+ const userDir = (0, import_node_path16.dirname)((0, import_node_path16.dirname)(mine));
16573
+ if (!(0, import_node_fs19.existsSync)(userDir)) return 0;
16269
16574
  const cutoff = Date.now() - maxAgeMs;
16270
- for (const tree of (0, import_node_fs18.readdirSync)(userDir, { withFileTypes: true })) {
16575
+ for (const tree of (0, import_node_fs19.readdirSync)(userDir, { withFileTypes: true })) {
16271
16576
  if (!tree.isDirectory()) continue;
16272
- const treePath = (0, import_node_path15.join)(userDir, tree.name);
16577
+ const treePath = (0, import_node_path16.join)(userDir, tree.name);
16273
16578
  let live = 0;
16274
- for (const entry of (0, import_node_fs18.readdirSync)(treePath, { withFileTypes: true })) {
16579
+ for (const entry of (0, import_node_fs19.readdirSync)(treePath, { withFileTypes: true })) {
16275
16580
  if (!entry.isDirectory()) continue;
16276
- const dir = (0, import_node_path15.join)(treePath, entry.name);
16581
+ const dir = (0, import_node_path16.join)(treePath, entry.name);
16277
16582
  if (dir === mine) {
16278
16583
  live++;
16279
16584
  continue;
16280
16585
  }
16281
16586
  try {
16282
- const log = (0, import_node_path15.join)(dir, "events.jsonl");
16283
- const at = (0, import_node_fs18.existsSync)(log) ? (0, import_node_fs18.statSync)(log).mtimeMs : (0, import_node_fs18.statSync)(dir).mtimeMs;
16587
+ const log = (0, import_node_path16.join)(dir, "events.jsonl");
16588
+ const at = (0, import_node_fs19.existsSync)(log) ? (0, import_node_fs19.statSync)(log).mtimeMs : (0, import_node_fs19.statSync)(dir).mtimeMs;
16284
16589
  if (at < cutoff) {
16285
- (0, import_node_fs18.rmSync)(dir, { recursive: true, force: true });
16590
+ (0, import_node_fs19.rmSync)(dir, { recursive: true, force: true });
16286
16591
  removed++;
16287
16592
  } else {
16288
16593
  live++;
@@ -16292,7 +16597,7 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
16292
16597
  }
16293
16598
  if (live === 0) {
16294
16599
  try {
16295
- (0, import_node_fs18.rmSync)(treePath, { recursive: false, force: false });
16600
+ (0, import_node_fs19.rmSync)(treePath, { recursive: false, force: false });
16296
16601
  } catch {
16297
16602
  }
16298
16603
  }
@@ -16309,8 +16614,8 @@ function sessionDossier(token, sessionId) {
16309
16614
  }
16310
16615
  function hasActiveGoal(d) {
16311
16616
  try {
16312
- if (!(0, import_node_fs18.existsSync)(d.eventsPath)) return false;
16313
- return (0, import_node_fs18.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
16617
+ if (!(0, import_node_fs19.existsSync)(d.eventsPath)) return false;
16618
+ return (0, import_node_fs19.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
16314
16619
  } catch {
16315
16620
  return false;
16316
16621
  }
@@ -16334,7 +16639,7 @@ function recordTurn(d, t) {
16334
16639
  for (const a of t.authored) {
16335
16640
  const origin = a.owner === "subagent" ? "subagent" : "edit_tool";
16336
16641
  const prior = t.known?.authored?.get(a.p);
16337
- const hash = fileHash((0, import_node_path15.join)(root, a.p));
16642
+ const hash = fileHash((0, import_node_path16.join)(root, a.p));
16338
16643
  const hunks = Math.max(0, a.h - (prior?.hunks ?? 0));
16339
16644
  const adds = Math.max(0, a.a - (prior?.adds ?? 0));
16340
16645
  const dels = Math.max(0, a.d - (prior?.dels ?? 0));
@@ -16367,7 +16672,7 @@ function recordTurn(d, t) {
16367
16672
  }
16368
16673
  const seenDivergence = t.known?.divergence ?? /* @__PURE__ */ new Set();
16369
16674
  for (const u of t.unobserved) {
16370
- const hash = fileHash((0, import_node_path15.join)(root, u.p));
16675
+ const hash = fileHash((0, import_node_path16.join)(root, u.p));
16371
16676
  if (seenDivergence.has(divergenceKey(u.p, hash))) continue;
16372
16677
  appendEvent(d, { k: "divergence", kind: "external_mutation", path: u.p, hash });
16373
16678
  }
@@ -16402,8 +16707,8 @@ function recordVerdict(d, v) {
16402
16707
  if (!sent.has(f.file)) continue;
16403
16708
  if (!lines.has(f.file)) {
16404
16709
  try {
16405
- const abs = (0, import_node_path15.join)(root, f.file);
16406
- lines.set(f.file, (0, import_node_fs18.existsSync)(abs) ? (0, import_node_fs18.readFileSync)(abs, "utf8").split("\n") : null);
16710
+ const abs = (0, import_node_path16.join)(root, f.file);
16711
+ lines.set(f.file, (0, import_node_fs19.existsSync)(abs) ? (0, import_node_fs19.readFileSync)(abs, "utf8").split("\n") : null);
16407
16712
  } catch {
16408
16713
  lines.set(f.file, null);
16409
16714
  }
@@ -16503,8 +16808,8 @@ function recallMemory(d, identity, opts) {
16503
16808
  budgetBytes: opts.budgetBytes,
16504
16809
  readFileLines: (file) => {
16505
16810
  try {
16506
- const abs = (0, import_node_path15.join)(root, file);
16507
- return (0, import_node_fs18.existsSync)(abs) ? (0, import_node_fs18.readFileSync)(abs, "utf8").split("\n") : null;
16811
+ const abs = (0, import_node_path16.join)(root, file);
16812
+ return (0, import_node_fs19.existsSync)(abs) ? (0, import_node_fs19.readFileSync)(abs, "utf8").split("\n") : null;
16508
16813
  } catch {
16509
16814
  return null;
16510
16815
  }
@@ -16648,46 +16953,46 @@ async function fireClassify(prompt, sessionId, globals) {
16648
16953
  }
16649
16954
 
16650
16955
  // src/commands/lifecycle.ts
16651
- var import_node_fs22 = require("node:fs");
16652
- var import_node_path20 = require("node:path");
16956
+ var import_node_fs23 = require("node:fs");
16957
+ var import_node_path21 = require("node:path");
16653
16958
 
16654
16959
  // src/lib/baseline.ts
16655
- var import_node_fs21 = require("node:fs");
16656
- var import_node_path19 = require("node:path");
16960
+ var import_node_fs22 = require("node:fs");
16961
+ var import_node_path20 = require("node:path");
16657
16962
  var import_node_crypto9 = require("node:crypto");
16658
16963
 
16659
16964
  // src/lib/snapshot.ts
16660
- var import_node_fs20 = require("node:fs");
16661
- var import_node_path18 = require("node:path");
16965
+ var import_node_fs21 = require("node:fs");
16966
+ var import_node_path19 = require("node:path");
16662
16967
  var import_node_child_process7 = require("node:child_process");
16663
16968
 
16664
16969
  // src/lib/files.ts
16665
- var import_node_path17 = require("node:path");
16970
+ var import_node_path18 = require("node:path");
16666
16971
 
16667
16972
  // src/lib/safe-read.ts
16668
- var import_node_fs19 = require("node:fs");
16669
- var import_node_path16 = require("node:path");
16670
- var FLAGS = import_node_fs19.constants;
16973
+ var import_node_fs20 = require("node:fs");
16974
+ var import_node_path17 = require("node:path");
16975
+ var FLAGS = import_node_fs20.constants;
16671
16976
  var NOFOLLOW = FLAGS.O_NOFOLLOW;
16672
16977
  var NONBLOCK = FLAGS.O_NONBLOCK;
16673
16978
  function closeOpened(fd) {
16674
16979
  try {
16675
- (0, import_node_fs19.closeSync)(fd);
16980
+ (0, import_node_fs20.closeSync)(fd);
16676
16981
  } catch {
16677
16982
  }
16678
16983
  }
16679
16984
  function isInsideRoot(realRoot, realPath) {
16680
- return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path16.sep) ? realRoot : realRoot + import_node_path16.sep);
16985
+ return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path17.sep) ? realRoot : realRoot + import_node_path17.sep);
16681
16986
  }
16682
16987
  function sameOpenedFile(opened, current, nofollowAvailable) {
16683
16988
  if (!nofollowAvailable && (opened.ino === 0n || current.ino === 0n)) return false;
16684
16989
  return opened.ino === current.ino && opened.dev === current.dev;
16685
16990
  }
16686
16991
  function openRegularInRoot(root, path) {
16687
- const full = (0, import_node_path16.isAbsolute)(path) ? path : (0, import_node_path16.join)(root, path);
16992
+ const full = (0, import_node_path17.isAbsolute)(path) ? path : (0, import_node_path17.join)(root, path);
16688
16993
  let fd;
16689
16994
  try {
16690
- fd = (0, import_node_fs19.openSync)(full, import_node_fs19.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
16995
+ fd = (0, import_node_fs20.openSync)(full, import_node_fs20.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
16691
16996
  } catch (err) {
16692
16997
  const code = err.code;
16693
16998
  if (code === "ELOOP" || code === "EMLINK" || code === "EFTYPE") return { ok: false, reason: "symlink" };
@@ -16695,18 +17000,18 @@ function openRegularInRoot(root, path) {
16695
17000
  return { ok: false, reason: "unreadable" };
16696
17001
  }
16697
17002
  try {
16698
- const opened = (0, import_node_fs19.fstatSync)(fd, { bigint: true });
17003
+ const opened = (0, import_node_fs20.fstatSync)(fd, { bigint: true });
16699
17004
  if (!opened.isFile()) {
16700
17005
  closeOpened(fd);
16701
17006
  return { ok: false, reason: "not-regular" };
16702
17007
  }
16703
- const realRoot = import_node_fs19.realpathSync.native(root);
16704
- const realPath = import_node_fs19.realpathSync.native(full);
17008
+ const realRoot = import_node_fs20.realpathSync.native(root);
17009
+ const realPath = import_node_fs20.realpathSync.native(full);
16705
17010
  if (!isInsideRoot(realRoot, realPath)) {
16706
17011
  closeOpened(fd);
16707
17012
  return { ok: false, reason: "outside-root" };
16708
17013
  }
16709
- const current = (0, import_node_fs19.statSync)(realPath, { bigint: true });
17014
+ const current = (0, import_node_fs20.statSync)(realPath, { bigint: true });
16710
17015
  if (!sameOpenedFile(opened, current, NOFOLLOW !== void 0)) {
16711
17016
  closeOpened(fd);
16712
17017
  return { ok: false, reason: NOFOLLOW === void 0 ? "unreadable" : "outside-root" };
@@ -16728,7 +17033,7 @@ function readOpened(fd, size) {
16728
17033
  const buffer = Buffer.alloc(size);
16729
17034
  let offset = 0;
16730
17035
  while (offset < size) {
16731
- const n = (0, import_node_fs19.readSync)(fd, buffer, offset, size - offset, offset);
17036
+ const n = (0, import_node_fs20.readSync)(fd, buffer, offset, size - offset, offset);
16732
17037
  if (n === 0) break;
16733
17038
  offset += n;
16734
17039
  }
@@ -16822,7 +17127,7 @@ var LANG_MAP = {
16822
17127
  mk: "make"
16823
17128
  };
16824
17129
  function detectLanguage(filepath) {
16825
- const ext = (0, import_node_path17.extname)(filepath).slice(1);
17130
+ const ext = (0, import_node_path18.extname)(filepath).slice(1);
16826
17131
  return LANG_MAP[ext] ?? ext;
16827
17132
  }
16828
17133
  function sortByMtime(files) {
@@ -16913,16 +17218,16 @@ function collectCodeDelta(files, opts) {
16913
17218
 
16914
17219
  // src/lib/snapshot.ts
16915
17220
  function generateSnapshotDiffs(files) {
16916
- if (!(0, import_node_fs20.existsSync)(SNAPSHOT_DIR)) {
17221
+ if (!(0, import_node_fs21.existsSync)(SNAPSHOT_DIR)) {
16917
17222
  return { diffs: [], has_snapshots: false };
16918
17223
  }
16919
17224
  const diffs = [];
16920
17225
  for (const file of files) {
16921
17226
  if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
16922
- const snapshotPath = (0, import_node_path18.join)(SNAPSHOT_DIR, file.path);
17227
+ const snapshotPath = (0, import_node_path19.join)(SNAPSHOT_DIR, file.path);
16923
17228
  const language = file.language ?? detectLanguage(file.path);
16924
- if ((0, import_node_fs20.existsSync)(snapshotPath)) {
16925
- const oldContent = (0, import_node_fs20.readFileSync)(snapshotPath, "utf-8");
17229
+ if ((0, import_node_fs21.existsSync)(snapshotPath)) {
17230
+ const oldContent = (0, import_node_fs21.readFileSync)(snapshotPath, "utf-8");
16926
17231
  if (oldContent === file.content) continue;
16927
17232
  const diff = computeDiff(oldContent, file.content, file.path);
16928
17233
  if (diff) {
@@ -16947,20 +17252,20 @@ function saveSnapshots(files) {
16947
17252
  const snapshotPaths = /* @__PURE__ */ new Set();
16948
17253
  for (const file of files) {
16949
17254
  if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
16950
- const snapshotPath = (0, import_node_path18.join)(SNAPSHOT_DIR, file.path);
17255
+ const snapshotPath = (0, import_node_path19.join)(SNAPSHOT_DIR, file.path);
16951
17256
  snapshotPaths.add(snapshotPath);
16952
- (0, import_node_fs20.mkdirSync)((0, import_node_path18.dirname)(snapshotPath), { recursive: true });
16953
- (0, import_node_fs20.writeFileSync)(snapshotPath, file.content);
17257
+ (0, import_node_fs21.mkdirSync)((0, import_node_path19.dirname)(snapshotPath), { recursive: true });
17258
+ (0, import_node_fs21.writeFileSync)(snapshotPath, file.content);
16954
17259
  }
16955
17260
  cleanStaleSnapshots(SNAPSHOT_DIR, snapshotPaths);
16956
17261
  }
16957
17262
  function computeDiff(oldContent, newContent, filePath) {
16958
- const tmpOld = (0, import_node_path18.join)(SNAPSHOT_DIR, ".diff-old.tmp");
16959
- const tmpNew = (0, import_node_path18.join)(SNAPSHOT_DIR, ".diff-new.tmp");
17263
+ const tmpOld = (0, import_node_path19.join)(SNAPSHOT_DIR, ".diff-old.tmp");
17264
+ const tmpNew = (0, import_node_path19.join)(SNAPSHOT_DIR, ".diff-new.tmp");
16960
17265
  try {
16961
- (0, import_node_fs20.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
16962
- (0, import_node_fs20.writeFileSync)(tmpOld, oldContent);
16963
- (0, import_node_fs20.writeFileSync)(tmpNew, newContent);
17266
+ (0, import_node_fs21.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
17267
+ (0, import_node_fs21.writeFileSync)(tmpOld, oldContent);
17268
+ (0, import_node_fs21.writeFileSync)(tmpNew, newContent);
16964
17269
  const result = (0, import_node_child_process7.execSync)(
16965
17270
  `git diff --no-index --unified=10 -- "${tmpOld}" "${tmpNew}"`,
16966
17271
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
@@ -16974,32 +17279,32 @@ function computeDiff(oldContent, newContent, filePath) {
16974
17279
  return null;
16975
17280
  } finally {
16976
17281
  try {
16977
- (0, import_node_fs20.unlinkSync)(tmpOld);
17282
+ (0, import_node_fs21.unlinkSync)(tmpOld);
16978
17283
  } catch {
16979
17284
  }
16980
17285
  try {
16981
- (0, import_node_fs20.unlinkSync)(tmpNew);
17286
+ (0, import_node_fs21.unlinkSync)(tmpNew);
16982
17287
  } catch {
16983
17288
  }
16984
17289
  }
16985
17290
  }
16986
17291
  function cleanStaleSnapshots(dir, keepSet) {
16987
- if (!(0, import_node_fs20.existsSync)(dir)) return;
17292
+ if (!(0, import_node_fs21.existsSync)(dir)) return;
16988
17293
  try {
16989
- const entries = (0, import_node_fs20.readdirSync)(dir, { withFileTypes: true });
17294
+ const entries = (0, import_node_fs21.readdirSync)(dir, { withFileTypes: true });
16990
17295
  for (const entry of entries) {
16991
17296
  if (dir === SNAPSHOT_DIR && (entry.name === ".diff-old.tmp" || entry.name === ".diff-new.tmp")) continue;
16992
- const fullPath = (0, import_node_path18.join)(dir, entry.name);
17297
+ const fullPath = (0, import_node_path19.join)(dir, entry.name);
16993
17298
  if (entry.isDirectory()) {
16994
17299
  cleanStaleSnapshots(fullPath, keepSet);
16995
17300
  try {
16996
- const remaining = (0, import_node_fs20.readdirSync)(fullPath);
16997
- if (remaining.length === 0) (0, import_node_fs20.rmdirSync)(fullPath);
17301
+ const remaining = (0, import_node_fs21.readdirSync)(fullPath);
17302
+ if (remaining.length === 0) (0, import_node_fs21.rmdirSync)(fullPath);
16998
17303
  } catch {
16999
17304
  }
17000
17305
  } else if (!keepSet.has(fullPath)) {
17001
17306
  try {
17002
- (0, import_node_fs20.unlinkSync)(fullPath);
17307
+ (0, import_node_fs21.unlinkSync)(fullPath);
17003
17308
  } catch {
17004
17309
  }
17005
17310
  }
@@ -17018,20 +17323,20 @@ function sessionKey(sessionId) {
17018
17323
  return (0, import_node_crypto9.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
17019
17324
  }
17020
17325
  function sessionDir(key) {
17021
- return (0, import_node_path19.join)(projectPath(BASELINE_DIR), key);
17326
+ return (0, import_node_path20.join)(projectPath(BASELINE_DIR), key);
17022
17327
  }
17023
17328
  function manifestPath(dir) {
17024
- return (0, import_node_path19.join)(dir, "manifest.json");
17329
+ return (0, import_node_path20.join)(dir, "manifest.json");
17025
17330
  }
17026
17331
  function mirrorPath(dir, repoRelPath) {
17027
- return (0, import_node_path19.join)(dir, "files", repoRelPath);
17332
+ return (0, import_node_path20.join)(dir, "files", repoRelPath);
17028
17333
  }
17029
17334
  var CARRY_FILE = `${BASELINE_DIR}/.carry`;
17030
17335
  var CARRY_WINDOW_MS = 12e4;
17031
17336
  function writeCarry(sessionId, headSha) {
17032
17337
  try {
17033
- (0, import_node_fs21.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
17034
- (0, import_node_fs21.writeFileSync)(
17338
+ (0, import_node_fs22.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
17339
+ (0, import_node_fs22.writeFileSync)(
17035
17340
  projectPath(CARRY_FILE),
17036
17341
  JSON.stringify({ from_key: sessionKey(sessionId), head_sha: headSha, ts: Date.now() })
17037
17342
  );
@@ -17041,10 +17346,10 @@ function writeCarry(sessionId, headSha) {
17041
17346
  function claimCarry(newKey) {
17042
17347
  const carryPath = projectPath(CARRY_FILE);
17043
17348
  try {
17044
- if (!(0, import_node_fs21.existsSync)(carryPath)) return null;
17045
- const carry = JSON.parse((0, import_node_fs21.readFileSync)(carryPath, "utf-8"));
17349
+ if (!(0, import_node_fs22.existsSync)(carryPath)) return null;
17350
+ const carry = JSON.parse((0, import_node_fs22.readFileSync)(carryPath, "utf-8"));
17046
17351
  try {
17047
- (0, import_node_fs21.rmSync)(carryPath, { force: true });
17352
+ (0, import_node_fs22.rmSync)(carryPath, { force: true });
17048
17353
  } catch {
17049
17354
  }
17050
17355
  if (!carry?.from_key || typeof carry.ts !== "number") return null;
@@ -17055,11 +17360,11 @@ function claimCarry(newKey) {
17055
17360
  if (!prior) return null;
17056
17361
  const toDir = sessionDir(newKey);
17057
17362
  try {
17058
- (0, import_node_fs21.rmSync)(toDir, { recursive: true, force: true });
17363
+ (0, import_node_fs22.rmSync)(toDir, { recursive: true, force: true });
17059
17364
  } catch {
17060
17365
  }
17061
- (0, import_node_fs21.renameSync)(fromDir, toDir);
17062
- (0, import_node_fs21.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
17366
+ (0, import_node_fs22.renameSync)(fromDir, toDir);
17367
+ (0, import_node_fs22.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
17063
17368
  return readManifest(toDir);
17064
17369
  } catch {
17065
17370
  return null;
@@ -17083,21 +17388,21 @@ function captureBaseline(opts = {}) {
17083
17388
  const head_sha = getCurrentCommit();
17084
17389
  const dirty = getDirtyFiles();
17085
17390
  try {
17086
- (0, import_node_fs21.rmSync)(dir, { recursive: true, force: true });
17391
+ (0, import_node_fs22.rmSync)(dir, { recursive: true, force: true });
17087
17392
  } catch {
17088
17393
  }
17089
- const filesDir = (0, import_node_path19.join)(dir, "files");
17394
+ const filesDir = (0, import_node_path20.join)(dir, "files");
17090
17395
  const mirrored = [];
17091
17396
  try {
17092
- (0, import_node_fs21.mkdirSync)(filesDir, { recursive: true });
17397
+ (0, import_node_fs22.mkdirSync)(filesDir, { recursive: true });
17093
17398
  for (const p of dirty) {
17094
17399
  if (p.includes("..")) continue;
17095
17400
  const content = safeReadForMirror(projectPath(p));
17096
17401
  if (content === null) continue;
17097
17402
  const dest = mirrorPath(dir, p);
17098
17403
  try {
17099
- (0, import_node_fs21.mkdirSync)((0, import_node_path19.dirname)(dest), { recursive: true });
17100
- (0, import_node_fs21.writeFileSync)(dest, content);
17404
+ (0, import_node_fs22.mkdirSync)((0, import_node_path20.dirname)(dest), { recursive: true });
17405
+ (0, import_node_fs22.writeFileSync)(dest, content);
17101
17406
  mirrored.push(p);
17102
17407
  } catch {
17103
17408
  }
@@ -17112,8 +17417,8 @@ function captureBaseline(opts = {}) {
17112
17417
  version: BASELINE_VERSION
17113
17418
  };
17114
17419
  try {
17115
- (0, import_node_fs21.mkdirSync)(dir, { recursive: true });
17116
- (0, import_node_fs21.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
17420
+ (0, import_node_fs22.mkdirSync)(dir, { recursive: true });
17421
+ (0, import_node_fs22.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
17117
17422
  } catch {
17118
17423
  }
17119
17424
  pruneOldBaselines();
@@ -17124,9 +17429,9 @@ function readBaseline(sessionId) {
17124
17429
  }
17125
17430
  function readManifest(dir) {
17126
17431
  const mp = manifestPath(dir);
17127
- if (!(0, import_node_fs21.existsSync)(mp)) return null;
17432
+ if (!(0, import_node_fs22.existsSync)(mp)) return null;
17128
17433
  try {
17129
- const parsed = JSON.parse((0, import_node_fs21.readFileSync)(mp, "utf-8"));
17434
+ const parsed = JSON.parse((0, import_node_fs22.readFileSync)(mp, "utf-8"));
17130
17435
  if (typeof parsed.head_sha !== "string" || typeof parsed.captured_at !== "number" || !Array.isArray(parsed.dirty_paths) || parsed.version !== BASELINE_VERSION) {
17131
17436
  return null;
17132
17437
  }
@@ -17157,9 +17462,9 @@ function preImage(repoRelPath, baseline) {
17157
17462
  function resolvePreImage(repoRelPath, baseline) {
17158
17463
  if (baseline.dirty_paths.includes(repoRelPath)) {
17159
17464
  const mp = mirrorPath(sessionDir(sessionKey(baseline.session_id)), repoRelPath);
17160
- if ((0, import_node_fs21.existsSync)(mp)) {
17465
+ if ((0, import_node_fs22.existsSync)(mp)) {
17161
17466
  try {
17162
- return { content: (0, import_node_fs21.readFileSync)(mp, "utf-8"), existed: true };
17467
+ return { content: (0, import_node_fs22.readFileSync)(mp, "utf-8"), existed: true };
17163
17468
  } catch {
17164
17469
  }
17165
17470
  }
@@ -17204,8 +17509,8 @@ function absorbIntoBaseline(paths, sessionId) {
17204
17509
  const content = safeReadForMirror(projectPath(p));
17205
17510
  if (content === null) continue;
17206
17511
  const dest = mirrorPath(dir, p);
17207
- (0, import_node_fs21.mkdirSync)((0, import_node_path19.dirname)(dest), { recursive: true });
17208
- (0, import_node_fs21.writeFileSync)(dest, content);
17512
+ (0, import_node_fs22.mkdirSync)((0, import_node_path20.dirname)(dest), { recursive: true });
17513
+ (0, import_node_fs22.writeFileSync)(dest, content);
17209
17514
  dirty.add(p);
17210
17515
  adopted++;
17211
17516
  } catch {
@@ -17214,7 +17519,7 @@ function absorbIntoBaseline(paths, sessionId) {
17214
17519
  if (adopted === 0) return 0;
17215
17520
  try {
17216
17521
  const updated = { ...baseline, dirty_paths: [...dirty] };
17217
- (0, import_node_fs21.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
17522
+ (0, import_node_fs22.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
17218
17523
  preImageCache.delete(baseline);
17219
17524
  } catch {
17220
17525
  return 0;
@@ -17225,7 +17530,7 @@ function changedSinceBaseline(repoRelPath, baseline) {
17225
17530
  const pre = preImage(repoRelPath, baseline);
17226
17531
  let current;
17227
17532
  try {
17228
- current = (0, import_node_fs21.readFileSync)(projectPath(repoRelPath), "utf-8");
17533
+ current = (0, import_node_fs22.readFileSync)(projectPath(repoRelPath), "utf-8");
17229
17534
  } catch {
17230
17535
  return pre.existed;
17231
17536
  }
@@ -17234,8 +17539,8 @@ function changedSinceBaseline(repoRelPath, baseline) {
17234
17539
  }
17235
17540
  function safeReadForMirror(absPath) {
17236
17541
  try {
17237
- if ((0, import_node_fs21.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
17238
- const buf = (0, import_node_fs21.readFileSync)(absPath);
17542
+ if ((0, import_node_fs22.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
17543
+ const buf = (0, import_node_fs22.readFileSync)(absPath);
17239
17544
  if (buf.includes(0)) return null;
17240
17545
  return buf.toString("utf-8");
17241
17546
  } catch {
@@ -17246,18 +17551,18 @@ function pruneOldBaselines() {
17246
17551
  const root = projectPath(BASELINE_DIR);
17247
17552
  let entries;
17248
17553
  try {
17249
- entries = (0, import_node_fs21.readdirSync)(root);
17554
+ entries = (0, import_node_fs22.readdirSync)(root);
17250
17555
  } catch {
17251
17556
  return;
17252
17557
  }
17253
17558
  const now = Date.now();
17254
17559
  for (const name of entries) {
17255
- const dir = (0, import_node_path19.join)(root, name);
17560
+ const dir = (0, import_node_path20.join)(root, name);
17256
17561
  const manifest = readManifest(dir);
17257
17562
  if (!manifest) {
17258
17563
  try {
17259
- if (now - (0, import_node_fs21.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
17260
- (0, import_node_fs21.rmSync)(dir, { recursive: true, force: true });
17564
+ if (now - (0, import_node_fs22.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
17565
+ (0, import_node_fs22.rmSync)(dir, { recursive: true, force: true });
17261
17566
  }
17262
17567
  } catch {
17263
17568
  }
@@ -17265,7 +17570,7 @@ function pruneOldBaselines() {
17265
17570
  }
17266
17571
  if (now - manifest.captured_at <= BASELINE_TTL_MS) continue;
17267
17572
  try {
17268
- (0, import_node_fs21.rmSync)(dir, { recursive: true, force: true });
17573
+ (0, import_node_fs22.rmSync)(dir, { recursive: true, force: true });
17269
17574
  } catch {
17270
17575
  }
17271
17576
  }
@@ -17440,8 +17745,8 @@ function buildCompactionContext(session) {
17440
17745
  commitsSince: commitsSincePaths(watermark, (state.authored ?? []).map((a) => a.path)),
17441
17746
  readFileLines: (file) => {
17442
17747
  try {
17443
- const abs = (0, import_node_path20.join)(root, file);
17444
- return (0, import_node_fs22.existsSync)(abs) ? (0, import_node_fs22.readFileSync)(abs, "utf8").split("\n") : null;
17748
+ const abs = (0, import_node_path21.join)(root, file);
17749
+ return (0, import_node_fs23.existsSync)(abs) ? (0, import_node_fs23.readFileSync)(abs, "utf8").split("\n") : null;
17445
17750
  } catch {
17446
17751
  return null;
17447
17752
  }
@@ -17497,25 +17802,25 @@ async function readHookStdin() {
17497
17802
  }
17498
17803
 
17499
17804
  // src/commands/standard.ts
17500
- var import_promises12 = require("node:fs/promises");
17501
- var import_node_fs29 = require("node:fs");
17805
+ var import_promises13 = require("node:fs/promises");
17806
+ var import_node_fs30 = require("node:fs");
17502
17807
  var import_yaml3 = __toESM(require_dist());
17503
17808
 
17504
17809
  // src/lib/synthesize.ts
17505
17810
  var import_node_child_process9 = require("node:child_process");
17506
- var import_node_fs25 = require("node:fs");
17507
- var import_promises9 = require("node:fs/promises");
17508
- var import_node_path23 = require("node:path");
17811
+ var import_node_fs26 = require("node:fs");
17812
+ var import_promises10 = require("node:fs/promises");
17813
+ var import_node_path24 = require("node:path");
17509
17814
  var import_yaml = __toESM(require_dist());
17510
17815
 
17511
17816
  // src/lib/data-dir.ts
17512
- var import_node_fs23 = require("node:fs");
17513
- var import_node_path21 = require("node:path");
17817
+ var import_node_fs24 = require("node:fs");
17818
+ var import_node_path22 = require("node:path");
17514
17819
  function resolveDataDir() {
17515
17820
  const candidates2 = [
17516
- (0, import_node_path21.join)(__dirname, "..", "data"),
17821
+ (0, import_node_path22.join)(__dirname, "..", "data"),
17517
17822
  // installed: node_modules/@codacy/verity-cli/data
17518
- (0, import_node_path21.join)(__dirname, "..", "..", "data"),
17823
+ (0, import_node_path22.join)(__dirname, "..", "..", "data"),
17519
17824
  // edge case: nested resolution
17520
17825
  // THE COMMITTED SOURCE, for a source checkout that has not been built.
17521
17826
  // cli/data/skills/ is a BUILD ARTIFACT (scripts/build.js copies client/skills
@@ -17524,14 +17829,14 @@ function resolveDataDir() {
17524
17829
  // without this the synthesizer throws "Could not find Verity skill data"
17525
17830
  // for every test and every `verity` run from source. Resolved from this
17526
17831
  // module's own location, never the cwd: see the warning below.
17527
- (0, import_node_path21.join)(__dirname, "..", "..", "client"),
17832
+ (0, import_node_path22.join)(__dirname, "..", "..", "client"),
17528
17833
  // bundled: cli/bin/ → ../../client
17529
- (0, import_node_path21.join)(__dirname, "..", "..", "..", "client"),
17834
+ (0, import_node_path22.join)(__dirname, "..", "..", "..", "client"),
17530
17835
  // tsx: cli/src/lib/ → ../../../client
17531
17836
  ...process.env.VERITY_DEV_DATA_DIR ? [process.env.VERITY_DEV_DATA_DIR] : []
17532
17837
  ];
17533
17838
  for (const candidate of candidates2) {
17534
- if ((0, import_node_fs23.existsSync)((0, import_node_path21.join)(candidate, "skills"))) {
17839
+ if ((0, import_node_fs24.existsSync)((0, import_node_path22.join)(candidate, "skills"))) {
17535
17840
  return candidate;
17536
17841
  }
17537
17842
  }
@@ -17540,13 +17845,13 @@ function resolveDataDir() {
17540
17845
  );
17541
17846
  }
17542
17847
  function setupDataPath(file) {
17543
- return (0, import_node_path21.join)(resolveDataDir(), "skills", "verity-setup", file);
17848
+ return (0, import_node_path22.join)(resolveDataDir(), "skills", "verity-setup", file);
17544
17849
  }
17545
17850
 
17546
17851
  // src/lib/detect.ts
17547
17852
  var import_node_child_process8 = require("node:child_process");
17548
- var import_node_fs24 = require("node:fs");
17549
- var import_node_path22 = require("node:path");
17853
+ var import_node_fs25 = require("node:fs");
17854
+ var import_node_path23 = require("node:path");
17550
17855
  var TOOLED_LANGUAGES = /* @__PURE__ */ new Set([
17551
17856
  "typescript",
17552
17857
  "javascript",
@@ -17603,25 +17908,25 @@ function walk(root) {
17603
17908
  if (depth > WALK_MAX_DEPTH || found.length >= WALK_MAX_FILES) return;
17604
17909
  let entries;
17605
17910
  try {
17606
- entries = (0, import_node_fs24.readdirSync)(dir, { withFileTypes: true });
17911
+ entries = (0, import_node_fs25.readdirSync)(dir, { withFileTypes: true });
17607
17912
  } catch {
17608
17913
  return;
17609
17914
  }
17610
17915
  for (const entry of entries) {
17611
17916
  if (found.length >= WALK_MAX_FILES) return;
17612
17917
  if (IGNORED_SEGMENTS.includes(entry.name)) continue;
17613
- const full = (0, import_node_path22.join)(dir, entry.name);
17918
+ const full = (0, import_node_path23.join)(dir, entry.name);
17614
17919
  if (entry.isDirectory()) visit(full, depth + 1);
17615
- else if (entry.isFile()) found.push((0, import_node_path22.relative)(root, full));
17920
+ else if (entry.isFile()) found.push((0, import_node_path23.relative)(root, full));
17616
17921
  }
17617
17922
  };
17618
17923
  visit(root, 0);
17619
17924
  return found;
17620
17925
  }
17621
17926
  function languageOf(path) {
17622
- const name = (0, import_node_path22.basename)(path);
17927
+ const name = (0, import_node_path23.basename)(path);
17623
17928
  if (/^Dockerfile(\..+)?$/i.test(name)) return "dockerfile";
17624
- if (!(0, import_node_path22.extname)(name)) return null;
17929
+ if (!(0, import_node_path23.extname)(name)) return null;
17625
17930
  const lang = detectLanguage(path);
17626
17931
  return lang || null;
17627
17932
  }
@@ -17678,7 +17983,7 @@ var TOOL_CONFIG_MARKERS = [
17678
17983
  ];
17679
17984
  function readJson(path) {
17680
17985
  try {
17681
- return JSON.parse((0, import_node_fs24.readFileSync)(path, "utf-8"));
17986
+ return JSON.parse((0, import_node_fs25.readFileSync)(path, "utf-8"));
17682
17987
  } catch {
17683
17988
  return null;
17684
17989
  }
@@ -17703,17 +18008,17 @@ function declaredDependencies(root, files) {
17703
18008
  if (deps && typeof deps === "object") names2.push(...Object.keys(deps));
17704
18009
  }
17705
18010
  };
17706
- readPackageJson((0, import_node_path22.join)(root, "package.json"));
17707
- const nested = files.filter((f) => f.includes("/") && (0, import_node_path22.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
17708
- for (const rel of nested) readPackageJson((0, import_node_path22.join)(root, rel));
18011
+ readPackageJson((0, import_node_path23.join)(root, "package.json"));
18012
+ const nested = files.filter((f) => f.includes("/") && (0, import_node_path23.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
18013
+ for (const rel of nested) readPackageJson((0, import_node_path23.join)(root, rel));
17709
18014
  const pythonManifests = [
17710
- ...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path22.join)(root, f)),
17711
- ...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path22.join)(root, f))
18015
+ ...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path23.join)(root, f)),
18016
+ ...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path23.join)(root, f))
17712
18017
  ];
17713
18018
  for (const path of pythonManifests) {
17714
- if (!(0, import_node_fs24.existsSync)(path)) continue;
18019
+ if (!(0, import_node_fs25.existsSync)(path)) continue;
17715
18020
  try {
17716
- const text = (0, import_node_fs24.readFileSync)(path, "utf-8");
18021
+ const text = (0, import_node_fs25.readFileSync)(path, "utf-8");
17717
18022
  for (const m of text.matchAll(/^\s*["']?([A-Za-z][A-Za-z0-9._-]+)/gm)) names2.push(m[1]);
17718
18023
  for (const line of text.split("\n")) {
17719
18024
  if (!/dependencies\s*=/.test(line)) continue;
@@ -17723,13 +18028,13 @@ function declaredDependencies(root, files) {
17723
18028
  }
17724
18029
  }
17725
18030
  const goMods = [
17726
- (0, import_node_path22.join)(root, "go.mod"),
17727
- ...files.filter((f) => f.includes("/") && (0, import_node_path22.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path22.join)(root, f))
18031
+ (0, import_node_path23.join)(root, "go.mod"),
18032
+ ...files.filter((f) => f.includes("/") && (0, import_node_path23.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path23.join)(root, f))
17728
18033
  ];
17729
18034
  for (const path of goMods) {
17730
- if (!(0, import_node_fs24.existsSync)(path)) continue;
18035
+ if (!(0, import_node_fs25.existsSync)(path)) continue;
17731
18036
  try {
17732
- const text = (0, import_node_fs24.readFileSync)(path, "utf-8");
18037
+ const text = (0, import_node_fs25.readFileSync)(path, "utf-8");
17733
18038
  for (const m of text.matchAll(/^\s+([\w.-]+\/[\w./-]+)\s+v/gm)) {
17734
18039
  names2.push(m[1].replace(/^github\.com\//, ""));
17735
18040
  }
@@ -17737,10 +18042,10 @@ function declaredDependencies(root, files) {
17737
18042
  }
17738
18043
  }
17739
18044
  for (const file of ["pom.xml", "build.gradle", "build.gradle.kts", "Gemfile", "Cargo.toml"]) {
17740
- const path = (0, import_node_path22.join)(root, file);
17741
- if (!(0, import_node_fs24.existsSync)(path)) continue;
18045
+ const path = (0, import_node_path23.join)(root, file);
18046
+ if (!(0, import_node_fs25.existsSync)(path)) continue;
17742
18047
  try {
17743
- const text = (0, import_node_fs24.readFileSync)(path, "utf-8");
18048
+ const text = (0, import_node_fs25.readFileSync)(path, "utf-8");
17744
18049
  for (const m of text.matchAll(/["'<]([A-Za-z][A-Za-z0-9._-]{2,})["'>]/g)) names2.push(m[1]);
17745
18050
  } catch {
17746
18051
  }
@@ -17748,7 +18053,7 @@ function declaredDependencies(root, files) {
17748
18053
  return names2;
17749
18054
  }
17750
18055
  function detectBuildSystem(root, files) {
17751
- const has = (f) => (0, import_node_fs24.existsSync)((0, import_node_path22.join)(root, f)) || files.some((p) => (0, import_node_path22.basename)(p) === f);
18056
+ const has = (f) => (0, import_node_fs25.existsSync)((0, import_node_path23.join)(root, f)) || files.some((p) => (0, import_node_path23.basename)(p) === f);
17752
18057
  if (has("pnpm-lock.yaml")) return "pnpm";
17753
18058
  if (has("yarn.lock")) return "yarn";
17754
18059
  if (has("bun.lock") || has("bun.lockb")) return "bun";
@@ -17765,8 +18070,8 @@ function detectBuildSystem(root, files) {
17765
18070
  }
17766
18071
  function detectArchitecture(root, files) {
17767
18072
  const workspaceMarkers = ["lerna.json", "pnpm-workspace.yaml", "nx.json", "turbo.json", "rush.json"];
17768
- if (workspaceMarkers.some((m) => (0, import_node_fs24.existsSync)((0, import_node_path22.join)(root, m)))) return "monorepo";
17769
- const pkg = readJson((0, import_node_path22.join)(root, "package.json"));
18073
+ if (workspaceMarkers.some((m) => (0, import_node_fs25.existsSync)((0, import_node_path23.join)(root, m)))) return "monorepo";
18074
+ const pkg = readJson((0, import_node_path23.join)(root, "package.json"));
17770
18075
  if (pkg && "workspaces" in pkg) return "monorepo";
17771
18076
  const manifests = files.filter((f) => /(^|\/)(package\.json|go\.mod|pyproject\.toml|Cargo\.toml|pom\.xml)$/.test(f));
17772
18077
  const nested = manifests.filter((f) => f.includes("/"));
@@ -17788,10 +18093,10 @@ function measureAvgFileLength(root, files, languages) {
17788
18093
  let total = 0;
17789
18094
  let counted = 0;
17790
18095
  for (let i = 0; i < candidates2.length; i += stride) {
17791
- const path = (0, import_node_path22.join)(root, candidates2[i]);
18096
+ const path = (0, import_node_path23.join)(root, candidates2[i]);
17792
18097
  try {
17793
- if ((0, import_node_fs24.statSync)(path).size > 2 * 1024 * 1024) continue;
17794
- total += (0, import_node_fs24.readFileSync)(path, "utf-8").split("\n").length;
18098
+ if ((0, import_node_fs25.statSync)(path).size > 2 * 1024 * 1024) continue;
18099
+ total += (0, import_node_fs25.readFileSync)(path, "utf-8").split("\n").length;
17795
18100
  counted++;
17796
18101
  } catch {
17797
18102
  }
@@ -17821,14 +18126,14 @@ function detectProject(root = repoRoot()) {
17821
18126
  const existingToolConfigs = [];
17822
18127
  for (const [tool, markers] of TOOL_CONFIG_MARKERS) {
17823
18128
  for (const marker of markers) {
17824
- if ((0, import_node_fs24.existsSync)((0, import_node_path22.join)(root, marker))) {
18129
+ if ((0, import_node_fs25.existsSync)((0, import_node_path23.join)(root, marker))) {
17825
18130
  existingToolConfigs.push({ tool, path: `./${marker}` });
17826
18131
  break;
17827
18132
  }
17828
18133
  }
17829
18134
  }
17830
18135
  return {
17831
- projectName: (0, import_node_path22.basename)(root),
18136
+ projectName: (0, import_node_path23.basename)(root),
17832
18137
  languages,
17833
18138
  languageCounts,
17834
18139
  frameworks: matchAll(dependencies, FRAMEWORK_BY_DEPENDENCY),
@@ -17926,8 +18231,8 @@ ${closingNote(input.origin)}
17926
18231
 
17927
18232
  // src/lib/synthesize.ts
17928
18233
  function loadCatalog() {
17929
- const catalog = (0, import_yaml.parse)((0, import_node_fs25.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
17930
- const template = (0, import_yaml.parse)((0, import_node_fs25.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
18234
+ const catalog = (0, import_yaml.parse)((0, import_node_fs26.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
18235
+ const template = (0, import_yaml.parse)((0, import_node_fs26.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
17931
18236
  return { catalog, template };
17932
18237
  }
17933
18238
  function selectTools(languages, intensity, catalog) {
@@ -18205,7 +18510,7 @@ function validatePatternIds() {
18205
18510
  }
18206
18511
  async function runSynthesis(opts) {
18207
18512
  const standardPath = projectPath(STANDARD_FILE);
18208
- if ((0, import_node_fs25.existsSync)(standardPath) && !opts.force) {
18513
+ if ((0, import_node_fs26.existsSync)(standardPath) && !opts.force) {
18209
18514
  return { refused: `${STANDARD_FILE} already exists \u2014 pass --force to replace it.` };
18210
18515
  }
18211
18516
  const detected = opts.detected ?? detectProject();
@@ -18274,8 +18579,8 @@ async function correctVerityMdVersion(opts) {
18274
18579
  }
18275
18580
  async function writeFileTo(relative2, body) {
18276
18581
  const target = projectPath(relative2);
18277
- await (0, import_promises9.mkdir)((0, import_node_path23.dirname)(target), { recursive: true });
18278
- await (0, import_promises9.writeFile)(target, body);
18582
+ await (0, import_promises10.mkdir)((0, import_node_path24.dirname)(target), { recursive: true });
18583
+ await (0, import_promises10.writeFile)(target, body);
18279
18584
  }
18280
18585
  async function deriveConfigForStandard(standard) {
18281
18586
  const spec = standard.knowledge_spec ?? {};
@@ -18332,14 +18637,14 @@ ${validation.detail}`);
18332
18637
  }
18333
18638
 
18334
18639
  // src/lib/setup-state.ts
18335
- var import_promises10 = require("node:fs/promises");
18336
- var import_node_fs26 = require("node:fs");
18640
+ var import_promises11 = require("node:fs/promises");
18641
+ var import_node_fs27 = require("node:fs");
18337
18642
  var SETUP_STATE_FILE = `${VERITY_DIR}/setup.json`;
18338
18643
  async function readSetupState() {
18339
18644
  const path = projectPath(SETUP_STATE_FILE);
18340
- if (!(0, import_node_fs26.existsSync)(path)) return null;
18645
+ if (!(0, import_node_fs27.existsSync)(path)) return null;
18341
18646
  try {
18342
- const parsed = JSON.parse(await (0, import_promises10.readFile)(path, "utf-8"));
18647
+ const parsed = JSON.parse(await (0, import_promises11.readFile)(path, "utf-8"));
18343
18648
  return parsed && typeof parsed === "object" ? parsed : null;
18344
18649
  } catch {
18345
18650
  return null;
@@ -18353,12 +18658,12 @@ async function writeSetupState(patch) {
18353
18658
  }
18354
18659
 
18355
18660
  // src/lib/push-setup.ts
18356
- var import_node_fs28 = require("node:fs");
18357
- var import_promises11 = require("node:fs/promises");
18661
+ var import_node_fs29 = require("node:fs");
18662
+ var import_promises12 = require("node:fs/promises");
18358
18663
  var import_yaml2 = __toESM(require_dist());
18359
18664
 
18360
18665
  // src/lib/verityignore.ts
18361
- var import_node_fs27 = require("node:fs");
18666
+ var import_node_fs28 = require("node:fs");
18362
18667
  var EMPTY = { rules: [], securityOverlap: [], problems: [] };
18363
18668
  var SECURITY_PROBES = [
18364
18669
  ".env",
@@ -18451,9 +18756,9 @@ function isIgnored3(ig, path) {
18451
18756
  }
18452
18757
  function loadVerityIgnore() {
18453
18758
  const file = projectPath(VERITYIGNORE_FILE);
18454
- if (!(0, import_node_fs27.existsSync)(file)) return EMPTY;
18759
+ if (!(0, import_node_fs28.existsSync)(file)) return EMPTY;
18455
18760
  try {
18456
- return parseVerityIgnore((0, import_node_fs27.readFileSync)(file, "utf-8"));
18761
+ return parseVerityIgnore((0, import_node_fs28.readFileSync)(file, "utf-8"));
18457
18762
  } catch {
18458
18763
  return EMPTY;
18459
18764
  }
@@ -18491,9 +18796,9 @@ function buildStandardUpload(standard, ignoreRaw) {
18491
18796
  }
18492
18797
  function readVerityIgnoreRaw() {
18493
18798
  const file = projectPath(VERITYIGNORE_FILE);
18494
- if (!(0, import_node_fs27.existsSync)(file)) return null;
18799
+ if (!(0, import_node_fs28.existsSync)(file)) return null;
18495
18800
  try {
18496
- return (0, import_node_fs27.readFileSync)(file, "utf-8");
18801
+ return (0, import_node_fs28.readFileSync)(file, "utf-8");
18497
18802
  } catch {
18498
18803
  return null;
18499
18804
  }
@@ -18521,9 +18826,9 @@ async function pushStandardAndConfig(globals, what = {}) {
18521
18826
  }
18522
18827
  let standardVersion = null;
18523
18828
  const standardPath = projectPath(STANDARD_FILE);
18524
- if (pushStandard && (0, import_node_fs28.existsSync)(standardPath)) {
18829
+ if (pushStandard && (0, import_node_fs29.existsSync)(standardPath)) {
18525
18830
  try {
18526
- const content = (0, import_yaml2.parse)(await (0, import_promises11.readFile)(standardPath, "utf-8"));
18831
+ const content = (0, import_yaml2.parse)(await (0, import_promises12.readFile)(standardPath, "utf-8"));
18527
18832
  const upload = buildStandardUpload(content, readVerityIgnoreRaw());
18528
18833
  if (upload.warning) lines.push(upload.warning);
18529
18834
  const result = await apiRequest({
@@ -18546,9 +18851,9 @@ async function pushStandardAndConfig(globals, what = {}) {
18546
18851
  }
18547
18852
  let configPushed = false;
18548
18853
  const configPath = projectPath(CODACY_CONFIG_FILE);
18549
- if (pushConfig && (0, import_node_fs28.existsSync)(configPath)) {
18854
+ if (pushConfig && (0, import_node_fs29.existsSync)(configPath)) {
18550
18855
  try {
18551
- const content = JSON.parse(await (0, import_promises11.readFile)(configPath, "utf-8"));
18856
+ const content = JSON.parse(await (0, import_promises12.readFile)(configPath, "utf-8"));
18552
18857
  const result = await apiRequest({
18553
18858
  method: "POST",
18554
18859
  path: "/analysis-configs",
@@ -18578,11 +18883,11 @@ function registerStandardCommands(program2) {
18578
18883
  const state = await readSetupState();
18579
18884
  if (opts.configOnly) {
18580
18885
  const standardPath = projectPath(STANDARD_FILE);
18581
- if (!(0, import_node_fs29.existsSync)(standardPath)) {
18886
+ if (!(0, import_node_fs30.existsSync)(standardPath)) {
18582
18887
  printError(`No ${STANDARD_FILE} here \u2014 run "verity standard synthesize" to create one.`);
18583
18888
  process.exit(1);
18584
18889
  }
18585
- const content = (0, import_yaml3.parse)(await (0, import_promises12.readFile)(standardPath, "utf-8"));
18890
+ const content = (0, import_yaml3.parse)(await (0, import_promises13.readFile)(standardPath, "utf-8"));
18586
18891
  const derived = await deriveConfigForStandard(content);
18587
18892
  for (const path of derived.written) printInfo(` ${path} \u2713`);
18588
18893
  for (const note of derived.notes) printWarn(` ${note}`);
@@ -18638,7 +18943,7 @@ function registerStandardCommands(program2) {
18638
18943
  }
18639
18944
  let yamlContent;
18640
18945
  try {
18641
- yamlContent = await (0, import_promises12.readFile)(opts.file, "utf-8");
18946
+ yamlContent = await (0, import_promises13.readFile)(opts.file, "utf-8");
18642
18947
  } catch {
18643
18948
  printError(`Cannot read ${opts.file}`);
18644
18949
  process.exit(1);
@@ -18735,7 +19040,7 @@ function parseIntensity(value) {
18735
19040
  }
18736
19041
 
18737
19042
  // src/commands/config.ts
18738
- var import_promises13 = require("node:fs/promises");
19043
+ var import_promises14 = require("node:fs/promises");
18739
19044
  function registerConfigCommands(program2) {
18740
19045
  const config = program2.command("config").description("Manage analysis configuration");
18741
19046
  config.command("service-url").description("Print the resolved service URL (used by the shipped skills)").action(async () => {
@@ -18781,7 +19086,7 @@ function registerConfigCommands(program2) {
18781
19086
  }
18782
19087
  let content;
18783
19088
  try {
18784
- const raw = await (0, import_promises13.readFile)(opts.file, "utf-8");
19089
+ const raw = await (0, import_promises14.readFile)(opts.file, "utf-8");
18785
19090
  content = JSON.parse(raw);
18786
19091
  } catch {
18787
19092
  printError(`Cannot read or parse ${opts.file}`);
@@ -18909,10 +19214,10 @@ function formatRunDetail(run2) {
18909
19214
  }
18910
19215
 
18911
19216
  // src/lib/ignore-declaration.ts
18912
- var import_node_fs31 = require("node:fs");
19217
+ var import_node_fs32 = require("node:fs");
18913
19218
 
18914
19219
  // src/lib/debounce.ts
18915
- var import_node_fs30 = require("node:fs");
19220
+ var import_node_fs31 = require("node:fs");
18916
19221
  var import_node_crypto10 = require("node:crypto");
18917
19222
  function scopedFile(base, sessionId) {
18918
19223
  if (!sessionId) return base;
@@ -18920,9 +19225,9 @@ function scopedFile(base, sessionId) {
18920
19225
  }
18921
19226
  function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
18922
19227
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
18923
- if (!(0, import_node_fs30.existsSync)(file)) return null;
19228
+ if (!(0, import_node_fs31.existsSync)(file)) return null;
18924
19229
  try {
18925
- const lastTs = parseInt((0, import_node_fs30.readFileSync)(file, "utf-8").trim(), 10);
19230
+ const lastTs = parseInt((0, import_node_fs31.readFileSync)(file, "utf-8").trim(), 10);
18926
19231
  const nowTs = Math.floor(Date.now() / 1e3);
18927
19232
  const elapsed = nowTs - lastTs;
18928
19233
  if (elapsed < debounceSeconds) {
@@ -18935,10 +19240,10 @@ function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
18935
19240
  function checkMtime(files, bypassForRecentCommits, sessionId) {
18936
19241
  if (bypassForRecentCommits) return null;
18937
19242
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
18938
- if (!(0, import_node_fs30.existsSync)(file)) return null;
19243
+ if (!(0, import_node_fs31.existsSync)(file)) return null;
18939
19244
  let debounceTime;
18940
19245
  try {
18941
- debounceTime = (0, import_node_fs30.statSync)(file).mtimeMs;
19246
+ debounceTime = (0, import_node_fs31.statSync)(file).mtimeMs;
18942
19247
  } catch {
18943
19248
  return null;
18944
19249
  }
@@ -18946,7 +19251,7 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
18946
19251
  const resolved = resolveFile(f);
18947
19252
  if (!resolved) continue;
18948
19253
  try {
18949
- const stat3 = (0, import_node_fs30.statSync)(resolved);
19254
+ const stat3 = (0, import_node_fs31.statSync)(resolved);
18950
19255
  if (stat3.mtimeMs > debounceTime) {
18951
19256
  return null;
18952
19257
  }
@@ -18962,8 +19267,8 @@ function computeContentHash(files) {
18962
19267
  for (const f of sorted) {
18963
19268
  const resolved = resolveFile(f) ?? f;
18964
19269
  try {
18965
- if ((0, import_node_fs30.existsSync)(resolved)) {
18966
- hash.update((0, import_node_fs30.readFileSync)(resolved));
19270
+ if ((0, import_node_fs31.existsSync)(resolved)) {
19271
+ hash.update((0, import_node_fs31.readFileSync)(resolved));
18967
19272
  }
18968
19273
  } catch {
18969
19274
  }
@@ -18973,9 +19278,9 @@ function computeContentHash(files) {
18973
19278
  function checkContentHash(files, sessionId) {
18974
19279
  const hash = computeContentHash(files);
18975
19280
  const file = scopedFile(HASH_FILE, sessionId);
18976
- if ((0, import_node_fs30.existsSync)(file)) {
19281
+ if ((0, import_node_fs31.existsSync)(file)) {
18977
19282
  try {
18978
- const storedHash = (0, import_node_fs30.readFileSync)(file, "utf-8").trim();
19283
+ const storedHash = (0, import_node_fs31.readFileSync)(file, "utf-8").trim();
18979
19284
  if (hash === storedHash) {
18980
19285
  return { skip: "No source changes since last analysis", hash };
18981
19286
  }
@@ -18985,24 +19290,24 @@ function checkContentHash(files, sessionId) {
18985
19290
  return { skip: null, hash };
18986
19291
  }
18987
19292
  function recordAnalysisStart(sessionId) {
18988
- (0, import_node_fs30.mkdirSync)(VERITY_DIR, { recursive: true });
18989
- (0, import_node_fs30.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
19293
+ (0, import_node_fs31.mkdirSync)(VERITY_DIR, { recursive: true });
19294
+ (0, import_node_fs31.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
18990
19295
  }
18991
19296
  function recordPassHash(hash, sessionId) {
18992
- (0, import_node_fs30.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
19297
+ (0, import_node_fs31.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
18993
19298
  }
18994
19299
  function narrowToRecent(files, sessionId) {
18995
19300
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
18996
- if (!(0, import_node_fs30.existsSync)(file)) return files;
19301
+ if (!(0, import_node_fs31.existsSync)(file)) return files;
18997
19302
  let debounceTime;
18998
19303
  try {
18999
- debounceTime = (0, import_node_fs30.statSync)(file).mtimeMs;
19304
+ debounceTime = (0, import_node_fs31.statSync)(file).mtimeMs;
19000
19305
  } catch {
19001
19306
  return files;
19002
19307
  }
19003
19308
  const recent = files.filter((f) => {
19004
19309
  try {
19005
- return (0, import_node_fs30.existsSync)(f) && (0, import_node_fs30.statSync)(f).mtimeMs > debounceTime;
19310
+ return (0, import_node_fs31.existsSync)(f) && (0, import_node_fs31.statSync)(f).mtimeMs > debounceTime;
19006
19311
  } catch {
19007
19312
  return false;
19008
19313
  }
@@ -19015,9 +19320,9 @@ function readIteration(currentCommit, _contentHash) {
19015
19320
  var NO_BLOCKS = { attempts: 0, blocks: 0, fingerprint: null };
19016
19321
  function readBlockState(currentCommit, opts) {
19017
19322
  if (opts?.newUserPrompt) return NO_BLOCKS;
19018
- if (!(0, import_node_fs30.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
19323
+ if (!(0, import_node_fs31.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
19019
19324
  try {
19020
- const stored = (0, import_node_fs30.readFileSync)(ITERATION_FILE, "utf-8").trim();
19325
+ const stored = (0, import_node_fs31.readFileSync)(ITERATION_FILE, "utf-8").trim();
19021
19326
  const parsed = stored.startsWith("{") ? parseJsonState(stored) : parseLegacyState(stored);
19022
19327
  if (!parsed) return NO_BLOCKS;
19023
19328
  if (parsed.commit !== currentCommit) return NO_BLOCKS;
@@ -19063,8 +19368,8 @@ function isSameProblem(previous, current) {
19063
19368
  return current.split(",").some((k) => prev.has(k));
19064
19369
  }
19065
19370
  function writeBlockState(commit, state) {
19066
- (0, import_node_fs30.mkdirSync)(VERITY_DIR, { recursive: true });
19067
- (0, import_node_fs30.writeFileSync)(
19371
+ (0, import_node_fs31.mkdirSync)(VERITY_DIR, { recursive: true });
19372
+ (0, import_node_fs31.writeFileSync)(
19068
19373
  ITERATION_FILE,
19069
19374
  JSON.stringify({
19070
19375
  v: 2,
@@ -19169,9 +19474,9 @@ function resolveIgnoreState(keys) {
19169
19474
  }
19170
19475
  function readIgnoreState(sessionId) {
19171
19476
  const file = stateFile(sessionId);
19172
- if (!(0, import_node_fs31.existsSync)(file)) return null;
19477
+ if (!(0, import_node_fs32.existsSync)(file)) return null;
19173
19478
  try {
19174
- const o = JSON.parse((0, import_node_fs31.readFileSync)(file, "utf-8")) ?? {};
19479
+ const o = JSON.parse((0, import_node_fs32.readFileSync)(file, "utf-8")) ?? {};
19175
19480
  const spent = typeof o.spent === "number" ? o.spent : 0;
19176
19481
  const raw = o.active;
19177
19482
  let active = null;
@@ -19195,8 +19500,8 @@ function readIgnoreState(sessionId) {
19195
19500
  }
19196
19501
  function writeIgnoreState(state, sessionId) {
19197
19502
  try {
19198
- (0, import_node_fs31.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
19199
- (0, import_node_fs31.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
19503
+ (0, import_node_fs32.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
19504
+ (0, import_node_fs32.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
19200
19505
  } catch {
19201
19506
  }
19202
19507
  }
@@ -19579,7 +19884,7 @@ function createRun(opts, globals) {
19579
19884
  }
19580
19885
 
19581
19886
  // src/commands/analyze/index.ts
19582
- var import_node_fs44 = require("node:fs");
19887
+ var import_node_fs45 = require("node:fs");
19583
19888
 
19584
19889
  // src/lib/repo-context.ts
19585
19890
  var import_node_child_process10 = require("node:child_process");
@@ -20407,10 +20712,10 @@ function installRunEvidence(run2) {
20407
20712
  }
20408
20713
 
20409
20714
  // src/lib/git-frame.ts
20410
- var import_node_fs32 = require("node:fs");
20715
+ var import_node_fs33 = require("node:fs");
20411
20716
  var import_node_os5 = require("node:os");
20412
- var import_node_path24 = require("node:path");
20413
20717
  var import_node_path25 = require("node:path");
20718
+ var import_node_path26 = require("node:path");
20414
20719
 
20415
20720
  // src/lib/hardened-git.ts
20416
20721
  var import_node_child_process11 = require("node:child_process");
@@ -20572,8 +20877,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
20572
20877
  if (SHELL_DYNAMIC.test(raw) || raw === "-") {
20573
20878
  return { dir: null, named: true, unresolvable: `cd target not statically resolvable: ${raw}` };
20574
20879
  }
20575
- const expanded = raw === "~" ? (0, import_node_os5.homedir)() : raw.startsWith("~/") ? (0, import_node_path25.join)((0, import_node_os5.homedir)(), raw.slice(2)) : raw;
20576
- dir = (0, import_node_path24.isAbsolute)(expanded) ? expanded : (0, import_node_path24.resolve)(dir, expanded);
20880
+ const expanded = raw === "~" ? (0, import_node_os5.homedir)() : raw.startsWith("~/") ? (0, import_node_path26.join)((0, import_node_os5.homedir)(), raw.slice(2)) : raw;
20881
+ dir = (0, import_node_path25.isAbsolute)(expanded) ? expanded : (0, import_node_path25.resolve)(dir, expanded);
20577
20882
  }
20578
20883
  const seg = segments[segmentIndex];
20579
20884
  const overrideMatch = /--(?:git-dir|work-tree)(?:=|\s)|\bGIT_(?:DIR|WORK_TREE|INDEX_FILE)=/.exec(seg);
@@ -20591,8 +20896,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
20591
20896
  if (SHELL_DYNAMIC.test(raw)) {
20592
20897
  return { dir: null, named: true, unresolvable: `-C target not statically resolvable: ${raw}` };
20593
20898
  }
20594
- const expanded = raw === "~" ? (0, import_node_os5.homedir)() : raw.startsWith("~/") ? (0, import_node_path25.join)((0, import_node_os5.homedir)(), raw.slice(2)) : raw;
20595
- dir = (0, import_node_path24.isAbsolute)(expanded) ? expanded : (0, import_node_path24.resolve)(dir, expanded);
20899
+ const expanded = raw === "~" ? (0, import_node_os5.homedir)() : raw.startsWith("~/") ? (0, import_node_path26.join)((0, import_node_os5.homedir)(), raw.slice(2)) : raw;
20900
+ dir = (0, import_node_path25.isAbsolute)(expanded) ? expanded : (0, import_node_path25.resolve)(dir, expanded);
20596
20901
  }
20597
20902
  }
20598
20903
  return { dir, named, unresolvable: null };
@@ -20652,14 +20957,14 @@ function gitAt(dir, args) {
20652
20957
  }
20653
20958
  function realpathOr2(p) {
20654
20959
  try {
20655
- return import_node_fs32.realpathSync.native(p);
20960
+ return import_node_fs33.realpathSync.native(p);
20656
20961
  } catch {
20657
- return (0, import_node_path24.resolve)(p);
20962
+ return (0, import_node_path25.resolve)(p);
20658
20963
  }
20659
20964
  }
20660
20965
  function resolveFrame(input) {
20661
20966
  const found = findMomentSegment(input.command, input.on);
20662
- const hookDirUsable = !!input.hookCwd && (0, import_node_fs32.existsSync)(input.hookCwd);
20967
+ const hookDirUsable = !!input.hookCwd && (0, import_node_fs33.existsSync)(input.hookCwd);
20663
20968
  const baseDir = hookDirUsable ? input.hookCwd : process.cwd();
20664
20969
  let anchor = hookDirUsable ? "hook-cwd" : "process-cwd";
20665
20970
  const refuse = (refusal) => ({
@@ -20682,7 +20987,7 @@ function resolveFrame(input) {
20682
20987
  if (dirs.size > 1) return refuse(`target:multiple ${found.moment} targets in one command`);
20683
20988
  const targetDir = dirs.size === 1 ? [...dirs][0] : baseDir;
20684
20989
  if (targetDir !== baseDir) {
20685
- if (!(0, import_node_fs32.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
20990
+ if (!(0, import_node_fs33.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
20686
20991
  dir = targetDir;
20687
20992
  }
20688
20993
  }
@@ -20693,7 +20998,7 @@ function resolveFrame(input) {
20693
20998
  const gitDirRaw = gitAt(dir, ["rev-parse", "--absolute-git-dir"]);
20694
20999
  const commonRaw = gitAt(dir, ["rev-parse", "--git-common-dir"]);
20695
21000
  const gitDir = gitDirRaw ? realpathOr2(gitDirRaw) : null;
20696
- const commonDir = commonRaw ? realpathOr2((0, import_node_path24.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path24.resolve)(dir, commonRaw)) : null;
21001
+ const commonDir = commonRaw ? realpathOr2((0, import_node_path25.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path25.resolve)(dir, commonRaw)) : null;
20697
21002
  const branchRaw = gitAt(dir, ["rev-parse", "--abbrev-ref", "HEAD"]);
20698
21003
  return {
20699
21004
  moment: found?.moment ?? null,
@@ -20868,8 +21173,8 @@ function stagedRange(frame, command) {
20868
21173
  if (plan.kind === "unpredictable") {
20869
21174
  return { kind: "staged", base: "HEAD", head: "INDEX", via: "staged-in-command", refusal: plan.reason };
20870
21175
  }
20871
- const mergeHead = frame.gitDir ? (0, import_node_path25.join)(frame.gitDir, "MERGE_HEAD") : null;
20872
- if (mergeHead && (0, import_node_fs32.existsSync)(mergeHead)) {
21176
+ const mergeHead = frame.gitDir ? (0, import_node_path26.join)(frame.gitDir, "MERGE_HEAD") : null;
21177
+ if (mergeHead && (0, import_node_fs33.existsSync)(mergeHead)) {
20873
21178
  const vsHead = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "HEAD"]).split("\n").filter(Boolean));
20874
21179
  const vsMerge = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "MERGE_HEAD"]).split("\n").filter(Boolean));
20875
21180
  const resolutions = new Set([...vsHead].filter((f) => vsMerge.has(f) && !isVerityOwnedPath(f)));
@@ -21003,7 +21308,7 @@ function truthy(v) {
21003
21308
  }
21004
21309
 
21005
21310
  // src/lib/transcript.ts
21006
- var import_node_fs33 = require("node:fs");
21311
+ var import_node_fs34 = require("node:fs");
21007
21312
  var MAX_READ_BYTES = 256 * 1024;
21008
21313
  var SMALL_FILE_BYTES = 64 * 1024;
21009
21314
  var MAX_FILES_LIST = 20;
@@ -21030,7 +21335,7 @@ async function extractActionSummary(transcriptPath) {
21030
21335
  function readTurnLines(transcriptPath) {
21031
21336
  let size;
21032
21337
  try {
21033
- size = (0, import_node_fs33.statSync)(transcriptPath).size;
21338
+ size = (0, import_node_fs34.statSync)(transcriptPath).size;
21034
21339
  } catch {
21035
21340
  return null;
21036
21341
  }
@@ -21038,7 +21343,7 @@ function readTurnLines(transcriptPath) {
21038
21343
  let raw;
21039
21344
  let windowed = false;
21040
21345
  if (size <= SMALL_FILE_BYTES) {
21041
- raw = (0, import_node_fs33.readFileSync)(transcriptPath, "utf-8");
21346
+ raw = (0, import_node_fs34.readFileSync)(transcriptPath, "utf-8");
21042
21347
  } else {
21043
21348
  windowed = true;
21044
21349
  const buf = Buffer.alloc(Math.min(MAX_READ_BYTES, size));
@@ -21546,7 +21851,7 @@ function channelSilence(input) {
21546
21851
  // src/lib/cli-version.ts
21547
21852
  function cliVersion() {
21548
21853
  try {
21549
- return true ? "0.32.6-experimental.8f2b5f7" : "dev";
21854
+ return true ? "0.32.6-experimental.df0a578" : "dev";
21550
21855
  } catch {
21551
21856
  return "dev";
21552
21857
  }
@@ -21587,7 +21892,7 @@ async function sendSkipBeacon(ctx, reason) {
21587
21892
 
21588
21893
  // src/lib/static-analysis.ts
21589
21894
  var import_node_child_process12 = require("node:child_process");
21590
- var import_node_fs34 = require("node:fs");
21895
+ var import_node_fs35 = require("node:fs");
21591
21896
  var SEVERITY_ORDER = {
21592
21897
  Error: 0,
21593
21898
  Critical: 0,
@@ -21635,7 +21940,7 @@ function runCodacyAnalysis(files) {
21635
21940
  if (files.length === 0) return empty;
21636
21941
  const existingFiles = files.filter((f) => {
21637
21942
  try {
21638
- return (0, import_node_fs34.existsSync)(f);
21943
+ return (0, import_node_fs35.existsSync)(f);
21639
21944
  } catch {
21640
21945
  return false;
21641
21946
  }
@@ -21904,8 +22209,8 @@ async function scope(run2) {
21904
22209
  }
21905
22210
 
21906
22211
  // src/lib/specs.ts
21907
- var import_node_fs35 = require("node:fs");
21908
- var import_node_path26 = require("node:path");
22212
+ var import_node_fs36 = require("node:fs");
22213
+ var import_node_path27 = require("node:path");
21909
22214
  var SPEC_CANDIDATES = [
21910
22215
  "CLAUDE.md",
21911
22216
  "AGENTS.md",
@@ -21936,7 +22241,7 @@ function discoverSpecs(consulted = []) {
21936
22241
  const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
21937
22242
  if (totalBytes >= totalCap) return false;
21938
22243
  if (seen.has(specPath)) return true;
21939
- if (!(0, import_node_fs35.existsSync)(specPath)) return true;
22244
+ if (!(0, import_node_fs36.existsSync)(specPath)) return true;
21940
22245
  seen.add(specPath);
21941
22246
  const remaining = totalCap - totalBytes;
21942
22247
  const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
@@ -21959,7 +22264,7 @@ function discoverSpecs(consulted = []) {
21959
22264
  if (!addSpec(candidate)) break;
21960
22265
  }
21961
22266
  for (const dir of ["spec", "docs"]) {
21962
- if (!(0, import_node_fs35.existsSync)(dir)) continue;
22267
+ if (!(0, import_node_fs36.existsSync)(dir)) continue;
21963
22268
  try {
21964
22269
  const mdFiles = findMdFiles(dir, 2).sort();
21965
22270
  for (const mdFile of mdFiles) {
@@ -21974,9 +22279,9 @@ function findMdFiles(dir, maxDepth, depth = 0) {
21974
22279
  if (depth >= maxDepth) return [];
21975
22280
  const result = [];
21976
22281
  try {
21977
- const entries = (0, import_node_fs35.readdirSync)(dir, { withFileTypes: true });
22282
+ const entries = (0, import_node_fs36.readdirSync)(dir, { withFileTypes: true });
21978
22283
  for (const entry of entries) {
21979
- const fullPath = (0, import_node_path26.join)(dir, entry.name);
22284
+ const fullPath = (0, import_node_path27.join)(dir, entry.name);
21980
22285
  if (entry.isFile() && entry.name.endsWith(".md")) {
21981
22286
  result.push(fullPath);
21982
22287
  } else if (entry.isDirectory() && depth < maxDepth - 1) {
@@ -21989,25 +22294,25 @@ function findMdFiles(dir, maxDepth, depth = 0) {
21989
22294
  }
21990
22295
  function discoverPlans() {
21991
22296
  const home = process.env.HOME ?? "";
21992
- const homePlansDir = (0, import_node_path26.join)(home, ".claude", "plans");
22297
+ const homePlansDir = (0, import_node_path27.join)(home, ".claude", "plans");
21993
22298
  const sources = [];
21994
22299
  if (isRealDirectoryChain(process.cwd(), [".claude", "plans"])) {
21995
- sources.push({ root: process.cwd(), prefix: (0, import_node_path26.join)(".claude", "plans") });
22300
+ sources.push({ root: process.cwd(), prefix: (0, import_node_path27.join)(".claude", "plans") });
21996
22301
  }
21997
- if (home && (0, import_node_fs35.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
22302
+ if (home && (0, import_node_fs36.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
21998
22303
  const candidates2 = [];
21999
22304
  const seen = /* @__PURE__ */ new Set();
22000
22305
  for (const source of sources) {
22001
22306
  let names2;
22002
22307
  try {
22003
- names2 = (0, import_node_fs35.readdirSync)(source.prefix ? (0, import_node_path26.join)(source.root, source.prefix) : source.root);
22308
+ names2 = (0, import_node_fs36.readdirSync)(source.prefix ? (0, import_node_path27.join)(source.root, source.prefix) : source.root);
22004
22309
  } catch {
22005
22310
  continue;
22006
22311
  }
22007
22312
  for (const f of names2) {
22008
22313
  if (!f.endsWith(".md") || seen.has(f)) continue;
22009
22314
  seen.add(f);
22010
- const relPath = source.prefix ? (0, import_node_path26.join)(source.prefix, f) : f;
22315
+ const relPath = source.prefix ? (0, import_node_path27.join)(source.prefix, f) : f;
22011
22316
  const stat3 = statRegularInRoot(source.root, relPath);
22012
22317
  if (!stat3.ok) continue;
22013
22318
  candidates2.push({ name: f, root: source.root, relPath, mtime: stat3.mtimeMs, size: stat3.size });
@@ -22025,9 +22330,9 @@ function discoverPlans() {
22025
22330
  function isRealDirectoryChain(root, parts) {
22026
22331
  let current = root;
22027
22332
  for (const part of parts) {
22028
- current = (0, import_node_path26.join)(current, part);
22333
+ current = (0, import_node_path27.join)(current, part);
22029
22334
  try {
22030
- if (!(0, import_node_fs35.lstatSync)(current).isDirectory()) return false;
22335
+ if (!(0, import_node_fs36.lstatSync)(current).isDirectory()) return false;
22031
22336
  } catch {
22032
22337
  return false;
22033
22338
  }
@@ -22042,7 +22347,7 @@ function discoverGuardDocs(rangeFiles2) {
22042
22347
  if (result.length >= MAX_SPEC_FILES) break;
22043
22348
  if (!GUARD_DOC_EXT.test(path)) continue;
22044
22349
  if (path.startsWith("/") || path.includes("..")) continue;
22045
- if (!(0, import_node_fs35.existsSync)(path)) continue;
22350
+ if (!(0, import_node_fs36.existsSync)(path)) continue;
22046
22351
  const opened = openRegularInRoot(process.cwd(), path);
22047
22352
  if (!opened.ok) continue;
22048
22353
  if (opened.size > MAX_PLAN_FILE_BYTES || totalBytes + opened.size > MAX_TOTAL_SPEC_BYTES) {
@@ -22228,8 +22533,8 @@ async function mode(run2) {
22228
22533
  }
22229
22534
 
22230
22535
  // src/lib/fold.ts
22231
- var import_node_fs36 = require("node:fs");
22232
- var import_node_path27 = require("node:path");
22536
+ var import_node_fs37 = require("node:fs");
22537
+ var import_node_path28 = require("node:path");
22233
22538
  var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
22234
22539
  "user",
22235
22540
  "assistant",
@@ -22366,7 +22671,7 @@ function candidateRoots(repoRoot2) {
22366
22671
  const norm = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
22367
22672
  const out = [norm];
22368
22673
  try {
22369
- const real = import_node_fs36.realpathSync.native(norm).replace(/\\/g, "/").replace(/\/+$/, "");
22674
+ const real = import_node_fs37.realpathSync.native(norm).replace(/\\/g, "/").replace(/\/+$/, "");
22370
22675
  if (real !== norm) out.push(real);
22371
22676
  } catch {
22372
22677
  }
@@ -22454,31 +22759,31 @@ function fold(transcriptPath, opts = {}) {
22454
22759
  }
22455
22760
  };
22456
22761
  try {
22457
- if (!(0, import_node_fs36.existsSync)(transcriptPath)) return result;
22458
- ingest((0, import_node_fs36.readFileSync)(transcriptPath, "utf8"), "agent");
22762
+ if (!(0, import_node_fs37.existsSync)(transcriptPath)) return result;
22763
+ ingest((0, import_node_fs37.readFileSync)(transcriptPath, "utf8"), "agent");
22459
22764
  result.coverage.complete = true;
22460
22765
  } catch {
22461
22766
  return result;
22462
22767
  }
22463
22768
  try {
22464
- const sidecarDir = (0, import_node_path27.join)(
22465
- (0, import_node_path27.dirname)(transcriptPath),
22466
- (0, import_node_path27.basename)(transcriptPath).replace(/\.jsonl$/, ""),
22769
+ const sidecarDir = (0, import_node_path28.join)(
22770
+ (0, import_node_path28.dirname)(transcriptPath),
22771
+ (0, import_node_path28.basename)(transcriptPath).replace(/\.jsonl$/, ""),
22467
22772
  "subagents"
22468
22773
  );
22469
- if ((0, import_node_fs36.existsSync)(sidecarDir)) {
22774
+ if ((0, import_node_fs37.existsSync)(sidecarDir)) {
22470
22775
  const maxFiles = opts.maxSidecars ?? 200;
22471
22776
  const maxBytes = opts.maxSidecarBytes ?? 16 * 1024 * 1024;
22472
22777
  const found = [];
22473
22778
  const walk2 = (d, depth) => {
22474
22779
  if (depth > 4) return;
22475
- for (const e of (0, import_node_fs36.readdirSync)(d, { withFileTypes: true })) {
22476
- const p = (0, import_node_path27.join)(d, e.name);
22780
+ for (const e of (0, import_node_fs37.readdirSync)(d, { withFileTypes: true })) {
22781
+ const p = (0, import_node_path28.join)(d, e.name);
22477
22782
  if (e.isDirectory()) {
22478
22783
  walk2(p, depth + 1);
22479
22784
  } else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
22480
22785
  try {
22481
- const st = (0, import_node_fs36.statSync)(p);
22786
+ const st = (0, import_node_fs37.statSync)(p);
22482
22787
  found.push({ path: p, size: st.size, mtimeMs: st.mtimeMs });
22483
22788
  } catch {
22484
22789
  result.coverage.malformed++;
@@ -22495,7 +22800,7 @@ function fold(transcriptPath, opts = {}) {
22495
22800
  continue;
22496
22801
  }
22497
22802
  try {
22498
- ingest((0, import_node_fs36.readFileSync)(f.path, "utf8"), "subagent");
22803
+ ingest((0, import_node_fs37.readFileSync)(f.path, "utf8"), "subagent");
22499
22804
  bytes += f.size;
22500
22805
  result.coverage.subagentFiles++;
22501
22806
  } catch {
@@ -22530,7 +22835,7 @@ function fold(transcriptPath, opts = {}) {
22530
22835
  }
22531
22836
  function classifyUnobserved(path) {
22532
22837
  try {
22533
- const st = (0, import_node_fs36.statSync)(path);
22838
+ const st = (0, import_node_fs37.statSync)(path);
22534
22839
  if (!st.isFile()) return "unreadable";
22535
22840
  } catch {
22536
22841
  return "unreadable";
@@ -22847,20 +23152,20 @@ async function evidence(run2) {
22847
23152
  }
22848
23153
 
22849
23154
  // src/lib/cache-cleanup.ts
22850
- var import_node_fs37 = require("node:fs");
22851
- var import_node_path28 = require("node:path");
23155
+ var import_node_fs38 = require("node:fs");
23156
+ var import_node_path29 = require("node:path");
22852
23157
  var CACHE_TTL_DAYS = 7;
22853
23158
  function pruneStaleCache() {
22854
23159
  try {
22855
23160
  const dir = projectPath(CACHE_DIR);
22856
23161
  const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
22857
- for (const entry of (0, import_node_fs37.readdirSync)(dir)) {
23162
+ for (const entry of (0, import_node_fs38.readdirSync)(dir)) {
22858
23163
  if (!entry.startsWith("pending-")) continue;
22859
- const path = (0, import_node_path28.join)(dir, entry);
23164
+ const path = (0, import_node_path29.join)(dir, entry);
22860
23165
  try {
22861
- const stat3 = (0, import_node_fs37.statSync)(path);
23166
+ const stat3 = (0, import_node_fs38.statSync)(path);
22862
23167
  if (stat3.mtimeMs < cutoff) {
22863
- (0, import_node_fs37.unlinkSync)(path);
23168
+ (0, import_node_fs38.unlinkSync)(path);
22864
23169
  logEvent("cache_entry_pruned", {
22865
23170
  path: entry,
22866
23171
  age_days: Math.round((Date.now() - stat3.mtimeMs) / 864e5)
@@ -22874,7 +23179,7 @@ function pruneStaleCache() {
22874
23179
  }
22875
23180
 
22876
23181
  // src/lib/context-files.ts
22877
- var import_node_fs38 = require("node:fs");
23182
+ var import_node_fs39 = require("node:fs");
22878
23183
  var import_node_os6 = require("node:os");
22879
23184
  var MAX_CONTEXT_FILES = 10;
22880
23185
  var MAX_CONTEXT_FILE_BYTES = 10240;
@@ -22932,7 +23237,7 @@ function gatherContextFiles(contextPaths, deltaFiles, opts) {
22932
23237
  continue;
22933
23238
  }
22934
23239
  try {
22935
- const content = (0, import_node_fs38.readFileSync)(safePath, "utf8");
23240
+ const content = (0, import_node_fs39.readFileSync)(safePath, "utf8");
22936
23241
  const bytes = Buffer.byteLength(content);
22937
23242
  if (bytes > MAX_CONTEXT_FILE_BYTES) {
22938
23243
  logEvent("context_file_skipped", { path: filePath, reason: "too_large", bytes });
@@ -23022,9 +23327,9 @@ async function repoContext(run2) {
23022
23327
  }
23023
23328
 
23024
23329
  // src/lib/seed-runner.ts
23025
- var import_promises14 = require("node:fs/promises");
23026
- var import_node_fs39 = require("node:fs");
23027
- var import_node_path29 = require("node:path");
23330
+ var import_promises15 = require("node:fs/promises");
23331
+ var import_node_fs40 = require("node:fs");
23332
+ var import_node_path30 = require("node:path");
23028
23333
  var import_yaml4 = __toESM(require_dist());
23029
23334
 
23030
23335
  // src/lib/seed.ts
@@ -23100,7 +23405,7 @@ function classifyClaudeSection(heading) {
23100
23405
  if (hasAny(["integration", "webhook", "third-party", "third party", "provider"])) return "integration";
23101
23406
  return "domain";
23102
23407
  }
23103
- function slugify(s) {
23408
+ function slugify2(s) {
23104
23409
  return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
23105
23410
  }
23106
23411
  var FRAMEWORK_GLOBS = [
@@ -23197,7 +23502,7 @@ _Extracted from README on setup. Update when project direction changes._`,
23197
23502
  for (const fwRaw of frameworks) {
23198
23503
  const fw = fwRaw.trim();
23199
23504
  if (!fw) continue;
23200
- const slug = slugify(fw);
23505
+ const slug = slugify2(fw);
23201
23506
  if (!slug || seenFrameworkSlugs.has(slug)) continue;
23202
23507
  seenFrameworkSlugs.add(slug);
23203
23508
  out.push({
@@ -23263,29 +23568,29 @@ function renderNodeMarkdown(candidate, nodeId, createdAt) {
23263
23568
  return fm;
23264
23569
  }
23265
23570
  async function runSeed(opts) {
23266
- if (!(0, import_node_fs39.existsSync)(STANDARD_FILE)) {
23571
+ if (!(0, import_node_fs40.existsSync)(STANDARD_FILE)) {
23267
23572
  return { created: 0, failed: 0, skipped: "no_standard", candidates: [] };
23268
23573
  }
23269
23574
  let standardDoc;
23270
23575
  try {
23271
- const raw = await (0, import_promises14.readFile)(STANDARD_FILE, "utf-8");
23576
+ const raw = await (0, import_promises15.readFile)(STANDARD_FILE, "utf-8");
23272
23577
  standardDoc = (0, import_yaml4.parse)(raw);
23273
23578
  } catch {
23274
23579
  return { created: 0, failed: 0, skipped: "no_standard", candidates: [] };
23275
23580
  }
23276
23581
  const knowledgeSpec = standardDoc.knowledge_spec ?? {};
23277
23582
  let readmeContent;
23278
- if ((0, import_node_fs39.existsSync)("README.md")) {
23583
+ if ((0, import_node_fs40.existsSync)("README.md")) {
23279
23584
  try {
23280
- readmeContent = await (0, import_promises14.readFile)("README.md", "utf-8");
23585
+ readmeContent = await (0, import_promises15.readFile)("README.md", "utf-8");
23281
23586
  } catch {
23282
23587
  }
23283
23588
  }
23284
23589
  let claudeMdContent;
23285
23590
  for (const p of ["CLAUDE.md", ".claude/CLAUDE.md"]) {
23286
- if ((0, import_node_fs39.existsSync)(p)) {
23591
+ if ((0, import_node_fs40.existsSync)(p)) {
23287
23592
  try {
23288
- claudeMdContent = await (0, import_promises14.readFile)(p, "utf-8");
23593
+ claudeMdContent = await (0, import_promises15.readFile)(p, "utf-8");
23289
23594
  break;
23290
23595
  } catch {
23291
23596
  }
@@ -23306,8 +23611,8 @@ async function runSeed(opts) {
23306
23611
  if (candidates2.length === 0) {
23307
23612
  return { created: 0, failed: 0, skipped: "no_candidates", candidates: [] };
23308
23613
  }
23309
- const overviewPath = (0, import_node_path29.join)(MEMORY_DIR, "domain", "project-overview.md");
23310
- if ((0, import_node_fs39.existsSync)(overviewPath) && !opts.force) {
23614
+ const overviewPath = (0, import_node_path30.join)(MEMORY_DIR, "domain", "project-overview.md");
23615
+ if ((0, import_node_fs40.existsSync)(overviewPath) && !opts.force) {
23311
23616
  return { created: 0, failed: 0, skipped: "already_seeded", candidates: candidates2 };
23312
23617
  }
23313
23618
  if (opts.dryRun) {
@@ -23349,8 +23654,8 @@ async function runSeed(opts) {
23349
23654
  continue;
23350
23655
  }
23351
23656
  try {
23352
- await (0, import_promises14.mkdir)((0, import_node_path29.dirname)(targetPath), { recursive: true });
23353
- await (0, import_promises14.writeFile)(targetPath, renderNodeMarkdown(c, nodeId, createdAt));
23657
+ await (0, import_promises15.mkdir)((0, import_node_path30.dirname)(targetPath), { recursive: true });
23658
+ await (0, import_promises15.writeFile)(targetPath, renderNodeMarkdown(c, nodeId, createdAt));
23354
23659
  created++;
23355
23660
  opts.onCreated?.(nodeId, filePathRel, c);
23356
23661
  } catch (err) {
@@ -23362,8 +23667,8 @@ async function runSeed(opts) {
23362
23667
  }
23363
23668
 
23364
23669
  // src/commands/analyze/phases/08-memory-manifest.ts
23365
- var import_node_fs40 = require("node:fs");
23366
- var import_node_path30 = require("node:path");
23670
+ var import_node_fs41 = require("node:fs");
23671
+ var import_node_path31 = require("node:path");
23367
23672
  async function memoryManifest(run2) {
23368
23673
  const { globals } = run2;
23369
23674
  const { serviceUrl, token } = run2;
@@ -23373,9 +23678,9 @@ async function memoryManifest(run2) {
23373
23678
  let autoSeedNotice = null;
23374
23679
  try {
23375
23680
  await ensureMemoryDir();
23376
- const seedMarker = (0, import_node_path30.join)(VERITY_DIR, ".seeded");
23377
- const hasStandard = (0, import_node_fs40.existsSync)(STANDARD_FILE);
23378
- const alreadyTried = (0, import_node_fs40.existsSync)(seedMarker);
23681
+ const seedMarker = (0, import_node_path31.join)(VERITY_DIR, ".seeded");
23682
+ const hasStandard = (0, import_node_fs41.existsSync)(STANDARD_FILE);
23683
+ const alreadyTried = (0, import_node_fs41.existsSync)(seedMarker);
23379
23684
  if (hasStandard && !alreadyTried) {
23380
23685
  const preManifest = await buildManifest();
23381
23686
  if (preManifest.nodes.length === 0) {
@@ -23388,7 +23693,7 @@ async function memoryManifest(run2) {
23388
23693
  dryRun: false
23389
23694
  });
23390
23695
  if (seedResult.created > 0) {
23391
- (0, import_node_fs40.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created}
23696
+ (0, import_node_fs41.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created}
23392
23697
  `);
23393
23698
  autoSeedNotice = `Seeded ${seedResult.created} knowledge node(s) from your existing Standard (one-time).`;
23394
23699
  logEvent("auto_seed_ran", {
@@ -23396,7 +23701,7 @@ async function memoryManifest(run2) {
23396
23701
  failed: seedResult.failed
23397
23702
  });
23398
23703
  } else if (seedResult.skipped === "already_seeded") {
23399
- (0, import_node_fs40.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
23704
+ (0, import_node_fs41.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
23400
23705
  `);
23401
23706
  } else {
23402
23707
  logEvent("auto_seed_noop", {
@@ -23491,7 +23796,7 @@ function computeIncrement(reviewedPaths, hashOf, priorAuthored) {
23491
23796
  }
23492
23797
 
23493
23798
  // src/commands/analyze/phases/10-working-memory.ts
23494
- var import_node_path31 = require("node:path");
23799
+ var import_node_path32 = require("node:path");
23495
23800
  async function workingMemory(run2) {
23496
23801
  const { opts } = run2;
23497
23802
  const { allForReview, baseline, conversation, foldResult, sessionId, token, transcriptPath } = run2;
@@ -23503,7 +23808,7 @@ async function workingMemory(run2) {
23503
23808
  const priorState = foldForMarks(memorySession.d);
23504
23809
  incrementReport = computeIncrement(
23505
23810
  allForReview,
23506
- (p) => fileHash((0, import_node_path31.join)(repoRoot(), p)),
23811
+ (p) => fileHash((0, import_node_path32.join)(repoRoot(), p)),
23507
23812
  priorState.authored_all.map((a) => ({
23508
23813
  path: a.path,
23509
23814
  hash_at_last_verdict: a.hash_at_last_verdict
@@ -23585,7 +23890,7 @@ async function workingMemory(run2) {
23585
23890
  }
23586
23891
 
23587
23892
  // src/lib/note-budget.ts
23588
- var import_node_fs41 = require("node:fs");
23893
+ var import_node_fs42 = require("node:fs");
23589
23894
  var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
23590
23895
  var EPISODE_STALE_SECONDS = 30 * 60;
23591
23896
  var FRESH = { delivered: 0, tasksCompleted: 0, ts: 0 };
@@ -23607,9 +23912,9 @@ function advisoryBudgetSpent(episode, rawDecision) {
23607
23912
  }
23608
23913
  function readAdvisoryEpisode(sessionId) {
23609
23914
  const file = scopedFile(ADVISORY_EPISODE_FILE, sessionId);
23610
- if (!(0, import_node_fs41.existsSync)(file)) return null;
23915
+ if (!(0, import_node_fs42.existsSync)(file)) return null;
23611
23916
  try {
23612
- const o = JSON.parse((0, import_node_fs41.readFileSync)(file, "utf-8")) ?? {};
23917
+ const o = JSON.parse((0, import_node_fs42.readFileSync)(file, "utf-8")) ?? {};
23613
23918
  const delivered = typeof o.delivered === "number" ? o.delivered : NaN;
23614
23919
  if (isNaN(delivered)) return null;
23615
23920
  return {
@@ -23623,8 +23928,8 @@ function readAdvisoryEpisode(sessionId) {
23623
23928
  }
23624
23929
  function writeAdvisoryEpisode(episode, sessionId) {
23625
23930
  try {
23626
- (0, import_node_fs41.mkdirSync)(VERITY_DIR, { recursive: true });
23627
- (0, import_node_fs41.writeFileSync)(
23931
+ (0, import_node_fs42.mkdirSync)(VERITY_DIR, { recursive: true });
23932
+ (0, import_node_fs42.writeFileSync)(
23628
23933
  scopedFile(ADVISORY_EPISODE_FILE, sessionId),
23629
23934
  JSON.stringify({ v: 1, ...episode })
23630
23935
  );
@@ -23932,14 +24237,14 @@ async function buildRequest(run2) {
23932
24237
  }
23933
24238
 
23934
24239
  // src/lib/offline.ts
23935
- var import_node_fs42 = require("node:fs");
24240
+ var import_node_fs43 = require("node:fs");
23936
24241
  var import_node_crypto11 = require("node:crypto");
23937
24242
  function cacheRequest(body) {
23938
24243
  try {
23939
- (0, import_node_fs42.mkdirSync)(CACHE_DIR, { recursive: true });
24244
+ (0, import_node_fs43.mkdirSync)(CACHE_DIR, { recursive: true });
23940
24245
  const suffix = (0, import_node_crypto11.randomBytes)(4).toString("hex");
23941
24246
  const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
23942
- (0, import_node_fs42.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body)));
24247
+ (0, import_node_fs43.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body)));
23943
24248
  } catch {
23944
24249
  }
23945
24250
  }
@@ -24058,8 +24363,8 @@ async function transmit(run2) {
24058
24363
  }
24059
24364
 
24060
24365
  // src/commands/analyze/phases/13-reconcile.ts
24061
- var import_node_fs43 = require("node:fs");
24062
- var import_node_path32 = require("node:path");
24366
+ var import_node_fs44 = require("node:fs");
24367
+ var import_node_path33 = require("node:path");
24063
24368
  async function reconcile(run2) {
24064
24369
  const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory, memorySession, response, reviewable, securityFiles, turnId } = run2;
24065
24370
  const sentPaths = codeDelta.files.map((f) => f.path);
@@ -24088,7 +24393,7 @@ async function reconcile(run2) {
24088
24393
  const st = foldDossier(memorySession.d);
24089
24394
  openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line) => {
24090
24395
  try {
24091
- const src = (0, import_node_fs43.readFileSync)((0, import_node_path32.join)(repoRoot(), file), "utf8").split("\n");
24396
+ const src = (0, import_node_fs44.readFileSync)((0, import_node_path33.join)(repoRoot(), file), "utf8").split("\n");
24092
24397
  const at = src[line - 1];
24093
24398
  return at === void 0 ? null : lineSha(at);
24094
24399
  } catch {
@@ -24353,7 +24658,7 @@ function describeRelease(release, input) {
24353
24658
 
24354
24659
  // src/lib/memory-pull.ts
24355
24660
  var import_node_child_process14 = require("node:child_process");
24356
- var import_promises15 = require("node:fs/promises");
24661
+ var import_promises16 = require("node:fs/promises");
24357
24662
  var pullStateFile = () => projectPath(`${VERITY_DIR}/.memory-pull-state.json`);
24358
24663
  var PAGE_SIZE = 200;
24359
24664
  var MAX_PAGES = 500;
@@ -24437,7 +24742,7 @@ async function recordServedFiles(served) {
24437
24742
  }
24438
24743
  async function readPullState() {
24439
24744
  try {
24440
- const parsed = JSON.parse(await (0, import_promises15.readFile)(pullStateFile(), "utf-8"));
24745
+ const parsed = JSON.parse(await (0, import_promises16.readFile)(pullStateFile(), "utf-8"));
24441
24746
  const served = /* @__PURE__ */ new Map();
24442
24747
  if (parsed?.served && typeof parsed.served === "object") {
24443
24748
  for (const [path, hash] of Object.entries(parsed.served)) {
@@ -24451,8 +24756,8 @@ async function readPullState() {
24451
24756
  }
24452
24757
  async function writePullState(state) {
24453
24758
  try {
24454
- await (0, import_promises15.mkdir)(projectPath(VERITY_DIR), { recursive: true });
24455
- await (0, import_promises15.writeFile)(pullStateFile(), JSON.stringify({
24759
+ await (0, import_promises16.mkdir)(projectPath(VERITY_DIR), { recursive: true });
24760
+ await (0, import_promises16.writeFile)(pullStateFile(), JSON.stringify({
24456
24761
  ...state.version ? { version: state.version } : {},
24457
24762
  pulled_at: (/* @__PURE__ */ new Date()).toISOString(),
24458
24763
  served: Object.fromEntries(state.served)
@@ -24895,7 +25200,7 @@ function registerAnalyzeCommand(program2) {
24895
25200
  var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
24896
25201
  async function runAnalyze(opts, globals) {
24897
25202
  if (!verityConfigured()) {
24898
- (0, import_node_fs44.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
25203
+ (0, import_node_fs45.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
24899
25204
  process.exit(0);
24900
25205
  }
24901
25206
  const run2 = createRun(opts, globals);
@@ -24916,11 +25221,11 @@ async function runAnalyze(opts, globals) {
24916
25221
  }
24917
25222
 
24918
25223
  // src/commands/baseline.ts
24919
- var import_node_fs46 = require("node:fs");
25224
+ var import_node_fs47 = require("node:fs");
24920
25225
 
24921
25226
  // src/lib/project-skills.ts
24922
- var import_node_fs45 = require("node:fs");
24923
- var import_node_path33 = require("node:path");
25227
+ var import_node_fs46 = require("node:fs");
25228
+ var import_node_path34 = require("node:path");
24924
25229
  var PROJECT_SKILL_NAMES = [
24925
25230
  "verity-setup",
24926
25231
  "verity-analyze",
@@ -24945,14 +25250,14 @@ var LEGACY_SKILL_NAMES = [
24945
25250
  var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
24946
25251
  function staleProjectSkills() {
24947
25252
  const root = projectPath(".claude/skills");
24948
- if (!(0, import_node_fs45.existsSync)(root)) return [];
24949
- return ALL.filter((name) => (0, import_node_fs45.existsSync)((0, import_node_path33.join)(root, name)));
25253
+ if (!(0, import_node_fs46.existsSync)(root)) return [];
25254
+ return ALL.filter((name) => (0, import_node_fs46.existsSync)((0, import_node_path34.join)(root, name)));
24950
25255
  }
24951
25256
  function removeProjectSkills() {
24952
25257
  const root = projectPath(".claude/skills");
24953
25258
  const removed = [];
24954
25259
  for (const name of staleProjectSkills()) {
24955
- (0, import_node_fs45.rmSync)((0, import_node_path33.join)(root, name), { recursive: true, force: true });
25260
+ (0, import_node_fs46.rmSync)((0, import_node_path34.join)(root, name), { recursive: true, force: true });
24956
25261
  removed.push(name);
24957
25262
  }
24958
25263
  return removed;
@@ -25017,13 +25322,13 @@ function registerBaselineCommands(program2) {
25017
25322
  let memoryMsg = null;
25018
25323
  let memoryAgentLine = null;
25019
25324
  const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
25020
- if (realStart && !(0, import_node_fs46.existsSync)(memoryNotice)) {
25325
+ if (realStart && !(0, import_node_fs47.existsSync)(memoryNotice)) {
25021
25326
  const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
25022
25327
  if (trackedGraph > 0) {
25023
25328
  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.`;
25024
25329
  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.`;
25025
25330
  try {
25026
- (0, import_node_fs46.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
25331
+ (0, import_node_fs47.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
25027
25332
  } catch {
25028
25333
  }
25029
25334
  }
@@ -25124,7 +25429,7 @@ function hookSource(value) {
25124
25429
  }
25125
25430
 
25126
25431
  // src/commands/review.ts
25127
- var import_node_fs47 = require("node:fs");
25432
+ var import_node_fs48 = require("node:fs");
25128
25433
  function registerReviewCommand(program2) {
25129
25434
  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) => {
25130
25435
  const globals = program2.opts();
@@ -25143,7 +25448,7 @@ async function runReview(opts, globals) {
25143
25448
  const securityFiles = filterSecurity(allFiles);
25144
25449
  let staticResults;
25145
25450
  if (isCodacyAvailable()) {
25146
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs47.existsSync)(f) || resolveFile(f) !== null);
25451
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs48.existsSync)(f) || resolveFile(f) !== null);
25147
25452
  staticResults = runCodacyAnalysis(scannable);
25148
25453
  } else {
25149
25454
  staticResults = {
@@ -25169,7 +25474,7 @@ async function runReview(opts, globals) {
25169
25474
  const specPaths = opts.specs.split(",").map((f) => f.trim()).filter(Boolean);
25170
25475
  specs = [];
25171
25476
  for (const p of specPaths) {
25172
- if (!(0, import_node_fs47.existsSync)(p)) continue;
25477
+ if (!(0, import_node_fs48.existsSync)(p)) continue;
25173
25478
  try {
25174
25479
  const { readFileSync: readFileSync26 } = await import("node:fs");
25175
25480
  const content = readFileSync26(p, "utf-8");
@@ -25229,8 +25534,8 @@ async function runReview(opts, globals) {
25229
25534
  }
25230
25535
 
25231
25536
  // src/commands/guard.ts
25232
- var import_node_fs48 = require("node:fs");
25233
- var import_node_path34 = require("node:path");
25537
+ var import_node_fs49 = require("node:fs");
25538
+ var import_node_path35 = require("node:path");
25234
25539
 
25235
25540
  // src/lib/terminal-text.ts
25236
25541
  var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/g;
@@ -25605,7 +25910,7 @@ async function buildAgentDiffs(ctx, paths, limits = { perFileChars: 24e3, totalC
25605
25910
  // src/commands/guard.ts
25606
25911
  var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
25607
25912
  var GUARD_BLOCK_CAP = 2;
25608
- var GUARD_ITER_FILE = (0, import_node_path34.join)(VERITY_DIR, ".guard-iteration");
25913
+ var GUARD_ITER_FILE = (0, import_node_path35.join)(VERITY_DIR, ".guard-iteration");
25609
25914
  function readPreToolUseStdin() {
25610
25915
  const empty = { command: "", cwd: null, sessionId: null };
25611
25916
  return new Promise((resolve6) => {
@@ -25650,7 +25955,7 @@ function readPreToolUseStdin() {
25650
25955
  }
25651
25956
  function readIterMap() {
25652
25957
  try {
25653
- const raw = JSON.parse((0, import_node_fs48.readFileSync)(GUARD_ITER_FILE, "utf-8"));
25958
+ const raw = JSON.parse((0, import_node_fs49.readFileSync)(GUARD_ITER_FILE, "utf-8"));
25654
25959
  if (raw && typeof raw === "object") {
25655
25960
  if (typeof raw.moment === "string" && typeof raw.count === "number") {
25656
25961
  return { [raw.moment]: raw.count };
@@ -25670,10 +25975,10 @@ function readIter(moment) {
25670
25975
  }
25671
25976
  function writeIter(moment, count) {
25672
25977
  try {
25673
- (0, import_node_fs48.mkdirSync)(VERITY_DIR, { recursive: true });
25978
+ (0, import_node_fs49.mkdirSync)(VERITY_DIR, { recursive: true });
25674
25979
  const map = readIterMap();
25675
25980
  map[moment] = count;
25676
- (0, import_node_fs48.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
25981
+ (0, import_node_fs49.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
25677
25982
  } catch {
25678
25983
  }
25679
25984
  }
@@ -25683,10 +25988,10 @@ function resetIter(moment) {
25683
25988
  if (!(moment in map)) return;
25684
25989
  delete map[moment];
25685
25990
  if (Object.keys(map).length === 0) {
25686
- if ((0, import_node_fs48.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs48.unlinkSync)(GUARD_ITER_FILE);
25991
+ if ((0, import_node_fs49.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs49.unlinkSync)(GUARD_ITER_FILE);
25687
25992
  } else {
25688
- (0, import_node_fs48.mkdirSync)(VERITY_DIR, { recursive: true });
25689
- (0, import_node_fs48.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
25993
+ (0, import_node_fs49.mkdirSync)(VERITY_DIR, { recursive: true });
25994
+ (0, import_node_fs49.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
25690
25995
  }
25691
25996
  } catch {
25692
25997
  }
@@ -25758,7 +26063,7 @@ function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedInte
25758
26063
  const securityFiles = filterSecurity(files);
25759
26064
  let staticResults;
25760
26065
  if (isCodacyAvailable()) {
25761
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs48.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
26066
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs49.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
25762
26067
  staticResults = runCodacyAnalysis(scannable);
25763
26068
  } else {
25764
26069
  staticResults = { tool: "@codacy/analysis-cli", findings: [], summary: { total_findings: 0, by_severity: {}, tools_run: [] } };
@@ -26261,7 +26566,7 @@ function registerIgnoreCommand(program2) {
26261
26566
 
26262
26567
  // src/commands/waive.ts
26263
26568
  var import_node_crypto12 = require("node:crypto");
26264
- var import_node_fs49 = require("node:fs");
26569
+ var import_node_fs50 = require("node:fs");
26265
26570
  function registerWaiveCommand(program2) {
26266
26571
  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) => {
26267
26572
  const globals = program2.opts();
@@ -26290,7 +26595,7 @@ function registerWaiveCommand(program2) {
26290
26595
  if (opts.file) {
26291
26596
  body.file = opts.file;
26292
26597
  try {
26293
- body.file_sha256 = (0, import_node_crypto12.createHash)("sha256").update((0, import_node_fs49.readFileSync)(opts.file)).digest("hex");
26598
+ body.file_sha256 = (0, import_node_crypto12.createHash)("sha256").update((0, import_node_fs50.readFileSync)(opts.file)).digest("hex");
26294
26599
  } catch {
26295
26600
  printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
26296
26601
  process.exit(1);
@@ -26315,10 +26620,10 @@ function registerWaiveCommand(program2) {
26315
26620
  }
26316
26621
 
26317
26622
  // src/commands/init.ts
26318
- var import_node_fs53 = require("node:fs");
26319
- var import_promises18 = require("node:fs/promises");
26623
+ var import_node_fs54 = require("node:fs");
26624
+ var import_promises19 = require("node:fs/promises");
26320
26625
  var import_yaml6 = __toESM(require_dist());
26321
- var import_node_path37 = require("node:path");
26626
+ var import_node_path38 = require("node:path");
26322
26627
  var import_node_child_process17 = require("node:child_process");
26323
26628
 
26324
26629
  // src/lib/banner.ts
@@ -26397,7 +26702,7 @@ function printPhase(n, of, title, subtitle) {
26397
26702
  }
26398
26703
 
26399
26704
  // src/commands/doctor.ts
26400
- var import_node_fs50 = require("node:fs");
26705
+ var import_node_fs51 = require("node:fs");
26401
26706
 
26402
26707
  // src/lib/prereqs.ts
26403
26708
  var import_node_child_process15 = require("node:child_process");
@@ -26513,7 +26818,7 @@ async function checkPrereqs(opts = {}) {
26513
26818
  }
26514
26819
 
26515
26820
  // src/lib/telemetry.ts
26516
- var import_promises16 = require("node:fs/promises");
26821
+ var import_promises17 = require("node:fs/promises");
26517
26822
  var SETTINGS_LOCAL_FILE2 = ".claude/settings.local.json";
26518
26823
  var GITIGNORE_FILE = ".gitignore";
26519
26824
  var GITIGNORE_ENTRY = SETTINGS_LOCAL_IGNORE_ENTRY;
@@ -26543,7 +26848,7 @@ function buildTelemetryEnv(serviceUrl) {
26543
26848
  var VERITY_TELEMETRY_KEYS = Object.keys(buildTelemetryEnv(""));
26544
26849
  async function readSettingsLocal() {
26545
26850
  try {
26546
- return JSON.parse(await (0, import_promises16.readFile)(projectPath(SETTINGS_LOCAL_FILE2), "utf-8"));
26851
+ return JSON.parse(await (0, import_promises17.readFile)(projectPath(SETTINGS_LOCAL_FILE2), "utf-8"));
26547
26852
  } catch {
26548
26853
  return {};
26549
26854
  }
@@ -26555,7 +26860,7 @@ async function ensureGitignore() {
26555
26860
  const file = projectPath(GITIGNORE_FILE);
26556
26861
  let content = "";
26557
26862
  try {
26558
- content = await (0, import_promises16.readFile)(file, "utf-8");
26863
+ content = await (0, import_promises17.readFile)(file, "utf-8");
26559
26864
  } catch {
26560
26865
  }
26561
26866
  const lines = content.split("\n").map((l) => l.trim());
@@ -26564,7 +26869,7 @@ async function ensureGitignore() {
26564
26869
  }
26565
26870
  const block = "# Verity telemetry \u2014 machine-local Claude Code settings\n" + GITIGNORE_ENTRY + "\n";
26566
26871
  const next = content ? content + (content.endsWith("\n") ? "" : "\n") + "\n" + block : block;
26567
- await (0, import_promises16.writeFile)(file, next);
26872
+ await (0, import_promises17.writeFile)(file, next);
26568
26873
  }
26569
26874
  async function installTelemetry(serviceUrl) {
26570
26875
  const env = buildTelemetryEnv(serviceUrl);
@@ -26609,11 +26914,11 @@ async function buildReport() {
26609
26914
  const wiring = await resolveHookWiring();
26610
26915
  const hooks = wiring.status;
26611
26916
  const telemetry = await checkTelemetry();
26612
- const hasConfig = (0, import_node_fs50.existsSync)(projectPath(CODACY_CONFIG_FILE));
26917
+ const hasConfig = (0, import_node_fs51.existsSync)(projectPath(CODACY_CONFIG_FILE));
26613
26918
  const artifacts = {
26614
- standard: (0, import_node_fs50.existsSync)(projectPath(STANDARD_FILE)),
26919
+ standard: (0, import_node_fs51.existsSync)(projectPath(STANDARD_FILE)),
26615
26920
  analysisConfig: hasConfig,
26616
- verityMd: (0, import_node_fs50.existsSync)(projectPath(VERITY_MD_FILE)),
26921
+ verityMd: (0, import_node_fs51.existsSync)(projectPath(VERITY_MD_FILE)),
26617
26922
  analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
26618
26923
  };
26619
26924
  const next = [];
@@ -26744,8 +27049,8 @@ function registerDoctorCommand(program2) {
26744
27049
  }
26745
27050
 
26746
27051
  // src/commands/migrate.ts
26747
- var import_node_fs51 = require("node:fs");
26748
- var import_node_path35 = require("node:path");
27052
+ var import_node_fs52 = require("node:fs");
27053
+ var import_node_path36 = require("node:path");
26749
27054
  var import_node_child_process16 = require("node:child_process");
26750
27055
  var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
26751
27056
  function defaultNpmRemover(pkg) {
@@ -26782,12 +27087,12 @@ async function runMigration(opts = {}) {
26782
27087
  return { actions, migrated: actions.length > 0 };
26783
27088
  }
26784
27089
  function migrateProjectDir(root, actions) {
26785
- const gateDir = (0, import_node_path35.join)(root, ".gate");
26786
- const verityDir = (0, import_node_path35.join)(root, ".verity");
26787
- if ((0, import_node_fs51.existsSync)(gateDir) && !(0, import_node_fs51.existsSync)(verityDir)) {
27090
+ const gateDir = (0, import_node_path36.join)(root, ".gate");
27091
+ const verityDir = (0, import_node_path36.join)(root, ".verity");
27092
+ if ((0, import_node_fs52.existsSync)(gateDir) && !(0, import_node_fs52.existsSync)(verityDir)) {
26788
27093
  return migrateProjectDirRename(root, gateDir, verityDir, actions);
26789
27094
  }
26790
- if ((0, import_node_fs51.existsSync)(gateDir) && (0, import_node_fs51.existsSync)(verityDir)) {
27095
+ if ((0, import_node_fs52.existsSync)(gateDir) && (0, import_node_fs52.existsSync)(verityDir)) {
26791
27096
  return migrateProjectDirCarry(gateDir, verityDir, actions);
26792
27097
  }
26793
27098
  return false;
@@ -26808,13 +27113,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
26808
27113
  }
26809
27114
  }
26810
27115
  if (moved) {
26811
- if ((0, import_node_fs51.existsSync)(gateDir)) {
27116
+ if ((0, import_node_fs52.existsSync)(gateDir)) {
26812
27117
  const carried = carryLegacyContents(gateDir, verityDir);
26813
27118
  if (carried > 0) {
26814
27119
  actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
26815
27120
  }
26816
27121
  try {
26817
- (0, import_node_fs51.rmSync)(gateDir, { recursive: true, force: true });
27122
+ (0, import_node_fs52.rmSync)(gateDir, { recursive: true, force: true });
26818
27123
  } catch {
26819
27124
  }
26820
27125
  }
@@ -26830,18 +27135,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
26830
27135
  actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
26831
27136
  }
26832
27137
  try {
26833
- (0, import_node_fs51.rmSync)(gateDir, { recursive: true, force: true });
27138
+ (0, import_node_fs52.rmSync)(gateDir, { recursive: true, force: true });
26834
27139
  } catch {
26835
27140
  }
26836
27141
  return carried > 0;
26837
27142
  }
26838
27143
  function migrateGlobalCredentials(home, actions) {
26839
27144
  if (!home) return;
26840
- const gateCreds = (0, import_node_path35.join)(home, ".gate", "credentials");
26841
- const verityCreds = (0, import_node_path35.join)(home, ".verity", "credentials");
26842
- if (!(0, import_node_fs51.existsSync)(gateCreds)) return;
26843
- if (!(0, import_node_fs51.existsSync)(verityCreds)) {
26844
- (0, import_node_fs51.mkdirSync)((0, import_node_path35.join)(home, ".verity"), { recursive: true });
27145
+ const gateCreds = (0, import_node_path36.join)(home, ".gate", "credentials");
27146
+ const verityCreds = (0, import_node_path36.join)(home, ".verity", "credentials");
27147
+ if (!(0, import_node_fs52.existsSync)(gateCreds)) return;
27148
+ if (!(0, import_node_fs52.existsSync)(verityCreds)) {
27149
+ (0, import_node_fs52.mkdirSync)((0, import_node_path36.join)(home, ".verity"), { recursive: true });
26845
27150
  moveFile(gateCreds, verityCreds);
26846
27151
  actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
26847
27152
  return;
@@ -26863,8 +27168,8 @@ async function migrateLegacyHooks(root, actions) {
26863
27168
  }
26864
27169
  }
26865
27170
  async function migrateClaudeMd(root, actions) {
26866
- const claudeMd = (0, import_node_path35.join)(root, "CLAUDE.md");
26867
- const hadLegacyBlock = (0, import_node_fs51.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
27171
+ const claudeMd = (0, import_node_path36.join)(root, "CLAUDE.md");
27172
+ const hadLegacyBlock = (0, import_node_fs52.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
26868
27173
  if (!hadLegacyBlock) return;
26869
27174
  try {
26870
27175
  await ensureClaudeMdPointer(root);
@@ -26874,9 +27179,9 @@ async function migrateClaudeMd(root, actions) {
26874
27179
  }
26875
27180
  }
26876
27181
  function migrateStandardFile(root, actions) {
26877
- const gateMd = (0, import_node_path35.join)(root, "GATE.md");
26878
- const verityMd = (0, import_node_path35.join)(root, "VERITY.md");
26879
- if (!(0, import_node_fs51.existsSync)(gateMd) || (0, import_node_fs51.existsSync)(verityMd)) return;
27182
+ const gateMd = (0, import_node_path36.join)(root, "GATE.md");
27183
+ const verityMd = (0, import_node_path36.join)(root, "VERITY.md");
27184
+ if (!(0, import_node_fs52.existsSync)(gateMd) || (0, import_node_fs52.existsSync)(verityMd)) return;
26880
27185
  let moved = false;
26881
27186
  if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
26882
27187
  try {
@@ -26888,12 +27193,12 @@ function migrateStandardFile(root, actions) {
26888
27193
  if (!moved) moveFile(gateMd, verityMd);
26889
27194
  const content = readFileSyncSafe(verityMd);
26890
27195
  const refreshed = content.split("GATE.md").join("VERITY.md");
26891
- if (refreshed !== content) (0, import_node_fs51.writeFileSync)(verityMd, refreshed);
27196
+ if (refreshed !== content) (0, import_node_fs52.writeFileSync)(verityMd, refreshed);
26892
27197
  actions.push("Renamed GATE.md \u2192 VERITY.md");
26893
27198
  }
26894
27199
  async function migrateTelemetryHeaders(root, actions) {
26895
- const file = (0, import_node_path35.join)(root, ".claude", "settings.local.json");
26896
- if (!(0, import_node_fs51.existsSync)(file)) return;
27200
+ const file = (0, import_node_path36.join)(root, ".claude", "settings.local.json");
27201
+ if (!(0, import_node_fs52.existsSync)(file)) return;
26897
27202
  let settings;
26898
27203
  try {
26899
27204
  settings = JSON.parse(readFileSyncSafe(file) || "{}");
@@ -26941,14 +27246,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
26941
27246
  }
26942
27247
  if (toAppend.length > 0) {
26943
27248
  const sep4 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
26944
- (0, import_node_fs51.writeFileSync)(verityCreds, verityContent + sep4 + toAppend.join("\n") + "\n");
27249
+ (0, import_node_fs52.writeFileSync)(verityCreds, verityContent + sep4 + toAppend.join("\n") + "\n");
26945
27250
  }
26946
- (0, import_node_fs51.rmSync)(gateCreds, { force: true });
27251
+ (0, import_node_fs52.rmSync)(gateCreds, { force: true });
26947
27252
  return toAppend.length;
26948
27253
  }
26949
27254
  function readFileSyncSafe(path) {
26950
27255
  try {
26951
- return (0, import_node_fs51.readFileSync)(path, "utf-8");
27256
+ return (0, import_node_fs52.readFileSync)(path, "utf-8");
26952
27257
  } catch {
26953
27258
  return "";
26954
27259
  }
@@ -26963,35 +27268,35 @@ function hasStagedChanges(root) {
26963
27268
  }
26964
27269
  function moveDir(from, to) {
26965
27270
  try {
26966
- (0, import_node_fs51.renameSync)(from, to);
27271
+ (0, import_node_fs52.renameSync)(from, to);
26967
27272
  } catch (err) {
26968
27273
  if (err.code !== "EXDEV") throw err;
26969
- (0, import_node_fs51.cpSync)(from, to, { recursive: true });
26970
- (0, import_node_fs51.rmSync)(from, { recursive: true, force: true });
27274
+ (0, import_node_fs52.cpSync)(from, to, { recursive: true });
27275
+ (0, import_node_fs52.rmSync)(from, { recursive: true, force: true });
26971
27276
  }
26972
27277
  }
26973
27278
  function moveFile(from, to) {
26974
27279
  try {
26975
- (0, import_node_fs51.renameSync)(from, to);
27280
+ (0, import_node_fs52.renameSync)(from, to);
26976
27281
  } catch (err) {
26977
27282
  if (err.code !== "EXDEV") throw err;
26978
- (0, import_node_fs51.cpSync)(from, to);
26979
- (0, import_node_fs51.rmSync)(from, { force: true });
27283
+ (0, import_node_fs52.cpSync)(from, to);
27284
+ (0, import_node_fs52.rmSync)(from, { force: true });
26980
27285
  }
26981
27286
  }
26982
27287
  function carryLegacyContents(gateDir, verityDir) {
26983
27288
  let copied = 0;
26984
27289
  const walk2 = (relDir) => {
26985
- const srcDir = (0, import_node_path35.join)(gateDir, relDir);
26986
- for (const entry of (0, import_node_fs51.readdirSync)(srcDir)) {
26987
- const rel = relDir ? (0, import_node_path35.join)(relDir, entry) : entry;
26988
- const src = (0, import_node_path35.join)(gateDir, rel);
26989
- const dest = (0, import_node_path35.join)(verityDir, rel);
26990
- if ((0, import_node_fs51.statSync)(src).isDirectory()) {
27290
+ const srcDir = (0, import_node_path36.join)(gateDir, relDir);
27291
+ for (const entry of (0, import_node_fs52.readdirSync)(srcDir)) {
27292
+ const rel = relDir ? (0, import_node_path36.join)(relDir, entry) : entry;
27293
+ const src = (0, import_node_path36.join)(gateDir, rel);
27294
+ const dest = (0, import_node_path36.join)(verityDir, rel);
27295
+ if ((0, import_node_fs52.statSync)(src).isDirectory()) {
26991
27296
  walk2(rel);
26992
- } else if (!(0, import_node_fs51.existsSync)(dest)) {
26993
- (0, import_node_fs51.mkdirSync)((0, import_node_path35.dirname)(dest), { recursive: true });
26994
- (0, import_node_fs51.cpSync)(src, dest);
27297
+ } else if (!(0, import_node_fs52.existsSync)(dest)) {
27298
+ (0, import_node_fs52.mkdirSync)((0, import_node_path36.dirname)(dest), { recursive: true });
27299
+ (0, import_node_fs52.cpSync)(src, dest);
26995
27300
  copied++;
26996
27301
  }
26997
27302
  }
@@ -27000,22 +27305,22 @@ function carryLegacyContents(gateDir, verityDir) {
27000
27305
  return copied;
27001
27306
  }
27002
27307
  async function needsMigration(root = repoRoot()) {
27003
- const gateDir = (0, import_node_path35.join)(root, ".gate");
27004
- const verityDir = (0, import_node_path35.join)(root, ".verity");
27005
- if ((0, import_node_fs51.existsSync)(gateDir) && !(0, import_node_fs51.existsSync)(verityDir)) return true;
27006
- if ((0, import_node_fs51.existsSync)(gateDir) && (0, import_node_fs51.existsSync)(verityDir)) {
27007
- if ((0, import_node_fs51.existsSync)((0, import_node_path35.join)(gateDir, "credentials")) && !(0, import_node_fs51.existsSync)((0, import_node_path35.join)(verityDir, "credentials"))) {
27308
+ const gateDir = (0, import_node_path36.join)(root, ".gate");
27309
+ const verityDir = (0, import_node_path36.join)(root, ".verity");
27310
+ if ((0, import_node_fs52.existsSync)(gateDir) && !(0, import_node_fs52.existsSync)(verityDir)) return true;
27311
+ if ((0, import_node_fs52.existsSync)(gateDir) && (0, import_node_fs52.existsSync)(verityDir)) {
27312
+ if ((0, import_node_fs52.existsSync)((0, import_node_path36.join)(gateDir, "credentials")) && !(0, import_node_fs52.existsSync)((0, import_node_path36.join)(verityDir, "credentials"))) {
27008
27313
  return true;
27009
27314
  }
27010
- if ((0, import_node_fs51.existsSync)((0, import_node_path35.join)(gateDir, "memory")) && !(0, import_node_fs51.existsSync)((0, import_node_path35.join)(verityDir, "memory"))) {
27315
+ if ((0, import_node_fs52.existsSync)((0, import_node_path36.join)(gateDir, "memory")) && !(0, import_node_fs52.existsSync)((0, import_node_path36.join)(verityDir, "memory"))) {
27011
27316
  return true;
27012
27317
  }
27013
27318
  }
27014
- const claudeMd = (0, import_node_path35.join)(root, "CLAUDE.md");
27015
- if ((0, import_node_fs51.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
27319
+ const claudeMd = (0, import_node_path36.join)(root, "CLAUDE.md");
27320
+ if ((0, import_node_fs52.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
27016
27321
  return true;
27017
27322
  }
27018
- if ((0, import_node_fs51.existsSync)((0, import_node_path35.join)(root, "GATE.md")) && !(0, import_node_fs51.existsSync)((0, import_node_path35.join)(root, "VERITY.md"))) {
27323
+ if ((0, import_node_fs52.existsSync)((0, import_node_path36.join)(root, "GATE.md")) && !(0, import_node_fs52.existsSync)((0, import_node_path36.join)(root, "VERITY.md"))) {
27019
27324
  return true;
27020
27325
  }
27021
27326
  if (await hasLegacyHooksAt(root)) return true;
@@ -27296,9 +27601,9 @@ async function promptMultiSelect(question, choices, fallback) {
27296
27601
  }
27297
27602
 
27298
27603
  // src/lib/remote-config.ts
27299
- var import_node_fs52 = require("node:fs");
27300
- var import_promises17 = require("node:fs/promises");
27301
- var import_node_path36 = require("node:path");
27604
+ var import_node_fs53 = require("node:fs");
27605
+ var import_promises18 = require("node:fs/promises");
27606
+ var import_node_path37 = require("node:path");
27302
27607
  var import_yaml5 = __toESM(require_dist());
27303
27608
  var IGNORE_RIDER = "verityignore";
27304
27609
  async function fetchRemoteSetup(opts) {
@@ -27343,11 +27648,11 @@ async function adoptRemoteSetup(found, opts) {
27343
27648
  written.push(STANDARD_FILE);
27344
27649
  if (rider !== null) {
27345
27650
  const localIgnore = projectPath(VERITYIGNORE_FILE);
27346
- if (!(0, import_node_fs52.existsSync)(localIgnore)) {
27651
+ if (!(0, import_node_fs53.existsSync)(localIgnore)) {
27347
27652
  await writeOut(VERITYIGNORE_FILE, rider);
27348
27653
  written.push(VERITYIGNORE_FILE);
27349
27654
  } else {
27350
- const local = await (0, import_promises17.readFile)(localIgnore, "utf-8").catch(() => null);
27655
+ const local = await (0, import_promises18.readFile)(localIgnore, "utf-8").catch(() => null);
27351
27656
  if (local !== null && local !== rider) {
27352
27657
  notes.push(`${VERITYIGNORE_FILE} already exists here and differs from the pushed copy \u2014 kept yours.`);
27353
27658
  }
@@ -27376,8 +27681,8 @@ async function adoptRemoteSetup(found, opts) {
27376
27681
  }
27377
27682
  async function writeOut(relative2, body) {
27378
27683
  const target = projectPath(relative2);
27379
- await (0, import_promises17.mkdir)((0, import_node_path36.dirname)(target), { recursive: true });
27380
- await (0, import_promises17.writeFile)(target, body);
27684
+ await (0, import_promises18.mkdir)((0, import_node_path37.dirname)(target), { recursive: true });
27685
+ await (0, import_promises18.writeFile)(target, body);
27381
27686
  }
27382
27687
  function describeRemote(found) {
27383
27688
  const when = found.standard.createdAt.slice(0, 10);
@@ -27493,15 +27798,15 @@ async function runOptionalAuth(resolution, opts = {}) {
27493
27798
  }
27494
27799
  function resolveDataDir2() {
27495
27800
  const candidates2 = [
27496
- (0, import_node_path37.join)(__dirname, "..", "data"),
27801
+ (0, import_node_path38.join)(__dirname, "..", "data"),
27497
27802
  // installed: node_modules/@codacy/verity-cli/data
27498
- (0, import_node_path37.join)(__dirname, "..", "..", "data"),
27803
+ (0, import_node_path38.join)(__dirname, "..", "..", "data"),
27499
27804
  // edge case: nested resolution
27500
- (0, import_node_path37.join)(process.cwd(), "cli", "data")
27805
+ (0, import_node_path38.join)(process.cwd(), "cli", "data")
27501
27806
  // local dev: running from repo root
27502
27807
  ];
27503
27808
  for (const candidate of candidates2) {
27504
- if ((0, import_node_fs53.existsSync)((0, import_node_path37.join)(candidate, "skills"))) {
27809
+ if ((0, import_node_fs54.existsSync)((0, import_node_path38.join)(candidate, "skills"))) {
27505
27810
  return candidate;
27506
27811
  }
27507
27812
  }
@@ -27510,16 +27815,16 @@ function resolveDataDir2() {
27510
27815
  );
27511
27816
  }
27512
27817
  async function copyDir(src, dest) {
27513
- await (0, import_promises18.mkdir)(dest, { recursive: true });
27514
- await (0, import_promises18.cp)(src, dest, { recursive: true, force: true });
27818
+ await (0, import_promises19.mkdir)(dest, { recursive: true });
27819
+ await (0, import_promises19.cp)(src, dest, { recursive: true, force: true });
27515
27820
  }
27516
27821
  async function skillIsCurrent(src, dest) {
27517
27822
  const list2 = (dir) => {
27518
27823
  const out = [];
27519
27824
  const walk2 = (d, prefix) => {
27520
- for (const e of (0, import_node_fs53.readdirSync)(d, { withFileTypes: true })) {
27825
+ for (const e of (0, import_node_fs54.readdirSync)(d, { withFileTypes: true })) {
27521
27826
  const rel = prefix ? `${prefix}/${e.name}` : e.name;
27522
- if (e.isDirectory()) walk2((0, import_node_path37.join)(d, e.name), rel);
27827
+ if (e.isDirectory()) walk2((0, import_node_path38.join)(d, e.name), rel);
27523
27828
  else if (e.isFile()) out.push(rel);
27524
27829
  }
27525
27830
  };
@@ -27530,8 +27835,8 @@ async function skillIsCurrent(src, dest) {
27530
27835
  const shipped = list2(src);
27531
27836
  if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
27532
27837
  for (const rel of shipped) {
27533
- const a = await (0, import_promises18.readFile)((0, import_node_path37.join)(src, rel), "utf-8");
27534
- const b = await (0, import_promises18.readFile)((0, import_node_path37.join)(dest, rel), "utf-8");
27838
+ const a = await (0, import_promises19.readFile)((0, import_node_path38.join)(src, rel), "utf-8");
27839
+ const b = await (0, import_promises19.readFile)((0, import_node_path38.join)(dest, rel), "utf-8");
27535
27840
  if (a !== b) return false;
27536
27841
  }
27537
27842
  return true;
@@ -27712,13 +28017,13 @@ async function synthesizeLocally(opts) {
27712
28017
  async function healStaleAnalysisConfig(globals) {
27713
28018
  const configPath = projectPath(CODACY_CONFIG_FILE);
27714
28019
  const standardPath = projectPath(STANDARD_FILE);
27715
- if (!(0, import_node_fs53.existsSync)(configPath) || !(0, import_node_fs53.existsSync)(standardPath)) return;
28020
+ if (!(0, import_node_fs54.existsSync)(configPath) || !(0, import_node_fs54.existsSync)(standardPath)) return;
27716
28021
  const validation = validatePatternIds();
27717
28022
  if (validation.status !== "invalid") return;
27718
28023
  printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
27719
28024
  printWarn(" running silently with nothing enabled. Re-deriving it from your Standard\u2026");
27720
28025
  try {
27721
- const content = (0, import_yaml6.parse)(await (0, import_promises18.readFile)(standardPath, "utf-8"));
28026
+ const content = (0, import_yaml6.parse)(await (0, import_promises19.readFile)(standardPath, "utf-8"));
27722
28027
  const derived = await deriveConfigForStandard(content);
27723
28028
  for (const path of derived.written) printInfo(` ${path} \u2713 (re-derived)`);
27724
28029
  for (const note of derived.notes) printWarn(` ${note}`);
@@ -27809,17 +28114,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
27809
28114
  async function installSkills(force, step) {
27810
28115
  step("Installing skills");
27811
28116
  const dataDir = resolveDataDir2();
27812
- const skillsSource = (0, import_node_path37.join)(dataDir, "skills");
28117
+ const skillsSource = (0, import_node_path38.join)(dataDir, "skills");
27813
28118
  const skillsDest = ".claude/skills";
27814
28119
  let skillsInstalled = 0;
27815
28120
  for (const skill of SKILLS) {
27816
- const src = (0, import_node_path37.join)(skillsSource, skill);
27817
- const dest = (0, import_node_path37.join)(skillsDest, skill);
27818
- if (!(0, import_node_fs53.existsSync)(src)) {
28121
+ const src = (0, import_node_path38.join)(skillsSource, skill);
28122
+ const dest = (0, import_node_path38.join)(skillsDest, skill);
28123
+ if (!(0, import_node_fs54.existsSync)(src)) {
27819
28124
  printWarn(` Skill data not found: ${skill}`);
27820
28125
  continue;
27821
28126
  }
27822
- if ((0, import_node_fs53.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
28127
+ if ((0, import_node_fs54.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
27823
28128
  skillsInstalled++;
27824
28129
  continue;
27825
28130
  }
@@ -27883,7 +28188,7 @@ async function checkPrerequisites(step) {
27883
28188
  }
27884
28189
  async function scaffoldProject(step, defaultsOnly) {
27885
28190
  step("Knowledge base, .gitignore and CLAUDE.md");
27886
- await (0, import_promises18.mkdir)(VERITY_DIR, { recursive: true });
28191
+ await (0, import_promises19.mkdir)(VERITY_DIR, { recursive: true });
27887
28192
  await ensureMemoryDir();
27888
28193
  const ignoreResult = ensureVerityGitignore();
27889
28194
  if (ignoreResult === "failed") {
@@ -27958,7 +28263,7 @@ function registerInitCommand(program2) {
27958
28263
  const staleMarker = clearStalePluginMarker();
27959
28264
  const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
27960
28265
  const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
27961
- const isProject = projectMarkers.some((m) => (0, import_node_fs53.existsSync)(m));
28266
+ const isProject = projectMarkers.some((m) => (0, import_node_fs54.existsSync)(m));
27962
28267
  if (!isProject) {
27963
28268
  printError("No project detected in the current directory.");
27964
28269
  printInfo('Run "verity init" from your project root.');
@@ -28048,8 +28353,8 @@ function registerInitCommand(program2) {
28048
28353
  printInfo(` intensity: ${intensity} \xB7 moments: ${moments.join(", ") || "none"} (no questions asked)`);
28049
28354
  }
28050
28355
  await scaffoldProject(step, defaultsOnly);
28051
- const globalVerityDir = (0, import_node_path37.join)(process.env.HOME ?? "", ".verity");
28052
- await (0, import_promises18.mkdir)(globalVerityDir, { recursive: true });
28356
+ const globalVerityDir = (0, import_node_path38.join)(process.env.HOME ?? "", ".verity");
28357
+ await (0, import_promises19.mkdir)(globalVerityDir, { recursive: true });
28053
28358
  console.log("");
28054
28359
  step("Wiring Claude Code hooks");
28055
28360
  const gitMoments = [
@@ -28117,7 +28422,7 @@ function registerInitCommand(program2) {
28117
28422
  }
28118
28423
  step("Your project's Standard");
28119
28424
  let haveStandard = false;
28120
- if ((0, import_node_fs53.existsSync)(projectPath(STANDARD_FILE))) {
28425
+ if ((0, import_node_fs54.existsSync)(projectPath(STANDARD_FILE))) {
28121
28426
  printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
28122
28427
  haveStandard = true;
28123
28428
  } else {
@@ -28147,7 +28452,7 @@ function registerInitCommand(program2) {
28147
28452
  ...telemetryChoice ? { telemetry: telemetryChoice } : {},
28148
28453
  init: {
28149
28454
  completed_at: (/* @__PURE__ */ new Date()).toISOString(),
28150
- cli_version: true ? "0.32.6-experimental.8f2b5f7" : "dev"
28455
+ cli_version: true ? "0.32.6-experimental.df0a578" : "dev"
28151
28456
  }
28152
28457
  });
28153
28458
  } catch (err) {
@@ -28197,8 +28502,8 @@ function registerInitCommand(program2) {
28197
28502
  }
28198
28503
 
28199
28504
  // src/commands/uninstall.ts
28200
- var import_node_fs54 = require("node:fs");
28201
- var import_node_path38 = require("node:path");
28505
+ var import_node_fs55 = require("node:fs");
28506
+ var import_node_path39 = require("node:path");
28202
28507
  function registerUninstallCommand(program2) {
28203
28508
  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) => {
28204
28509
  const dryRun = opts.dryRun ?? false;
@@ -28207,11 +28512,11 @@ function registerUninstallCommand(program2) {
28207
28512
  const actions = [];
28208
28513
  const skillsRoot = projectPath(".claude/skills");
28209
28514
  for (const name of PROJECT_SKILL_NAMES) {
28210
- const dir = (0, import_node_path38.join)(skillsRoot, name);
28211
- if ((0, import_node_fs54.existsSync)(dir)) {
28515
+ const dir = (0, import_node_path39.join)(skillsRoot, name);
28516
+ if ((0, import_node_fs55.existsSync)(dir)) {
28212
28517
  actions.push({
28213
28518
  label: `Remove .claude/skills/${name}/`,
28214
- apply: () => (0, import_node_fs54.rmSync)(dir, { recursive: true, force: true })
28519
+ apply: () => (0, import_node_fs55.rmSync)(dir, { recursive: true, force: true })
28215
28520
  });
28216
28521
  }
28217
28522
  }
@@ -28225,24 +28530,24 @@ function registerUninstallCommand(program2) {
28225
28530
  });
28226
28531
  }
28227
28532
  const verityDir = projectPath(VERITY_DIR);
28228
- if ((0, import_node_fs54.existsSync)(verityDir)) {
28533
+ if ((0, import_node_fs55.existsSync)(verityDir)) {
28229
28534
  actions.push({
28230
28535
  label: `Remove ${VERITY_DIR}/`,
28231
- apply: () => (0, import_node_fs54.rmSync)(verityDir, { recursive: true, force: true })
28536
+ apply: () => (0, import_node_fs55.rmSync)(verityDir, { recursive: true, force: true })
28232
28537
  });
28233
28538
  }
28234
28539
  if (!keepVerityMd) {
28235
28540
  const verityMd = projectPath(VERITY_MD_FILE);
28236
- if ((0, import_node_fs54.existsSync)(verityMd)) {
28541
+ if ((0, import_node_fs55.existsSync)(verityMd)) {
28237
28542
  actions.push({
28238
28543
  label: `Remove ${VERITY_MD_FILE}`,
28239
- apply: () => (0, import_node_fs54.rmSync)(verityMd, { force: true })
28544
+ apply: () => (0, import_node_fs55.rmSync)(verityMd, { force: true })
28240
28545
  });
28241
28546
  }
28242
28547
  }
28243
28548
  const cleanupEmptyDir = (path) => {
28244
- if ((0, import_node_fs54.existsSync)(path) && (0, import_node_fs54.statSync)(path).isDirectory() && (0, import_node_fs54.readdirSync)(path).length === 0) {
28245
- (0, import_node_fs54.rmdirSync)(path);
28549
+ if ((0, import_node_fs55.existsSync)(path) && (0, import_node_fs55.statSync)(path).isDirectory() && (0, import_node_fs55.readdirSync)(path).length === 0) {
28550
+ (0, import_node_fs55.rmdirSync)(path);
28246
28551
  }
28247
28552
  };
28248
28553
  actions.push({
@@ -28253,11 +28558,11 @@ function registerUninstallCommand(program2) {
28253
28558
  }
28254
28559
  });
28255
28560
  const home = process.env.HOME ?? "";
28256
- const globalVerityDir = (0, import_node_path38.join)(home, ".verity");
28257
- if (purgeGlobal && (0, import_node_fs54.existsSync)(globalVerityDir)) {
28561
+ const globalVerityDir = (0, import_node_path39.join)(home, ".verity");
28562
+ if (purgeGlobal && (0, import_node_fs55.existsSync)(globalVerityDir)) {
28258
28563
  actions.push({
28259
28564
  label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
28260
- apply: () => (0, import_node_fs54.rmSync)(globalVerityDir, { recursive: true, force: true })
28565
+ apply: () => (0, import_node_fs55.rmSync)(globalVerityDir, { recursive: true, force: true })
28261
28566
  });
28262
28567
  }
28263
28568
  if (actions.length === 0) {
@@ -28451,8 +28756,8 @@ function registerTaskCommands(program2) {
28451
28756
  }
28452
28757
 
28453
28758
  // src/commands/reset.ts
28454
- var import_node_fs55 = require("node:fs");
28455
- var import_node_path39 = require("node:path");
28759
+ var import_node_fs56 = require("node:fs");
28760
+ var import_node_path40 = require("node:path");
28456
28761
  function registerResetCommand(program2) {
28457
28762
  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) => {
28458
28763
  const globals = program2.opts();
@@ -28489,11 +28794,11 @@ function registerResetCommand(program2) {
28489
28794
  }
28490
28795
  const cacheDir = projectPath(CACHE_DIR);
28491
28796
  let purged = 0;
28492
- if ((0, import_node_fs55.existsSync)(cacheDir)) {
28493
- for (const entry of (0, import_node_fs55.readdirSync)(cacheDir)) {
28797
+ if ((0, import_node_fs56.existsSync)(cacheDir)) {
28798
+ for (const entry of (0, import_node_fs56.readdirSync)(cacheDir)) {
28494
28799
  if (entry.startsWith("pending-")) {
28495
28800
  try {
28496
- (0, import_node_fs55.unlinkSync)((0, import_node_path39.join)(cacheDir, entry));
28801
+ (0, import_node_fs56.unlinkSync)((0, import_node_path40.join)(cacheDir, entry));
28497
28802
  purged++;
28498
28803
  } catch {
28499
28804
  }
@@ -28508,19 +28813,19 @@ function registerResetCommand(program2) {
28508
28813
  projectPath(`${VERITY_DIR}/.last-analysis`)
28509
28814
  ];
28510
28815
  for (const file of filesToClear) {
28511
- if ((0, import_node_fs55.existsSync)(file)) {
28816
+ if ((0, import_node_fs56.existsSync)(file)) {
28512
28817
  try {
28513
- (0, import_node_fs55.writeFileSync)(file, "");
28818
+ (0, import_node_fs56.writeFileSync)(file, "");
28514
28819
  } catch {
28515
28820
  }
28516
28821
  }
28517
28822
  }
28518
28823
  if (opts.all) {
28519
28824
  const logsDir = projectPath(`${VERITY_DIR}/.logs`);
28520
- if ((0, import_node_fs55.existsSync)(logsDir)) {
28521
- for (const entry of (0, import_node_fs55.readdirSync)(logsDir)) {
28825
+ if ((0, import_node_fs56.existsSync)(logsDir)) {
28826
+ for (const entry of (0, import_node_fs56.readdirSync)(logsDir)) {
28522
28827
  try {
28523
- (0, import_node_fs55.unlinkSync)((0, import_node_path39.join)(logsDir, entry));
28828
+ (0, import_node_fs56.unlinkSync)((0, import_node_path40.join)(logsDir, entry));
28524
28829
  } catch {
28525
28830
  }
28526
28831
  }
@@ -28532,7 +28837,7 @@ function registerResetCommand(program2) {
28532
28837
  }
28533
28838
 
28534
28839
  // src/commands/reflect.ts
28535
- var import_node_fs56 = require("node:fs");
28840
+ var import_node_fs57 = require("node:fs");
28536
28841
 
28537
28842
  // src/lib/reflection-globs.ts
28538
28843
  var MAX_GLOBS = 6;
@@ -28570,7 +28875,7 @@ async function writeNodeToDisk(args) {
28570
28875
  { treePaths: listTrackedFiles(), recordBaseline: false }
28571
28876
  );
28572
28877
  if (written === 0) return false;
28573
- return (0, import_node_fs56.existsSync)(projectPath(`${VERITY_DIR}/memory/${args.filePath}`));
28878
+ return (0, import_node_fs57.existsSync)(projectPath(`${VERITY_DIR}/memory/${args.filePath}`));
28574
28879
  } catch {
28575
28880
  return false;
28576
28881
  }
@@ -28815,6 +29120,88 @@ function registerMemoryCommand(program2) {
28815
29120
  if (!quiet) {
28816
29121
  printInfo(result.status === "unchanged" ? "Knowledge graph is up to date." : result.status === "tracked" ? "Skipped: .verity/memory/ is tracked by git here, and the pull never rewrites tracked files. Run `verity memory untrack` to make the graph machine-local." : `Pulled ${result.received} node(s); ${result.written} new or updated file(s) written to .verity/memory/.`);
28817
29122
  }
29123
+ let org;
29124
+ try {
29125
+ org = await pullOrgKnowledge({
29126
+ serviceUrl: urlResult.data,
29127
+ token: tokenResult.data.token,
29128
+ verbose: globals.verbose,
29129
+ force: !!opts.force
29130
+ });
29131
+ } catch (err) {
29132
+ org = { ok: false, error: err.message };
29133
+ }
29134
+ logEvent("memory_org_pull", org.ok ? { status: org.status, received: org.received } : { status: "failed", category: org.category ?? null });
29135
+ if (!quiet) {
29136
+ if (!org.ok) printWarn(`Could not refresh the org knowledge mirror: ${org.error}`);
29137
+ else if (org.status === "pulled") printInfo(`Org knowledge: ${org.received} claim(s) mirrored at ${org.dir}.`);
29138
+ else if (org.status === "unchanged") printInfo("Org knowledge mirror is up to date.");
29139
+ }
29140
+ process.exit(0);
29141
+ });
29142
+ memory.command("org").description("List the org knowledge mirrored for this repository's organization").action(async () => {
29143
+ try {
29144
+ process.chdir(repoRoot());
29145
+ } catch {
29146
+ }
29147
+ const dir = orgMirrorDir();
29148
+ if (!dir) {
29149
+ printError("Not a repository with an origin remote, so there is no organization to list.");
29150
+ process.exit(1);
29151
+ }
29152
+ const claims = await readOrgMirror();
29153
+ if (claims.length === 0) {
29154
+ printInfo(`No org knowledge mirrored yet (${dir}). Run \`verity memory pull\`.`);
29155
+ process.exit(0);
29156
+ }
29157
+ for (const c of claims) console.log(`${c.tag_id} ${c.kind.padEnd(11)} ${c.title} \xB7 ${c.origin}`);
29158
+ printInfo(`${claims.length} claim(s) at ${dir}. Demote one with \`verity memory demote <id> --reason "\u2026"\`.`);
29159
+ process.exit(0);
29160
+ });
29161
+ memory.command("demote <claim-id>").description("Demote an org knowledge claim for the whole organization, with a reason").requiredOption("--reason <text>", "Why this claim should no longer be shared (1\u2013500 characters)").action(async (claimId, opts) => {
29162
+ const globals = program2.opts();
29163
+ try {
29164
+ process.chdir(repoRoot());
29165
+ } catch {
29166
+ }
29167
+ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(claimId)) {
29168
+ printError("The claim id is the `id` in the mirrored file, a uuid. `verity memory org` lists them.");
29169
+ process.exit(1);
29170
+ }
29171
+ const reason = opts.reason.trim();
29172
+ if (reason.length === 0 || reason.length > 500) {
29173
+ printError("--reason is 1 to 500 characters.");
29174
+ process.exit(1);
29175
+ }
29176
+ const tokenResult = await resolveToken(globals.token);
29177
+ if (!tokenResult.ok) {
29178
+ printError(tokenResult.error);
29179
+ process.exit(1);
29180
+ }
29181
+ const urlResult = await resolveServiceUrl(globals.serviceUrl);
29182
+ if (!urlResult.ok) {
29183
+ printError(urlResult.error);
29184
+ process.exit(1);
29185
+ }
29186
+ const res = await apiRequest({
29187
+ method: "POST",
29188
+ path: `/memory/org/claims/${claimId}/demote`,
29189
+ serviceUrl: urlResult.data,
29190
+ token: tokenResult.data.token,
29191
+ body: { reason },
29192
+ verbose: globals.verbose,
29193
+ cmd: "memory-demote",
29194
+ extraHeaders: { "X-Verity-Via": "cli" }
29195
+ });
29196
+ if (!res.ok) {
29197
+ printError(`Could not demote the claim: ${res.error}`);
29198
+ process.exit(1);
29199
+ }
29200
+ printInfo(`Demoted ${claimId} for the whole organization. Restore it from the dashboard if that was wrong.`);
29201
+ try {
29202
+ await pullOrgKnowledge({ serviceUrl: urlResult.data, token: tokenResult.data.token, verbose: globals.verbose, force: true });
29203
+ } catch {
29204
+ }
28818
29205
  process.exit(0);
28819
29206
  });
28820
29207
  memory.command("untrack").description("Stop committing .verity/memory/ \u2014 the graph stays on disk and leaves your diffs").action(() => {
@@ -28980,8 +29367,8 @@ function registerTelemetryCommands(program2) {
28980
29367
  }
28981
29368
 
28982
29369
  // src/cli.ts
28983
- program.name("verity").description("CLI for Verity quality gate service").version("0.32.6-experimental.8f2b5f7").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) => {
28984
- installStderrLog(actionCommand.name(), process.argv.slice(2), "0.32.6-experimental.8f2b5f7");
29370
+ program.name("verity").description("CLI for Verity quality gate service").version("0.32.6-experimental.df0a578").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) => {
29371
+ installStderrLog(actionCommand.name(), process.argv.slice(2), "0.32.6-experimental.df0a578");
28985
29372
  setUserNamedServiceUrl(program.opts().serviceUrl);
28986
29373
  try {
28987
29374
  await foldLegacyLocalCredential();