@codacy/verity-cli 0.33.3-experimental.7124bbc → 0.33.3-experimental.d8b96f8

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 +653 -1142
  2. package/package.json +1 -1
package/bin/verity.js CHANGED
@@ -10970,8 +10970,8 @@ function filterReviewable(files) {
10970
10970
  const ext = (0, import_node_path3.extname)(f).slice(1);
10971
10971
  if (ANALYZABLE_EXTENSIONS.has(ext)) return false;
10972
10972
  if (REVIEWABLE_EXTENSIONS.has(ext)) return true;
10973
- const basename6 = f.split("/").pop() ?? "";
10974
- if (REVIEWABLE_FILENAMES.has(basename6)) return true;
10973
+ const basename5 = f.split("/").pop() ?? "";
10974
+ if (REVIEWABLE_FILENAMES.has(basename5)) return true;
10975
10975
  if (REVIEWABLE_PATH_PATTERNS.some((p) => p.test(f))) return true;
10976
10976
  return false;
10977
10977
  });
@@ -13457,7 +13457,7 @@ function registerHooksCommands(program2) {
13457
13457
  }
13458
13458
 
13459
13459
  // src/commands/intent.ts
13460
- var import_node_crypto9 = require("node:crypto");
13460
+ var import_node_crypto8 = require("node:crypto");
13461
13461
 
13462
13462
  // src/lib/conversation-buffer.ts
13463
13463
  var import_promises5 = require("node:fs/promises");
@@ -14009,8 +14009,8 @@ async function appendEntry(taskId, entry) {
14009
14009
 
14010
14010
  // src/lib/memory-retrieval.ts
14011
14011
  var import_promises8 = require("node:fs/promises");
14012
- var import_node_fs14 = require("node:fs");
14013
- var import_node_path14 = require("node:path");
14012
+ var import_node_fs13 = require("node:fs");
14013
+ var import_node_path13 = require("node:path");
14014
14014
 
14015
14015
  // src/lib/org-mirror.ts
14016
14016
  var import_node_fs12 = require("node:fs");
@@ -14201,216 +14201,16 @@ async function readOrgMirror(remote = requestRemote()) {
14201
14201
  return out;
14202
14202
  }
14203
14203
 
14204
- // src/lib/safe-read.ts
14205
- var import_node_fs13 = require("node:fs");
14206
- var import_node_path13 = require("node:path");
14207
- var FLAGS = import_node_fs13.constants;
14208
- var NOFOLLOW = FLAGS.O_NOFOLLOW;
14209
- var NONBLOCK = FLAGS.O_NONBLOCK;
14210
- function closeOpened(fd) {
14211
- try {
14212
- (0, import_node_fs13.closeSync)(fd);
14213
- } catch {
14214
- }
14215
- }
14216
- function isInsideRoot(realRoot, realPath) {
14217
- return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path13.sep) ? realRoot : realRoot + import_node_path13.sep);
14218
- }
14219
- function sameOpenedFile(opened, current, nofollowAvailable) {
14220
- if (!nofollowAvailable && (opened.ino === 0n || current.ino === 0n)) return false;
14221
- return opened.ino === current.ino && opened.dev === current.dev;
14222
- }
14223
- function openRegularInRoot(root, path) {
14224
- const full = (0, import_node_path13.isAbsolute)(path) ? path : (0, import_node_path13.join)(root, path);
14225
- let fd;
14226
- try {
14227
- fd = (0, import_node_fs13.openSync)(full, import_node_fs13.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
14228
- } catch (err) {
14229
- const code = err.code;
14230
- if (code === "ELOOP" || code === "EMLINK" || code === "EFTYPE") return { ok: false, reason: "symlink" };
14231
- if (code === "ENOENT" || code === "ENOTDIR") return { ok: false, reason: "missing" };
14232
- return { ok: false, reason: "unreadable" };
14233
- }
14234
- try {
14235
- const opened = (0, import_node_fs13.fstatSync)(fd, { bigint: true });
14236
- if (!opened.isFile()) {
14237
- closeOpened(fd);
14238
- return { ok: false, reason: "not-regular" };
14239
- }
14240
- const realRoot = import_node_fs13.realpathSync.native(root);
14241
- const realPath = import_node_fs13.realpathSync.native(full);
14242
- if (!isInsideRoot(realRoot, realPath)) {
14243
- closeOpened(fd);
14244
- return { ok: false, reason: "outside-root" };
14245
- }
14246
- const current = (0, import_node_fs13.statSync)(realPath, { bigint: true });
14247
- if (!sameOpenedFile(opened, current, NOFOLLOW !== void 0)) {
14248
- closeOpened(fd);
14249
- return { ok: false, reason: NOFOLLOW === void 0 ? "unreadable" : "outside-root" };
14250
- }
14251
- return { ok: true, fd, size: Number(opened.size), mtimeMs: Number(opened.mtimeMs) };
14252
- } catch {
14253
- closeOpened(fd);
14254
- return { ok: false, reason: "unreadable" };
14255
- }
14256
- }
14257
- function statRegularInRoot(root, path) {
14258
- const opened = openRegularInRoot(root, path);
14259
- if (!opened.ok) return opened;
14260
- closeOpened(opened.fd);
14261
- return { ok: true, size: opened.size, mtimeMs: opened.mtimeMs };
14262
- }
14263
- function readOpened(fd, size) {
14264
- try {
14265
- const buffer = Buffer.alloc(size);
14266
- let offset = 0;
14267
- while (offset < size) {
14268
- const n = (0, import_node_fs13.readSync)(fd, buffer, offset, size - offset, offset);
14269
- if (n === 0) break;
14270
- offset += n;
14271
- }
14272
- return buffer.subarray(0, offset);
14273
- } finally {
14274
- closeOpened(fd);
14275
- }
14276
- }
14277
- function readOpenedUtf8(fd, size) {
14278
- return readOpened(fd, size).toString("utf-8");
14279
- }
14280
- function readRegularFileInRoot(root, path, maxBytes) {
14281
- const opened = openRegularInRoot(root, path);
14282
- if (!opened.ok) return opened;
14283
- if (opened.size > maxBytes) {
14284
- closeOpened(opened.fd);
14285
- return { ok: false, reason: "too-large", size: opened.size };
14286
- }
14287
- try {
14288
- return { ok: true, content: readOpenedUtf8(opened.fd, opened.size), size: opened.size };
14289
- } catch {
14290
- return { ok: false, reason: "unreadable" };
14291
- }
14292
- }
14293
-
14294
- // src/lib/knowledge-score.ts
14295
- var KIND_PRIOR_MEAN = {
14296
- decision: 0.78,
14297
- pattern: 0.89,
14298
- security: 0.8,
14299
- quality: 0.71,
14300
- integration: 0.71,
14301
- domain: 0.71,
14302
- gotcha: 0.53,
14303
- intent: 0.53
14304
- };
14305
- var DEFAULT_PRIOR_MEAN = 0.6;
14306
- var PRIOR_STRENGTH = 2;
14307
- var RELEVANCE_FLOOR = 0.15;
14308
- var TAG_SATURATION = 1.5;
14309
- var STOPWORDS = /* @__PURE__ */ new Set([
14310
- "the",
14311
- "and",
14312
- "for",
14313
- "are",
14314
- "but",
14315
- "not",
14316
- "you",
14317
- "all",
14318
- "any",
14319
- "can",
14320
- "had",
14321
- "has",
14322
- "her",
14323
- "was",
14324
- "one",
14325
- "our",
14326
- "out",
14327
- "him",
14328
- "his",
14329
- "how",
14330
- "its",
14331
- "may",
14332
- "who",
14333
- "did",
14334
- "get",
14335
- "got",
14336
- "let",
14337
- "say",
14338
- "she",
14339
- "too",
14340
- "use",
14341
- "via",
14342
- "yes",
14343
- "yet",
14344
- "now",
14345
- "new",
14346
- "also",
14347
- "been",
14348
- "both",
14349
- "does",
14350
- "each",
14351
- "from",
14352
- "have",
14353
- "here",
14354
- "into",
14355
- "just",
14356
- "like",
14357
- "make",
14358
- "more",
14359
- "most",
14360
- "much",
14361
- "must",
14362
- "need",
14363
- "only",
14364
- "over",
14365
- "same",
14366
- "some",
14367
- "such",
14368
- "than",
14369
- "that",
14370
- "them",
14371
- "then",
14372
- "there",
14373
- "these",
14374
- "they",
14375
- "this",
14376
- "those",
14377
- "very",
14378
- "want",
14379
- "were",
14380
- "what",
14381
- "when",
14382
- "where",
14383
- "which",
14384
- "while",
14385
- "will",
14386
- "with",
14387
- "would",
14388
- "your",
14389
- "about",
14390
- "after",
14391
- "again",
14392
- "being",
14393
- "could",
14394
- "other",
14395
- "should",
14396
- "their",
14397
- "because",
14398
- "before",
14399
- "doing",
14400
- "going",
14401
- "still",
14402
- "think",
14403
- "thing",
14404
- "things",
14405
- "well",
14406
- "way",
14407
- "why",
14408
- "within",
14409
- "without"
14410
- ]);
14204
+ // src/lib/memory-retrieval.ts
14205
+ var memoryDir = () => projectPath(`${VERITY_DIR}/memory`);
14206
+ var DOMAINS = ["decisions", "quality", "security", "intent", "gotchas", "patterns", "domain", "integrations"];
14207
+ var DEFAULT_BUDGET_TOKENS = 2e3;
14208
+ var MAX_BUDGET_TOKENS = 4e3;
14209
+ var MIN_SCORE = 0.5;
14210
+ var ORG_MIN_SHARED_TERMS = 2;
14411
14211
  function tokenize(text) {
14412
14212
  return new Set(
14413
- text.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((w) => w.length > 2 && !STOPWORDS.has(w))
14213
+ text.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((w) => w.length > 2)
14414
14214
  );
14415
14215
  }
14416
14216
  function jaccardKeywords(a, b) {
@@ -14420,78 +14220,6 @@ function jaccardKeywords(a, b) {
14420
14220
  const union = a.size + b.size - inter;
14421
14221
  return union === 0 ? 0 : inter / union;
14422
14222
  }
14423
- function relevance(node, ctx) {
14424
- const globHit = node.globHit === true;
14425
- let tagScore = 0;
14426
- const nodeTags = node.context_tags ?? [];
14427
- if (nodeTags.length > 0 && ctx.changeTags && ctx.changeTags.length > 0) {
14428
- const change = new Set(ctx.changeTags);
14429
- let hit = 0;
14430
- for (const t of nodeTags) {
14431
- if (!change.has(t)) continue;
14432
- hit += t.startsWith("pkg:") || t.startsWith("tbl:") ? 1 : t.startsWith("sym:") ? 0.8 : t.startsWith("dir:") ? 0.4 : 0.15;
14433
- }
14434
- tagScore = Math.min(1, hit / TAG_SATURATION);
14435
- }
14436
- let textScore = 0;
14437
- if (ctx.promptTokens && ctx.promptTokens.size > 0) {
14438
- textScore = jaccardKeywords(tokenize(`${node.title} ${node.body}`), ctx.promptTokens);
14439
- textScore = Math.min(1, textScore * 4);
14440
- }
14441
- const distance = node.distance ?? 0;
14442
- const hopScore = distance > 0 ? Math.min(1, node.hopWeight ?? 1) * 0.45 * Math.pow(0.6, distance - 1) : 0;
14443
- const globEvidence = globHit && (node.kind !== "integration" || tagScore > 0 || textScore > 0);
14444
- const evidence2 = [globEvidence ? 0.85 : 0, tagScore * 0.9, textScore * 0.7, hopScore];
14445
- let miss = 1;
14446
- for (const e of evidence2) miss *= 1 - Math.max(0, Math.min(1, e));
14447
- let score = 1 - miss;
14448
- if (distance > 0) score *= Math.pow(0.85, distance);
14449
- return { score, via: { glob: globHit, tag: tagScore, text: textScore } };
14450
- }
14451
- var KIND_POOL_STRENGTH = 20;
14452
- function priorFor(kind, pooled) {
14453
- const base = KIND_PRIOR_MEAN[kind] ?? DEFAULT_PRIOR_MEAN;
14454
- const a = pooled ? Math.max(0, pooled.alpha) : 0;
14455
- const b = pooled ? Math.max(0, pooled.beta) : 0;
14456
- const mean = pooled && kind !== "integration" ? (KIND_POOL_STRENGTH * base + a) / (KIND_POOL_STRENGTH + a + b) : base;
14457
- return { alpha: mean * PRIOR_STRENGTH, beta: (1 - mean) * PRIOR_STRENGTH };
14458
- }
14459
- function posteriorFor(kind, own, pooled) {
14460
- const p = priorFor(kind, pooled);
14461
- if (!own || kind === "integration") return p;
14462
- return { alpha: p.alpha + Math.max(0, own.alpha), beta: p.beta + Math.max(0, own.beta) };
14463
- }
14464
- function posteriorMean(p) {
14465
- const n = p.alpha + p.beta;
14466
- return n <= 0 ? DEFAULT_PRIOR_MEAN : p.alpha / n;
14467
- }
14468
- function scoreCandidates(nodes, ctx, opts = {}) {
14469
- const floor = opts.relevanceFloor ?? RELEVANCE_FLOOR;
14470
- const out = [];
14471
- for (const n of nodes) {
14472
- const rel = relevance(n, ctx);
14473
- if (rel.score < floor) continue;
14474
- const post = posteriorFor(n.kind, opts.posteriors?.get(n.id), opts.kindPosteriors?.get(n.kind));
14475
- const usefulness = posteriorMean(post);
14476
- out.push({ id: n.id, score: rel.score * usefulness, relevance: rel.score, usefulness, via: rel.via });
14477
- }
14478
- out.sort((a, b) => b.score - a.score || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
14479
- return out;
14480
- }
14481
-
14482
- // src/lib/memory-retrieval.ts
14483
- var memoryDir = () => projectPath(`${VERITY_DIR}/memory`);
14484
- var DOMAINS = ["decisions", "quality", "security", "intent", "gotchas", "patterns", "domain", "integrations"];
14485
- var DEFAULT_BUDGET_TOKENS = 2e3;
14486
- var MAX_BUDGET_TOKENS = 4e3;
14487
- var MAX_NODE_FILE_BYTES = 64 * 1024;
14488
- var MIN_SCORE = RELEVANCE_FLOOR * 0.5;
14489
- var ORG_MIN_SHARED_TERMS = 2;
14490
- function orgTerms(text) {
14491
- return new Set(
14492
- text.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((w) => w.length > 2)
14493
- );
14494
- }
14495
14223
  function sharedTerms(a, b) {
14496
14224
  let n = 0;
14497
14225
  for (const w of a) if (b.has(w)) n++;
@@ -14520,27 +14248,34 @@ function globMatch(glob, filePath) {
14520
14248
  return false;
14521
14249
  }
14522
14250
  function scoreNode(node, promptTokens, taskFiles) {
14523
- const globHit = node.fileGlobs.length > 0 && taskFiles.length > 0 && node.fileGlobs.some((glob) => taskFiles.some((file) => globMatch(glob, file)));
14524
- const [scored] = scoreCandidates(
14525
- [{
14526
- id: node.nodeId,
14527
- kind: node.kind,
14528
- title: node.title,
14529
- body: node.body,
14530
- file_globs: node.fileGlobs,
14531
- // Not yet synced to the client graph; absent means "no tag evidence",
14532
- // never "excluded" (KL18).
14533
- context_tags: [],
14534
- globHit
14535
- }],
14536
- { promptTokens }
14537
- // ⚠ The gate is on RELEVANCE, as on the server. This once passed
14538
- // `relevanceFloor: 0` and left MIN_SCORE (on the product) as the only
14539
- // filter, so a sub-floor match rode a strong kind prior past it: 30% of
14540
- // replayed injections had r < RELEVANCE_FLOOR. MIN_SCORE stays as a second
14541
- // guard for a very weak kind; it can no longer admit what the gate refused.
14542
- );
14543
- return scored?.score ?? 0;
14251
+ let score = 0;
14252
+ score += node.confidence * 0.5;
14253
+ score += Math.log(1 + node.citedCount) * 0.3;
14254
+ const nodeTokens = tokenize(`${node.title} ${node.body}`);
14255
+ score += jaccardKeywords(nodeTokens, promptTokens) * 2;
14256
+ if (node.fileGlobs.length > 0 && taskFiles.length > 0) {
14257
+ for (const glob of node.fileGlobs) {
14258
+ for (const file of taskFiles) {
14259
+ if (globMatch(glob, file)) {
14260
+ score += 1.5;
14261
+ break;
14262
+ }
14263
+ }
14264
+ if (score > 3) break;
14265
+ }
14266
+ }
14267
+ const kindPriors = {
14268
+ security: 0.4,
14269
+ gotcha: 0.4,
14270
+ decision: 0.3,
14271
+ pattern: 0.2,
14272
+ integration: 0.3,
14273
+ domain: 0.2,
14274
+ quality: 0.1,
14275
+ intent: 0.1
14276
+ };
14277
+ score += kindPriors[node.kind] ?? 0;
14278
+ return score;
14544
14279
  }
14545
14280
  function parseFrontmatter(content) {
14546
14281
  const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
@@ -14580,22 +14315,20 @@ function parseFrontmatter(content) {
14580
14315
  return { fm, body: match[2].trim() };
14581
14316
  }
14582
14317
  async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = DEFAULT_BUDGET_TOKENS) {
14583
- const hasRepoGraph = (0, import_node_fs14.existsSync)(memoryDir());
14318
+ const hasRepoGraph = (0, import_node_fs13.existsSync)(memoryDir());
14584
14319
  const budget = Math.min(budgetTokens, MAX_BUDGET_TOKENS);
14585
14320
  const promptTokens = tokenize(promptText);
14586
- const orgPromptTerms = orgTerms(promptText);
14587
14321
  const nodes = [];
14588
14322
  for (const domain of hasRepoGraph ? DOMAINS : []) {
14589
- const domainDir = (0, import_node_path14.join)(memoryDir(), domain);
14590
- if (!(0, import_node_fs14.existsSync)(domainDir)) continue;
14323
+ const domainDir = (0, import_node_path13.join)(memoryDir(), domain);
14324
+ if (!(0, import_node_fs13.existsSync)(domainDir)) continue;
14591
14325
  try {
14592
14326
  const files = await (0, import_promises8.readdir)(domainDir);
14593
14327
  for (const file of files) {
14594
14328
  if (!file.endsWith(".md")) continue;
14595
14329
  try {
14596
- const read = readRegularFileInRoot(memoryDir(), `${domain}/${file}`, MAX_NODE_FILE_BYTES);
14597
- if (!read.ok) continue;
14598
- const { fm, body } = parseFrontmatter(read.content);
14330
+ const content = await (0, import_promises8.readFile)((0, import_node_path13.join)(domainDir, file), "utf-8");
14331
+ const { fm, body } = parseFrontmatter(content);
14599
14332
  if (fm.status && fm.status !== "active") continue;
14600
14333
  nodes.push({
14601
14334
  path: `${domain}/${file}`,
@@ -14617,7 +14350,7 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
14617
14350
  try {
14618
14351
  for (const claim of await readOrgMirror()) {
14619
14352
  const local = orgNodeToLocal(claim);
14620
- if (sharedTerms(orgTerms(`${local.title} ${local.body}`), orgPromptTerms) >= ORG_MIN_SHARED_TERMS) nodes.push(local);
14353
+ if (sharedTerms(tokenize(`${local.title} ${local.body}`), promptTokens) >= ORG_MIN_SHARED_TERMS) nodes.push(local);
14621
14354
  }
14622
14355
  } catch {
14623
14356
  }
@@ -14655,216 +14388,19 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
14655
14388
  return {
14656
14389
  nodes: selected,
14657
14390
  contextBlock: lines.join("\n"),
14658
- tokensUsed,
14659
- eligible: filtered.length
14391
+ tokensUsed
14660
14392
  };
14661
14393
  }
14662
14394
 
14663
- // src/lib/injection-record.ts
14664
- var import_node_fs16 = require("node:fs");
14665
- var import_node_crypto3 = require("node:crypto");
14666
-
14667
- // src/lib/safe-write.ts
14668
- var import_node_fs15 = require("node:fs");
14669
- var import_node_path15 = require("node:path");
14670
- var FLAGS2 = import_node_fs15.constants;
14671
- var O_NOFOLLOW = FLAGS2.O_NOFOLLOW ?? 0;
14672
- var NOFOLLOW_AVAILABLE = O_NOFOLLOW !== 0;
14673
- function validateRoot(root) {
14674
- try {
14675
- const parentReal = (0, import_node_fs15.realpathSync)((0, import_node_path15.dirname)(root));
14676
- const expected = (0, import_node_path15.join)(parentReal, (0, import_node_path15.basename)(root));
14677
- try {
14678
- (0, import_node_fs15.mkdirSync)(expected);
14679
- } catch (e) {
14680
- if (e.code !== "EEXIST") return null;
14681
- }
14682
- const st = (0, import_node_fs15.lstatSync)(expected, { bigint: true });
14683
- if (st.isSymbolicLink() || !st.isDirectory()) return null;
14684
- if ((0, import_node_fs15.realpathSync)(expected) !== expected) return null;
14685
- return { real: expected, dev: st.dev, ino: st.ino };
14686
- } catch {
14687
- return null;
14688
- }
14689
- }
14690
- function rootUnchanged(root) {
14691
- try {
14692
- const st = (0, import_node_fs15.lstatSync)(root.real, { bigint: true });
14693
- return !st.isSymbolicLink() && st.isDirectory() && st.dev === root.dev && st.ino === root.ino;
14694
- } catch {
14695
- return false;
14696
- }
14697
- }
14698
- function bareName(name) {
14699
- return !!name && name === (0, import_node_path15.basename)(name) && name !== "." && name !== ".." && !name.includes("\0");
14700
- }
14701
- function absentOrRegular(path) {
14702
- try {
14703
- const st = (0, import_node_fs15.lstatSync)(path);
14704
- return st.isFile() && !st.isSymbolicLink();
14705
- } catch (e) {
14706
- return e.code === "ENOENT";
14707
- }
14708
- }
14709
- function verifyOpened(fd, path, root) {
14710
- try {
14711
- const opened = (0, import_node_fs15.fstatSync)(fd, { bigint: true });
14712
- if (!opened.isFile() || opened.nlink !== 1n) return false;
14713
- const real = (0, import_node_fs15.realpathSync)(path);
14714
- if (!isInsideRoot(root.real, real)) return false;
14715
- const current = (0, import_node_fs15.statSync)(real, { bigint: true });
14716
- if (!sameOpenedFile(opened, current, NOFOLLOW_AVAILABLE)) return false;
14717
- return rootUnchanged(root);
14718
- } catch {
14719
- return false;
14720
- }
14721
- }
14722
- function removeIfOurs(fd, path) {
14723
- try {
14724
- const opened = (0, import_node_fs15.fstatSync)(fd, { bigint: true });
14725
- const at = (0, import_node_fs15.lstatSync)(path, { bigint: true });
14726
- if (!at.isSymbolicLink() && at.dev === opened.dev && at.ino === opened.ino) (0, import_node_fs15.unlinkSync)(path);
14727
- } catch {
14728
- }
14729
- }
14730
- function openTarget(path, append2) {
14731
- const base = import_node_fs15.constants.O_WRONLY | (append2 ? import_node_fs15.constants.O_APPEND : 0) | O_NOFOLLOW;
14732
- try {
14733
- return { fd: (0, import_node_fs15.openSync)(path, base), created: false };
14734
- } catch (e) {
14735
- if (e.code !== "ENOENT") return null;
14736
- }
14737
- try {
14738
- return { fd: (0, import_node_fs15.openSync)(path, base | import_node_fs15.constants.O_CREAT | import_node_fs15.constants.O_EXCL, 384), created: true };
14739
- } catch {
14740
- return null;
14741
- }
14742
- }
14743
- function writeVerified(root, name, hooks, append2, write) {
14744
- const r = validateRoot(root);
14745
- if (!r || !bareName(name)) return false;
14746
- const path = (0, import_node_path15.join)(r.real, name);
14747
- if (!absentOrRegular(path)) return false;
14748
- if (!runHook(hooks)) return false;
14749
- const opened = openTarget(path, append2);
14750
- if (!opened) return false;
14751
- try {
14752
- if (!verifyOpened(opened.fd, path, r)) {
14753
- if (opened.created) removeIfOurs(opened.fd, path);
14754
- return false;
14755
- }
14756
- write(opened.fd);
14757
- return true;
14758
- } catch {
14759
- return false;
14760
- } finally {
14761
- try {
14762
- (0, import_node_fs15.closeSync)(opened.fd);
14763
- } catch {
14764
- }
14765
- }
14766
- }
14767
- function runHook(hooks) {
14768
- try {
14769
- hooks.afterRootValidated?.();
14770
- return true;
14771
- } catch {
14772
- return false;
14773
- }
14774
- }
14775
- function appendInRoot(root, name, text, hooks = {}) {
14776
- return writeVerified(root, name, hooks, true, (fd) => {
14777
- (0, import_node_fs15.writeSync)(fd, text);
14778
- });
14779
- }
14780
- function replaceInRoot(root, name, text, hooks = {}) {
14781
- return writeVerified(root, name, hooks, false, (fd) => {
14782
- (0, import_node_fs15.ftruncateSync)(fd, 0);
14783
- (0, import_node_fs15.writeSync)(fd, text, 0);
14784
- });
14785
- }
14786
-
14787
- // src/lib/injection-record.ts
14788
- var MAX_PENDING = 200;
14789
- var MAX_RECORD_BYTES = 1024 * 1024;
14790
- var COMPACT_AT_BYTES = 256 * 1024;
14791
- var MAX_NODES = 50;
14792
- var SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
14793
- var VIA = /^[A-Za-z0-9_+,:.-]{0,40}$/;
14794
- var PROMPT_HASH = /^[0-9a-f]{16}$/;
14795
- var nonNegInt = (v, max) => typeof v === "number" && Number.isInteger(v) && v >= 0 && v <= max;
14796
- function parseInjectionEvent(raw) {
14797
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
14798
- const o = raw;
14799
- if (typeof o.ts !== "number" || !Number.isFinite(o.ts) || o.ts <= 0 || o.ts > 1e13) return null;
14800
- if (!(o.session_id === null || typeof o.session_id === "string" && SAFE_ID.test(o.session_id))) return null;
14801
- if (typeof o.prompt_hash !== "string" || !PROMPT_HASH.test(o.prompt_hash)) return null;
14802
- if (o.arm !== "injected" && o.arm !== "withheld") return null;
14803
- if (!nonNegInt(o.eligible, 1e5) || !nonNegInt(o.tokens, 1e6)) return null;
14804
- if (!Array.isArray(o.nodes) || o.nodes.length > MAX_NODES) return null;
14805
- const nodes = [];
14806
- for (const n of o.nodes) {
14807
- if (!n || typeof n !== "object") return null;
14808
- const r = n;
14809
- if (typeof r.id !== "string" || !SAFE_ID.test(r.id)) return null;
14810
- if (typeof r.score !== "number" || !Number.isFinite(r.score) || r.score < 0 || r.score > 10) return null;
14811
- if (typeof r.via !== "string" || !VIA.test(r.via)) return null;
14812
- nodes.push({ id: r.id, score: r.score, via: r.via });
14813
- }
14814
- return {
14815
- ts: o.ts,
14816
- session_id: o.session_id,
14817
- prompt_hash: o.prompt_hash,
14818
- arm: o.arm,
14819
- nodes,
14820
- eligible: o.eligible,
14821
- tokens: o.tokens
14822
- };
14823
- }
14824
- var recordPath = () => projectPath(`${VERITY_DIR}/injections.jsonl`);
14825
- function hashPrompt(prompt) {
14826
- return (0, import_node_crypto3.createHash)("sha256").update(prompt).digest("hex").slice(0, 16);
14827
- }
14828
- function recordInjection(event) {
14829
- if (!appendInRoot(projectPath(VERITY_DIR), "injections.jsonl", JSON.stringify(event) + "\n")) return;
14830
- try {
14831
- if ((0, import_node_fs16.lstatSync)(recordPath()).size > COMPACT_AT_BYTES) writeEvents(readPendingInjections());
14832
- } catch {
14833
- }
14834
- }
14835
- function writeEvents(events) {
14836
- replaceInRoot(projectPath(VERITY_DIR), "injections.jsonl", events.map((e) => JSON.stringify(e)).join("\n") + (events.length ? "\n" : ""));
14837
- }
14838
- function readPendingInjections() {
14839
- try {
14840
- const p = recordPath();
14841
- if (!(0, import_node_fs16.existsSync)(p)) return [];
14842
- const read = readRegularFileInRoot(projectPath(VERITY_DIR), "injections.jsonl", MAX_RECORD_BYTES);
14843
- if (!read.ok) return [];
14844
- const out = [];
14845
- for (const line of read.content.split("\n")) {
14846
- if (!line.trim()) continue;
14847
- try {
14848
- const e = parseInjectionEvent(JSON.parse(line));
14849
- if (e) out.push(e);
14850
- } catch {
14851
- }
14852
- }
14853
- return out.slice(-MAX_PENDING);
14854
- } catch {
14855
- return [];
14856
- }
14857
- }
14858
-
14859
14395
  // src/lib/memory-sync.ts
14860
14396
  var import_promises9 = require("node:fs/promises");
14861
- var import_node_fs19 = require("node:fs");
14862
- var import_node_path17 = require("node:path");
14863
- var import_node_crypto4 = require("node:crypto");
14397
+ var import_node_fs16 = require("node:fs");
14398
+ var import_node_path15 = require("node:path");
14399
+ var import_node_crypto3 = require("node:crypto");
14864
14400
 
14865
14401
  // src/lib/gitignore.ts
14866
14402
  var import_node_child_process6 = require("node:child_process");
14867
- var import_node_fs17 = require("node:fs");
14403
+ var import_node_fs14 = require("node:fs");
14868
14404
  var VERITY_GITIGNORE_MARKER = "# Verity \u2014 machine-local state.";
14869
14405
  var SETTINGS_LOCAL_IGNORE_ENTRY = ".claude/settings.local.json";
14870
14406
  var VERITY_GITIGNORE_BLOCK = [
@@ -14948,7 +14484,7 @@ function fenceMemoryLines(lines) {
14948
14484
  function ensureVerityGitignore() {
14949
14485
  let content = "";
14950
14486
  try {
14951
- content = (0, import_node_fs17.readFileSync)(".gitignore", "utf-8");
14487
+ content = (0, import_node_fs14.readFileSync)(".gitignore", "utf-8");
14952
14488
  } catch {
14953
14489
  }
14954
14490
  const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
@@ -14975,7 +14511,7 @@ function ensureVerityGitignore() {
14975
14511
  const sep4 = text === "" ? "" : text.endsWith("\n") ? "\n" : "\n\n";
14976
14512
  text = text + sep4 + VERITY_GITIGNORE_BLOCK;
14977
14513
  }
14978
- if (text !== content) (0, import_node_fs17.writeFileSync)(".gitignore", text);
14514
+ if (text !== content) (0, import_node_fs14.writeFileSync)(".gitignore", text);
14979
14515
  return verified(
14980
14516
  memoryIsCommitted ? "memory-tracked" : hasSupersededMemory ? "memory-fenced" : needsRepair ? "repaired" : "added"
14981
14517
  );
@@ -14995,7 +14531,7 @@ function untrackMemory() {
14995
14531
  function writeFencedBlock() {
14996
14532
  let content = "";
14997
14533
  try {
14998
- content = (0, import_node_fs17.readFileSync)(".gitignore", "utf-8");
14534
+ content = (0, import_node_fs14.readFileSync)(".gitignore", "utf-8");
14999
14535
  } catch {
15000
14536
  }
15001
14537
  const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
@@ -15007,7 +14543,7 @@ function writeFencedBlock() {
15007
14543
  text = text + sep4 + VERITY_GITIGNORE_BLOCK;
15008
14544
  }
15009
14545
  try {
15010
- (0, import_node_fs17.writeFileSync)(".gitignore", text);
14546
+ (0, import_node_fs14.writeFileSync)(".gitignore", text);
15011
14547
  return true;
15012
14548
  } catch {
15013
14549
  return false;
@@ -15016,14 +14552,14 @@ function writeFencedBlock() {
15016
14552
  function fenceMemory() {
15017
14553
  let original = null;
15018
14554
  try {
15019
- original = (0, import_node_fs17.readFileSync)(".gitignore", "utf-8");
14555
+ original = (0, import_node_fs14.readFileSync)(".gitignore", "utf-8");
15020
14556
  } catch {
15021
14557
  original = null;
15022
14558
  }
15023
14559
  const restore = () => {
15024
14560
  try {
15025
- if (original === null) (0, import_node_fs17.rmSync)(".gitignore", { force: true });
15026
- else (0, import_node_fs17.writeFileSync)(".gitignore", original);
14561
+ if (original === null) (0, import_node_fs14.rmSync)(".gitignore", { force: true });
14562
+ else (0, import_node_fs14.writeFileSync)(".gitignore", original);
15027
14563
  } catch {
15028
14564
  }
15029
14565
  };
@@ -15041,7 +14577,7 @@ function fenceMemory() {
15041
14577
  }
15042
14578
  function memoryOptOut() {
15043
14579
  try {
15044
- return (0, import_node_fs17.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
14580
+ return (0, import_node_fs14.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
15045
14581
  } catch {
15046
14582
  return false;
15047
14583
  }
@@ -15049,13 +14585,13 @@ function memoryOptOut() {
15049
14585
  function keepMemoryTracked() {
15050
14586
  let content = "";
15051
14587
  try {
15052
- content = (0, import_node_fs17.readFileSync)(".gitignore", "utf-8");
14588
+ content = (0, import_node_fs14.readFileSync)(".gitignore", "utf-8");
15053
14589
  } catch {
15054
14590
  }
15055
14591
  if (content.includes(MEMORY_OPT_OUT_MARKER)) return "already";
15056
14592
  try {
15057
14593
  const sep4 = content === "" ? "" : content.endsWith("\n") ? "\n" : "\n\n";
15058
- (0, import_node_fs17.writeFileSync)(".gitignore", content + sep4 + MEMORY_OPT_OUT_STANZA);
14594
+ (0, import_node_fs14.writeFileSync)(".gitignore", content + sep4 + MEMORY_OPT_OUT_STANZA);
15059
14595
  } catch {
15060
14596
  return "failed";
15061
14597
  }
@@ -15090,26 +14626,26 @@ function untrackVerityState() {
15090
14626
  }
15091
14627
 
15092
14628
  // src/lib/safe-path.ts
15093
- var import_node_fs18 = require("node:fs");
15094
- var import_node_path16 = require("node:path");
14629
+ var import_node_fs15 = require("node:fs");
14630
+ var import_node_path14 = require("node:path");
15095
14631
  function resolveInside(baseDir, candidate) {
15096
14632
  if (typeof candidate !== "string" || candidate.length === 0) return null;
15097
- if ((0, import_node_path16.isAbsolute)(candidate)) return null;
15098
- const baseAbs = (0, import_node_path16.resolve)(baseDir);
15099
- const full = (0, import_node_path16.resolve)(baseAbs, candidate);
15100
- const baseSep = baseAbs.endsWith(import_node_path16.sep) ? baseAbs : baseAbs + import_node_path16.sep;
14633
+ if ((0, import_node_path14.isAbsolute)(candidate)) return null;
14634
+ const baseAbs = (0, import_node_path14.resolve)(baseDir);
14635
+ const full = (0, import_node_path14.resolve)(baseAbs, candidate);
14636
+ const baseSep = baseAbs.endsWith(import_node_path14.sep) ? baseAbs : baseAbs + import_node_path14.sep;
15101
14637
  if (full !== baseAbs && !full.startsWith(baseSep)) return null;
15102
14638
  try {
15103
- if ((0, import_node_fs18.existsSync)(baseAbs)) {
15104
- const realBase = (0, import_node_fs18.realpathSync)(baseAbs);
15105
- const realBaseSep = realBase.endsWith(import_node_path16.sep) ? realBase : realBase + import_node_path16.sep;
14639
+ if ((0, import_node_fs15.existsSync)(baseAbs)) {
14640
+ const realBase = (0, import_node_fs15.realpathSync)(baseAbs);
14641
+ const realBaseSep = realBase.endsWith(import_node_path14.sep) ? realBase : realBase + import_node_path14.sep;
15106
14642
  let probe = full;
15107
- while (!(0, import_node_fs18.existsSync)(probe)) {
15108
- const parent = (0, import_node_path16.dirname)(probe);
14643
+ while (!(0, import_node_fs15.existsSync)(probe)) {
14644
+ const parent = (0, import_node_path14.dirname)(probe);
15109
14645
  if (parent === probe) break;
15110
14646
  probe = parent;
15111
14647
  }
15112
- const realProbe = (0, import_node_fs18.realpathSync)(probe);
14648
+ const realProbe = (0, import_node_fs15.realpathSync)(probe);
15113
14649
  if (realProbe !== realBase && !realProbe.startsWith(realBaseSep)) return null;
15114
14650
  }
15115
14651
  } catch {
@@ -15117,37 +14653,37 @@ function resolveInside(baseDir, candidate) {
15117
14653
  }
15118
14654
  return full;
15119
14655
  }
15120
- var O_NOFOLLOW2 = typeof import_node_fs18.constants.O_NOFOLLOW === "number" ? import_node_fs18.constants.O_NOFOLLOW : 0;
14656
+ var O_NOFOLLOW = typeof import_node_fs15.constants.O_NOFOLLOW === "number" ? import_node_fs15.constants.O_NOFOLLOW : 0;
15121
14657
  function readFileInside(baseDir, candidate, maxBytes) {
15122
14658
  const full = resolveInside(baseDir, candidate);
15123
14659
  if (!full) return null;
15124
14660
  let realParent;
15125
14661
  let realBase;
15126
14662
  try {
15127
- realParent = (0, import_node_fs18.realpathSync)((0, import_node_path16.dirname)(full));
15128
- realBase = (0, import_node_fs18.realpathSync)((0, import_node_path16.resolve)(baseDir));
14663
+ realParent = (0, import_node_fs15.realpathSync)((0, import_node_path14.dirname)(full));
14664
+ realBase = (0, import_node_fs15.realpathSync)((0, import_node_path14.resolve)(baseDir));
15129
14665
  } catch {
15130
14666
  return null;
15131
14667
  }
15132
- const realBaseSep = realBase.endsWith(import_node_path16.sep) ? realBase : realBase + import_node_path16.sep;
14668
+ const realBaseSep = realBase.endsWith(import_node_path14.sep) ? realBase : realBase + import_node_path14.sep;
15133
14669
  if (realParent !== realBase && !realParent.startsWith(realBaseSep)) return null;
15134
- const target = (0, import_node_path16.join)(realParent, (0, import_node_path16.basename)(full));
14670
+ const target = (0, import_node_path14.join)(realParent, (0, import_node_path14.basename)(full));
15135
14671
  let fd = null;
15136
14672
  try {
15137
- fd = (0, import_node_fs18.openSync)(target, import_node_fs18.constants.O_RDONLY | O_NOFOLLOW2);
15138
- const st = (0, import_node_fs18.fstatSync)(fd);
14673
+ fd = (0, import_node_fs15.openSync)(target, import_node_fs15.constants.O_RDONLY | O_NOFOLLOW);
14674
+ const st = (0, import_node_fs15.fstatSync)(fd);
15139
14675
  if (!st.isFile()) return null;
15140
14676
  const cap = Math.min(maxBytes, st.size);
15141
14677
  if (cap <= 0) return "";
15142
14678
  const buf = Buffer.alloc(cap);
15143
- const bytesRead = (0, import_node_fs18.readSync)(fd, buf, 0, cap, 0);
14679
+ const bytesRead = (0, import_node_fs15.readSync)(fd, buf, 0, cap, 0);
15144
14680
  return buf.subarray(0, bytesRead).toString("utf-8");
15145
14681
  } catch {
15146
14682
  return null;
15147
14683
  } finally {
15148
14684
  if (fd !== null) {
15149
14685
  try {
15150
- (0, import_node_fs18.closeSync)(fd);
14686
+ (0, import_node_fs15.closeSync)(fd);
15151
14687
  } catch {
15152
14688
  }
15153
14689
  }
@@ -15230,35 +14766,35 @@ var syncStateFile = () => projectPath(`${VERITY_DIR}/.memory-sync-state.json`);
15230
14766
  async function ensureMemoryDir() {
15231
14767
  await (0, import_promises9.mkdir)(memoryDir2(), { recursive: true });
15232
14768
  for (const domain of DOMAINS2) {
15233
- await (0, import_promises9.mkdir)((0, import_node_path17.join)(memoryDir2(), domain), { recursive: true });
14769
+ await (0, import_promises9.mkdir)((0, import_node_path15.join)(memoryDir2(), domain), { recursive: true });
15234
14770
  }
15235
- if (!(0, import_node_fs19.existsSync)((0, import_node_path17.join)(memoryDir2(), "SCHEMA.md"))) {
15236
- await (0, import_promises9.writeFile)((0, import_node_path17.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
14771
+ if (!(0, import_node_fs16.existsSync)((0, import_node_path15.join)(memoryDir2(), "SCHEMA.md"))) {
14772
+ await (0, import_promises9.writeFile)((0, import_node_path15.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
15237
14773
  }
15238
- if (!(0, import_node_fs19.existsSync)((0, import_node_path17.join)(memoryDir2(), "index.md"))) {
15239
- await (0, import_promises9.writeFile)((0, import_node_path17.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
14774
+ if (!(0, import_node_fs16.existsSync)((0, import_node_path15.join)(memoryDir2(), "index.md"))) {
14775
+ await (0, import_promises9.writeFile)((0, import_node_path15.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
15240
14776
  }
15241
- if (!(0, import_node_fs19.existsSync)((0, import_node_path17.join)(memoryDir2(), "log.md"))) {
15242
- await (0, import_promises9.writeFile)((0, import_node_path17.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
14777
+ if (!(0, import_node_fs16.existsSync)((0, import_node_path15.join)(memoryDir2(), "log.md"))) {
14778
+ await (0, import_promises9.writeFile)((0, import_node_path15.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
15243
14779
  }
15244
14780
  }
15245
14781
  async function buildManifest() {
15246
- if (!(0, import_node_fs19.existsSync)(memoryDir2())) {
14782
+ if (!(0, import_node_fs16.existsSync)(memoryDir2())) {
15247
14783
  return { schema_version: 1, nodes: [], index_hash: null, log_length: 0 };
15248
14784
  }
15249
14785
  const nodes = [];
15250
14786
  for (const domain of DOMAINS2) {
15251
- const domainDir = (0, import_node_path17.join)(memoryDir2(), domain);
15252
- if (!(0, import_node_fs19.existsSync)(domainDir)) continue;
14787
+ const domainDir = (0, import_node_path15.join)(memoryDir2(), domain);
14788
+ if (!(0, import_node_fs16.existsSync)(domainDir)) continue;
15253
14789
  try {
15254
14790
  const files = await (0, import_promises9.readdir)(domainDir);
15255
14791
  for (const file of files) {
15256
14792
  if (!file.endsWith(".md")) continue;
15257
14793
  const filePath = `${domain}/${file}`;
15258
- const fullPath = (0, import_node_path17.join)(memoryDir2(), filePath);
14794
+ const fullPath = (0, import_node_path15.join)(memoryDir2(), filePath);
15259
14795
  try {
15260
14796
  const content = await (0, import_promises9.readFile)(fullPath, "utf-8");
15261
- const hash = (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex").slice(0, 16);
14797
+ const hash = (0, import_node_crypto3.createHash)("sha256").update(content).digest("hex").slice(0, 16);
15262
14798
  nodes.push({ path: filePath, content_hash: `sha256:${hash}` });
15263
14799
  } catch {
15264
14800
  }
@@ -15268,32 +14804,32 @@ async function buildManifest() {
15268
14804
  }
15269
14805
  let indexHash = null;
15270
14806
  try {
15271
- const indexContent = await (0, import_promises9.readFile)((0, import_node_path17.join)(memoryDir2(), "index.md"), "utf-8");
15272
- indexHash = `sha256:${(0, import_node_crypto4.createHash)("sha256").update(indexContent).digest("hex").slice(0, 16)}`;
14807
+ const indexContent = await (0, import_promises9.readFile)((0, import_node_path15.join)(memoryDir2(), "index.md"), "utf-8");
14808
+ indexHash = `sha256:${(0, import_node_crypto3.createHash)("sha256").update(indexContent).digest("hex").slice(0, 16)}`;
15273
14809
  } catch {
15274
14810
  }
15275
14811
  let logLength = 0;
15276
14812
  try {
15277
- const logContent = await (0, import_promises9.readFile)((0, import_node_path17.join)(memoryDir2(), "log.md"), "utf-8");
14813
+ const logContent = await (0, import_promises9.readFile)((0, import_node_path15.join)(memoryDir2(), "log.md"), "utf-8");
15278
14814
  logLength = logContent.split("\n").length;
15279
14815
  } catch {
15280
14816
  }
15281
14817
  return { schema_version: 1, nodes, index_hash: indexHash, log_length: logLength };
15282
14818
  }
15283
14819
  function hashContent(content) {
15284
- return `sha256:${(0, import_node_crypto4.createHash)("sha256").update(content).digest("hex").slice(0, 16)}`;
14820
+ return `sha256:${(0, import_node_crypto3.createHash)("sha256").update(content).digest("hex").slice(0, 16)}`;
15285
14821
  }
15286
14822
  async function readOnDiskNodes() {
15287
14823
  const out = /* @__PURE__ */ new Map();
15288
- if (!(0, import_node_fs19.existsSync)(memoryDir2())) return out;
14824
+ if (!(0, import_node_fs16.existsSync)(memoryDir2())) return out;
15289
14825
  for (const domain of DOMAINS2) {
15290
- const domainDir = (0, import_node_path17.join)(memoryDir2(), domain);
15291
- if (!(0, import_node_fs19.existsSync)(domainDir)) continue;
14826
+ const domainDir = (0, import_node_path15.join)(memoryDir2(), domain);
14827
+ if (!(0, import_node_fs16.existsSync)(domainDir)) continue;
15292
14828
  try {
15293
14829
  for (const file of await (0, import_promises9.readdir)(domainDir)) {
15294
14830
  if (!file.endsWith(".md")) continue;
15295
14831
  try {
15296
- out.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0, import_node_path17.join)(domainDir, file), "utf-8")));
14832
+ out.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0, import_node_path15.join)(domainDir, file), "utf-8")));
15297
14833
  } catch {
15298
14834
  }
15299
14835
  }
@@ -15330,7 +14866,7 @@ async function recordSyncedNodePaths() {
15330
14866
  }
15331
14867
  }
15332
14868
  async function writeFileAtomic(path, content) {
15333
- await (0, import_promises9.mkdir)((0, import_node_path17.dirname)(path), { recursive: true });
14869
+ await (0, import_promises9.mkdir)((0, import_node_path15.dirname)(path), { recursive: true });
15334
14870
  const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
15335
14871
  await (0, import_promises9.writeFile)(tmp, content);
15336
14872
  await (0, import_promises9.rename)(tmp, path);
@@ -15344,8 +14880,8 @@ async function computeEditedNodeUploads() {
15344
14880
  const uploads = [];
15345
14881
  for (const [path, prevHash] of prev) {
15346
14882
  if (prevHash == null) continue;
15347
- const full = (0, import_node_path17.join)(memoryDir2(), path);
15348
- if (!(0, import_node_fs19.existsSync)(full)) continue;
14883
+ const full = (0, import_node_path15.join)(memoryDir2(), path);
14884
+ if (!(0, import_node_fs16.existsSync)(full)) continue;
15349
14885
  let content;
15350
14886
  try {
15351
14887
  content = await (0, import_promises9.readFile)(full, "utf-8");
@@ -15389,8 +14925,8 @@ async function applyMemoryWrites(writes, opts = {}) {
15389
14925
  const logLines = [`- ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 16)} \u2014 Applied ${count} write(s) from server`];
15390
14926
  for (const n of notes) logLines.push(` - ${n}`);
15391
14927
  try {
15392
- const existing = (0, import_node_fs19.existsSync)((0, import_node_path17.join)(memoryDir2(), "log.md")) ? await (0, import_promises9.readFile)((0, import_node_path17.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
15393
- await (0, import_promises9.writeFile)((0, import_node_path17.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
14928
+ const existing = (0, import_node_fs16.existsSync)((0, import_node_path15.join)(memoryDir2(), "log.md")) ? await (0, import_promises9.readFile)((0, import_node_path15.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
14929
+ await (0, import_promises9.writeFile)((0, import_node_path15.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
15394
14930
  } catch {
15395
14931
  }
15396
14932
  if (opts.baseline === "written") await mergeSyncBaseline(synced);
@@ -15400,7 +14936,7 @@ async function applyMemoryWrites(writes, opts = {}) {
15400
14936
  async function mergeSyncBaseline(entries) {
15401
14937
  if (entries.size === 0) return;
15402
14938
  try {
15403
- if ((0, import_node_fs19.existsSync)(syncStateFile())) {
14939
+ if ((0, import_node_fs16.existsSync)(syncStateFile())) {
15404
14940
  try {
15405
14941
  JSON.parse(await (0, import_promises9.readFile)(syncStateFile(), "utf-8"));
15406
14942
  } catch {
@@ -15428,7 +14964,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
15428
14964
  notes.push(`${write.path}: dropped unmatched file_globs [${grounded.dropped.join(", ")}]`);
15429
14965
  }
15430
14966
  }
15431
- if ((0, import_node_fs19.existsSync)(fullPath)) {
14967
+ if ((0, import_node_fs16.existsSync)(fullPath)) {
15432
14968
  let existing = "";
15433
14969
  try {
15434
14970
  existing = await (0, import_promises9.readFile)(fullPath, "utf-8");
@@ -15444,7 +14980,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
15444
14980
  notes.push(`${write.path}: updated from server (untouched here since the server delivered it)`);
15445
14981
  }
15446
14982
  }
15447
- await (0, import_promises9.mkdir)((0, import_node_path17.dirname)(fullPath), { recursive: true });
14983
+ await (0, import_promises9.mkdir)((0, import_node_path15.dirname)(fullPath), { recursive: true });
15448
14984
  await (0, import_promises9.writeFile)(fullPath, content);
15449
14985
  return { written: true, syncedHash: hashContent(content), notes };
15450
14986
  }
@@ -15485,8 +15021,8 @@ async function regenerateIndex() {
15485
15021
  ];
15486
15022
  let totalNodes = 0;
15487
15023
  for (const domain of DOMAINS2.filter((d) => d !== "_archive")) {
15488
- const domainDir = (0, import_node_path17.join)(memoryDir2(), domain);
15489
- if (!(0, import_node_fs19.existsSync)(domainDir)) continue;
15024
+ const domainDir = (0, import_node_path15.join)(memoryDir2(), domain);
15025
+ if (!(0, import_node_fs16.existsSync)(domainDir)) continue;
15490
15026
  try {
15491
15027
  const files = await (0, import_promises9.readdir)(domainDir);
15492
15028
  const mdFiles = files.filter((f) => f.endsWith(".md"));
@@ -15496,7 +15032,7 @@ async function regenerateIndex() {
15496
15032
  for (const file of mdFiles.sort()) {
15497
15033
  const slug = file.replace(/\.md$/, "");
15498
15034
  try {
15499
- const content = await (0, import_promises9.readFile)((0, import_node_path17.join)(domainDir, file), "utf-8");
15035
+ const content = await (0, import_promises9.readFile)((0, import_node_path15.join)(domainDir, file), "utf-8");
15500
15036
  const title = pickFrontmatter(content, "title") ?? slug;
15501
15037
  const kind = pickFrontmatter(content, "kind") ?? "-";
15502
15038
  const confidence = pickFrontmatter(content, "confidence");
@@ -15520,7 +15056,7 @@ async function regenerateIndex() {
15520
15056
  lines.push("No nodes yet. Run an analysis to start building the knowledge graph.");
15521
15057
  }
15522
15058
  const next = lines.join("\n") + "\n";
15523
- const indexPath = (0, import_node_path17.join)(memoryDir2(), "index.md");
15059
+ const indexPath = (0, import_node_path15.join)(memoryDir2(), "index.md");
15524
15060
  let existing = null;
15525
15061
  try {
15526
15062
  existing = await (0, import_promises9.readFile)(indexPath, "utf-8");
@@ -15917,9 +15453,9 @@ function hasLegacyMemoryBlock(text) {
15917
15453
  return findMarker(text, LEGACY_MD_START) !== -1;
15918
15454
  }
15919
15455
  async function ensureClaudeMdPointer(cwd = repoRoot()) {
15920
- const claudeMdPath = (0, import_node_path17.join)(cwd, "CLAUDE.md");
15456
+ const claudeMdPath = (0, import_node_path15.join)(cwd, "CLAUDE.md");
15921
15457
  let existing = "";
15922
- if ((0, import_node_fs19.existsSync)(claudeMdPath)) {
15458
+ if ((0, import_node_fs16.existsSync)(claudeMdPath)) {
15923
15459
  existing = await (0, import_promises9.readFile)(claudeMdPath, "utf-8");
15924
15460
  }
15925
15461
  let startTag = CLAUDE_MD_START;
@@ -16060,9 +15596,9 @@ Body content (\u22648KB). Use [[node-id]] wikilinks for cross-references.
16060
15596
  `;
16061
15597
 
16062
15598
  // src/lib/dossier-session.ts
16063
- var import_node_fs24 = require("node:fs");
16064
- var import_node_crypto8 = require("node:crypto");
16065
- var import_node_path20 = require("node:path");
15599
+ var import_node_fs21 = require("node:fs");
15600
+ var import_node_crypto7 = require("node:crypto");
15601
+ var import_node_path18 = require("node:path");
16066
15602
 
16067
15603
  // src/lib/pending-repeat.ts
16068
15604
  var STOP = /* @__PURE__ */ new Set([
@@ -16166,9 +15702,9 @@ function statementAnchorKey(file, patternId) {
16166
15702
  }
16167
15703
 
16168
15704
  // src/lib/dossier/log.ts
16169
- var import_node_crypto5 = require("node:crypto");
16170
- var import_node_fs20 = require("node:fs");
16171
- var import_node_path18 = require("node:path");
15705
+ var import_node_crypto4 = require("node:crypto");
15706
+ var import_node_fs17 = require("node:fs");
15707
+ var import_node_path16 = require("node:path");
16172
15708
  var CRC_TABLE = (() => {
16173
15709
  const t = new Int32Array(256);
16174
15710
  for (let i = 0; i < 256; i++) {
@@ -16187,13 +15723,13 @@ function crc32(s) {
16187
15723
  function openDossier(identity) {
16188
15724
  try {
16189
15725
  const dir = dossierDir(identity);
16190
- (0, import_node_fs20.mkdirSync)(dir, { recursive: true, mode: 448 });
15726
+ (0, import_node_fs17.mkdirSync)(dir, { recursive: true, mode: 448 });
16191
15727
  return {
16192
15728
  dir,
16193
15729
  identity,
16194
- eventsPath: (0, import_node_path18.join)(dir, "events.jsonl"),
16195
- foldPath: (0, import_node_path18.join)(dir, "fold.json"),
16196
- rotatedDir: (0, import_node_path18.join)(dir, "rotated")
15730
+ eventsPath: (0, import_node_path16.join)(dir, "events.jsonl"),
15731
+ foldPath: (0, import_node_path16.join)(dir, "fold.json"),
15732
+ rotatedDir: (0, import_node_path16.join)(dir, "rotated")
16197
15733
  };
16198
15734
  } catch {
16199
15735
  return null;
@@ -16208,7 +15744,7 @@ function nextSeq() {
16208
15744
  function encodeEvent(ev) {
16209
15745
  const full = {
16210
15746
  v: 1,
16211
- id: (0, import_node_crypto5.randomBytes)(4).toString("hex"),
15747
+ id: (0, import_node_crypto4.randomBytes)(4).toString("hex"),
16212
15748
  ...ev
16213
15749
  };
16214
15750
  let body = JSON.stringify(full);
@@ -16255,7 +15791,7 @@ function appendEvent(d, ev) {
16255
15791
  at: ev.at ?? (/* @__PURE__ */ new Date()).toISOString(),
16256
15792
  ...ev
16257
15793
  });
16258
- (0, import_node_fs20.appendFileSync)(d.eventsPath, line, { mode: 384 });
15794
+ (0, import_node_fs17.appendFileSync)(d.eventsPath, line, { mode: 384 });
16259
15795
  return true;
16260
15796
  } catch {
16261
15797
  return false;
@@ -16263,14 +15799,14 @@ function appendEvent(d, ev) {
16263
15799
  }
16264
15800
  function rotateIfNeeded2(d) {
16265
15801
  try {
16266
- if (!(0, import_node_fs20.existsSync)(d.eventsPath)) return;
16267
- if ((0, import_node_fs20.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
16268
- (0, import_node_fs20.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
16269
- (0, import_node_fs20.renameSync)(d.eventsPath, (0, import_node_path18.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
16270
- const kept = (0, import_node_fs20.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
15802
+ if (!(0, import_node_fs17.existsSync)(d.eventsPath)) return;
15803
+ if ((0, import_node_fs17.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
15804
+ (0, import_node_fs17.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
15805
+ (0, import_node_fs17.renameSync)(d.eventsPath, (0, import_node_path16.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
15806
+ const kept = (0, import_node_fs17.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
16271
15807
  for (const stale of kept.slice(0, Math.max(0, kept.length - ROTATE_KEEP))) {
16272
15808
  try {
16273
- (0, import_node_fs20.renameSync)((0, import_node_path18.join)(d.rotatedDir, stale), (0, import_node_path18.join)(d.rotatedDir, `${stale}.pruned`));
15809
+ (0, import_node_fs17.renameSync)((0, import_node_path16.join)(d.rotatedDir, stale), (0, import_node_path16.join)(d.rotatedDir, `${stale}.pruned`));
16274
15810
  } catch {
16275
15811
  }
16276
15812
  }
@@ -16279,9 +15815,9 @@ function rotateIfNeeded2(d) {
16279
15815
  }
16280
15816
 
16281
15817
  // src/lib/dossier/fold-dossier.ts
16282
- var import_node_crypto6 = require("node:crypto");
16283
- var import_node_fs21 = require("node:fs");
16284
- var import_node_path19 = require("node:path");
15818
+ var import_node_crypto5 = require("node:crypto");
15819
+ var import_node_fs18 = require("node:fs");
15820
+ var import_node_path17 = require("node:path");
16285
15821
  var EMPTY_CAPABILITIES = () => ({
16286
15822
  human_reachable: { value: "unknown", tier: "unknown" },
16287
15823
  authorship_observability: { value: "unknown", tier: "unknown" },
@@ -16332,12 +15868,12 @@ function foldDossier(d, opts = {}) {
16332
15868
  }
16333
15869
  };
16334
15870
  try {
16335
- if ((0, import_node_fs21.existsSync)(d.rotatedDir)) {
16336
- const files = (0, import_node_fs21.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
15871
+ if ((0, import_node_fs18.existsSync)(d.rotatedDir)) {
15872
+ const files = (0, import_node_fs18.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
16337
15873
  state.meta.rotations = files.length;
16338
15874
  for (const f of files) {
16339
15875
  try {
16340
- ingest((0, import_node_fs21.readFileSync)((0, import_node_path19.join)(d.rotatedDir, f), "utf8"));
15876
+ ingest((0, import_node_fs18.readFileSync)((0, import_node_path17.join)(d.rotatedDir, f), "utf8"));
16341
15877
  } catch {
16342
15878
  state.meta.dropped_lines++;
16343
15879
  }
@@ -16346,9 +15882,9 @@ function foldDossier(d, opts = {}) {
16346
15882
  } catch {
16347
15883
  }
16348
15884
  try {
16349
- if ((0, import_node_fs21.existsSync)(d.eventsPath)) {
16350
- state.meta.upto_offset = (0, import_node_fs21.statSync)(d.eventsPath).size;
16351
- ingest((0, import_node_fs21.readFileSync)(d.eventsPath, "utf8"));
15885
+ if ((0, import_node_fs18.existsSync)(d.eventsPath)) {
15886
+ state.meta.upto_offset = (0, import_node_fs18.statSync)(d.eventsPath).size;
15887
+ ingest((0, import_node_fs18.readFileSync)(d.eventsPath, "utf8"));
16352
15888
  }
16353
15889
  } catch {
16354
15890
  }
@@ -16371,7 +15907,7 @@ function reduce(state, events, now) {
16371
15907
  state.meta.seq = Math.max(state.meta.seq, ev.seq);
16372
15908
  switch (ev.k) {
16373
15909
  case "goal": {
16374
- const hash = (0, import_node_crypto6.createHash)("sha256").update(ev.text).digest("hex").slice(0, 16);
15910
+ const hash = (0, import_node_crypto5.createHash)("sha256").update(ev.text).digest("hex").slice(0, 16);
16375
15911
  const prev = state.goal[state.goal.length - 1];
16376
15912
  if (prev && prev.hash === hash) {
16377
15913
  prev.repeats = (prev.repeats ?? 0) + 1;
@@ -16619,7 +16155,7 @@ function applyBounds(state, input) {
16619
16155
  }
16620
16156
 
16621
16157
  // src/lib/dossier/cache.ts
16622
- var import_node_fs22 = require("node:fs");
16158
+ var import_node_fs19 = require("node:fs");
16623
16159
  function compactState(s) {
16624
16160
  const ms = (iso) => Date.parse(iso) || 0;
16625
16161
  return {
@@ -16748,20 +16284,20 @@ function encodeState(s) {
16748
16284
  function writeFoldCache(d, state) {
16749
16285
  try {
16750
16286
  const tmp = `${d.foldPath}.${process.pid}.tmp`;
16751
- (0, import_node_fs22.writeFileSync)(tmp, encodeState(state), { mode: 384 });
16752
- (0, import_node_fs22.renameSync)(tmp, d.foldPath);
16287
+ (0, import_node_fs19.writeFileSync)(tmp, encodeState(state), { mode: 384 });
16288
+ (0, import_node_fs19.renameSync)(tmp, d.foldPath);
16753
16289
  } catch {
16754
16290
  }
16755
16291
  }
16756
16292
  function readFoldCache(d) {
16757
16293
  try {
16758
- if (!(0, import_node_fs22.existsSync)(d.foldPath)) return null;
16759
- const raw = JSON.parse((0, import_node_fs22.readFileSync)(d.foldPath, "utf8"));
16294
+ if (!(0, import_node_fs19.existsSync)(d.foldPath)) return null;
16295
+ const raw = JSON.parse((0, import_node_fs19.readFileSync)(d.foldPath, "utf8"));
16760
16296
  if (raw?.v !== 1) return null;
16761
16297
  const cached2 = expandState(raw);
16762
16298
  if (!cached2?.meta) return null;
16763
- const size = (0, import_node_fs22.existsSync)(d.eventsPath) ? (0, import_node_fs22.statSync)(d.eventsPath).size : 0;
16764
- const rotations = (0, import_node_fs22.existsSync)(d.rotatedDir) ? (0, import_node_fs22.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
16299
+ const size = (0, import_node_fs19.existsSync)(d.eventsPath) ? (0, import_node_fs19.statSync)(d.eventsPath).size : 0;
16300
+ const rotations = (0, import_node_fs19.existsSync)(d.rotatedDir) ? (0, import_node_fs19.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
16765
16301
  if (cached2.meta.upto_offset !== size || cached2.meta.rotations !== rotations) return null;
16766
16302
  return cached2;
16767
16303
  } catch {
@@ -16811,14 +16347,14 @@ function assessContinuity(i) {
16811
16347
  }
16812
16348
 
16813
16349
  // src/lib/dossier/reanchor.ts
16814
- var import_node_crypto7 = require("node:crypto");
16815
- var import_node_fs23 = require("node:fs");
16350
+ var import_node_crypto6 = require("node:crypto");
16351
+ var import_node_fs20 = require("node:fs");
16816
16352
  function lineSha(text) {
16817
- return (0, import_node_crypto7.createHash)("sha256").update(text.trim()).digest("hex").slice(0, HASH_WIDTH);
16353
+ return (0, import_node_crypto6.createHash)("sha256").update(text.trim()).digest("hex").slice(0, HASH_WIDTH);
16818
16354
  }
16819
16355
  function fileHash(path) {
16820
16356
  try {
16821
- return (0, import_node_crypto7.createHash)("sha256").update((0, import_node_fs23.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
16357
+ return (0, import_node_crypto6.createHash)("sha256").update((0, import_node_fs20.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
16822
16358
  } catch {
16823
16359
  return null;
16824
16360
  }
@@ -17190,20 +16726,20 @@ function foreignAuthoredPaths(identity, opts = {}) {
17190
16726
  let sessions = 0;
17191
16727
  try {
17192
16728
  const dir = treeDir(identity);
17193
- if (!(0, import_node_fs24.existsSync)(dir)) return { paths: [], sessions: 0 };
17194
- for (const entry of (0, import_node_fs24.readdirSync)(dir, { withFileTypes: true })) {
16729
+ if (!(0, import_node_fs21.existsSync)(dir)) return { paths: [], sessions: 0 };
16730
+ for (const entry of (0, import_node_fs21.readdirSync)(dir, { withFileTypes: true })) {
17195
16731
  if (!entry.isDirectory()) continue;
17196
16732
  if (entry.name === identity.sessionKey) continue;
17197
- const log = (0, import_node_path20.join)(dir, entry.name, "events.jsonl");
16733
+ const log = (0, import_node_path18.join)(dir, entry.name, "events.jsonl");
17198
16734
  try {
17199
- if (!(0, import_node_fs24.existsSync)(log)) continue;
17200
- if (now - (0, import_node_fs24.statSync)(log).mtimeMs > windowMs) continue;
16735
+ if (!(0, import_node_fs21.existsSync)(log)) continue;
16736
+ if (now - (0, import_node_fs21.statSync)(log).mtimeMs > windowMs) continue;
17201
16737
  const sib = {
17202
- dir: (0, import_node_path20.join)(dir, entry.name),
16738
+ dir: (0, import_node_path18.join)(dir, entry.name),
17203
16739
  identity,
17204
16740
  eventsPath: log,
17205
- foldPath: (0, import_node_path20.join)(dir, entry.name, "fold.json"),
17206
- rotatedDir: (0, import_node_path20.join)(dir, entry.name, "rotated")
16741
+ foldPath: (0, import_node_path18.join)(dir, entry.name, "fold.json"),
16742
+ rotatedDir: (0, import_node_path18.join)(dir, entry.name, "rotated")
17207
16743
  };
17208
16744
  const state = readFoldCache(sib) ?? foldDossier(sib);
17209
16745
  sessions++;
@@ -17231,25 +16767,25 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
17231
16767
  let removed = 0;
17232
16768
  try {
17233
16769
  const mine = dossierDir(identity);
17234
- const userDir = (0, import_node_path20.dirname)((0, import_node_path20.dirname)(mine));
17235
- if (!(0, import_node_fs24.existsSync)(userDir)) return 0;
16770
+ const userDir = (0, import_node_path18.dirname)((0, import_node_path18.dirname)(mine));
16771
+ if (!(0, import_node_fs21.existsSync)(userDir)) return 0;
17236
16772
  const cutoff = Date.now() - maxAgeMs;
17237
- for (const tree of (0, import_node_fs24.readdirSync)(userDir, { withFileTypes: true })) {
16773
+ for (const tree of (0, import_node_fs21.readdirSync)(userDir, { withFileTypes: true })) {
17238
16774
  if (!tree.isDirectory()) continue;
17239
- const treePath = (0, import_node_path20.join)(userDir, tree.name);
16775
+ const treePath = (0, import_node_path18.join)(userDir, tree.name);
17240
16776
  let live = 0;
17241
- for (const entry of (0, import_node_fs24.readdirSync)(treePath, { withFileTypes: true })) {
16777
+ for (const entry of (0, import_node_fs21.readdirSync)(treePath, { withFileTypes: true })) {
17242
16778
  if (!entry.isDirectory()) continue;
17243
- const dir = (0, import_node_path20.join)(treePath, entry.name);
16779
+ const dir = (0, import_node_path18.join)(treePath, entry.name);
17244
16780
  if (dir === mine) {
17245
16781
  live++;
17246
16782
  continue;
17247
16783
  }
17248
16784
  try {
17249
- const log = (0, import_node_path20.join)(dir, "events.jsonl");
17250
- const at = (0, import_node_fs24.existsSync)(log) ? (0, import_node_fs24.statSync)(log).mtimeMs : (0, import_node_fs24.statSync)(dir).mtimeMs;
16785
+ const log = (0, import_node_path18.join)(dir, "events.jsonl");
16786
+ const at = (0, import_node_fs21.existsSync)(log) ? (0, import_node_fs21.statSync)(log).mtimeMs : (0, import_node_fs21.statSync)(dir).mtimeMs;
17251
16787
  if (at < cutoff) {
17252
- (0, import_node_fs24.rmSync)(dir, { recursive: true, force: true });
16788
+ (0, import_node_fs21.rmSync)(dir, { recursive: true, force: true });
17253
16789
  removed++;
17254
16790
  } else {
17255
16791
  live++;
@@ -17259,7 +16795,7 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
17259
16795
  }
17260
16796
  if (live === 0) {
17261
16797
  try {
17262
- (0, import_node_fs24.rmSync)(treePath, { recursive: false, force: false });
16798
+ (0, import_node_fs21.rmSync)(treePath, { recursive: false, force: false });
17263
16799
  } catch {
17264
16800
  }
17265
16801
  }
@@ -17276,8 +16812,8 @@ function sessionDossier(token, sessionId) {
17276
16812
  }
17277
16813
  function hasActiveGoal(d) {
17278
16814
  try {
17279
- if (!(0, import_node_fs24.existsSync)(d.eventsPath)) return false;
17280
- return (0, import_node_fs24.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
16815
+ if (!(0, import_node_fs21.existsSync)(d.eventsPath)) return false;
16816
+ return (0, import_node_fs21.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
17281
16817
  } catch {
17282
16818
  return false;
17283
16819
  }
@@ -17301,7 +16837,7 @@ function recordTurn(d, t) {
17301
16837
  for (const a of t.authored) {
17302
16838
  const origin = a.owner === "subagent" ? "subagent" : "edit_tool";
17303
16839
  const prior = t.known?.authored?.get(a.p);
17304
- const hash = fileHash((0, import_node_path20.join)(root, a.p));
16840
+ const hash = fileHash((0, import_node_path18.join)(root, a.p));
17305
16841
  const hunks = Math.max(0, a.h - (prior?.hunks ?? 0));
17306
16842
  const adds = Math.max(0, a.a - (prior?.adds ?? 0));
17307
16843
  const dels = Math.max(0, a.d - (prior?.dels ?? 0));
@@ -17315,7 +16851,7 @@ function recordTurn(d, t) {
17315
16851
  // Identity is the COMMAND, not its category — otherwise `npm test -- a` and
17316
16852
  // `npm test -- b` are one row and the streak counts two different commands
17317
16853
  // as a run of one.
17318
- cmd_hash: (0, import_node_crypto8.createHash)("sha256").update(c.head || c.class).digest("hex").slice(0, 12),
16854
+ cmd_hash: (0, import_node_crypto7.createHash)("sha256").update(c.head || c.class).digest("hex").slice(0, 12),
17319
16855
  head: c.head || c.class,
17320
16856
  status: toStatus(c.last_status)
17321
16857
  });
@@ -17334,7 +16870,7 @@ function recordTurn(d, t) {
17334
16870
  }
17335
16871
  const seenDivergence = t.known?.divergence ?? /* @__PURE__ */ new Set();
17336
16872
  for (const u of t.unobserved) {
17337
- const hash = fileHash((0, import_node_path20.join)(root, u.p));
16873
+ const hash = fileHash((0, import_node_path18.join)(root, u.p));
17338
16874
  if (seenDivergence.has(divergenceKey(u.p, hash))) continue;
17339
16875
  appendEvent(d, { k: "divergence", kind: "external_mutation", path: u.p, hash });
17340
16876
  }
@@ -17369,8 +16905,8 @@ function recordVerdict(d, v) {
17369
16905
  if (!sent.has(f.file)) continue;
17370
16906
  if (!lines.has(f.file)) {
17371
16907
  try {
17372
- const abs = (0, import_node_path20.join)(root, f.file);
17373
- lines.set(f.file, (0, import_node_fs24.existsSync)(abs) ? (0, import_node_fs24.readFileSync)(abs, "utf8").split("\n") : null);
16908
+ const abs = (0, import_node_path18.join)(root, f.file);
16909
+ lines.set(f.file, (0, import_node_fs21.existsSync)(abs) ? (0, import_node_fs21.readFileSync)(abs, "utf8").split("\n") : null);
17374
16910
  } catch {
17375
16911
  lines.set(f.file, null);
17376
16912
  }
@@ -17470,8 +17006,8 @@ function recallMemory(d, identity, opts) {
17470
17006
  budgetBytes: opts.budgetBytes,
17471
17007
  readFileLines: (file) => {
17472
17008
  try {
17473
- const abs = (0, import_node_path20.join)(root, file);
17474
- return (0, import_node_fs24.existsSync)(abs) ? (0, import_node_fs24.readFileSync)(abs, "utf8").split("\n") : null;
17009
+ const abs = (0, import_node_path18.join)(root, file);
17010
+ return (0, import_node_fs21.existsSync)(abs) ? (0, import_node_fs21.readFileSync)(abs, "utf8").split("\n") : null;
17475
17011
  } catch {
17476
17012
  return null;
17477
17013
  }
@@ -17490,9 +17026,6 @@ function recallMemory(d, identity, opts) {
17490
17026
  }
17491
17027
 
17492
17028
  // src/commands/intent.ts
17493
- var MAX_PROMPT_EVENT_BYTES = 2 * 1024 * 1024;
17494
- var MAX_PROMPT_CHARS2 = 2e5;
17495
- var SESSION_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
17496
17029
  function registerIntentCommands(program2) {
17497
17030
  const intent = program2.command("intent").description("Manage intent capture");
17498
17031
  intent.command("capture").description("Capture user intent from stdin (used by UserPromptSubmit hook)").action(async () => {
@@ -17506,24 +17039,16 @@ function registerIntentCommands(program2) {
17506
17039
  process.exit(0);
17507
17040
  }
17508
17041
  const chunks = [];
17509
- let size = 0;
17510
17042
  for await (const chunk of process.stdin) {
17511
- size += chunk.length;
17512
- if (size <= MAX_PROMPT_EVENT_BYTES) chunks.push(chunk);
17043
+ chunks.push(chunk);
17513
17044
  }
17514
- const input = size > MAX_PROMPT_EVENT_BYTES ? "" : Buffer.concat(chunks).toString("utf-8").trim();
17045
+ const input = Buffer.concat(chunks).toString("utf-8").trim();
17515
17046
  if (!input) {
17516
17047
  process.exit(0);
17517
17048
  }
17518
- let event = {};
17049
+ let event;
17519
17050
  try {
17520
- const parsed = JSON.parse(input);
17521
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) process.exit(0);
17522
- const o = parsed;
17523
- event = {
17524
- prompt: typeof o.prompt === "string" ? o.prompt.slice(0, MAX_PROMPT_CHARS2) : void 0,
17525
- session_id: typeof o.session_id === "string" && SESSION_ID_RE.test(o.session_id) ? o.session_id : void 0
17526
- };
17051
+ event = JSON.parse(input);
17527
17052
  } catch {
17528
17053
  process.exit(0);
17529
17054
  }
@@ -17552,19 +17077,6 @@ function registerIntentCommands(program2) {
17552
17077
  const injection = await retrieveForInjection(prompt);
17553
17078
  if (injection) {
17554
17079
  process.stdout.write(injection.contextBlock);
17555
- recordInjection({
17556
- ts: Date.now(),
17557
- session_id: scopeSession || null,
17558
- prompt_hash: hashPrompt(prompt),
17559
- arm: "injected",
17560
- eligible: injection.eligible,
17561
- tokens: injection.tokensUsed,
17562
- nodes: injection.nodes.map((n) => ({
17563
- id: n.nodeId,
17564
- score: Math.round(n.score * 1e3) / 1e3,
17565
- via: `${n.fileGlobs.length ? "g" : ""}${n.scope === "org" ? "o" : ""}x`
17566
- }))
17567
- });
17568
17080
  }
17569
17081
  } catch {
17570
17082
  }
@@ -17601,7 +17113,7 @@ async function fireClassify(prompt, sessionId, globals) {
17601
17113
  logEvent("classify_skipped", { reason: "no_service_url", detail: urlResult.error });
17602
17114
  return;
17603
17115
  }
17604
- const promptHash = (0, import_node_crypto9.createHash)("sha256").update(prompt).digest("hex");
17116
+ const promptHash = (0, import_node_crypto8.createHash)("sha256").update(prompt).digest("hex");
17605
17117
  const result = await apiRequest({
17606
17118
  method: "POST",
17607
17119
  path: "/classify-task",
@@ -17639,21 +17151,113 @@ async function fireClassify(prompt, sessionId, globals) {
17639
17151
  }
17640
17152
 
17641
17153
  // src/commands/lifecycle.ts
17642
- var import_node_fs27 = require("node:fs");
17643
- var import_node_path24 = require("node:path");
17154
+ var import_node_fs25 = require("node:fs");
17155
+ var import_node_path23 = require("node:path");
17644
17156
 
17645
17157
  // src/lib/baseline.ts
17646
- var import_node_fs26 = require("node:fs");
17647
- var import_node_path23 = require("node:path");
17648
- var import_node_crypto10 = require("node:crypto");
17158
+ var import_node_fs24 = require("node:fs");
17159
+ var import_node_path22 = require("node:path");
17160
+ var import_node_crypto9 = require("node:crypto");
17649
17161
 
17650
17162
  // src/lib/snapshot.ts
17651
- var import_node_fs25 = require("node:fs");
17652
- var import_node_path22 = require("node:path");
17163
+ var import_node_fs23 = require("node:fs");
17164
+ var import_node_path21 = require("node:path");
17653
17165
  var import_node_child_process7 = require("node:child_process");
17654
17166
 
17655
17167
  // src/lib/files.ts
17656
- var import_node_path21 = require("node:path");
17168
+ var import_node_path20 = require("node:path");
17169
+
17170
+ // src/lib/safe-read.ts
17171
+ var import_node_fs22 = require("node:fs");
17172
+ var import_node_path19 = require("node:path");
17173
+ var FLAGS = import_node_fs22.constants;
17174
+ var NOFOLLOW = FLAGS.O_NOFOLLOW;
17175
+ var NONBLOCK = FLAGS.O_NONBLOCK;
17176
+ function closeOpened(fd) {
17177
+ try {
17178
+ (0, import_node_fs22.closeSync)(fd);
17179
+ } catch {
17180
+ }
17181
+ }
17182
+ function isInsideRoot(realRoot, realPath) {
17183
+ return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path19.sep) ? realRoot : realRoot + import_node_path19.sep);
17184
+ }
17185
+ function sameOpenedFile(opened, current, nofollowAvailable) {
17186
+ if (!nofollowAvailable && (opened.ino === 0n || current.ino === 0n)) return false;
17187
+ return opened.ino === current.ino && opened.dev === current.dev;
17188
+ }
17189
+ function openRegularInRoot(root, path) {
17190
+ const full = (0, import_node_path19.isAbsolute)(path) ? path : (0, import_node_path19.join)(root, path);
17191
+ let fd;
17192
+ try {
17193
+ fd = (0, import_node_fs22.openSync)(full, import_node_fs22.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
17194
+ } catch (err) {
17195
+ const code = err.code;
17196
+ if (code === "ELOOP" || code === "EMLINK" || code === "EFTYPE") return { ok: false, reason: "symlink" };
17197
+ if (code === "ENOENT" || code === "ENOTDIR") return { ok: false, reason: "missing" };
17198
+ return { ok: false, reason: "unreadable" };
17199
+ }
17200
+ try {
17201
+ const opened = (0, import_node_fs22.fstatSync)(fd, { bigint: true });
17202
+ if (!opened.isFile()) {
17203
+ closeOpened(fd);
17204
+ return { ok: false, reason: "not-regular" };
17205
+ }
17206
+ const realRoot = import_node_fs22.realpathSync.native(root);
17207
+ const realPath = import_node_fs22.realpathSync.native(full);
17208
+ if (!isInsideRoot(realRoot, realPath)) {
17209
+ closeOpened(fd);
17210
+ return { ok: false, reason: "outside-root" };
17211
+ }
17212
+ const current = (0, import_node_fs22.statSync)(realPath, { bigint: true });
17213
+ if (!sameOpenedFile(opened, current, NOFOLLOW !== void 0)) {
17214
+ closeOpened(fd);
17215
+ return { ok: false, reason: NOFOLLOW === void 0 ? "unreadable" : "outside-root" };
17216
+ }
17217
+ return { ok: true, fd, size: Number(opened.size), mtimeMs: Number(opened.mtimeMs) };
17218
+ } catch {
17219
+ closeOpened(fd);
17220
+ return { ok: false, reason: "unreadable" };
17221
+ }
17222
+ }
17223
+ function statRegularInRoot(root, path) {
17224
+ const opened = openRegularInRoot(root, path);
17225
+ if (!opened.ok) return opened;
17226
+ closeOpened(opened.fd);
17227
+ return { ok: true, size: opened.size, mtimeMs: opened.mtimeMs };
17228
+ }
17229
+ function readOpened(fd, size) {
17230
+ try {
17231
+ const buffer = Buffer.alloc(size);
17232
+ let offset = 0;
17233
+ while (offset < size) {
17234
+ const n = (0, import_node_fs22.readSync)(fd, buffer, offset, size - offset, offset);
17235
+ if (n === 0) break;
17236
+ offset += n;
17237
+ }
17238
+ return buffer.subarray(0, offset);
17239
+ } finally {
17240
+ closeOpened(fd);
17241
+ }
17242
+ }
17243
+ function readOpenedUtf8(fd, size) {
17244
+ return readOpened(fd, size).toString("utf-8");
17245
+ }
17246
+ function readRegularFileInRoot(root, path, maxBytes) {
17247
+ const opened = openRegularInRoot(root, path);
17248
+ if (!opened.ok) return opened;
17249
+ if (opened.size > maxBytes) {
17250
+ closeOpened(opened.fd);
17251
+ return { ok: false, reason: "too-large", size: opened.size };
17252
+ }
17253
+ try {
17254
+ return { ok: true, content: readOpenedUtf8(opened.fd, opened.size), size: opened.size };
17255
+ } catch {
17256
+ return { ok: false, reason: "unreadable" };
17257
+ }
17258
+ }
17259
+
17260
+ // src/lib/files.ts
17657
17261
  var LANG_MAP = {
17658
17262
  // Analyzable (static analysis + Gemini)
17659
17263
  ts: "typescript",
@@ -17721,7 +17325,7 @@ var LANG_MAP = {
17721
17325
  mk: "make"
17722
17326
  };
17723
17327
  function detectLanguage(filepath) {
17724
- const ext = (0, import_node_path21.extname)(filepath).slice(1);
17328
+ const ext = (0, import_node_path20.extname)(filepath).slice(1);
17725
17329
  return LANG_MAP[ext] ?? ext;
17726
17330
  }
17727
17331
  function sortByMtime(files) {
@@ -17812,16 +17416,16 @@ function collectCodeDelta(files, opts) {
17812
17416
 
17813
17417
  // src/lib/snapshot.ts
17814
17418
  function generateSnapshotDiffs(files) {
17815
- if (!(0, import_node_fs25.existsSync)(SNAPSHOT_DIR)) {
17419
+ if (!(0, import_node_fs23.existsSync)(SNAPSHOT_DIR)) {
17816
17420
  return { diffs: [], has_snapshots: false };
17817
17421
  }
17818
17422
  const diffs = [];
17819
17423
  for (const file of files) {
17820
17424
  if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
17821
- const snapshotPath = (0, import_node_path22.join)(SNAPSHOT_DIR, file.path);
17425
+ const snapshotPath = (0, import_node_path21.join)(SNAPSHOT_DIR, file.path);
17822
17426
  const language = file.language ?? detectLanguage(file.path);
17823
- if ((0, import_node_fs25.existsSync)(snapshotPath)) {
17824
- const oldContent = (0, import_node_fs25.readFileSync)(snapshotPath, "utf-8");
17427
+ if ((0, import_node_fs23.existsSync)(snapshotPath)) {
17428
+ const oldContent = (0, import_node_fs23.readFileSync)(snapshotPath, "utf-8");
17825
17429
  if (oldContent === file.content) continue;
17826
17430
  const diff = computeDiff(oldContent, file.content, file.path);
17827
17431
  if (diff) {
@@ -17846,20 +17450,20 @@ function saveSnapshots(files) {
17846
17450
  const snapshotPaths = /* @__PURE__ */ new Set();
17847
17451
  for (const file of files) {
17848
17452
  if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
17849
- const snapshotPath = (0, import_node_path22.join)(SNAPSHOT_DIR, file.path);
17453
+ const snapshotPath = (0, import_node_path21.join)(SNAPSHOT_DIR, file.path);
17850
17454
  snapshotPaths.add(snapshotPath);
17851
- (0, import_node_fs25.mkdirSync)((0, import_node_path22.dirname)(snapshotPath), { recursive: true });
17852
- (0, import_node_fs25.writeFileSync)(snapshotPath, file.content);
17455
+ (0, import_node_fs23.mkdirSync)((0, import_node_path21.dirname)(snapshotPath), { recursive: true });
17456
+ (0, import_node_fs23.writeFileSync)(snapshotPath, file.content);
17853
17457
  }
17854
17458
  cleanStaleSnapshots(SNAPSHOT_DIR, snapshotPaths);
17855
17459
  }
17856
17460
  function computeDiff(oldContent, newContent, filePath) {
17857
- const tmpOld = (0, import_node_path22.join)(SNAPSHOT_DIR, ".diff-old.tmp");
17858
- const tmpNew = (0, import_node_path22.join)(SNAPSHOT_DIR, ".diff-new.tmp");
17461
+ const tmpOld = (0, import_node_path21.join)(SNAPSHOT_DIR, ".diff-old.tmp");
17462
+ const tmpNew = (0, import_node_path21.join)(SNAPSHOT_DIR, ".diff-new.tmp");
17859
17463
  try {
17860
- (0, import_node_fs25.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
17861
- (0, import_node_fs25.writeFileSync)(tmpOld, oldContent);
17862
- (0, import_node_fs25.writeFileSync)(tmpNew, newContent);
17464
+ (0, import_node_fs23.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
17465
+ (0, import_node_fs23.writeFileSync)(tmpOld, oldContent);
17466
+ (0, import_node_fs23.writeFileSync)(tmpNew, newContent);
17863
17467
  const result = (0, import_node_child_process7.execSync)(
17864
17468
  `git diff --no-index --unified=10 -- "${tmpOld}" "${tmpNew}"`,
17865
17469
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
@@ -17873,32 +17477,32 @@ function computeDiff(oldContent, newContent, filePath) {
17873
17477
  return null;
17874
17478
  } finally {
17875
17479
  try {
17876
- (0, import_node_fs25.unlinkSync)(tmpOld);
17480
+ (0, import_node_fs23.unlinkSync)(tmpOld);
17877
17481
  } catch {
17878
17482
  }
17879
17483
  try {
17880
- (0, import_node_fs25.unlinkSync)(tmpNew);
17484
+ (0, import_node_fs23.unlinkSync)(tmpNew);
17881
17485
  } catch {
17882
17486
  }
17883
17487
  }
17884
17488
  }
17885
17489
  function cleanStaleSnapshots(dir, keepSet) {
17886
- if (!(0, import_node_fs25.existsSync)(dir)) return;
17490
+ if (!(0, import_node_fs23.existsSync)(dir)) return;
17887
17491
  try {
17888
- const entries = (0, import_node_fs25.readdirSync)(dir, { withFileTypes: true });
17492
+ const entries = (0, import_node_fs23.readdirSync)(dir, { withFileTypes: true });
17889
17493
  for (const entry of entries) {
17890
17494
  if (dir === SNAPSHOT_DIR && (entry.name === ".diff-old.tmp" || entry.name === ".diff-new.tmp")) continue;
17891
- const fullPath = (0, import_node_path22.join)(dir, entry.name);
17495
+ const fullPath = (0, import_node_path21.join)(dir, entry.name);
17892
17496
  if (entry.isDirectory()) {
17893
17497
  cleanStaleSnapshots(fullPath, keepSet);
17894
17498
  try {
17895
- const remaining = (0, import_node_fs25.readdirSync)(fullPath);
17896
- if (remaining.length === 0) (0, import_node_fs25.rmdirSync)(fullPath);
17499
+ const remaining = (0, import_node_fs23.readdirSync)(fullPath);
17500
+ if (remaining.length === 0) (0, import_node_fs23.rmdirSync)(fullPath);
17897
17501
  } catch {
17898
17502
  }
17899
17503
  } else if (!keepSet.has(fullPath)) {
17900
17504
  try {
17901
- (0, import_node_fs25.unlinkSync)(fullPath);
17505
+ (0, import_node_fs23.unlinkSync)(fullPath);
17902
17506
  } catch {
17903
17507
  }
17904
17508
  }
@@ -17914,23 +17518,23 @@ var MIRROR_MAX_BYTES = 2 * 1024 * 1024;
17914
17518
  var DEFAULT_SESSION_KEY = "_default";
17915
17519
  function sessionKey(sessionId) {
17916
17520
  if (!sessionId) return DEFAULT_SESSION_KEY;
17917
- return (0, import_node_crypto10.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
17521
+ return (0, import_node_crypto9.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
17918
17522
  }
17919
17523
  function sessionDir(key) {
17920
- return (0, import_node_path23.join)(projectPath(BASELINE_DIR), key);
17524
+ return (0, import_node_path22.join)(projectPath(BASELINE_DIR), key);
17921
17525
  }
17922
17526
  function manifestPath(dir) {
17923
- return (0, import_node_path23.join)(dir, "manifest.json");
17527
+ return (0, import_node_path22.join)(dir, "manifest.json");
17924
17528
  }
17925
17529
  function mirrorPath(dir, repoRelPath) {
17926
- return (0, import_node_path23.join)(dir, "files", repoRelPath);
17530
+ return (0, import_node_path22.join)(dir, "files", repoRelPath);
17927
17531
  }
17928
17532
  var CARRY_FILE = `${BASELINE_DIR}/.carry`;
17929
17533
  var CARRY_WINDOW_MS = 12e4;
17930
17534
  function writeCarry(sessionId, headSha) {
17931
17535
  try {
17932
- (0, import_node_fs26.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
17933
- (0, import_node_fs26.writeFileSync)(
17536
+ (0, import_node_fs24.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
17537
+ (0, import_node_fs24.writeFileSync)(
17934
17538
  projectPath(CARRY_FILE),
17935
17539
  JSON.stringify({ from_key: sessionKey(sessionId), head_sha: headSha, ts: Date.now() })
17936
17540
  );
@@ -17940,10 +17544,10 @@ function writeCarry(sessionId, headSha) {
17940
17544
  function claimCarry(newKey) {
17941
17545
  const carryPath = projectPath(CARRY_FILE);
17942
17546
  try {
17943
- if (!(0, import_node_fs26.existsSync)(carryPath)) return null;
17944
- const carry = JSON.parse((0, import_node_fs26.readFileSync)(carryPath, "utf-8"));
17547
+ if (!(0, import_node_fs24.existsSync)(carryPath)) return null;
17548
+ const carry = JSON.parse((0, import_node_fs24.readFileSync)(carryPath, "utf-8"));
17945
17549
  try {
17946
- (0, import_node_fs26.rmSync)(carryPath, { force: true });
17550
+ (0, import_node_fs24.rmSync)(carryPath, { force: true });
17947
17551
  } catch {
17948
17552
  }
17949
17553
  if (!carry?.from_key || typeof carry.ts !== "number") return null;
@@ -17954,11 +17558,11 @@ function claimCarry(newKey) {
17954
17558
  if (!prior) return null;
17955
17559
  const toDir = sessionDir(newKey);
17956
17560
  try {
17957
- (0, import_node_fs26.rmSync)(toDir, { recursive: true, force: true });
17561
+ (0, import_node_fs24.rmSync)(toDir, { recursive: true, force: true });
17958
17562
  } catch {
17959
17563
  }
17960
- (0, import_node_fs26.renameSync)(fromDir, toDir);
17961
- (0, import_node_fs26.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
17564
+ (0, import_node_fs24.renameSync)(fromDir, toDir);
17565
+ (0, import_node_fs24.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
17962
17566
  return readManifest(toDir);
17963
17567
  } catch {
17964
17568
  return null;
@@ -17982,21 +17586,21 @@ function captureBaseline(opts = {}) {
17982
17586
  const head_sha = getCurrentCommit();
17983
17587
  const dirty = getDirtyFiles();
17984
17588
  try {
17985
- (0, import_node_fs26.rmSync)(dir, { recursive: true, force: true });
17589
+ (0, import_node_fs24.rmSync)(dir, { recursive: true, force: true });
17986
17590
  } catch {
17987
17591
  }
17988
- const filesDir = (0, import_node_path23.join)(dir, "files");
17592
+ const filesDir = (0, import_node_path22.join)(dir, "files");
17989
17593
  const mirrored = [];
17990
17594
  try {
17991
- (0, import_node_fs26.mkdirSync)(filesDir, { recursive: true });
17595
+ (0, import_node_fs24.mkdirSync)(filesDir, { recursive: true });
17992
17596
  for (const p of dirty) {
17993
17597
  if (p.includes("..")) continue;
17994
17598
  const content = safeReadForMirror(projectPath(p));
17995
17599
  if (content === null) continue;
17996
17600
  const dest = mirrorPath(dir, p);
17997
17601
  try {
17998
- (0, import_node_fs26.mkdirSync)((0, import_node_path23.dirname)(dest), { recursive: true });
17999
- (0, import_node_fs26.writeFileSync)(dest, content);
17602
+ (0, import_node_fs24.mkdirSync)((0, import_node_path22.dirname)(dest), { recursive: true });
17603
+ (0, import_node_fs24.writeFileSync)(dest, content);
18000
17604
  mirrored.push(p);
18001
17605
  } catch {
18002
17606
  }
@@ -18011,8 +17615,8 @@ function captureBaseline(opts = {}) {
18011
17615
  version: BASELINE_VERSION
18012
17616
  };
18013
17617
  try {
18014
- (0, import_node_fs26.mkdirSync)(dir, { recursive: true });
18015
- (0, import_node_fs26.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
17618
+ (0, import_node_fs24.mkdirSync)(dir, { recursive: true });
17619
+ (0, import_node_fs24.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
18016
17620
  } catch {
18017
17621
  }
18018
17622
  pruneOldBaselines();
@@ -18023,9 +17627,9 @@ function readBaseline(sessionId) {
18023
17627
  }
18024
17628
  function readManifest(dir) {
18025
17629
  const mp = manifestPath(dir);
18026
- if (!(0, import_node_fs26.existsSync)(mp)) return null;
17630
+ if (!(0, import_node_fs24.existsSync)(mp)) return null;
18027
17631
  try {
18028
- const parsed = JSON.parse((0, import_node_fs26.readFileSync)(mp, "utf-8"));
17632
+ const parsed = JSON.parse((0, import_node_fs24.readFileSync)(mp, "utf-8"));
18029
17633
  if (typeof parsed.head_sha !== "string" || typeof parsed.captured_at !== "number" || !Array.isArray(parsed.dirty_paths) || parsed.version !== BASELINE_VERSION) {
18030
17634
  return null;
18031
17635
  }
@@ -18056,9 +17660,9 @@ function preImage(repoRelPath, baseline) {
18056
17660
  function resolvePreImage(repoRelPath, baseline) {
18057
17661
  if (baseline.dirty_paths.includes(repoRelPath)) {
18058
17662
  const mp = mirrorPath(sessionDir(sessionKey(baseline.session_id)), repoRelPath);
18059
- if ((0, import_node_fs26.existsSync)(mp)) {
17663
+ if ((0, import_node_fs24.existsSync)(mp)) {
18060
17664
  try {
18061
- return { content: (0, import_node_fs26.readFileSync)(mp, "utf-8"), existed: true };
17665
+ return { content: (0, import_node_fs24.readFileSync)(mp, "utf-8"), existed: true };
18062
17666
  } catch {
18063
17667
  }
18064
17668
  }
@@ -18103,8 +17707,8 @@ function absorbIntoBaseline(paths, sessionId) {
18103
17707
  const content = safeReadForMirror(projectPath(p));
18104
17708
  if (content === null) continue;
18105
17709
  const dest = mirrorPath(dir, p);
18106
- (0, import_node_fs26.mkdirSync)((0, import_node_path23.dirname)(dest), { recursive: true });
18107
- (0, import_node_fs26.writeFileSync)(dest, content);
17710
+ (0, import_node_fs24.mkdirSync)((0, import_node_path22.dirname)(dest), { recursive: true });
17711
+ (0, import_node_fs24.writeFileSync)(dest, content);
18108
17712
  dirty.add(p);
18109
17713
  adopted++;
18110
17714
  } catch {
@@ -18113,7 +17717,7 @@ function absorbIntoBaseline(paths, sessionId) {
18113
17717
  if (adopted === 0) return 0;
18114
17718
  try {
18115
17719
  const updated = { ...baseline, dirty_paths: [...dirty] };
18116
- (0, import_node_fs26.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
17720
+ (0, import_node_fs24.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
18117
17721
  preImageCache.delete(baseline);
18118
17722
  } catch {
18119
17723
  return 0;
@@ -18124,7 +17728,7 @@ function changedSinceBaseline(repoRelPath, baseline) {
18124
17728
  const pre = preImage(repoRelPath, baseline);
18125
17729
  let current;
18126
17730
  try {
18127
- current = (0, import_node_fs26.readFileSync)(projectPath(repoRelPath), "utf-8");
17731
+ current = (0, import_node_fs24.readFileSync)(projectPath(repoRelPath), "utf-8");
18128
17732
  } catch {
18129
17733
  return pre.existed;
18130
17734
  }
@@ -18133,8 +17737,8 @@ function changedSinceBaseline(repoRelPath, baseline) {
18133
17737
  }
18134
17738
  function safeReadForMirror(absPath) {
18135
17739
  try {
18136
- if ((0, import_node_fs26.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
18137
- const buf = (0, import_node_fs26.readFileSync)(absPath);
17740
+ if ((0, import_node_fs24.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
17741
+ const buf = (0, import_node_fs24.readFileSync)(absPath);
18138
17742
  if (buf.includes(0)) return null;
18139
17743
  return buf.toString("utf-8");
18140
17744
  } catch {
@@ -18145,18 +17749,18 @@ function pruneOldBaselines() {
18145
17749
  const root = projectPath(BASELINE_DIR);
18146
17750
  let entries;
18147
17751
  try {
18148
- entries = (0, import_node_fs26.readdirSync)(root);
17752
+ entries = (0, import_node_fs24.readdirSync)(root);
18149
17753
  } catch {
18150
17754
  return;
18151
17755
  }
18152
17756
  const now = Date.now();
18153
17757
  for (const name of entries) {
18154
- const dir = (0, import_node_path23.join)(root, name);
17758
+ const dir = (0, import_node_path22.join)(root, name);
18155
17759
  const manifest = readManifest(dir);
18156
17760
  if (!manifest) {
18157
17761
  try {
18158
- if (now - (0, import_node_fs26.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
18159
- (0, import_node_fs26.rmSync)(dir, { recursive: true, force: true });
17762
+ if (now - (0, import_node_fs24.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
17763
+ (0, import_node_fs24.rmSync)(dir, { recursive: true, force: true });
18160
17764
  }
18161
17765
  } catch {
18162
17766
  }
@@ -18164,7 +17768,7 @@ function pruneOldBaselines() {
18164
17768
  }
18165
17769
  if (now - manifest.captured_at <= BASELINE_TTL_MS) continue;
18166
17770
  try {
18167
- (0, import_node_fs26.rmSync)(dir, { recursive: true, force: true });
17771
+ (0, import_node_fs24.rmSync)(dir, { recursive: true, force: true });
18168
17772
  } catch {
18169
17773
  }
18170
17774
  }
@@ -18339,8 +17943,8 @@ function buildCompactionContext(session) {
18339
17943
  commitsSince: commitsSincePaths(watermark, (state.authored ?? []).map((a) => a.path)),
18340
17944
  readFileLines: (file) => {
18341
17945
  try {
18342
- const abs = (0, import_node_path24.join)(root, file);
18343
- return (0, import_node_fs27.existsSync)(abs) ? (0, import_node_fs27.readFileSync)(abs, "utf8").split("\n") : null;
17946
+ const abs = (0, import_node_path23.join)(root, file);
17947
+ return (0, import_node_fs25.existsSync)(abs) ? (0, import_node_fs25.readFileSync)(abs, "utf8").split("\n") : null;
18344
17948
  } catch {
18345
17949
  return null;
18346
17950
  }
@@ -18397,24 +18001,24 @@ async function readHookStdin() {
18397
18001
 
18398
18002
  // src/commands/standard.ts
18399
18003
  var import_promises13 = require("node:fs/promises");
18400
- var import_node_fs34 = require("node:fs");
18004
+ var import_node_fs32 = require("node:fs");
18401
18005
  var import_yaml3 = __toESM(require_dist());
18402
18006
 
18403
18007
  // src/lib/synthesize.ts
18404
18008
  var import_node_child_process9 = require("node:child_process");
18405
- var import_node_fs30 = require("node:fs");
18009
+ var import_node_fs28 = require("node:fs");
18406
18010
  var import_promises10 = require("node:fs/promises");
18407
- var import_node_path27 = require("node:path");
18011
+ var import_node_path26 = require("node:path");
18408
18012
  var import_yaml = __toESM(require_dist());
18409
18013
 
18410
18014
  // src/lib/data-dir.ts
18411
- var import_node_fs28 = require("node:fs");
18412
- var import_node_path25 = require("node:path");
18015
+ var import_node_fs26 = require("node:fs");
18016
+ var import_node_path24 = require("node:path");
18413
18017
  function resolveDataDir() {
18414
18018
  const candidates2 = [
18415
- (0, import_node_path25.join)(__dirname, "..", "data"),
18019
+ (0, import_node_path24.join)(__dirname, "..", "data"),
18416
18020
  // installed: node_modules/@codacy/verity-cli/data
18417
- (0, import_node_path25.join)(__dirname, "..", "..", "data"),
18021
+ (0, import_node_path24.join)(__dirname, "..", "..", "data"),
18418
18022
  // edge case: nested resolution
18419
18023
  // THE COMMITTED SOURCE, for a source checkout that has not been built.
18420
18024
  // cli/data/skills/ is a BUILD ARTIFACT (scripts/build.js copies client/skills
@@ -18423,14 +18027,14 @@ function resolveDataDir() {
18423
18027
  // without this the synthesizer throws "Could not find Verity skill data"
18424
18028
  // for every test and every `verity` run from source. Resolved from this
18425
18029
  // module's own location, never the cwd: see the warning below.
18426
- (0, import_node_path25.join)(__dirname, "..", "..", "client"),
18030
+ (0, import_node_path24.join)(__dirname, "..", "..", "client"),
18427
18031
  // bundled: cli/bin/ → ../../client
18428
- (0, import_node_path25.join)(__dirname, "..", "..", "..", "client"),
18032
+ (0, import_node_path24.join)(__dirname, "..", "..", "..", "client"),
18429
18033
  // tsx: cli/src/lib/ → ../../../client
18430
18034
  ...process.env.VERITY_DEV_DATA_DIR ? [process.env.VERITY_DEV_DATA_DIR] : []
18431
18035
  ];
18432
18036
  for (const candidate of candidates2) {
18433
- if ((0, import_node_fs28.existsSync)((0, import_node_path25.join)(candidate, "skills"))) {
18037
+ if ((0, import_node_fs26.existsSync)((0, import_node_path24.join)(candidate, "skills"))) {
18434
18038
  return candidate;
18435
18039
  }
18436
18040
  }
@@ -18439,13 +18043,13 @@ function resolveDataDir() {
18439
18043
  );
18440
18044
  }
18441
18045
  function setupDataPath(file) {
18442
- return (0, import_node_path25.join)(resolveDataDir(), "skills", "verity-setup", file);
18046
+ return (0, import_node_path24.join)(resolveDataDir(), "skills", "verity-setup", file);
18443
18047
  }
18444
18048
 
18445
18049
  // src/lib/detect.ts
18446
18050
  var import_node_child_process8 = require("node:child_process");
18447
- var import_node_fs29 = require("node:fs");
18448
- var import_node_path26 = require("node:path");
18051
+ var import_node_fs27 = require("node:fs");
18052
+ var import_node_path25 = require("node:path");
18449
18053
  var TOOLED_LANGUAGES = /* @__PURE__ */ new Set([
18450
18054
  "typescript",
18451
18055
  "javascript",
@@ -18502,25 +18106,25 @@ function walk(root) {
18502
18106
  if (depth > WALK_MAX_DEPTH || found.length >= WALK_MAX_FILES) return;
18503
18107
  let entries;
18504
18108
  try {
18505
- entries = (0, import_node_fs29.readdirSync)(dir, { withFileTypes: true });
18109
+ entries = (0, import_node_fs27.readdirSync)(dir, { withFileTypes: true });
18506
18110
  } catch {
18507
18111
  return;
18508
18112
  }
18509
18113
  for (const entry of entries) {
18510
18114
  if (found.length >= WALK_MAX_FILES) return;
18511
18115
  if (IGNORED_SEGMENTS.includes(entry.name)) continue;
18512
- const full = (0, import_node_path26.join)(dir, entry.name);
18116
+ const full = (0, import_node_path25.join)(dir, entry.name);
18513
18117
  if (entry.isDirectory()) visit(full, depth + 1);
18514
- else if (entry.isFile()) found.push((0, import_node_path26.relative)(root, full));
18118
+ else if (entry.isFile()) found.push((0, import_node_path25.relative)(root, full));
18515
18119
  }
18516
18120
  };
18517
18121
  visit(root, 0);
18518
18122
  return found;
18519
18123
  }
18520
18124
  function languageOf(path) {
18521
- const name = (0, import_node_path26.basename)(path);
18125
+ const name = (0, import_node_path25.basename)(path);
18522
18126
  if (/^Dockerfile(\..+)?$/i.test(name)) return "dockerfile";
18523
- if (!(0, import_node_path26.extname)(name)) return null;
18127
+ if (!(0, import_node_path25.extname)(name)) return null;
18524
18128
  const lang = detectLanguage(path);
18525
18129
  return lang || null;
18526
18130
  }
@@ -18577,7 +18181,7 @@ var TOOL_CONFIG_MARKERS = [
18577
18181
  ];
18578
18182
  function readJson2(path) {
18579
18183
  try {
18580
- return JSON.parse((0, import_node_fs29.readFileSync)(path, "utf-8"));
18184
+ return JSON.parse((0, import_node_fs27.readFileSync)(path, "utf-8"));
18581
18185
  } catch {
18582
18186
  return null;
18583
18187
  }
@@ -18602,17 +18206,17 @@ function declaredDependencies(root, files) {
18602
18206
  if (deps && typeof deps === "object") names2.push(...Object.keys(deps));
18603
18207
  }
18604
18208
  };
18605
- readPackageJson((0, import_node_path26.join)(root, "package.json"));
18606
- const nested = files.filter((f) => f.includes("/") && (0, import_node_path26.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
18607
- for (const rel of nested) readPackageJson((0, import_node_path26.join)(root, rel));
18209
+ readPackageJson((0, import_node_path25.join)(root, "package.json"));
18210
+ const nested = files.filter((f) => f.includes("/") && (0, import_node_path25.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
18211
+ for (const rel of nested) readPackageJson((0, import_node_path25.join)(root, rel));
18608
18212
  const pythonManifests = [
18609
- ...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path26.join)(root, f)),
18610
- ...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path26.join)(root, f))
18213
+ ...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path25.join)(root, f)),
18214
+ ...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path25.join)(root, f))
18611
18215
  ];
18612
18216
  for (const path of pythonManifests) {
18613
- if (!(0, import_node_fs29.existsSync)(path)) continue;
18217
+ if (!(0, import_node_fs27.existsSync)(path)) continue;
18614
18218
  try {
18615
- const text = (0, import_node_fs29.readFileSync)(path, "utf-8");
18219
+ const text = (0, import_node_fs27.readFileSync)(path, "utf-8");
18616
18220
  for (const m of text.matchAll(/^\s*["']?([A-Za-z][A-Za-z0-9._-]+)/gm)) names2.push(m[1]);
18617
18221
  for (const line of text.split("\n")) {
18618
18222
  if (!/dependencies\s*=/.test(line)) continue;
@@ -18622,13 +18226,13 @@ function declaredDependencies(root, files) {
18622
18226
  }
18623
18227
  }
18624
18228
  const goMods = [
18625
- (0, import_node_path26.join)(root, "go.mod"),
18626
- ...files.filter((f) => f.includes("/") && (0, import_node_path26.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path26.join)(root, f))
18229
+ (0, import_node_path25.join)(root, "go.mod"),
18230
+ ...files.filter((f) => f.includes("/") && (0, import_node_path25.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path25.join)(root, f))
18627
18231
  ];
18628
18232
  for (const path of goMods) {
18629
- if (!(0, import_node_fs29.existsSync)(path)) continue;
18233
+ if (!(0, import_node_fs27.existsSync)(path)) continue;
18630
18234
  try {
18631
- const text = (0, import_node_fs29.readFileSync)(path, "utf-8");
18235
+ const text = (0, import_node_fs27.readFileSync)(path, "utf-8");
18632
18236
  for (const m of text.matchAll(/^\s+([\w.-]+\/[\w./-]+)\s+v/gm)) {
18633
18237
  names2.push(m[1].replace(/^github\.com\//, ""));
18634
18238
  }
@@ -18636,10 +18240,10 @@ function declaredDependencies(root, files) {
18636
18240
  }
18637
18241
  }
18638
18242
  for (const file of ["pom.xml", "build.gradle", "build.gradle.kts", "Gemfile", "Cargo.toml"]) {
18639
- const path = (0, import_node_path26.join)(root, file);
18640
- if (!(0, import_node_fs29.existsSync)(path)) continue;
18243
+ const path = (0, import_node_path25.join)(root, file);
18244
+ if (!(0, import_node_fs27.existsSync)(path)) continue;
18641
18245
  try {
18642
- const text = (0, import_node_fs29.readFileSync)(path, "utf-8");
18246
+ const text = (0, import_node_fs27.readFileSync)(path, "utf-8");
18643
18247
  for (const m of text.matchAll(/["'<]([A-Za-z][A-Za-z0-9._-]{2,})["'>]/g)) names2.push(m[1]);
18644
18248
  } catch {
18645
18249
  }
@@ -18647,7 +18251,7 @@ function declaredDependencies(root, files) {
18647
18251
  return names2;
18648
18252
  }
18649
18253
  function detectBuildSystem(root, files) {
18650
- const has = (f) => (0, import_node_fs29.existsSync)((0, import_node_path26.join)(root, f)) || files.some((p) => (0, import_node_path26.basename)(p) === f);
18254
+ const has = (f) => (0, import_node_fs27.existsSync)((0, import_node_path25.join)(root, f)) || files.some((p) => (0, import_node_path25.basename)(p) === f);
18651
18255
  if (has("pnpm-lock.yaml")) return "pnpm";
18652
18256
  if (has("yarn.lock")) return "yarn";
18653
18257
  if (has("bun.lock") || has("bun.lockb")) return "bun";
@@ -18664,8 +18268,8 @@ function detectBuildSystem(root, files) {
18664
18268
  }
18665
18269
  function detectArchitecture(root, files) {
18666
18270
  const workspaceMarkers = ["lerna.json", "pnpm-workspace.yaml", "nx.json", "turbo.json", "rush.json"];
18667
- if (workspaceMarkers.some((m) => (0, import_node_fs29.existsSync)((0, import_node_path26.join)(root, m)))) return "monorepo";
18668
- const pkg = readJson2((0, import_node_path26.join)(root, "package.json"));
18271
+ if (workspaceMarkers.some((m) => (0, import_node_fs27.existsSync)((0, import_node_path25.join)(root, m)))) return "monorepo";
18272
+ const pkg = readJson2((0, import_node_path25.join)(root, "package.json"));
18669
18273
  if (pkg && "workspaces" in pkg) return "monorepo";
18670
18274
  const manifests = files.filter((f) => /(^|\/)(package\.json|go\.mod|pyproject\.toml|Cargo\.toml|pom\.xml)$/.test(f));
18671
18275
  const nested = manifests.filter((f) => f.includes("/"));
@@ -18687,10 +18291,10 @@ function measureAvgFileLength(root, files, languages) {
18687
18291
  let total = 0;
18688
18292
  let counted = 0;
18689
18293
  for (let i = 0; i < candidates2.length; i += stride) {
18690
- const path = (0, import_node_path26.join)(root, candidates2[i]);
18294
+ const path = (0, import_node_path25.join)(root, candidates2[i]);
18691
18295
  try {
18692
- if ((0, import_node_fs29.statSync)(path).size > 2 * 1024 * 1024) continue;
18693
- total += (0, import_node_fs29.readFileSync)(path, "utf-8").split("\n").length;
18296
+ if ((0, import_node_fs27.statSync)(path).size > 2 * 1024 * 1024) continue;
18297
+ total += (0, import_node_fs27.readFileSync)(path, "utf-8").split("\n").length;
18694
18298
  counted++;
18695
18299
  } catch {
18696
18300
  }
@@ -18720,14 +18324,14 @@ function detectProject(root = repoRoot()) {
18720
18324
  const existingToolConfigs = [];
18721
18325
  for (const [tool, markers] of TOOL_CONFIG_MARKERS) {
18722
18326
  for (const marker of markers) {
18723
- if ((0, import_node_fs29.existsSync)((0, import_node_path26.join)(root, marker))) {
18327
+ if ((0, import_node_fs27.existsSync)((0, import_node_path25.join)(root, marker))) {
18724
18328
  existingToolConfigs.push({ tool, path: `./${marker}` });
18725
18329
  break;
18726
18330
  }
18727
18331
  }
18728
18332
  }
18729
18333
  return {
18730
- projectName: (0, import_node_path26.basename)(root),
18334
+ projectName: (0, import_node_path25.basename)(root),
18731
18335
  languages,
18732
18336
  languageCounts,
18733
18337
  frameworks: matchAll(dependencies, FRAMEWORK_BY_DEPENDENCY),
@@ -18825,8 +18429,8 @@ ${closingNote(input.origin)}
18825
18429
 
18826
18430
  // src/lib/synthesize.ts
18827
18431
  function loadCatalog() {
18828
- const catalog = (0, import_yaml.parse)((0, import_node_fs30.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
18829
- const template = (0, import_yaml.parse)((0, import_node_fs30.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
18432
+ const catalog = (0, import_yaml.parse)((0, import_node_fs28.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
18433
+ const template = (0, import_yaml.parse)((0, import_node_fs28.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
18830
18434
  return { catalog, template };
18831
18435
  }
18832
18436
  function selectTools(languages, intensity, catalog) {
@@ -19104,7 +18708,7 @@ function validatePatternIds() {
19104
18708
  }
19105
18709
  async function runSynthesis(opts) {
19106
18710
  const standardPath = projectPath(STANDARD_FILE);
19107
- if ((0, import_node_fs30.existsSync)(standardPath) && !opts.force) {
18711
+ if ((0, import_node_fs28.existsSync)(standardPath) && !opts.force) {
19108
18712
  return { refused: `${STANDARD_FILE} already exists \u2014 pass --force to replace it.` };
19109
18713
  }
19110
18714
  const detected = opts.detected ?? detectProject();
@@ -19173,7 +18777,7 @@ async function correctVerityMdVersion(opts) {
19173
18777
  }
19174
18778
  async function writeFileTo(relative3, body) {
19175
18779
  const target = projectPath(relative3);
19176
- await (0, import_promises10.mkdir)((0, import_node_path27.dirname)(target), { recursive: true });
18780
+ await (0, import_promises10.mkdir)((0, import_node_path26.dirname)(target), { recursive: true });
19177
18781
  await (0, import_promises10.writeFile)(target, body);
19178
18782
  }
19179
18783
  async function deriveConfigForStandard(standard) {
@@ -19232,11 +18836,11 @@ ${validation.detail}`);
19232
18836
 
19233
18837
  // src/lib/setup-state.ts
19234
18838
  var import_promises11 = require("node:fs/promises");
19235
- var import_node_fs31 = require("node:fs");
18839
+ var import_node_fs29 = require("node:fs");
19236
18840
  var SETUP_STATE_FILE = `${VERITY_DIR}/setup.json`;
19237
18841
  async function readSetupState() {
19238
18842
  const path = projectPath(SETUP_STATE_FILE);
19239
- if (!(0, import_node_fs31.existsSync)(path)) return null;
18843
+ if (!(0, import_node_fs29.existsSync)(path)) return null;
19240
18844
  try {
19241
18845
  const parsed = JSON.parse(await (0, import_promises11.readFile)(path, "utf-8"));
19242
18846
  return parsed && typeof parsed === "object" ? parsed : null;
@@ -19252,12 +18856,12 @@ async function writeSetupState(patch) {
19252
18856
  }
19253
18857
 
19254
18858
  // src/lib/push-setup.ts
19255
- var import_node_fs33 = require("node:fs");
18859
+ var import_node_fs31 = require("node:fs");
19256
18860
  var import_promises12 = require("node:fs/promises");
19257
18861
  var import_yaml2 = __toESM(require_dist());
19258
18862
 
19259
18863
  // src/lib/verityignore.ts
19260
- var import_node_fs32 = require("node:fs");
18864
+ var import_node_fs30 = require("node:fs");
19261
18865
  var EMPTY = { rules: [], securityOverlap: [], problems: [] };
19262
18866
  var SECURITY_PROBES = [
19263
18867
  ".env",
@@ -19350,9 +18954,9 @@ function isIgnored3(ig, path) {
19350
18954
  }
19351
18955
  function loadVerityIgnore() {
19352
18956
  const file = projectPath(VERITYIGNORE_FILE);
19353
- if (!(0, import_node_fs32.existsSync)(file)) return EMPTY;
18957
+ if (!(0, import_node_fs30.existsSync)(file)) return EMPTY;
19354
18958
  try {
19355
- return parseVerityIgnore((0, import_node_fs32.readFileSync)(file, "utf-8"));
18959
+ return parseVerityIgnore((0, import_node_fs30.readFileSync)(file, "utf-8"));
19356
18960
  } catch {
19357
18961
  return EMPTY;
19358
18962
  }
@@ -19390,9 +18994,9 @@ function buildStandardUpload(standard, ignoreRaw) {
19390
18994
  }
19391
18995
  function readVerityIgnoreRaw() {
19392
18996
  const file = projectPath(VERITYIGNORE_FILE);
19393
- if (!(0, import_node_fs32.existsSync)(file)) return null;
18997
+ if (!(0, import_node_fs30.existsSync)(file)) return null;
19394
18998
  try {
19395
- return (0, import_node_fs32.readFileSync)(file, "utf-8");
18999
+ return (0, import_node_fs30.readFileSync)(file, "utf-8");
19396
19000
  } catch {
19397
19001
  return null;
19398
19002
  }
@@ -19420,7 +19024,7 @@ async function pushStandardAndConfig(globals, what = {}) {
19420
19024
  }
19421
19025
  let standardVersion = null;
19422
19026
  const standardPath = projectPath(STANDARD_FILE);
19423
- if (pushStandard && (0, import_node_fs33.existsSync)(standardPath)) {
19027
+ if (pushStandard && (0, import_node_fs31.existsSync)(standardPath)) {
19424
19028
  try {
19425
19029
  const content = (0, import_yaml2.parse)(await (0, import_promises12.readFile)(standardPath, "utf-8"));
19426
19030
  const upload = buildStandardUpload(content, readVerityIgnoreRaw());
@@ -19445,7 +19049,7 @@ async function pushStandardAndConfig(globals, what = {}) {
19445
19049
  }
19446
19050
  let configPushed = false;
19447
19051
  const configPath = projectPath(CODACY_CONFIG_FILE);
19448
- if (pushConfig && (0, import_node_fs33.existsSync)(configPath)) {
19052
+ if (pushConfig && (0, import_node_fs31.existsSync)(configPath)) {
19449
19053
  try {
19450
19054
  const content = JSON.parse(await (0, import_promises12.readFile)(configPath, "utf-8"));
19451
19055
  const result = await apiRequest({
@@ -19477,7 +19081,7 @@ function registerStandardCommands(program2) {
19477
19081
  const state = await readSetupState();
19478
19082
  if (opts.configOnly) {
19479
19083
  const standardPath = projectPath(STANDARD_FILE);
19480
- if (!(0, import_node_fs34.existsSync)(standardPath)) {
19084
+ if (!(0, import_node_fs32.existsSync)(standardPath)) {
19481
19085
  printError(`No ${STANDARD_FILE} here \u2014 run "verity standard synthesize" to create one.`);
19482
19086
  process.exit(1);
19483
19087
  }
@@ -19810,20 +19414,20 @@ function formatRunDetail(run2) {
19810
19414
  }
19811
19415
 
19812
19416
  // src/lib/ignore-declaration.ts
19813
- var import_node_fs36 = require("node:fs");
19417
+ var import_node_fs34 = require("node:fs");
19814
19418
 
19815
19419
  // src/lib/debounce.ts
19816
- var import_node_fs35 = require("node:fs");
19817
- var import_node_crypto11 = require("node:crypto");
19420
+ var import_node_fs33 = require("node:fs");
19421
+ var import_node_crypto10 = require("node:crypto");
19818
19422
  function scopedFile(base, sessionId) {
19819
19423
  if (!sessionId) return base;
19820
- return `${base}.${(0, import_node_crypto11.createHash)("sha1").update(sessionId).digest("hex").slice(0, 12)}`;
19424
+ return `${base}.${(0, import_node_crypto10.createHash)("sha1").update(sessionId).digest("hex").slice(0, 12)}`;
19821
19425
  }
19822
19426
  function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
19823
19427
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
19824
- if (!(0, import_node_fs35.existsSync)(file)) return null;
19428
+ if (!(0, import_node_fs33.existsSync)(file)) return null;
19825
19429
  try {
19826
- const lastTs = parseInt((0, import_node_fs35.readFileSync)(file, "utf-8").trim(), 10);
19430
+ const lastTs = parseInt((0, import_node_fs33.readFileSync)(file, "utf-8").trim(), 10);
19827
19431
  const nowTs = Math.floor(Date.now() / 1e3);
19828
19432
  const elapsed = nowTs - lastTs;
19829
19433
  if (elapsed < debounceSeconds) {
@@ -19836,10 +19440,10 @@ function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
19836
19440
  function checkMtime(files, bypassForRecentCommits, sessionId) {
19837
19441
  if (bypassForRecentCommits) return null;
19838
19442
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
19839
- if (!(0, import_node_fs35.existsSync)(file)) return null;
19443
+ if (!(0, import_node_fs33.existsSync)(file)) return null;
19840
19444
  let debounceTime;
19841
19445
  try {
19842
- debounceTime = (0, import_node_fs35.statSync)(file).mtimeMs;
19446
+ debounceTime = (0, import_node_fs33.statSync)(file).mtimeMs;
19843
19447
  } catch {
19844
19448
  return null;
19845
19449
  }
@@ -19847,7 +19451,7 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
19847
19451
  const resolved = resolveFile(f);
19848
19452
  if (!resolved) continue;
19849
19453
  try {
19850
- const stat3 = (0, import_node_fs35.statSync)(resolved);
19454
+ const stat3 = (0, import_node_fs33.statSync)(resolved);
19851
19455
  if (stat3.mtimeMs > debounceTime) {
19852
19456
  return null;
19853
19457
  }
@@ -19858,13 +19462,13 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
19858
19462
  return "No files modified since last analysis";
19859
19463
  }
19860
19464
  function computeContentHash(files) {
19861
- const hash = (0, import_node_crypto11.createHash)("sha1");
19465
+ const hash = (0, import_node_crypto10.createHash)("sha1");
19862
19466
  const sorted = [...files].sort();
19863
19467
  for (const f of sorted) {
19864
19468
  const resolved = resolveFile(f) ?? f;
19865
19469
  try {
19866
- if ((0, import_node_fs35.existsSync)(resolved)) {
19867
- hash.update((0, import_node_fs35.readFileSync)(resolved));
19470
+ if ((0, import_node_fs33.existsSync)(resolved)) {
19471
+ hash.update((0, import_node_fs33.readFileSync)(resolved));
19868
19472
  }
19869
19473
  } catch {
19870
19474
  }
@@ -19874,9 +19478,9 @@ function computeContentHash(files) {
19874
19478
  function checkContentHash(files, sessionId) {
19875
19479
  const hash = computeContentHash(files);
19876
19480
  const file = scopedFile(HASH_FILE, sessionId);
19877
- if ((0, import_node_fs35.existsSync)(file)) {
19481
+ if ((0, import_node_fs33.existsSync)(file)) {
19878
19482
  try {
19879
- const storedHash = (0, import_node_fs35.readFileSync)(file, "utf-8").trim();
19483
+ const storedHash = (0, import_node_fs33.readFileSync)(file, "utf-8").trim();
19880
19484
  if (hash === storedHash) {
19881
19485
  return { skip: "No source changes since last analysis", hash };
19882
19486
  }
@@ -19886,24 +19490,24 @@ function checkContentHash(files, sessionId) {
19886
19490
  return { skip: null, hash };
19887
19491
  }
19888
19492
  function recordAnalysisStart(sessionId) {
19889
- (0, import_node_fs35.mkdirSync)(VERITY_DIR, { recursive: true });
19890
- (0, import_node_fs35.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
19493
+ (0, import_node_fs33.mkdirSync)(VERITY_DIR, { recursive: true });
19494
+ (0, import_node_fs33.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
19891
19495
  }
19892
19496
  function recordPassHash(hash, sessionId) {
19893
- (0, import_node_fs35.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
19497
+ (0, import_node_fs33.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
19894
19498
  }
19895
19499
  function narrowToRecent(files, sessionId) {
19896
19500
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
19897
- if (!(0, import_node_fs35.existsSync)(file)) return files;
19501
+ if (!(0, import_node_fs33.existsSync)(file)) return files;
19898
19502
  let debounceTime;
19899
19503
  try {
19900
- debounceTime = (0, import_node_fs35.statSync)(file).mtimeMs;
19504
+ debounceTime = (0, import_node_fs33.statSync)(file).mtimeMs;
19901
19505
  } catch {
19902
19506
  return files;
19903
19507
  }
19904
19508
  const recent = files.filter((f) => {
19905
19509
  try {
19906
- return (0, import_node_fs35.existsSync)(f) && (0, import_node_fs35.statSync)(f).mtimeMs > debounceTime;
19510
+ return (0, import_node_fs33.existsSync)(f) && (0, import_node_fs33.statSync)(f).mtimeMs > debounceTime;
19907
19511
  } catch {
19908
19512
  return false;
19909
19513
  }
@@ -19916,9 +19520,9 @@ function readIteration(currentCommit, _contentHash) {
19916
19520
  var NO_BLOCKS = { attempts: 0, blocks: 0, fingerprint: null };
19917
19521
  function readBlockState(currentCommit, opts) {
19918
19522
  if (opts?.newUserPrompt) return NO_BLOCKS;
19919
- if (!(0, import_node_fs35.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
19523
+ if (!(0, import_node_fs33.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
19920
19524
  try {
19921
- const stored = (0, import_node_fs35.readFileSync)(ITERATION_FILE, "utf-8").trim();
19525
+ const stored = (0, import_node_fs33.readFileSync)(ITERATION_FILE, "utf-8").trim();
19922
19526
  const parsed = stored.startsWith("{") ? parseJsonState(stored) : parseLegacyState(stored);
19923
19527
  if (!parsed) return NO_BLOCKS;
19924
19528
  if (parsed.commit !== currentCommit) return NO_BLOCKS;
@@ -19964,8 +19568,8 @@ function isSameProblem(previous, current) {
19964
19568
  return current.split(",").some((k) => prev.has(k));
19965
19569
  }
19966
19570
  function writeBlockState(commit, state) {
19967
- (0, import_node_fs35.mkdirSync)(VERITY_DIR, { recursive: true });
19968
- (0, import_node_fs35.writeFileSync)(
19571
+ (0, import_node_fs33.mkdirSync)(VERITY_DIR, { recursive: true });
19572
+ (0, import_node_fs33.writeFileSync)(
19969
19573
  ITERATION_FILE,
19970
19574
  JSON.stringify({
19971
19575
  v: 2,
@@ -20070,9 +19674,9 @@ function resolveIgnoreState(keys) {
20070
19674
  }
20071
19675
  function readIgnoreState(sessionId) {
20072
19676
  const file = stateFile(sessionId);
20073
- if (!(0, import_node_fs36.existsSync)(file)) return null;
19677
+ if (!(0, import_node_fs34.existsSync)(file)) return null;
20074
19678
  try {
20075
- const o = JSON.parse((0, import_node_fs36.readFileSync)(file, "utf-8")) ?? {};
19679
+ const o = JSON.parse((0, import_node_fs34.readFileSync)(file, "utf-8")) ?? {};
20076
19680
  const spent = typeof o.spent === "number" ? o.spent : 0;
20077
19681
  const raw = o.active;
20078
19682
  let active = null;
@@ -20096,8 +19700,8 @@ function readIgnoreState(sessionId) {
20096
19700
  }
20097
19701
  function writeIgnoreState(state, sessionId) {
20098
19702
  try {
20099
- (0, import_node_fs36.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
20100
- (0, import_node_fs36.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
19703
+ (0, import_node_fs34.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
19704
+ (0, import_node_fs34.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
20101
19705
  } catch {
20102
19706
  }
20103
19707
  }
@@ -20480,7 +20084,7 @@ function createRun(opts, globals) {
20480
20084
  }
20481
20085
 
20482
20086
  // src/commands/analyze/index.ts
20483
- var import_node_fs49 = require("node:fs");
20087
+ var import_node_fs47 = require("node:fs");
20484
20088
 
20485
20089
  // src/lib/repo-context.ts
20486
20090
  var import_node_child_process10 = require("node:child_process");
@@ -21416,10 +21020,10 @@ function installRunEvidence(run2) {
21416
21020
  }
21417
21021
 
21418
21022
  // src/lib/git-frame.ts
21419
- var import_node_fs37 = require("node:fs");
21023
+ var import_node_fs35 = require("node:fs");
21420
21024
  var import_node_os6 = require("node:os");
21025
+ var import_node_path27 = require("node:path");
21421
21026
  var import_node_path28 = require("node:path");
21422
- var import_node_path29 = require("node:path");
21423
21027
 
21424
21028
  // src/lib/hardened-git.ts
21425
21029
  var import_node_child_process11 = require("node:child_process");
@@ -21581,8 +21185,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
21581
21185
  if (SHELL_DYNAMIC.test(raw) || raw === "-") {
21582
21186
  return { dir: null, named: true, unresolvable: `cd target not statically resolvable: ${raw}` };
21583
21187
  }
21584
- const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path29.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
21585
- dir = (0, import_node_path28.isAbsolute)(expanded) ? expanded : (0, import_node_path28.resolve)(dir, expanded);
21188
+ const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path28.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
21189
+ dir = (0, import_node_path27.isAbsolute)(expanded) ? expanded : (0, import_node_path27.resolve)(dir, expanded);
21586
21190
  }
21587
21191
  const seg = segments[segmentIndex];
21588
21192
  const overrideMatch = /--(?:git-dir|work-tree)(?:=|\s)|\bGIT_(?:DIR|WORK_TREE|INDEX_FILE)=/.exec(seg);
@@ -21600,8 +21204,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
21600
21204
  if (SHELL_DYNAMIC.test(raw)) {
21601
21205
  return { dir: null, named: true, unresolvable: `-C target not statically resolvable: ${raw}` };
21602
21206
  }
21603
- const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path29.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
21604
- dir = (0, import_node_path28.isAbsolute)(expanded) ? expanded : (0, import_node_path28.resolve)(dir, expanded);
21207
+ const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path28.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
21208
+ dir = (0, import_node_path27.isAbsolute)(expanded) ? expanded : (0, import_node_path27.resolve)(dir, expanded);
21605
21209
  }
21606
21210
  }
21607
21211
  return { dir, named, unresolvable: null };
@@ -21661,14 +21265,14 @@ function gitAt(dir, args) {
21661
21265
  }
21662
21266
  function realpathOr2(p) {
21663
21267
  try {
21664
- return import_node_fs37.realpathSync.native(p);
21268
+ return import_node_fs35.realpathSync.native(p);
21665
21269
  } catch {
21666
- return (0, import_node_path28.resolve)(p);
21270
+ return (0, import_node_path27.resolve)(p);
21667
21271
  }
21668
21272
  }
21669
21273
  function resolveFrame(input) {
21670
21274
  const found = findMomentSegment(input.command, input.on);
21671
- const hookDirUsable = !!input.hookCwd && (0, import_node_fs37.existsSync)(input.hookCwd);
21275
+ const hookDirUsable = !!input.hookCwd && (0, import_node_fs35.existsSync)(input.hookCwd);
21672
21276
  const baseDir = hookDirUsable ? input.hookCwd : process.cwd();
21673
21277
  let anchor = hookDirUsable ? "hook-cwd" : "process-cwd";
21674
21278
  const refuse = (refusal) => ({
@@ -21691,7 +21295,7 @@ function resolveFrame(input) {
21691
21295
  if (dirs.size > 1) return refuse(`target:multiple ${found.moment} targets in one command`);
21692
21296
  const targetDir = dirs.size === 1 ? [...dirs][0] : baseDir;
21693
21297
  if (targetDir !== baseDir) {
21694
- if (!(0, import_node_fs37.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
21298
+ if (!(0, import_node_fs35.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
21695
21299
  dir = targetDir;
21696
21300
  }
21697
21301
  }
@@ -21702,7 +21306,7 @@ function resolveFrame(input) {
21702
21306
  const gitDirRaw = gitAt(dir, ["rev-parse", "--absolute-git-dir"]);
21703
21307
  const commonRaw = gitAt(dir, ["rev-parse", "--git-common-dir"]);
21704
21308
  const gitDir = gitDirRaw ? realpathOr2(gitDirRaw) : null;
21705
- const commonDir = commonRaw ? realpathOr2((0, import_node_path28.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path28.resolve)(dir, commonRaw)) : null;
21309
+ const commonDir = commonRaw ? realpathOr2((0, import_node_path27.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path27.resolve)(dir, commonRaw)) : null;
21706
21310
  const branchRaw = gitAt(dir, ["rev-parse", "--abbrev-ref", "HEAD"]);
21707
21311
  return {
21708
21312
  moment: found?.moment ?? null,
@@ -21877,8 +21481,8 @@ function stagedRange(frame, command) {
21877
21481
  if (plan.kind === "unpredictable") {
21878
21482
  return { kind: "staged", base: "HEAD", head: "INDEX", via: "staged-in-command", refusal: plan.reason };
21879
21483
  }
21880
- const mergeHead = frame.gitDir ? (0, import_node_path29.join)(frame.gitDir, "MERGE_HEAD") : null;
21881
- if (mergeHead && (0, import_node_fs37.existsSync)(mergeHead)) {
21484
+ const mergeHead = frame.gitDir ? (0, import_node_path28.join)(frame.gitDir, "MERGE_HEAD") : null;
21485
+ if (mergeHead && (0, import_node_fs35.existsSync)(mergeHead)) {
21882
21486
  const vsHead = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "HEAD"]).split("\n").filter(Boolean));
21883
21487
  const vsMerge = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "MERGE_HEAD"]).split("\n").filter(Boolean));
21884
21488
  const resolutions = new Set([...vsHead].filter((f) => vsMerge.has(f) && !isVerityOwnedPath(f)));
@@ -22012,7 +21616,7 @@ function truthy(v) {
22012
21616
  }
22013
21617
 
22014
21618
  // src/lib/transcript.ts
22015
- var import_node_fs38 = require("node:fs");
21619
+ var import_node_fs36 = require("node:fs");
22016
21620
  var MAX_READ_BYTES = 256 * 1024;
22017
21621
  var SMALL_FILE_BYTES = 64 * 1024;
22018
21622
  var MAX_FILES_LIST = 20;
@@ -22039,7 +21643,7 @@ async function extractActionSummary(transcriptPath) {
22039
21643
  function readTurnLines(transcriptPath) {
22040
21644
  let size;
22041
21645
  try {
22042
- size = (0, import_node_fs38.statSync)(transcriptPath).size;
21646
+ size = (0, import_node_fs36.statSync)(transcriptPath).size;
22043
21647
  } catch {
22044
21648
  return null;
22045
21649
  }
@@ -22047,7 +21651,7 @@ function readTurnLines(transcriptPath) {
22047
21651
  let raw;
22048
21652
  let windowed = false;
22049
21653
  if (size <= SMALL_FILE_BYTES) {
22050
- raw = (0, import_node_fs38.readFileSync)(transcriptPath, "utf-8");
21654
+ raw = (0, import_node_fs36.readFileSync)(transcriptPath, "utf-8");
22051
21655
  } else {
22052
21656
  windowed = true;
22053
21657
  const buf = Buffer.alloc(Math.min(MAX_READ_BYTES, size));
@@ -22438,52 +22042,6 @@ function partitionVerityOwned(paths) {
22438
22042
  return { kept, owned };
22439
22043
  }
22440
22044
 
22441
- // src/lib/knowledge-note-state.ts
22442
- var stateDir = () => projectPath(VERITY_DIR);
22443
- var STATE_FILE2 = "knowledge-note-state.json";
22444
- function parseKnowledgeNote(raw) {
22445
- if (!raw || typeof raw !== "object") return null;
22446
- const o = raw;
22447
- const node_id = typeof o.node_id === "string" ? o.node_id.trim() : "";
22448
- const text = typeof o.text === "string" ? o.text.trim() : "";
22449
- if (!node_id || !text) return null;
22450
- if (text.length > 1e3) return null;
22451
- return {
22452
- node_id,
22453
- text,
22454
- file: typeof o.file === "string" && o.file ? o.file : null,
22455
- line: typeof o.line === "number" && Number.isFinite(o.line) && o.line > 0 ? Math.floor(o.line) : null
22456
- };
22457
- }
22458
- function recordNoteOutcome(runId, delivered) {
22459
- replaceInRoot(stateDir(), STATE_FILE2, JSON.stringify({ run_id: runId, delivered }));
22460
- }
22461
- function peekNoteOutcome() {
22462
- try {
22463
- const read = readRegularFileInRoot(stateDir(), STATE_FILE2, 4096);
22464
- if (!read.ok || !read.content.trim()) return null;
22465
- const parsed = JSON.parse(read.content);
22466
- if (!parsed || typeof parsed !== "object") return null;
22467
- const o = parsed;
22468
- if (typeof o.run_id !== "string" || !/^run-\d{14}-[0-9a-f]{8}$/.test(o.run_id)) return null;
22469
- if (typeof o.delivered !== "boolean") return null;
22470
- return { run_id: o.run_id, delivered: o.delivered };
22471
- } catch {
22472
- return null;
22473
- }
22474
- }
22475
- function clearNoteOutcome() {
22476
- replaceInRoot(stateDir(), STATE_FILE2, "");
22477
- }
22478
- function episodeForWire(e, humanSpoke) {
22479
- return {
22480
- delivered: e?.delivered ?? 0,
22481
- tasks_completed: e?.tasksCompleted ?? 0,
22482
- ts: e?.ts ?? 0,
22483
- human_spoke: humanSpoke
22484
- };
22485
- }
22486
-
22487
22045
  // src/lib/channel.ts
22488
22046
  var MAX_AGENT_CONTEXT_CHARS = 1500;
22489
22047
  var MAX_AGENT_ITEMS = 5;
@@ -22505,14 +22063,7 @@ function channelInputFrom(response, intentRepeat = 0, priorPendingFingerprints =
22505
22063
  reviewStatus: metadata.review_status,
22506
22064
  coverage: metadata.coverage,
22507
22065
  intentVerdict: intent.verdict,
22508
- intentGaps: intent.gaps,
22509
- // Phase 5. Parsed defensively: a malformed or oversized note degrades to
22510
- // silence rather than to a broken agent message, and an old server simply
22511
- // sends nothing — which is indistinguishable from a server that chose to
22512
- // stay quiet, as it should be.
22513
- knowledgeNote: parseKnowledgeNote(
22514
- response.knowledge_note ?? metadata.knowledge_note
22515
- )?.text
22066
+ intentGaps: intent.gaps
22516
22067
  };
22517
22068
  }
22518
22069
  function classifyChannelContent(input) {
@@ -22520,13 +22071,7 @@ function classifyChannelContent(input) {
22520
22071
  const intentFlag = input.intentVerdict === "misaligned" || input.intentVerdict === "partial";
22521
22072
  const advisory = (input.findings ?? []).some((f) => f.scope !== "pre-existing") || (input.pendingItems ?? []).some(
22522
22073
  (p) => p.pattern_id !== "intent-misalignment" && !!(p.description ?? p.title ?? p.reason)
22523
- ) || // ⚠ A KNOWLEDGE NOTE IS ADVISORY CONTENT, and it must be classified as such
22524
- // or the invariant above breaks: `buildAgentContext` would return a message
22525
- // on a run where all three classes are false, which is exactly the drift
22526
- // this pair is written to prevent. It is advisory rather than refusal or
22527
- // intent because it costs the agent a turn — the same cost the episode
22528
- // budget exists to bound.
22529
- !!input.knowledgeNote;
22074
+ );
22530
22075
  return { refusal, intentFlag, advisory };
22531
22076
  }
22532
22077
  function buildAgentContext(input) {
@@ -22553,9 +22098,6 @@ function buildAgentContext(input) {
22553
22098
  );
22554
22099
  }
22555
22100
  }
22556
- if (input.knowledgeNote && lines.length < MAX_AGENT_ITEMS) {
22557
- lines.push(`- ${input.knowledgeNote}`);
22558
- }
22559
22101
  const agentFindings = (input.findings ?? []).filter((f) => f.scope !== "pre-existing");
22560
22102
  for (const f of agentFindings) {
22561
22103
  if (lines.length >= MAX_AGENT_ITEMS) break;
@@ -22617,7 +22159,7 @@ function channelSilence(input) {
22617
22159
  // src/lib/cli-version.ts
22618
22160
  function cliVersion() {
22619
22161
  try {
22620
- return true ? "0.33.3-experimental.7124bbc" : "dev";
22162
+ return true ? "0.33.3-experimental.d8b96f8" : "dev";
22621
22163
  } catch {
22622
22164
  return "dev";
22623
22165
  }
@@ -22658,7 +22200,7 @@ async function sendSkipBeacon(ctx, reason) {
22658
22200
 
22659
22201
  // src/lib/static-analysis.ts
22660
22202
  var import_node_child_process12 = require("node:child_process");
22661
- var import_node_fs39 = require("node:fs");
22203
+ var import_node_fs37 = require("node:fs");
22662
22204
  var SEVERITY_ORDER = {
22663
22205
  Error: 0,
22664
22206
  Critical: 0,
@@ -22714,7 +22256,7 @@ function runCodacyAnalysis(files) {
22714
22256
  if (files.length === 0) return empty;
22715
22257
  const existingFiles = files.filter((f) => {
22716
22258
  try {
22717
- return (0, import_node_fs39.existsSync)(f);
22259
+ return (0, import_node_fs37.existsSync)(f);
22718
22260
  } catch {
22719
22261
  return false;
22720
22262
  }
@@ -22983,8 +22525,8 @@ async function scope(run2) {
22983
22525
  }
22984
22526
 
22985
22527
  // src/lib/specs.ts
22986
- var import_node_fs40 = require("node:fs");
22987
- var import_node_path30 = require("node:path");
22528
+ var import_node_fs38 = require("node:fs");
22529
+ var import_node_path29 = require("node:path");
22988
22530
  var SPEC_CANDIDATES = [
22989
22531
  "CLAUDE.md",
22990
22532
  "AGENTS.md",
@@ -23006,7 +22548,7 @@ var UNCONSULTED_TOTAL_BYTES = 30720;
23006
22548
  function readSpecFiles(specsOpt, root) {
23007
22549
  const out = [];
23008
22550
  for (const raw of specsOpt.split(",").map((f) => f.trim()).filter(Boolean)) {
23009
- const candidate = (0, import_node_path30.isAbsolute)(raw) ? (0, import_node_path30.relative)(root, raw) : raw;
22551
+ const candidate = (0, import_node_path29.isAbsolute)(raw) ? (0, import_node_path29.relative)(root, raw) : raw;
23010
22552
  const content = readFileInside(root, candidate, MAX_EXPLICIT_SPEC_FILE_BYTES);
23011
22553
  if (content === null) continue;
23012
22554
  out.push({ path: raw, content });
@@ -23025,7 +22567,7 @@ function discoverSpecs(consulted = []) {
23025
22567
  const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
23026
22568
  if (totalBytes >= totalCap) return false;
23027
22569
  if (seen.has(specPath)) return true;
23028
- if (!(0, import_node_fs40.existsSync)(specPath)) return true;
22570
+ if (!(0, import_node_fs38.existsSync)(specPath)) return true;
23029
22571
  seen.add(specPath);
23030
22572
  const remaining = totalCap - totalBytes;
23031
22573
  const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
@@ -23048,7 +22590,7 @@ function discoverSpecs(consulted = []) {
23048
22590
  if (!addSpec(candidate)) break;
23049
22591
  }
23050
22592
  for (const dir of ["spec", "docs"]) {
23051
- if (!(0, import_node_fs40.existsSync)(dir)) continue;
22593
+ if (!(0, import_node_fs38.existsSync)(dir)) continue;
23052
22594
  try {
23053
22595
  const mdFiles = findMdFiles(dir, 2).sort();
23054
22596
  for (const mdFile of mdFiles) {
@@ -23063,9 +22605,9 @@ function findMdFiles(dir, maxDepth, depth = 0) {
23063
22605
  if (depth >= maxDepth) return [];
23064
22606
  const result = [];
23065
22607
  try {
23066
- const entries = (0, import_node_fs40.readdirSync)(dir, { withFileTypes: true });
22608
+ const entries = (0, import_node_fs38.readdirSync)(dir, { withFileTypes: true });
23067
22609
  for (const entry of entries) {
23068
- const fullPath = (0, import_node_path30.join)(dir, entry.name);
22610
+ const fullPath = (0, import_node_path29.join)(dir, entry.name);
23069
22611
  if (entry.isFile() && entry.name.endsWith(".md")) {
23070
22612
  result.push(fullPath);
23071
22613
  } else if (entry.isDirectory() && depth < maxDepth - 1) {
@@ -23078,25 +22620,25 @@ function findMdFiles(dir, maxDepth, depth = 0) {
23078
22620
  }
23079
22621
  function discoverPlans() {
23080
22622
  const home = process.env.HOME ?? "";
23081
- const homePlansDir = (0, import_node_path30.join)(home, ".claude", "plans");
22623
+ const homePlansDir = (0, import_node_path29.join)(home, ".claude", "plans");
23082
22624
  const sources = [];
23083
22625
  if (isRealDirectoryChain(process.cwd(), [".claude", "plans"])) {
23084
- sources.push({ root: process.cwd(), prefix: (0, import_node_path30.join)(".claude", "plans") });
22626
+ sources.push({ root: process.cwd(), prefix: (0, import_node_path29.join)(".claude", "plans") });
23085
22627
  }
23086
- if (home && (0, import_node_fs40.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
22628
+ if (home && (0, import_node_fs38.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
23087
22629
  const candidates2 = [];
23088
22630
  const seen = /* @__PURE__ */ new Set();
23089
22631
  for (const source of sources) {
23090
22632
  let names2;
23091
22633
  try {
23092
- names2 = (0, import_node_fs40.readdirSync)(source.prefix ? (0, import_node_path30.join)(source.root, source.prefix) : source.root);
22634
+ names2 = (0, import_node_fs38.readdirSync)(source.prefix ? (0, import_node_path29.join)(source.root, source.prefix) : source.root);
23093
22635
  } catch {
23094
22636
  continue;
23095
22637
  }
23096
22638
  for (const f of names2) {
23097
22639
  if (!f.endsWith(".md") || seen.has(f)) continue;
23098
22640
  seen.add(f);
23099
- const relPath = source.prefix ? (0, import_node_path30.join)(source.prefix, f) : f;
22641
+ const relPath = source.prefix ? (0, import_node_path29.join)(source.prefix, f) : f;
23100
22642
  const stat3 = statRegularInRoot(source.root, relPath);
23101
22643
  if (!stat3.ok) continue;
23102
22644
  candidates2.push({ name: f, root: source.root, relPath, mtime: stat3.mtimeMs, size: stat3.size });
@@ -23114,9 +22656,9 @@ function discoverPlans() {
23114
22656
  function isRealDirectoryChain(root, parts) {
23115
22657
  let current = root;
23116
22658
  for (const part of parts) {
23117
- current = (0, import_node_path30.join)(current, part);
22659
+ current = (0, import_node_path29.join)(current, part);
23118
22660
  try {
23119
- if (!(0, import_node_fs40.lstatSync)(current).isDirectory()) return false;
22661
+ if (!(0, import_node_fs38.lstatSync)(current).isDirectory()) return false;
23120
22662
  } catch {
23121
22663
  return false;
23122
22664
  }
@@ -23131,7 +22673,7 @@ function discoverGuardDocs(rangeFiles2) {
23131
22673
  if (result.length >= MAX_SPEC_FILES) break;
23132
22674
  if (!GUARD_DOC_EXT.test(path)) continue;
23133
22675
  if (path.startsWith("/") || path.includes("..")) continue;
23134
- if (!(0, import_node_fs40.existsSync)(path)) continue;
22676
+ if (!(0, import_node_fs38.existsSync)(path)) continue;
23135
22677
  const opened = openRegularInRoot(process.cwd(), path);
23136
22678
  if (!opened.ok) continue;
23137
22679
  if (opened.size > MAX_PLAN_FILE_BYTES || totalBytes + opened.size > MAX_TOTAL_SPEC_BYTES) {
@@ -23317,8 +22859,8 @@ async function mode(run2) {
23317
22859
  }
23318
22860
 
23319
22861
  // src/lib/fold.ts
23320
- var import_node_fs41 = require("node:fs");
23321
- var import_node_path31 = require("node:path");
22862
+ var import_node_fs39 = require("node:fs");
22863
+ var import_node_path30 = require("node:path");
23322
22864
  var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
23323
22865
  "user",
23324
22866
  "assistant",
@@ -23455,7 +22997,7 @@ function candidateRoots(repoRoot2) {
23455
22997
  const norm = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
23456
22998
  const out = [norm];
23457
22999
  try {
23458
- const real = import_node_fs41.realpathSync.native(norm).replace(/\\/g, "/").replace(/\/+$/, "");
23000
+ const real = import_node_fs39.realpathSync.native(norm).replace(/\\/g, "/").replace(/\/+$/, "");
23459
23001
  if (real !== norm) out.push(real);
23460
23002
  } catch {
23461
23003
  }
@@ -23543,31 +23085,31 @@ function fold(transcriptPath, opts = {}) {
23543
23085
  }
23544
23086
  };
23545
23087
  try {
23546
- if (!(0, import_node_fs41.existsSync)(transcriptPath)) return result;
23547
- ingest((0, import_node_fs41.readFileSync)(transcriptPath, "utf8"), "agent");
23088
+ if (!(0, import_node_fs39.existsSync)(transcriptPath)) return result;
23089
+ ingest((0, import_node_fs39.readFileSync)(transcriptPath, "utf8"), "agent");
23548
23090
  result.coverage.complete = true;
23549
23091
  } catch {
23550
23092
  return result;
23551
23093
  }
23552
23094
  try {
23553
- const sidecarDir = (0, import_node_path31.join)(
23554
- (0, import_node_path31.dirname)(transcriptPath),
23555
- (0, import_node_path31.basename)(transcriptPath).replace(/\.jsonl$/, ""),
23095
+ const sidecarDir = (0, import_node_path30.join)(
23096
+ (0, import_node_path30.dirname)(transcriptPath),
23097
+ (0, import_node_path30.basename)(transcriptPath).replace(/\.jsonl$/, ""),
23556
23098
  "subagents"
23557
23099
  );
23558
- if ((0, import_node_fs41.existsSync)(sidecarDir)) {
23100
+ if ((0, import_node_fs39.existsSync)(sidecarDir)) {
23559
23101
  const maxFiles = opts.maxSidecars ?? 200;
23560
23102
  const maxBytes = opts.maxSidecarBytes ?? 16 * 1024 * 1024;
23561
23103
  const found = [];
23562
23104
  const walk2 = (d, depth) => {
23563
23105
  if (depth > 4) return;
23564
- for (const e of (0, import_node_fs41.readdirSync)(d, { withFileTypes: true })) {
23565
- const p = (0, import_node_path31.join)(d, e.name);
23106
+ for (const e of (0, import_node_fs39.readdirSync)(d, { withFileTypes: true })) {
23107
+ const p = (0, import_node_path30.join)(d, e.name);
23566
23108
  if (e.isDirectory()) {
23567
23109
  walk2(p, depth + 1);
23568
23110
  } else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
23569
23111
  try {
23570
- const st = (0, import_node_fs41.statSync)(p);
23112
+ const st = (0, import_node_fs39.statSync)(p);
23571
23113
  found.push({ path: p, size: st.size, mtimeMs: st.mtimeMs });
23572
23114
  } catch {
23573
23115
  result.coverage.malformed++;
@@ -23584,7 +23126,7 @@ function fold(transcriptPath, opts = {}) {
23584
23126
  continue;
23585
23127
  }
23586
23128
  try {
23587
- ingest((0, import_node_fs41.readFileSync)(f.path, "utf8"), "subagent");
23129
+ ingest((0, import_node_fs39.readFileSync)(f.path, "utf8"), "subagent");
23588
23130
  bytes += f.size;
23589
23131
  result.coverage.subagentFiles++;
23590
23132
  } catch {
@@ -23619,7 +23161,7 @@ function fold(transcriptPath, opts = {}) {
23619
23161
  }
23620
23162
  function classifyUnobserved(path) {
23621
23163
  try {
23622
- const st = (0, import_node_fs41.statSync)(path);
23164
+ const st = (0, import_node_fs39.statSync)(path);
23623
23165
  if (!st.isFile()) return "unreadable";
23624
23166
  } catch {
23625
23167
  return "unreadable";
@@ -23934,20 +23476,20 @@ async function evidence(run2) {
23934
23476
  }
23935
23477
 
23936
23478
  // src/lib/cache-cleanup.ts
23937
- var import_node_fs42 = require("node:fs");
23938
- var import_node_path32 = require("node:path");
23479
+ var import_node_fs40 = require("node:fs");
23480
+ var import_node_path31 = require("node:path");
23939
23481
  var CACHE_TTL_DAYS = 7;
23940
23482
  function pruneStaleCache() {
23941
23483
  try {
23942
23484
  const dir = projectPath(CACHE_DIR);
23943
23485
  const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
23944
- for (const entry of (0, import_node_fs42.readdirSync)(dir)) {
23486
+ for (const entry of (0, import_node_fs40.readdirSync)(dir)) {
23945
23487
  if (!entry.startsWith("pending-")) continue;
23946
- const path = (0, import_node_path32.join)(dir, entry);
23488
+ const path = (0, import_node_path31.join)(dir, entry);
23947
23489
  try {
23948
- const stat3 = (0, import_node_fs42.statSync)(path);
23490
+ const stat3 = (0, import_node_fs40.statSync)(path);
23949
23491
  if (stat3.mtimeMs < cutoff) {
23950
- (0, import_node_fs42.unlinkSync)(path);
23492
+ (0, import_node_fs40.unlinkSync)(path);
23951
23493
  logEvent("cache_entry_pruned", {
23952
23494
  path: entry,
23953
23495
  age_days: Math.round((Date.now() - stat3.mtimeMs) / 864e5)
@@ -23961,7 +23503,7 @@ function pruneStaleCache() {
23961
23503
  }
23962
23504
 
23963
23505
  // src/lib/context-files.ts
23964
- var import_node_fs43 = require("node:fs");
23506
+ var import_node_fs41 = require("node:fs");
23965
23507
  var import_node_os7 = require("node:os");
23966
23508
  var MAX_CONTEXT_FILES = 10;
23967
23509
  var MAX_CONTEXT_FILE_BYTES = 10240;
@@ -24019,7 +23561,7 @@ function gatherContextFiles(contextPaths, deltaFiles, opts) {
24019
23561
  continue;
24020
23562
  }
24021
23563
  try {
24022
- const content = (0, import_node_fs43.readFileSync)(safePath, "utf8");
23564
+ const content = (0, import_node_fs41.readFileSync)(safePath, "utf8");
24023
23565
  const bytes = Buffer.byteLength(content);
24024
23566
  if (bytes > MAX_CONTEXT_FILE_BYTES) {
24025
23567
  logEvent("context_file_skipped", { path: filePath, reason: "too_large", bytes });
@@ -24111,8 +23653,8 @@ async function repoContext(run2) {
24111
23653
 
24112
23654
  // src/lib/seed-runner.ts
24113
23655
  var import_promises15 = require("node:fs/promises");
24114
- var import_node_fs44 = require("node:fs");
24115
- var import_node_path33 = require("node:path");
23656
+ var import_node_fs42 = require("node:fs");
23657
+ var import_node_path32 = require("node:path");
24116
23658
  var import_yaml4 = __toESM(require_dist());
24117
23659
 
24118
23660
  // src/lib/seed.ts
@@ -24335,8 +23877,8 @@ function normalizeTitle(title) {
24335
23877
  async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
24336
23878
  const titles = /* @__PURE__ */ new Set();
24337
23879
  for (const dir of NODE_DIRS) {
24338
- const full = (0, import_node_path33.join)(memoryDir3, dir);
24339
- if (!(0, import_node_fs44.existsSync)(full)) continue;
23880
+ const full = (0, import_node_path32.join)(memoryDir3, dir);
23881
+ if (!(0, import_node_fs42.existsSync)(full)) continue;
24340
23882
  let files;
24341
23883
  try {
24342
23884
  files = await (0, import_promises15.readdir)(full);
@@ -24347,7 +23889,7 @@ async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
24347
23889
  if (!file.endsWith(".md")) continue;
24348
23890
  let content;
24349
23891
  try {
24350
- content = await (0, import_promises15.readFile)((0, import_node_path33.join)(full, file), "utf-8");
23892
+ content = await (0, import_promises15.readFile)((0, import_node_path32.join)(full, file), "utf-8");
24351
23893
  } catch {
24352
23894
  continue;
24353
23895
  }
@@ -24418,7 +23960,7 @@ function renderNodeMarkdown(candidate, nodeId, createdAt) {
24418
23960
  return fm;
24419
23961
  }
24420
23962
  async function runSeed(opts) {
24421
- if (!(0, import_node_fs44.existsSync)(STANDARD_FILE)) {
23963
+ if (!(0, import_node_fs42.existsSync)(STANDARD_FILE)) {
24422
23964
  return { created: 0, existing: 0, failed: 0, skipped: "no_standard", candidates: [] };
24423
23965
  }
24424
23966
  let standardDoc;
@@ -24430,7 +23972,7 @@ async function runSeed(opts) {
24430
23972
  }
24431
23973
  const knowledgeSpec = standardDoc.knowledge_spec ?? {};
24432
23974
  let readmeContent;
24433
- if ((0, import_node_fs44.existsSync)("README.md")) {
23975
+ if ((0, import_node_fs42.existsSync)("README.md")) {
24434
23976
  try {
24435
23977
  readmeContent = await (0, import_promises15.readFile)("README.md", "utf-8");
24436
23978
  } catch {
@@ -24438,7 +23980,7 @@ async function runSeed(opts) {
24438
23980
  }
24439
23981
  let claudeMdContent;
24440
23982
  for (const p of ["CLAUDE.md", ".claude/CLAUDE.md"]) {
24441
- if ((0, import_node_fs44.existsSync)(p)) {
23983
+ if ((0, import_node_fs42.existsSync)(p)) {
24442
23984
  try {
24443
23985
  claudeMdContent = await (0, import_promises15.readFile)(p, "utf-8");
24444
23986
  break;
@@ -24518,13 +24060,13 @@ async function runSeed(opts) {
24518
24060
  continue;
24519
24061
  }
24520
24062
  const deduplicated = res.data.deduplicated === true;
24521
- if (deduplicated && (0, import_node_fs44.existsSync)(targetPath)) {
24063
+ if (deduplicated && (0, import_node_fs42.existsSync)(targetPath)) {
24522
24064
  existing++;
24523
24065
  continue;
24524
24066
  }
24525
24067
  const content = typeof res.data.content === "string" && res.data.content.length > 0 ? res.data.content : renderNodeMarkdown(c, nodeId, createdAt);
24526
24068
  try {
24527
- await (0, import_promises15.mkdir)((0, import_node_path33.dirname)(targetPath), { recursive: true });
24069
+ await (0, import_promises15.mkdir)((0, import_node_path32.dirname)(targetPath), { recursive: true });
24528
24070
  await (0, import_promises15.writeFile)(targetPath, content);
24529
24071
  if (deduplicated) existing++;
24530
24072
  else {
@@ -24540,8 +24082,8 @@ async function runSeed(opts) {
24540
24082
  }
24541
24083
 
24542
24084
  // src/commands/analyze/phases/08-memory-manifest.ts
24543
- var import_node_fs45 = require("node:fs");
24544
- var import_node_path34 = require("node:path");
24085
+ var import_node_fs43 = require("node:fs");
24086
+ var import_node_path33 = require("node:path");
24545
24087
  async function memoryManifest(run2) {
24546
24088
  const { globals } = run2;
24547
24089
  const { serviceUrl, token } = run2;
@@ -24551,9 +24093,9 @@ async function memoryManifest(run2) {
24551
24093
  let autoSeedNotice = null;
24552
24094
  try {
24553
24095
  await ensureMemoryDir();
24554
- const seedMarker = (0, import_node_path34.join)(VERITY_DIR, ".seeded");
24555
- const hasStandard = (0, import_node_fs45.existsSync)(STANDARD_FILE);
24556
- const alreadyTried = (0, import_node_fs45.existsSync)(seedMarker);
24096
+ const seedMarker = (0, import_node_path33.join)(VERITY_DIR, ".seeded");
24097
+ const hasStandard = (0, import_node_fs43.existsSync)(STANDARD_FILE);
24098
+ const alreadyTried = (0, import_node_fs43.existsSync)(seedMarker);
24557
24099
  if (hasStandard && !alreadyTried) {
24558
24100
  const preManifest = await buildManifest();
24559
24101
  if (preManifest.nodes.length === 0) {
@@ -24566,7 +24108,7 @@ async function memoryManifest(run2) {
24566
24108
  dryRun: false
24567
24109
  });
24568
24110
  if (seedResult.created > 0 || seedResult.existing > 0) {
24569
- (0, import_node_fs45.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created} existing=${seedResult.existing}
24111
+ (0, import_node_fs43.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created} existing=${seedResult.existing}
24570
24112
  `);
24571
24113
  if (seedResult.created > 0) {
24572
24114
  autoSeedNotice = `Seeded ${seedResult.created} knowledge node(s) from your existing Standard (one-time).`;
@@ -24577,7 +24119,7 @@ async function memoryManifest(run2) {
24577
24119
  failed: seedResult.failed
24578
24120
  });
24579
24121
  } else if (seedResult.skipped === "already_seeded") {
24580
- (0, import_node_fs45.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
24122
+ (0, import_node_fs43.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
24581
24123
  `);
24582
24124
  } else {
24583
24125
  logEvent("auto_seed_noop", {
@@ -24672,7 +24214,7 @@ function computeIncrement(reviewedPaths, hashOf, priorAuthored) {
24672
24214
  }
24673
24215
 
24674
24216
  // src/commands/analyze/phases/10-working-memory.ts
24675
- var import_node_path35 = require("node:path");
24217
+ var import_node_path34 = require("node:path");
24676
24218
  async function workingMemory(run2) {
24677
24219
  const { opts } = run2;
24678
24220
  const { allForReview, baseline, conversation, foldResult, sessionId, token, transcriptPath } = run2;
@@ -24684,7 +24226,7 @@ async function workingMemory(run2) {
24684
24226
  const priorState = foldForMarks(memorySession.d);
24685
24227
  incrementReport = computeIncrement(
24686
24228
  allForReview,
24687
- (p) => fileHash((0, import_node_path35.join)(repoRoot(), p)),
24229
+ (p) => fileHash((0, import_node_path34.join)(repoRoot(), p)),
24688
24230
  priorState.authored_all.map((a) => ({
24689
24231
  path: a.path,
24690
24232
  hash_at_last_verdict: a.hash_at_last_verdict
@@ -24766,7 +24308,7 @@ async function workingMemory(run2) {
24766
24308
  }
24767
24309
 
24768
24310
  // src/lib/note-budget.ts
24769
- var import_node_fs46 = require("node:fs");
24311
+ var import_node_fs44 = require("node:fs");
24770
24312
  var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
24771
24313
  var EPISODE_STALE_SECONDS = 30 * 60;
24772
24314
  var FRESH = { delivered: 0, tasksCompleted: 0, ts: 0 };
@@ -24788,9 +24330,9 @@ function advisoryBudgetSpent(episode, rawDecision) {
24788
24330
  }
24789
24331
  function readAdvisoryEpisode(sessionId) {
24790
24332
  const file = scopedFile(ADVISORY_EPISODE_FILE, sessionId);
24791
- if (!(0, import_node_fs46.existsSync)(file)) return null;
24333
+ if (!(0, import_node_fs44.existsSync)(file)) return null;
24792
24334
  try {
24793
- const o = JSON.parse((0, import_node_fs46.readFileSync)(file, "utf-8")) ?? {};
24335
+ const o = JSON.parse((0, import_node_fs44.readFileSync)(file, "utf-8")) ?? {};
24794
24336
  const delivered = typeof o.delivered === "number" ? o.delivered : NaN;
24795
24337
  if (isNaN(delivered)) return null;
24796
24338
  return {
@@ -24804,8 +24346,8 @@ function readAdvisoryEpisode(sessionId) {
24804
24346
  }
24805
24347
  function writeAdvisoryEpisode(episode, sessionId) {
24806
24348
  try {
24807
- (0, import_node_fs46.mkdirSync)(VERITY_DIR, { recursive: true });
24808
- (0, import_node_fs46.writeFileSync)(
24349
+ (0, import_node_fs44.mkdirSync)(VERITY_DIR, { recursive: true });
24350
+ (0, import_node_fs44.writeFileSync)(
24809
24351
  scopedFile(ADVISORY_EPISODE_FILE, sessionId),
24810
24352
  JSON.stringify({ v: 1, ...episode })
24811
24353
  );
@@ -24874,11 +24416,6 @@ var MAX_ASSISTANT_RESPONSE_CHARS_PLAN = 32768;
24874
24416
  var MAX_ASSISTANT_RESPONSE_CHARS_DEFAULT = 8e3;
24875
24417
  async function buildRequest(run2) {
24876
24418
  const { actionSummary, allChanged, allForReview, analysisMode, analyzable, assistantResponse, codeDelta, conversation, deletedNodePaths, editedUploads, foldConservation, foldResult, incrementReport, iteration, memory, memoryManifest: memoryManifest2, memorySession, plans, reachability, reviewable, securityFiles, sessionId, snapshotResult, specs, staticResults, stopReason, turnId } = run2;
24877
- const advisoryEpisode = episodeForWire(
24878
- readAdvisoryEpisode(run2.baselineSessionId),
24879
- (conversation?.prompts?.length ?? 0) > 0
24880
- );
24881
- const noteConfirmation = peekNoteOutcome();
24882
24419
  const excludedByReason = {};
24883
24420
  for (const e of codeDelta.excluded ?? []) {
24884
24421
  excludedByReason[e.reason] = (excludedByReason[e.reason] ?? 0) + 1;
@@ -25049,26 +24586,7 @@ async function buildRequest(run2) {
25049
24586
  },
25050
24587
  ...memoryManifest2 && { memory_manifest: memoryManifest2 },
25051
24588
  ...deletedNodePaths.length > 0 && { deleted_node_paths: deletedNodePaths },
25052
- ...editedUploads.length > 0 && { memory_files_upload: editedUploads },
25053
- // --- KNOWLEDGE-LOOP phase 5 -------------------------------------------
25054
- //
25055
- // The server decides whether to speak a memory node, and needs the episode
25056
- // state to apply the SAME budget the client applies to its own advisory
25057
- // content (`note-budget.ts`, ported and parity-tested). Sending it is not a
25058
- // request for a note: it is what lets the budget be evaluated before the
25059
- // ε-coin, which is what keeps the two holdout arms comparable.
25060
- //
25061
- // Absent on an old CLI, and the server answers `no_episode_state` rather
25062
- // than guessing — silence is the safe direction when a forced turn cannot
25063
- // be accounted for.
25064
- advisory_episode: advisoryEpisode,
25065
- // What the PREVIOUS run did with the note it was sent. The server decides,
25066
- // but only the client knows whether the sentence actually reached the
25067
- // agent, and an undelivered note must be voided rather than counted.
25068
- ...noteConfirmation && {
25069
- knowledge_note_run_id: noteConfirmation.run_id,
25070
- knowledge_note_delivered: noteConfirmation.delivered
25071
- }
24589
+ ...editedUploads.length > 0 && { memory_files_upload: editedUploads }
25072
24590
  };
25073
24591
  if (snapshotResult.has_snapshots && snapshotResult.diffs.length > 0) {
25074
24592
  requestBody.snapshot_diffs = snapshotResult.diffs;
@@ -25137,14 +24655,14 @@ async function buildRequest(run2) {
25137
24655
  }
25138
24656
 
25139
24657
  // src/lib/offline.ts
25140
- var import_node_fs47 = require("node:fs");
25141
- var import_node_crypto12 = require("node:crypto");
24658
+ var import_node_fs45 = require("node:fs");
24659
+ var import_node_crypto11 = require("node:crypto");
25142
24660
  function cacheRequest(body) {
25143
24661
  try {
25144
- (0, import_node_fs47.mkdirSync)(CACHE_DIR, { recursive: true });
25145
- const suffix = (0, import_node_crypto12.randomBytes)(4).toString("hex");
24662
+ (0, import_node_fs45.mkdirSync)(CACHE_DIR, { recursive: true });
24663
+ const suffix = (0, import_node_crypto11.randomBytes)(4).toString("hex");
25146
24664
  const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
25147
- (0, import_node_fs47.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body)));
24665
+ (0, import_node_fs45.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body)));
25148
24666
  } catch {
25149
24667
  }
25150
24668
  }
@@ -25263,8 +24781,8 @@ async function transmit(run2) {
25263
24781
  }
25264
24782
 
25265
24783
  // src/commands/analyze/phases/13-reconcile.ts
25266
- var import_node_fs48 = require("node:fs");
25267
- var import_node_path36 = require("node:path");
24784
+ var import_node_fs46 = require("node:fs");
24785
+ var import_node_path35 = require("node:path");
25268
24786
  async function reconcile(run2) {
25269
24787
  const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory, memorySession, response, reviewable, securityFiles, turnId } = run2;
25270
24788
  const sentPaths = codeDelta.files.map((f) => f.path);
@@ -25293,7 +24811,7 @@ async function reconcile(run2) {
25293
24811
  const st = foldDossier(memorySession.d);
25294
24812
  openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line) => {
25295
24813
  try {
25296
- const src = (0, import_node_fs48.readFileSync)((0, import_node_path36.join)(repoRoot(), file), "utf8").split("\n");
24814
+ const src = (0, import_node_fs46.readFileSync)((0, import_node_path35.join)(repoRoot(), file), "utf8").split("\n");
25297
24815
  const at = src[line - 1];
25298
24816
  return at === void 0 ? null : lineSha(at);
25299
24817
  } catch {
@@ -25746,14 +25264,7 @@ function screenRemediation(fix, findingFile) {
25746
25264
 
25747
25265
  // src/commands/analyze/phases/14-render.ts
25748
25266
  function agentContextFor(response, intentRepeat = 0, priorPendingFingerprints = []) {
25749
- const built = buildAgentContext(channelInputFrom(response, intentRepeat, priorPendingFingerprints));
25750
- clearNoteOutcome();
25751
- const note = parseKnowledgeNote(response.knowledge_note);
25752
- if (note) {
25753
- const runId = typeof response.run_id === "string" ? response.run_id : null;
25754
- if (runId) recordNoteOutcome(runId, !!built && built.includes(note.text));
25755
- }
25756
- return built;
25267
+ return buildAgentContext(channelInputFrom(response, intentRepeat, priorPendingFingerprints));
25757
25268
  }
25758
25269
  async function render(run2) {
25759
25270
  const { opts, globals } = run2;
@@ -26115,7 +25626,7 @@ function registerAnalyzeCommand(program2) {
26115
25626
  var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
26116
25627
  async function runAnalyze(opts, globals) {
26117
25628
  if (!verityConfigured()) {
26118
- (0, import_node_fs49.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
25629
+ (0, import_node_fs47.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
26119
25630
  process.exit(0);
26120
25631
  }
26121
25632
  const run2 = createRun(opts, globals);
@@ -26136,11 +25647,11 @@ async function runAnalyze(opts, globals) {
26136
25647
  }
26137
25648
 
26138
25649
  // src/commands/baseline.ts
26139
- var import_node_fs51 = require("node:fs");
25650
+ var import_node_fs49 = require("node:fs");
26140
25651
 
26141
25652
  // src/lib/project-skills.ts
26142
- var import_node_fs50 = require("node:fs");
26143
- var import_node_path37 = require("node:path");
25653
+ var import_node_fs48 = require("node:fs");
25654
+ var import_node_path36 = require("node:path");
26144
25655
  var PROJECT_SKILL_NAMES = [
26145
25656
  "verity-setup",
26146
25657
  "verity-analyze",
@@ -26165,14 +25676,14 @@ var LEGACY_SKILL_NAMES = [
26165
25676
  var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
26166
25677
  function staleProjectSkills() {
26167
25678
  const root = projectPath(".claude/skills");
26168
- if (!(0, import_node_fs50.existsSync)(root)) return [];
26169
- return ALL.filter((name) => (0, import_node_fs50.existsSync)((0, import_node_path37.join)(root, name)));
25679
+ if (!(0, import_node_fs48.existsSync)(root)) return [];
25680
+ return ALL.filter((name) => (0, import_node_fs48.existsSync)((0, import_node_path36.join)(root, name)));
26170
25681
  }
26171
25682
  function removeProjectSkills() {
26172
25683
  const root = projectPath(".claude/skills");
26173
25684
  const removed = [];
26174
25685
  for (const name of staleProjectSkills()) {
26175
- (0, import_node_fs50.rmSync)((0, import_node_path37.join)(root, name), { recursive: true, force: true });
25686
+ (0, import_node_fs48.rmSync)((0, import_node_path36.join)(root, name), { recursive: true, force: true });
26176
25687
  removed.push(name);
26177
25688
  }
26178
25689
  return removed;
@@ -26237,13 +25748,13 @@ function registerBaselineCommands(program2) {
26237
25748
  let memoryMsg = null;
26238
25749
  let memoryAgentLine = null;
26239
25750
  const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
26240
- if (realStart && !(0, import_node_fs51.existsSync)(memoryNotice)) {
25751
+ if (realStart && !(0, import_node_fs49.existsSync)(memoryNotice)) {
26241
25752
  const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
26242
25753
  if (trackedGraph > 0) {
26243
25754
  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.`;
26244
25755
  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.`;
26245
25756
  try {
26246
- (0, import_node_fs51.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
25757
+ (0, import_node_fs49.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
26247
25758
  } catch {
26248
25759
  }
26249
25760
  }
@@ -26314,7 +25825,7 @@ function registerBaselineCommands(program2) {
26314
25825
  }
26315
25826
  var MAX_HOOK_EVENT_BYTES = 64 * 1024;
26316
25827
  var HOOK_SOURCES = /* @__PURE__ */ new Set(["startup", "resume", "clear", "compact"]);
26317
- var SESSION_ID_RE2 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
25828
+ var SESSION_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
26318
25829
  async function readStdin() {
26319
25830
  const chunks = [];
26320
25831
  let size = 0;
@@ -26336,7 +25847,7 @@ function parseHookEvent(input) {
26336
25847
  return { sessionId: validSessionId(id), source: hookSource(source) };
26337
25848
  }
26338
25849
  function validSessionId(value) {
26339
- return typeof value === "string" && SESSION_ID_RE2.test(value) ? value : void 0;
25850
+ return typeof value === "string" && SESSION_ID_RE.test(value) ? value : void 0;
26340
25851
  }
26341
25852
  function hookSource(value) {
26342
25853
  if (typeof value !== "string") return void 0;
@@ -26344,7 +25855,7 @@ function hookSource(value) {
26344
25855
  }
26345
25856
 
26346
25857
  // src/commands/review.ts
26347
- var import_node_fs52 = require("node:fs");
25858
+ var import_node_fs50 = require("node:fs");
26348
25859
  function registerReviewCommand(program2) {
26349
25860
  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) => {
26350
25861
  const globals = program2.opts();
@@ -26361,7 +25872,7 @@ async function runReview(opts, globals) {
26361
25872
  const changedFiles = opts.changed ? opts.changed.split(",").map((f) => f.trim()).filter(Boolean) : allFiles;
26362
25873
  const analyzable = filterAnalyzable(allFiles);
26363
25874
  const securityFiles = filterSecurity(allFiles);
26364
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs52.existsSync)(f) || resolveFile(f) !== null);
25875
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs50.existsSync)(f) || resolveFile(f) !== null);
26365
25876
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
26366
25877
  const codeDelta = collectCodeDelta(allFiles);
26367
25878
  const tokenResult = await resolveToken(globals.token);
@@ -26427,8 +25938,8 @@ async function runReview(opts, globals) {
26427
25938
  }
26428
25939
 
26429
25940
  // src/commands/guard.ts
26430
- var import_node_fs53 = require("node:fs");
26431
- var import_node_path38 = require("node:path");
25941
+ var import_node_fs51 = require("node:fs");
25942
+ var import_node_path37 = require("node:path");
26432
25943
 
26433
25944
  // src/lib/terminal-text.ts
26434
25945
  var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/g;
@@ -26803,7 +26314,7 @@ async function buildAgentDiffs(ctx, paths, limits = { perFileChars: 24e3, totalC
26803
26314
  // src/commands/guard.ts
26804
26315
  var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
26805
26316
  var GUARD_BLOCK_CAP = 2;
26806
- var GUARD_ITER_FILE = (0, import_node_path38.join)(VERITY_DIR, ".guard-iteration");
26317
+ var GUARD_ITER_FILE = (0, import_node_path37.join)(VERITY_DIR, ".guard-iteration");
26807
26318
  function readPreToolUseStdin() {
26808
26319
  const empty = { command: "", cwd: null, sessionId: null };
26809
26320
  return new Promise((resolve6) => {
@@ -26848,7 +26359,7 @@ function readPreToolUseStdin() {
26848
26359
  }
26849
26360
  function readIterMap() {
26850
26361
  try {
26851
- const raw = JSON.parse((0, import_node_fs53.readFileSync)(GUARD_ITER_FILE, "utf-8"));
26362
+ const raw = JSON.parse((0, import_node_fs51.readFileSync)(GUARD_ITER_FILE, "utf-8"));
26852
26363
  if (raw && typeof raw === "object") {
26853
26364
  if (typeof raw.moment === "string" && typeof raw.count === "number") {
26854
26365
  return { [raw.moment]: raw.count };
@@ -26868,10 +26379,10 @@ function readIter(moment) {
26868
26379
  }
26869
26380
  function writeIter(moment, count) {
26870
26381
  try {
26871
- (0, import_node_fs53.mkdirSync)(VERITY_DIR, { recursive: true });
26382
+ (0, import_node_fs51.mkdirSync)(VERITY_DIR, { recursive: true });
26872
26383
  const map = readIterMap();
26873
26384
  map[moment] = count;
26874
- (0, import_node_fs53.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
26385
+ (0, import_node_fs51.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
26875
26386
  } catch {
26876
26387
  }
26877
26388
  }
@@ -26881,10 +26392,10 @@ function resetIter(moment) {
26881
26392
  if (!(moment in map)) return;
26882
26393
  delete map[moment];
26883
26394
  if (Object.keys(map).length === 0) {
26884
- if ((0, import_node_fs53.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs53.unlinkSync)(GUARD_ITER_FILE);
26395
+ if ((0, import_node_fs51.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs51.unlinkSync)(GUARD_ITER_FILE);
26885
26396
  } else {
26886
- (0, import_node_fs53.mkdirSync)(VERITY_DIR, { recursive: true });
26887
- (0, import_node_fs53.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
26397
+ (0, import_node_fs51.mkdirSync)(VERITY_DIR, { recursive: true });
26398
+ (0, import_node_fs51.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
26888
26399
  }
26889
26400
  } catch {
26890
26401
  }
@@ -26954,7 +26465,7 @@ function hasBlockingFinding(response, sentFiles) {
26954
26465
  function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
26955
26466
  const analyzable = filterAnalyzable(files);
26956
26467
  const securityFiles = filterSecurity(files);
26957
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs53.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
26468
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs51.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
26958
26469
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
26959
26470
  const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
26960
26471
  const requestBody = {
@@ -27463,8 +26974,8 @@ function registerIgnoreCommand(program2) {
27463
26974
  }
27464
26975
 
27465
26976
  // src/commands/waive.ts
27466
- var import_node_crypto13 = require("node:crypto");
27467
- var import_node_fs54 = require("node:fs");
26977
+ var import_node_crypto12 = require("node:crypto");
26978
+ var import_node_fs52 = require("node:fs");
27468
26979
  function registerWaiveCommand(program2) {
27469
26980
  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) => {
27470
26981
  const globals = program2.opts();
@@ -27493,7 +27004,7 @@ function registerWaiveCommand(program2) {
27493
27004
  if (opts.file) {
27494
27005
  body.file = opts.file;
27495
27006
  try {
27496
- body.file_sha256 = (0, import_node_crypto13.createHash)("sha256").update((0, import_node_fs54.readFileSync)(opts.file)).digest("hex");
27007
+ body.file_sha256 = (0, import_node_crypto12.createHash)("sha256").update((0, import_node_fs52.readFileSync)(opts.file)).digest("hex");
27497
27008
  } catch {
27498
27009
  printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
27499
27010
  process.exit(1);
@@ -27518,10 +27029,10 @@ function registerWaiveCommand(program2) {
27518
27029
  }
27519
27030
 
27520
27031
  // src/commands/init.ts
27521
- var import_node_fs58 = require("node:fs");
27032
+ var import_node_fs56 = require("node:fs");
27522
27033
  var import_promises19 = require("node:fs/promises");
27523
27034
  var import_yaml6 = __toESM(require_dist());
27524
- var import_node_path41 = require("node:path");
27035
+ var import_node_path40 = require("node:path");
27525
27036
  var import_node_child_process17 = require("node:child_process");
27526
27037
 
27527
27038
  // src/lib/banner.ts
@@ -27600,7 +27111,7 @@ function printPhase(n, of, title, subtitle) {
27600
27111
  }
27601
27112
 
27602
27113
  // src/commands/doctor.ts
27603
- var import_node_fs55 = require("node:fs");
27114
+ var import_node_fs53 = require("node:fs");
27604
27115
 
27605
27116
  // src/lib/prereqs.ts
27606
27117
  var import_node_child_process15 = require("node:child_process");
@@ -27808,11 +27319,11 @@ async function buildReport() {
27808
27319
  const hooks = wiring.status;
27809
27320
  const provenance = cliProvenance();
27810
27321
  const telemetry = await checkTelemetry();
27811
- const hasConfig = (0, import_node_fs55.existsSync)(projectPath(CODACY_CONFIG_FILE));
27322
+ const hasConfig = (0, import_node_fs53.existsSync)(projectPath(CODACY_CONFIG_FILE));
27812
27323
  const artifacts = {
27813
- standard: (0, import_node_fs55.existsSync)(projectPath(STANDARD_FILE)),
27324
+ standard: (0, import_node_fs53.existsSync)(projectPath(STANDARD_FILE)),
27814
27325
  analysisConfig: hasConfig,
27815
- verityMd: (0, import_node_fs55.existsSync)(projectPath(VERITY_MD_FILE)),
27326
+ verityMd: (0, import_node_fs53.existsSync)(projectPath(VERITY_MD_FILE)),
27816
27327
  analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
27817
27328
  };
27818
27329
  const next = [];
@@ -27953,8 +27464,8 @@ function registerDoctorCommand(program2) {
27953
27464
  }
27954
27465
 
27955
27466
  // src/commands/migrate.ts
27956
- var import_node_fs56 = require("node:fs");
27957
- var import_node_path39 = require("node:path");
27467
+ var import_node_fs54 = require("node:fs");
27468
+ var import_node_path38 = require("node:path");
27958
27469
  var import_node_child_process16 = require("node:child_process");
27959
27470
  var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
27960
27471
  function defaultNpmRemover(pkg) {
@@ -27991,12 +27502,12 @@ async function runMigration(opts = {}) {
27991
27502
  return { actions, migrated: actions.length > 0 };
27992
27503
  }
27993
27504
  function migrateProjectDir(root, actions) {
27994
- const gateDir = (0, import_node_path39.join)(root, ".gate");
27995
- const verityDir = (0, import_node_path39.join)(root, ".verity");
27996
- if ((0, import_node_fs56.existsSync)(gateDir) && !(0, import_node_fs56.existsSync)(verityDir)) {
27505
+ const gateDir = (0, import_node_path38.join)(root, ".gate");
27506
+ const verityDir = (0, import_node_path38.join)(root, ".verity");
27507
+ if ((0, import_node_fs54.existsSync)(gateDir) && !(0, import_node_fs54.existsSync)(verityDir)) {
27997
27508
  return migrateProjectDirRename(root, gateDir, verityDir, actions);
27998
27509
  }
27999
- if ((0, import_node_fs56.existsSync)(gateDir) && (0, import_node_fs56.existsSync)(verityDir)) {
27510
+ if ((0, import_node_fs54.existsSync)(gateDir) && (0, import_node_fs54.existsSync)(verityDir)) {
28000
27511
  return migrateProjectDirCarry(gateDir, verityDir, actions);
28001
27512
  }
28002
27513
  return false;
@@ -28017,13 +27528,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
28017
27528
  }
28018
27529
  }
28019
27530
  if (moved) {
28020
- if ((0, import_node_fs56.existsSync)(gateDir)) {
27531
+ if ((0, import_node_fs54.existsSync)(gateDir)) {
28021
27532
  const carried = carryLegacyContents(gateDir, verityDir);
28022
27533
  if (carried > 0) {
28023
27534
  actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
28024
27535
  }
28025
27536
  try {
28026
- (0, import_node_fs56.rmSync)(gateDir, { recursive: true, force: true });
27537
+ (0, import_node_fs54.rmSync)(gateDir, { recursive: true, force: true });
28027
27538
  } catch {
28028
27539
  }
28029
27540
  }
@@ -28039,18 +27550,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
28039
27550
  actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
28040
27551
  }
28041
27552
  try {
28042
- (0, import_node_fs56.rmSync)(gateDir, { recursive: true, force: true });
27553
+ (0, import_node_fs54.rmSync)(gateDir, { recursive: true, force: true });
28043
27554
  } catch {
28044
27555
  }
28045
27556
  return carried > 0;
28046
27557
  }
28047
27558
  function migrateGlobalCredentials(home, actions) {
28048
27559
  if (!home) return;
28049
- const gateCreds = (0, import_node_path39.join)(home, ".gate", "credentials");
28050
- const verityCreds = (0, import_node_path39.join)(home, ".verity", "credentials");
28051
- if (!(0, import_node_fs56.existsSync)(gateCreds)) return;
28052
- if (!(0, import_node_fs56.existsSync)(verityCreds)) {
28053
- (0, import_node_fs56.mkdirSync)((0, import_node_path39.join)(home, ".verity"), { recursive: true });
27560
+ const gateCreds = (0, import_node_path38.join)(home, ".gate", "credentials");
27561
+ const verityCreds = (0, import_node_path38.join)(home, ".verity", "credentials");
27562
+ if (!(0, import_node_fs54.existsSync)(gateCreds)) return;
27563
+ if (!(0, import_node_fs54.existsSync)(verityCreds)) {
27564
+ (0, import_node_fs54.mkdirSync)((0, import_node_path38.join)(home, ".verity"), { recursive: true });
28054
27565
  moveFile(gateCreds, verityCreds);
28055
27566
  actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
28056
27567
  return;
@@ -28072,8 +27583,8 @@ async function migrateLegacyHooks(root, actions) {
28072
27583
  }
28073
27584
  }
28074
27585
  async function migrateClaudeMd(root, actions) {
28075
- const claudeMd = (0, import_node_path39.join)(root, "CLAUDE.md");
28076
- const hadLegacyBlock = (0, import_node_fs56.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
27586
+ const claudeMd = (0, import_node_path38.join)(root, "CLAUDE.md");
27587
+ const hadLegacyBlock = (0, import_node_fs54.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
28077
27588
  if (!hadLegacyBlock) return;
28078
27589
  try {
28079
27590
  await ensureClaudeMdPointer(root);
@@ -28083,9 +27594,9 @@ async function migrateClaudeMd(root, actions) {
28083
27594
  }
28084
27595
  }
28085
27596
  function migrateStandardFile(root, actions) {
28086
- const gateMd = (0, import_node_path39.join)(root, "GATE.md");
28087
- const verityMd = (0, import_node_path39.join)(root, "VERITY.md");
28088
- if (!(0, import_node_fs56.existsSync)(gateMd) || (0, import_node_fs56.existsSync)(verityMd)) return;
27597
+ const gateMd = (0, import_node_path38.join)(root, "GATE.md");
27598
+ const verityMd = (0, import_node_path38.join)(root, "VERITY.md");
27599
+ if (!(0, import_node_fs54.existsSync)(gateMd) || (0, import_node_fs54.existsSync)(verityMd)) return;
28089
27600
  let moved = false;
28090
27601
  if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
28091
27602
  try {
@@ -28097,12 +27608,12 @@ function migrateStandardFile(root, actions) {
28097
27608
  if (!moved) moveFile(gateMd, verityMd);
28098
27609
  const content = readFileSyncSafe(verityMd);
28099
27610
  const refreshed = content.split("GATE.md").join("VERITY.md");
28100
- if (refreshed !== content) (0, import_node_fs56.writeFileSync)(verityMd, refreshed);
27611
+ if (refreshed !== content) (0, import_node_fs54.writeFileSync)(verityMd, refreshed);
28101
27612
  actions.push("Renamed GATE.md \u2192 VERITY.md");
28102
27613
  }
28103
27614
  async function migrateTelemetryHeaders(root, actions) {
28104
- const file = (0, import_node_path39.join)(root, ".claude", "settings.local.json");
28105
- if (!(0, import_node_fs56.existsSync)(file)) return;
27615
+ const file = (0, import_node_path38.join)(root, ".claude", "settings.local.json");
27616
+ if (!(0, import_node_fs54.existsSync)(file)) return;
28106
27617
  let settings;
28107
27618
  try {
28108
27619
  settings = JSON.parse(readFileSyncSafe(file) || "{}");
@@ -28150,14 +27661,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
28150
27661
  }
28151
27662
  if (toAppend.length > 0) {
28152
27663
  const sep4 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
28153
- (0, import_node_fs56.writeFileSync)(verityCreds, verityContent + sep4 + toAppend.join("\n") + "\n");
27664
+ (0, import_node_fs54.writeFileSync)(verityCreds, verityContent + sep4 + toAppend.join("\n") + "\n");
28154
27665
  }
28155
- (0, import_node_fs56.rmSync)(gateCreds, { force: true });
27666
+ (0, import_node_fs54.rmSync)(gateCreds, { force: true });
28156
27667
  return toAppend.length;
28157
27668
  }
28158
27669
  function readFileSyncSafe(path) {
28159
27670
  try {
28160
- return (0, import_node_fs56.readFileSync)(path, "utf-8");
27671
+ return (0, import_node_fs54.readFileSync)(path, "utf-8");
28161
27672
  } catch {
28162
27673
  return "";
28163
27674
  }
@@ -28172,35 +27683,35 @@ function hasStagedChanges(root) {
28172
27683
  }
28173
27684
  function moveDir(from, to) {
28174
27685
  try {
28175
- (0, import_node_fs56.renameSync)(from, to);
27686
+ (0, import_node_fs54.renameSync)(from, to);
28176
27687
  } catch (err) {
28177
27688
  if (err.code !== "EXDEV") throw err;
28178
- (0, import_node_fs56.cpSync)(from, to, { recursive: true });
28179
- (0, import_node_fs56.rmSync)(from, { recursive: true, force: true });
27689
+ (0, import_node_fs54.cpSync)(from, to, { recursive: true });
27690
+ (0, import_node_fs54.rmSync)(from, { recursive: true, force: true });
28180
27691
  }
28181
27692
  }
28182
27693
  function moveFile(from, to) {
28183
27694
  try {
28184
- (0, import_node_fs56.renameSync)(from, to);
27695
+ (0, import_node_fs54.renameSync)(from, to);
28185
27696
  } catch (err) {
28186
27697
  if (err.code !== "EXDEV") throw err;
28187
- (0, import_node_fs56.cpSync)(from, to);
28188
- (0, import_node_fs56.rmSync)(from, { force: true });
27698
+ (0, import_node_fs54.cpSync)(from, to);
27699
+ (0, import_node_fs54.rmSync)(from, { force: true });
28189
27700
  }
28190
27701
  }
28191
27702
  function carryLegacyContents(gateDir, verityDir) {
28192
27703
  let copied = 0;
28193
27704
  const walk2 = (relDir) => {
28194
- const srcDir = (0, import_node_path39.join)(gateDir, relDir);
28195
- for (const entry of (0, import_node_fs56.readdirSync)(srcDir)) {
28196
- const rel = relDir ? (0, import_node_path39.join)(relDir, entry) : entry;
28197
- const src = (0, import_node_path39.join)(gateDir, rel);
28198
- const dest = (0, import_node_path39.join)(verityDir, rel);
28199
- if ((0, import_node_fs56.statSync)(src).isDirectory()) {
27705
+ const srcDir = (0, import_node_path38.join)(gateDir, relDir);
27706
+ for (const entry of (0, import_node_fs54.readdirSync)(srcDir)) {
27707
+ const rel = relDir ? (0, import_node_path38.join)(relDir, entry) : entry;
27708
+ const src = (0, import_node_path38.join)(gateDir, rel);
27709
+ const dest = (0, import_node_path38.join)(verityDir, rel);
27710
+ if ((0, import_node_fs54.statSync)(src).isDirectory()) {
28200
27711
  walk2(rel);
28201
- } else if (!(0, import_node_fs56.existsSync)(dest)) {
28202
- (0, import_node_fs56.mkdirSync)((0, import_node_path39.dirname)(dest), { recursive: true });
28203
- (0, import_node_fs56.cpSync)(src, dest);
27712
+ } else if (!(0, import_node_fs54.existsSync)(dest)) {
27713
+ (0, import_node_fs54.mkdirSync)((0, import_node_path38.dirname)(dest), { recursive: true });
27714
+ (0, import_node_fs54.cpSync)(src, dest);
28204
27715
  copied++;
28205
27716
  }
28206
27717
  }
@@ -28209,22 +27720,22 @@ function carryLegacyContents(gateDir, verityDir) {
28209
27720
  return copied;
28210
27721
  }
28211
27722
  async function needsMigration(root = repoRoot()) {
28212
- const gateDir = (0, import_node_path39.join)(root, ".gate");
28213
- const verityDir = (0, import_node_path39.join)(root, ".verity");
28214
- if ((0, import_node_fs56.existsSync)(gateDir) && !(0, import_node_fs56.existsSync)(verityDir)) return true;
28215
- if ((0, import_node_fs56.existsSync)(gateDir) && (0, import_node_fs56.existsSync)(verityDir)) {
28216
- if ((0, import_node_fs56.existsSync)((0, import_node_path39.join)(gateDir, "credentials")) && !(0, import_node_fs56.existsSync)((0, import_node_path39.join)(verityDir, "credentials"))) {
27723
+ const gateDir = (0, import_node_path38.join)(root, ".gate");
27724
+ const verityDir = (0, import_node_path38.join)(root, ".verity");
27725
+ if ((0, import_node_fs54.existsSync)(gateDir) && !(0, import_node_fs54.existsSync)(verityDir)) return true;
27726
+ if ((0, import_node_fs54.existsSync)(gateDir) && (0, import_node_fs54.existsSync)(verityDir)) {
27727
+ if ((0, import_node_fs54.existsSync)((0, import_node_path38.join)(gateDir, "credentials")) && !(0, import_node_fs54.existsSync)((0, import_node_path38.join)(verityDir, "credentials"))) {
28217
27728
  return true;
28218
27729
  }
28219
- if ((0, import_node_fs56.existsSync)((0, import_node_path39.join)(gateDir, "memory")) && !(0, import_node_fs56.existsSync)((0, import_node_path39.join)(verityDir, "memory"))) {
27730
+ if ((0, import_node_fs54.existsSync)((0, import_node_path38.join)(gateDir, "memory")) && !(0, import_node_fs54.existsSync)((0, import_node_path38.join)(verityDir, "memory"))) {
28220
27731
  return true;
28221
27732
  }
28222
27733
  }
28223
- const claudeMd = (0, import_node_path39.join)(root, "CLAUDE.md");
28224
- if ((0, import_node_fs56.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
27734
+ const claudeMd = (0, import_node_path38.join)(root, "CLAUDE.md");
27735
+ if ((0, import_node_fs54.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
28225
27736
  return true;
28226
27737
  }
28227
- if ((0, import_node_fs56.existsSync)((0, import_node_path39.join)(root, "GATE.md")) && !(0, import_node_fs56.existsSync)((0, import_node_path39.join)(root, "VERITY.md"))) {
27738
+ if ((0, import_node_fs54.existsSync)((0, import_node_path38.join)(root, "GATE.md")) && !(0, import_node_fs54.existsSync)((0, import_node_path38.join)(root, "VERITY.md"))) {
28228
27739
  return true;
28229
27740
  }
28230
27741
  if (await hasLegacyHooksAt(root)) return true;
@@ -28505,9 +28016,9 @@ async function promptMultiSelect(question, choices, fallback) {
28505
28016
  }
28506
28017
 
28507
28018
  // src/lib/remote-config.ts
28508
- var import_node_fs57 = require("node:fs");
28019
+ var import_node_fs55 = require("node:fs");
28509
28020
  var import_promises18 = require("node:fs/promises");
28510
- var import_node_path40 = require("node:path");
28021
+ var import_node_path39 = require("node:path");
28511
28022
  var import_yaml5 = __toESM(require_dist());
28512
28023
  var IGNORE_RIDER = "verityignore";
28513
28024
  async function fetchRemoteSetup(opts) {
@@ -28552,7 +28063,7 @@ async function adoptRemoteSetup(found, opts) {
28552
28063
  written.push(STANDARD_FILE);
28553
28064
  if (rider !== null) {
28554
28065
  const localIgnore = projectPath(VERITYIGNORE_FILE);
28555
- if (!(0, import_node_fs57.existsSync)(localIgnore)) {
28066
+ if (!(0, import_node_fs55.existsSync)(localIgnore)) {
28556
28067
  await writeOut(VERITYIGNORE_FILE, rider);
28557
28068
  written.push(VERITYIGNORE_FILE);
28558
28069
  } else {
@@ -28585,7 +28096,7 @@ async function adoptRemoteSetup(found, opts) {
28585
28096
  }
28586
28097
  async function writeOut(relative3, body) {
28587
28098
  const target = projectPath(relative3);
28588
- await (0, import_promises18.mkdir)((0, import_node_path40.dirname)(target), { recursive: true });
28099
+ await (0, import_promises18.mkdir)((0, import_node_path39.dirname)(target), { recursive: true });
28589
28100
  await (0, import_promises18.writeFile)(target, body);
28590
28101
  }
28591
28102
  function describeRemote(found) {
@@ -28702,15 +28213,15 @@ async function runOptionalAuth(resolution, opts = {}) {
28702
28213
  }
28703
28214
  function resolveDataDir2() {
28704
28215
  const candidates2 = [
28705
- (0, import_node_path41.join)(__dirname, "..", "data"),
28216
+ (0, import_node_path40.join)(__dirname, "..", "data"),
28706
28217
  // installed: node_modules/@codacy/verity-cli/data
28707
- (0, import_node_path41.join)(__dirname, "..", "..", "data"),
28218
+ (0, import_node_path40.join)(__dirname, "..", "..", "data"),
28708
28219
  // edge case: nested resolution
28709
- (0, import_node_path41.join)(process.cwd(), "cli", "data")
28220
+ (0, import_node_path40.join)(process.cwd(), "cli", "data")
28710
28221
  // local dev: running from repo root
28711
28222
  ];
28712
28223
  for (const candidate of candidates2) {
28713
- if ((0, import_node_fs58.existsSync)((0, import_node_path41.join)(candidate, "skills"))) {
28224
+ if ((0, import_node_fs56.existsSync)((0, import_node_path40.join)(candidate, "skills"))) {
28714
28225
  return candidate;
28715
28226
  }
28716
28227
  }
@@ -28726,9 +28237,9 @@ async function skillIsCurrent(src, dest) {
28726
28237
  const list2 = (dir) => {
28727
28238
  const out = [];
28728
28239
  const walk2 = (d, prefix) => {
28729
- for (const e of (0, import_node_fs58.readdirSync)(d, { withFileTypes: true })) {
28240
+ for (const e of (0, import_node_fs56.readdirSync)(d, { withFileTypes: true })) {
28730
28241
  const rel = prefix ? `${prefix}/${e.name}` : e.name;
28731
- if (e.isDirectory()) walk2((0, import_node_path41.join)(d, e.name), rel);
28242
+ if (e.isDirectory()) walk2((0, import_node_path40.join)(d, e.name), rel);
28732
28243
  else if (e.isFile()) out.push(rel);
28733
28244
  }
28734
28245
  };
@@ -28739,8 +28250,8 @@ async function skillIsCurrent(src, dest) {
28739
28250
  const shipped = list2(src);
28740
28251
  if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
28741
28252
  for (const rel of shipped) {
28742
- const a = await (0, import_promises19.readFile)((0, import_node_path41.join)(src, rel), "utf-8");
28743
- const b = await (0, import_promises19.readFile)((0, import_node_path41.join)(dest, rel), "utf-8");
28253
+ const a = await (0, import_promises19.readFile)((0, import_node_path40.join)(src, rel), "utf-8");
28254
+ const b = await (0, import_promises19.readFile)((0, import_node_path40.join)(dest, rel), "utf-8");
28744
28255
  if (a !== b) return false;
28745
28256
  }
28746
28257
  return true;
@@ -28921,7 +28432,7 @@ async function synthesizeLocally(opts) {
28921
28432
  async function healStaleAnalysisConfig(globals) {
28922
28433
  const configPath = projectPath(CODACY_CONFIG_FILE);
28923
28434
  const standardPath = projectPath(STANDARD_FILE);
28924
- if (!(0, import_node_fs58.existsSync)(configPath) || !(0, import_node_fs58.existsSync)(standardPath)) return;
28435
+ if (!(0, import_node_fs56.existsSync)(configPath) || !(0, import_node_fs56.existsSync)(standardPath)) return;
28925
28436
  const validation = validatePatternIds();
28926
28437
  if (validation.status !== "invalid") return;
28927
28438
  printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
@@ -29018,17 +28529,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
29018
28529
  async function installSkills(force, step) {
29019
28530
  step("Installing skills");
29020
28531
  const dataDir = resolveDataDir2();
29021
- const skillsSource = (0, import_node_path41.join)(dataDir, "skills");
28532
+ const skillsSource = (0, import_node_path40.join)(dataDir, "skills");
29022
28533
  const skillsDest = ".claude/skills";
29023
28534
  let skillsInstalled = 0;
29024
28535
  for (const skill of SKILLS) {
29025
- const src = (0, import_node_path41.join)(skillsSource, skill);
29026
- const dest = (0, import_node_path41.join)(skillsDest, skill);
29027
- if (!(0, import_node_fs58.existsSync)(src)) {
28536
+ const src = (0, import_node_path40.join)(skillsSource, skill);
28537
+ const dest = (0, import_node_path40.join)(skillsDest, skill);
28538
+ if (!(0, import_node_fs56.existsSync)(src)) {
29028
28539
  printWarn(` Skill data not found: ${skill}`);
29029
28540
  continue;
29030
28541
  }
29031
- if ((0, import_node_fs58.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
28542
+ if ((0, import_node_fs56.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
29032
28543
  skillsInstalled++;
29033
28544
  continue;
29034
28545
  }
@@ -29167,7 +28678,7 @@ function registerInitCommand(program2) {
29167
28678
  const staleMarker = clearStalePluginMarker();
29168
28679
  const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
29169
28680
  const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
29170
- const isProject = projectMarkers.some((m) => (0, import_node_fs58.existsSync)(m));
28681
+ const isProject = projectMarkers.some((m) => (0, import_node_fs56.existsSync)(m));
29171
28682
  if (!isProject) {
29172
28683
  printError("No project detected in the current directory.");
29173
28684
  printInfo('Run "verity init" from your project root.');
@@ -29257,7 +28768,7 @@ function registerInitCommand(program2) {
29257
28768
  printInfo(` intensity: ${intensity} \xB7 moments: ${moments.join(", ") || "none"} (no questions asked)`);
29258
28769
  }
29259
28770
  await scaffoldProject(step, defaultsOnly);
29260
- const globalVerityDir = (0, import_node_path41.join)(process.env.HOME ?? "", ".verity");
28771
+ const globalVerityDir = (0, import_node_path40.join)(process.env.HOME ?? "", ".verity");
29261
28772
  await (0, import_promises19.mkdir)(globalVerityDir, { recursive: true });
29262
28773
  console.log("");
29263
28774
  step("Wiring Claude Code hooks");
@@ -29326,7 +28837,7 @@ function registerInitCommand(program2) {
29326
28837
  }
29327
28838
  step("Your project's Standard");
29328
28839
  let haveStandard = false;
29329
- if ((0, import_node_fs58.existsSync)(projectPath(STANDARD_FILE))) {
28840
+ if ((0, import_node_fs56.existsSync)(projectPath(STANDARD_FILE))) {
29330
28841
  printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
29331
28842
  haveStandard = true;
29332
28843
  } else {
@@ -29356,7 +28867,7 @@ function registerInitCommand(program2) {
29356
28867
  ...telemetryChoice ? { telemetry: telemetryChoice } : {},
29357
28868
  init: {
29358
28869
  completed_at: (/* @__PURE__ */ new Date()).toISOString(),
29359
- cli_version: true ? "0.33.3-experimental.7124bbc" : "dev"
28870
+ cli_version: true ? "0.33.3-experimental.d8b96f8" : "dev"
29360
28871
  }
29361
28872
  });
29362
28873
  } catch (err) {
@@ -29406,8 +28917,8 @@ function registerInitCommand(program2) {
29406
28917
  }
29407
28918
 
29408
28919
  // src/commands/uninstall.ts
29409
- var import_node_fs59 = require("node:fs");
29410
- var import_node_path42 = require("node:path");
28920
+ var import_node_fs57 = require("node:fs");
28921
+ var import_node_path41 = require("node:path");
29411
28922
  function registerUninstallCommand(program2) {
29412
28923
  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) => {
29413
28924
  const dryRun = opts.dryRun ?? false;
@@ -29416,11 +28927,11 @@ function registerUninstallCommand(program2) {
29416
28927
  const actions = [];
29417
28928
  const skillsRoot = projectPath(".claude/skills");
29418
28929
  for (const name of PROJECT_SKILL_NAMES) {
29419
- const dir = (0, import_node_path42.join)(skillsRoot, name);
29420
- if ((0, import_node_fs59.existsSync)(dir)) {
28930
+ const dir = (0, import_node_path41.join)(skillsRoot, name);
28931
+ if ((0, import_node_fs57.existsSync)(dir)) {
29421
28932
  actions.push({
29422
28933
  label: `Remove .claude/skills/${name}/`,
29423
- apply: () => (0, import_node_fs59.rmSync)(dir, { recursive: true, force: true })
28934
+ apply: () => (0, import_node_fs57.rmSync)(dir, { recursive: true, force: true })
29424
28935
  });
29425
28936
  }
29426
28937
  }
@@ -29434,24 +28945,24 @@ function registerUninstallCommand(program2) {
29434
28945
  });
29435
28946
  }
29436
28947
  const verityDir = projectPath(VERITY_DIR);
29437
- if ((0, import_node_fs59.existsSync)(verityDir)) {
28948
+ if ((0, import_node_fs57.existsSync)(verityDir)) {
29438
28949
  actions.push({
29439
28950
  label: `Remove ${VERITY_DIR}/`,
29440
- apply: () => (0, import_node_fs59.rmSync)(verityDir, { recursive: true, force: true })
28951
+ apply: () => (0, import_node_fs57.rmSync)(verityDir, { recursive: true, force: true })
29441
28952
  });
29442
28953
  }
29443
28954
  if (!keepVerityMd) {
29444
28955
  const verityMd = projectPath(VERITY_MD_FILE);
29445
- if ((0, import_node_fs59.existsSync)(verityMd)) {
28956
+ if ((0, import_node_fs57.existsSync)(verityMd)) {
29446
28957
  actions.push({
29447
28958
  label: `Remove ${VERITY_MD_FILE}`,
29448
- apply: () => (0, import_node_fs59.rmSync)(verityMd, { force: true })
28959
+ apply: () => (0, import_node_fs57.rmSync)(verityMd, { force: true })
29449
28960
  });
29450
28961
  }
29451
28962
  }
29452
28963
  const cleanupEmptyDir = (path) => {
29453
- if ((0, import_node_fs59.existsSync)(path) && (0, import_node_fs59.statSync)(path).isDirectory() && (0, import_node_fs59.readdirSync)(path).length === 0) {
29454
- (0, import_node_fs59.rmdirSync)(path);
28964
+ if ((0, import_node_fs57.existsSync)(path) && (0, import_node_fs57.statSync)(path).isDirectory() && (0, import_node_fs57.readdirSync)(path).length === 0) {
28965
+ (0, import_node_fs57.rmdirSync)(path);
29455
28966
  }
29456
28967
  };
29457
28968
  actions.push({
@@ -29462,11 +28973,11 @@ function registerUninstallCommand(program2) {
29462
28973
  }
29463
28974
  });
29464
28975
  const home = process.env.HOME ?? "";
29465
- const globalVerityDir = (0, import_node_path42.join)(home, ".verity");
29466
- if (purgeGlobal && (0, import_node_fs59.existsSync)(globalVerityDir)) {
28976
+ const globalVerityDir = (0, import_node_path41.join)(home, ".verity");
28977
+ if (purgeGlobal && (0, import_node_fs57.existsSync)(globalVerityDir)) {
29467
28978
  actions.push({
29468
28979
  label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
29469
- apply: () => (0, import_node_fs59.rmSync)(globalVerityDir, { recursive: true, force: true })
28980
+ apply: () => (0, import_node_fs57.rmSync)(globalVerityDir, { recursive: true, force: true })
29470
28981
  });
29471
28982
  }
29472
28983
  if (actions.length === 0) {
@@ -29660,8 +29171,8 @@ function registerTaskCommands(program2) {
29660
29171
  }
29661
29172
 
29662
29173
  // src/commands/reset.ts
29663
- var import_node_fs60 = require("node:fs");
29664
- var import_node_path43 = require("node:path");
29174
+ var import_node_fs58 = require("node:fs");
29175
+ var import_node_path42 = require("node:path");
29665
29176
  function registerResetCommand(program2) {
29666
29177
  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) => {
29667
29178
  const globals = program2.opts();
@@ -29698,11 +29209,11 @@ function registerResetCommand(program2) {
29698
29209
  }
29699
29210
  const cacheDir = projectPath(CACHE_DIR);
29700
29211
  let purged = 0;
29701
- if ((0, import_node_fs60.existsSync)(cacheDir)) {
29702
- for (const entry of (0, import_node_fs60.readdirSync)(cacheDir)) {
29212
+ if ((0, import_node_fs58.existsSync)(cacheDir)) {
29213
+ for (const entry of (0, import_node_fs58.readdirSync)(cacheDir)) {
29703
29214
  if (entry.startsWith("pending-")) {
29704
29215
  try {
29705
- (0, import_node_fs60.unlinkSync)((0, import_node_path43.join)(cacheDir, entry));
29216
+ (0, import_node_fs58.unlinkSync)((0, import_node_path42.join)(cacheDir, entry));
29706
29217
  purged++;
29707
29218
  } catch {
29708
29219
  }
@@ -29717,19 +29228,19 @@ function registerResetCommand(program2) {
29717
29228
  projectPath(`${VERITY_DIR}/.last-analysis`)
29718
29229
  ];
29719
29230
  for (const file of filesToClear) {
29720
- if ((0, import_node_fs60.existsSync)(file)) {
29231
+ if ((0, import_node_fs58.existsSync)(file)) {
29721
29232
  try {
29722
- (0, import_node_fs60.writeFileSync)(file, "");
29233
+ (0, import_node_fs58.writeFileSync)(file, "");
29723
29234
  } catch {
29724
29235
  }
29725
29236
  }
29726
29237
  }
29727
29238
  if (opts.all) {
29728
29239
  const logsDir = projectPath(`${VERITY_DIR}/.logs`);
29729
- if ((0, import_node_fs60.existsSync)(logsDir)) {
29730
- for (const entry of (0, import_node_fs60.readdirSync)(logsDir)) {
29240
+ if ((0, import_node_fs58.existsSync)(logsDir)) {
29241
+ for (const entry of (0, import_node_fs58.readdirSync)(logsDir)) {
29731
29242
  try {
29732
- (0, import_node_fs60.unlinkSync)((0, import_node_path43.join)(logsDir, entry));
29243
+ (0, import_node_fs58.unlinkSync)((0, import_node_path42.join)(logsDir, entry));
29733
29244
  } catch {
29734
29245
  }
29735
29246
  }
@@ -29741,7 +29252,7 @@ function registerResetCommand(program2) {
29741
29252
  }
29742
29253
 
29743
29254
  // src/commands/reflect.ts
29744
- var import_node_fs61 = require("node:fs");
29255
+ var import_node_fs59 = require("node:fs");
29745
29256
 
29746
29257
  // src/lib/reflection-globs.ts
29747
29258
  var MAX_GLOBS = 6;
@@ -29779,7 +29290,7 @@ async function writeNodeToDisk(args) {
29779
29290
  { treePaths: listTrackedFiles(), recordBaseline: false }
29780
29291
  );
29781
29292
  if (written === 0) return false;
29782
- return (0, import_node_fs61.existsSync)(projectPath(`${VERITY_DIR}/memory/${args.filePath}`));
29293
+ return (0, import_node_fs59.existsSync)(projectPath(`${VERITY_DIR}/memory/${args.filePath}`));
29783
29294
  } catch {
29784
29295
  return false;
29785
29296
  }
@@ -30279,8 +29790,8 @@ function registerTelemetryCommands(program2) {
30279
29790
  }
30280
29791
 
30281
29792
  // src/cli.ts
30282
- program.name("verity").description("CLI for Verity quality gate service").version("0.33.3-experimental.7124bbc").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) => {
30283
- installStderrLog(actionCommand.name(), process.argv.slice(2), "0.33.3-experimental.7124bbc");
29793
+ program.name("verity").description("CLI for Verity quality gate service").version("0.33.3-experimental.d8b96f8").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) => {
29794
+ installStderrLog(actionCommand.name(), process.argv.slice(2), "0.33.3-experimental.d8b96f8");
30284
29795
  setUserNamedServiceUrl(program.opts().serviceUrl);
30285
29796
  try {
30286
29797
  await foldLegacyLocalCredential();